From d1096bf5a2df213f0f3e7ae898ed4faa76c8c457 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Thu, 19 Jan 2023 14:53:20 +0200 Subject: [PATCH 01/66] Added draft for typestate connection state machine Signed-off-by: Bogdan Mircea --- .../connection/mediated_connection.rs | 4 +- .../protocols/connection/initiation_type.rs | 6 + .../src/protocols/connection/invitee/mod.rs | 320 +++++++++++++++++- .../connection/invitee/state_machine.rs | 28 +- .../connection/invitee/states/complete.rs | 19 +- .../connection/invitee/states/initial.rs | 13 +- .../connection/invitee/states/invited.rs | 7 + .../connection/invitee/states/mod.rs | 10 +- .../connection/invitee/states/requested.rs | 36 +- .../connection/invitee/states/responded.rs | 9 +- .../src/protocols/connection/inviter/mod.rs | 270 +++++++++++++++ .../connection/inviter/state_machine.rs | 4 +- .../connection/inviter/states/complete.rs | 20 +- .../connection/inviter/states/invited.rs | 2 +- .../connection/inviter/states/requested.rs | 7 + .../connection/inviter/states/responded.rs | 7 + aries_vcx/src/protocols/connection/mod.rs | 109 ++++++ .../src/protocols/connection/trait_bounds.rs | 7 + ...Q6Ef6E2LQQb85jb8kATZPHTZwiKBsCC9PAPtr5kbQx | Bin 0 -> 642 bytes ...534m78fJiVNAj2q1qBxQPKjmNPhXYjrJyNXLsRP44M | Bin 0 -> 642 bytes ...kgu2n6Vu6kPygbNj8z5vxV722opVxnFx7waHRDUcKK | Bin 0 -> 642 bytes ...EM3wbxe1x4GoaX3xyyts6MSDs1ixyYmTQKkE4b7PQ1 | Bin 0 -> 642 bytes ...pMG1o8JK4tkcVyryFuJ73RZ4gShjwEjfNVGccRCckZ | Bin 0 -> 642 bytes ...PW4UTEAXfPJJkszuBkFxvEGNzEF9bp44WCpHcab5K1 | Bin 0 -> 642 bytes 24 files changed, 842 insertions(+), 36 deletions(-) create mode 100644 aries_vcx/src/protocols/connection/initiation_type.rs create mode 100644 aries_vcx/src/protocols/connection/trait_bounds.rs create mode 100644 aries_vcx/tails.txt/3KQ6Ef6E2LQQb85jb8kATZPHTZwiKBsCC9PAPtr5kbQx create mode 100644 aries_vcx/tails.txt/5b534m78fJiVNAj2q1qBxQPKjmNPhXYjrJyNXLsRP44M create mode 100644 aries_vcx/tails.txt/Azkgu2n6Vu6kPygbNj8z5vxV722opVxnFx7waHRDUcKK create mode 100644 aries_vcx/tails.txt/BpEM3wbxe1x4GoaX3xyyts6MSDs1ixyYmTQKkE4b7PQ1 create mode 100644 aries_vcx/tails.txt/HcpMG1o8JK4tkcVyryFuJ73RZ4gShjwEjfNVGccRCckZ create mode 100644 aries_vcx/tails.txt/HfPW4UTEAXfPJJkszuBkFxvEGNzEF9bp44WCpHcab5K1 diff --git a/aries_vcx/src/handlers/connection/mediated_connection.rs b/aries_vcx/src/handlers/connection/mediated_connection.rs index c5a6247891..08f6a6cccf 100644 --- a/aries_vcx/src/handlers/connection/mediated_connection.rs +++ b/aries_vcx/src/handlers/connection/mediated_connection.rs @@ -245,7 +245,7 @@ impl MediatedConnection { } } - pub fn get_remote_protocols(&self) -> Option> { + pub fn get_remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { match &self.connection_sm { SmConnection::Inviter(sm_inviter) => sm_inviter.get_remote_protocols(), SmConnection::Invitee(sm_invitee) => sm_invitee.get_remote_protocols(), @@ -898,7 +898,7 @@ impl MediatedConnection { recipient_keys: did_doc.recipient_keys()?, routing_keys: did_doc.routing_keys(), service_endpoint: did_doc.get_endpoint(), - protocols: self.get_remote_protocols(), + protocols: self.get_remote_protocols().map(ToOwned::to_owned), }), None => None, }; diff --git a/aries_vcx/src/protocols/connection/initiation_type.rs b/aries_vcx/src/protocols/connection/initiation_type.rs new file mode 100644 index 0000000000..597c16e747 --- /dev/null +++ b/aries_vcx/src/protocols/connection/initiation_type.rs @@ -0,0 +1,6 @@ + +/// Unit struct illustrating that the connection was initiated by an inviter. +pub struct Inviter; + +/// Unit struct illustrating that the connection was initiated by an invitee. +pub struct Invitee; \ No newline at end of file diff --git a/aries_vcx/src/protocols/connection/invitee/mod.rs b/aries_vcx/src/protocols/connection/invitee/mod.rs index 6b37a228b6..424496499a 100644 --- a/aries_vcx/src/protocols/connection/invitee/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/mod.rs @@ -1,2 +1,320 @@ pub mod state_machine; -mod states; +pub mod states; + +use messages::{ + diddoc::aries::diddoc::AriesDidDoc, + protocols::{ + connection::invite::Invitation, + discovery::disclose::{Disclose, ProtocolDescriptor}, + }, +}; + +use crate::errors::error::VcxResult; + +use self::states::{ + complete::CompleteState, initial::InitialState, invited::InvitedState, requested::RequestedState, + responded::RespondedState, +}; + +use std::{collections::HashMap, sync::Arc}; + +use messages::{ + a2a::A2AMessage, + concepts::ack::Ack, + protocols::connection::{problem_report::ProblemReport, request::Request, response::SignedResponse}, +}; + +use super::{initiation_type::Invitee, Connection}; +use crate::{ + common::signing::decode_signed_connection_response, + errors::error::{AriesVcxError, AriesVcxErrorKind}, + handlers::util::verify_thread_id, + plugins::wallet::base_wallet::BaseWallet, + protocols::{connection::pairwise_info::PairwiseInfo, SendClosureConnection}, +}; + +/// Convenience alias +pub type InviteeConnection = Connection; + +impl InviteeConnection { + pub fn new_invitee( + source_id: String, + pairwise_info: PairwiseInfo, + did_doc: AriesDidDoc, + transport_type: T, + ) -> InviteeConnection { + Connection { + source_id, + thread_id: String::new(), + state: InitialState::new(None, did_doc), + pairwise_info, + initiation_type: Invitee, + transport_type, + } + } +} + +impl InviteeConnection { + /// Tries to convert [`InviteeNonMediatedConnection`] to [`InviteeNonMediatedConnection`] + /// by handling a received invitation. + /// + /// # Errors + /// Will error out if the there's no thread ID in the [`Invitation`]. + pub fn handle_invitation(self, invitation: Invitation) -> VcxResult> { + let thread_id = invitation.get_id()?; + + let did_doc = self.state.did_doc; + let state = InvitedState { invitation, did_doc }; + + // Convert to `InvitedState` + Ok(Connection { + state, + thread_id, + source_id: self.source_id, + pairwise_info: self.pairwise_info, + initiation_type: Invitee, + transport_type: self.transport_type, + }) + } + + pub fn process_invite(self, invitation: Invitation) -> VcxResult> { + trace!("Connection::process_invite >>> invitation: {:?}", invitation); + self.handle_invitation(invitation) + } +} + +impl InviteeConnection { + pub fn get_invitation(&self) -> &Invitation { + &self.state.invitation + } + + fn build_connection_request_msg( + &self, + routing_keys: Vec, + service_endpoint: String, + ) -> VcxResult<(Request, String)> { + let recipient_keys = vec![self.pairwise_info.pw_vk.clone()]; + let request = Request::create() + .set_label(self.source_id.to_string()) + .set_did(self.pairwise_info.pw_did.to_string()) + .set_service_endpoint(service_endpoint) + .set_keys(recipient_keys, routing_keys) + .set_out_time(); + + let request_id = request.id.0.clone(); + + let (request, thread_id) = match &self.state.invitation { + Invitation::Public(_) => ( + request + .set_parent_thread_id(&self.thread_id) + .set_thread_id_matching_id(), + request_id, + ), + Invitation::Pairwise(_) => (request.set_thread_id(&self.thread_id), self.thread_id().to_owned()), + Invitation::OutOfBand(invite) => ( + request.set_parent_thread_id(&invite.id.0).set_thread_id_matching_id(), + request_id, + ), + }; + Ok((request, thread_id)) + } + + /// Tries to convert [`SmConnectionInvitee2`] to [`SmConnectionInvitee2`] + /// by sending a connection request. + /// + /// # Errors + /// Will error out if building or sending the connection request message fails. + pub async fn send_connection_request( + self, + routing_keys: Vec, + service_endpoint: String, + send_message: SendClosureConnection, + ) -> VcxResult> { + let (request, thread_id) = self.build_connection_request_msg(routing_keys, service_endpoint)?; + let did_doc = self.state.did_doc; + + send_message( + request.to_a2a_message(), + self.pairwise_info.pw_vk.clone(), + did_doc.clone(), + ) + .await?; + + let state = RequestedState { request, did_doc }; + + Ok(Connection { + state, + thread_id, + source_id: self.source_id, + pairwise_info: self.pairwise_info, + initiation_type: Invitee, + transport_type: self.transport_type, + }) + } + + pub fn handle_problem_report(self, problem_report: ProblemReport) -> VcxResult> { + let Self { + source_id, + thread_id, + pairwise_info, + transport_type, + state, + .. + } = self; + + let state = InitialState::new(Some(problem_report), state.did_doc); + + Ok(Connection { + state, + source_id, + thread_id, + pairwise_info, + initiation_type: Invitee, + transport_type, + }) + } +} + +impl InviteeConnection { + /// Returns the first entry from the map for which the message indicates a progressable state. + pub fn find_message_to_update_state(&self, messages: HashMap) -> Option<(String, A2AMessage)> { + messages + .into_iter() + .find(|(_, message)| Self::can_progress_state(message)) + } + + /// Determines whether the message indicates a progressable state. + pub fn can_progress_state(message: &A2AMessage) -> bool { + matches!( + message, + A2AMessage::ConnectionResponse(_) | A2AMessage::ConnectionProblemReport(_) + ) + } + + /// Tries to convert [`SmConnectionInvitee2`] to [`SmConnectionInvitee2`] + /// by handling a connection response. + /// + /// # Errors + /// Will error out if the thread ID verification fails, there are no keys in the DidDoc + /// or decoding the response fails. + // + // TODO: Why only convert the state to `InitialState` if the decoding fails? + // Why not on any other errors? + pub async fn handle_connection_response( + self, + wallet: &Arc, + response: SignedResponse, + _send_message: SendClosureConnection, + ) -> VcxResult> { + verify_thread_id(self.thread_id(), &A2AMessage::ConnectionResponse(response.clone()))?; + + let remote_vk: String = + self.state + .did_doc + .recipient_keys()? + .first() + .cloned() + .ok_or(AriesVcxError::from_msg( + AriesVcxErrorKind::InvalidState, + "Cannot handle response: remote verkey not found", + ))?; + + let Self { + source_id, + thread_id, + pairwise_info, + state, + transport_type, + .. + } = self; + + let state = decode_signed_connection_response(wallet, response.clone(), &remote_vk) + .await + .and_then(|response| state.try_into_responded(response))?; + + Ok(Connection { + state, + source_id, + thread_id, + pairwise_info, + initiation_type: Invitee, + transport_type, + }) + } + + pub fn handle_problem_report(self, problem_report: ProblemReport) -> VcxResult> { + let Self { + source_id, + thread_id, + pairwise_info, + transport_type, + state, + .. + } = self; + + let state = InitialState::new(Some(problem_report), state.did_doc); + + Ok(Connection { + state, + source_id, + thread_id, + pairwise_info, + initiation_type: Invitee, + transport_type, + }) + } +} + +impl InviteeConnection { + fn build_connection_ack_msg(&self) -> Ack { + Ack::create().set_out_time().set_thread_id(&self.thread_id) + } + + pub async fn handle_send_ack( + self, + send_message: SendClosureConnection, + ) -> VcxResult> { + let sender_vk = self.pairwise_info().pw_vk.clone(); + let did_doc = self.state.response.connection.did_doc.clone(); + + send_message(self.build_connection_ack_msg().to_a2a_message(), sender_vk, did_doc).await?; + + let Self { + source_id, + thread_id, + pairwise_info, + state, + transport_type, + .. + } = self; + + let state = CompleteState { + did_doc: state.did_doc, + bootstrap_did_doc: state.response.connection.did_doc, + protocols: None, + }; + + Ok(Connection { + state, + source_id, + thread_id, + pairwise_info, + initiation_type: Invitee, + transport_type, + }) + } +} + +impl InviteeConnection { + pub fn bootstrap_did_doc(&self) -> &AriesDidDoc { + &self.state.bootstrap_did_doc + } + + pub fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { + self.state.remote_protocols() + } + + pub fn handle_disclose(&mut self, disclose: Disclose) { + self.state.handle_disclose(disclose) + } +} diff --git a/aries_vcx/src/protocols/connection/invitee/state_machine.rs b/aries_vcx/src/protocols/connection/invitee/state_machine.rs index 2fc959b035..18fe9f4a2a 100644 --- a/aries_vcx/src/protocols/connection/invitee/state_machine.rs +++ b/aries_vcx/src/protocols/connection/invitee/state_machine.rs @@ -72,7 +72,7 @@ impl SmConnectionInvitee { SmConnectionInvitee { source_id: source_id.to_string(), thread_id: String::new(), - state: InviteeFullState::Initial(InitialState::new(None, Some(did_doc))), + state: InviteeFullState::Initial(InitialState::new(None, did_doc)), pairwise_info, } } @@ -112,7 +112,7 @@ impl SmConnectionInvitee { pub fn their_did_doc(&self) -> Option { match self.state { - InviteeFullState::Initial(ref state) => state.did_doc.clone(), + InviteeFullState::Initial(ref state) => Some(state.did_doc.clone()), InviteeFullState::Invited(ref state) => Some(state.did_doc.clone()), InviteeFullState::Requested(ref state) => Some(state.did_doc.clone()), InviteeFullState::Responded(ref state) => Some(state.did_doc.clone()), @@ -122,7 +122,7 @@ impl SmConnectionInvitee { pub async fn bootstrap_did_doc(&self) -> Option { match self.state { - InviteeFullState::Initial(ref state) => state.did_doc.clone(), + InviteeFullState::Initial(ref state) => Some(state.did_doc.clone()), InviteeFullState::Invited(ref state) => Some(state.did_doc.clone()), InviteeFullState::Requested(ref state) => Some(state.did_doc.clone()), InviteeFullState::Responded(ref state) => Some(state.did_doc.clone()), @@ -150,9 +150,9 @@ impl SmConnectionInvitee { ProtocolRegistry::init().protocols() } - pub fn get_remote_protocols(&self) -> Option> { + pub fn get_remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { match self.state { - InviteeFullState::Completed(ref state) => state.protocols.clone(), + InviteeFullState::Completed(ref state) => state.remote_protocols(), _ => None, } } @@ -242,17 +242,9 @@ impl SmConnectionInvitee { let Self { state, .. } = self; let thread_id = invitation.get_id()?; let state = match state { - InviteeFullState::Initial(state) => InviteeFullState::Invited( - ( - state.clone(), - invitation, - state.did_doc.ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidState, - "Expected none None state.did_doc result given current state", - ))?, - ) - .into(), - ), + InviteeFullState::Initial(state) => { + InviteeFullState::Invited((state.clone(), invitation, state.did_doc).into()) + } s => { return Err(AriesVcxError::from_msg( AriesVcxErrorKind::InvalidState, @@ -373,8 +365,8 @@ impl SmConnectionInvitee { pub fn handle_problem_report(self, _problem_report: ProblemReport) -> VcxResult { let state = match self.state { - InviteeFullState::Requested(_state) => InviteeFullState::Initial(InitialState::new(None, None)), - InviteeFullState::Invited(_state) => InviteeFullState::Initial(InitialState::new(None, None)), + InviteeFullState::Requested(_state) => InviteeFullState::Initial(InitialState::new(None, _state.did_doc)), + InviteeFullState::Invited(_state) => InviteeFullState::Initial(InitialState::new(None, _state.did_doc)), _ => self.state.clone(), }; Ok(Self { state, ..self }) diff --git a/aries_vcx/src/protocols/connection/invitee/states/complete.rs b/aries_vcx/src/protocols/connection/invitee/states/complete.rs index fed457c333..bf4fa9d8f7 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/complete.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/complete.rs @@ -2,9 +2,10 @@ use std::clone::Clone; use crate::protocols::connection::invitee::states::requested::RequestedState; use crate::protocols::connection::invitee::states::responded::RespondedState; +use crate::protocols::connection::trait_bounds::{TheirDidDoc}; use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::connection::response::Response; -use messages::protocols::discovery::disclose::ProtocolDescriptor; +use messages::protocols::discovery::disclose::{ProtocolDescriptor, Disclose}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct CompleteState { @@ -13,6 +14,16 @@ pub struct CompleteState { pub protocols: Option>, } +impl CompleteState { + pub fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { + self.protocols.as_deref() + } + + pub fn handle_disclose(&mut self, disclose: Disclose) { + self.protocols = Some(disclose.protocols) + } +} + impl From<(CompleteState, Vec)> for CompleteState { fn from((state, protocols): (CompleteState, Vec)) -> CompleteState { trace!("ConnectionInvitee: transit state from CompleteState to CompleteState"); @@ -45,3 +56,9 @@ impl From for CompleteState { } } } + +impl TheirDidDoc for CompleteState { + fn their_did_doc(&self) -> &AriesDidDoc { + &self.did_doc + } +} \ No newline at end of file diff --git a/aries_vcx/src/protocols/connection/invitee/states/initial.rs b/aries_vcx/src/protocols/connection/invitee/states/initial.rs index 7522e6afc6..40da42a151 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/initial.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/initial.rs @@ -1,12 +1,13 @@ use crate::protocols::connection::invitee::states::invited::InvitedState; +use crate::protocols::connection::trait_bounds::TheirDidDoc; use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::connection::invite::Invitation; use messages::protocols::connection::problem_report::ProblemReport; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct InitialState { - problem_report: Option, - pub did_doc: Option, + pub problem_report: Option, + pub did_doc: AriesDidDoc, } impl From<(InitialState, Invitation, AriesDidDoc)> for InvitedState { @@ -17,10 +18,16 @@ impl From<(InitialState, Invitation, AriesDidDoc)> for InvitedState { } impl InitialState { - pub fn new(problem_report: Option, did_doc: Option) -> Self { + pub fn new(problem_report: Option, did_doc: AriesDidDoc) -> Self { InitialState { problem_report, did_doc, } } } + +impl TheirDidDoc for InitialState { + fn their_did_doc(&self) -> &AriesDidDoc { + &self.did_doc + } +} \ No newline at end of file diff --git a/aries_vcx/src/protocols/connection/invitee/states/invited.rs b/aries_vcx/src/protocols/connection/invitee/states/invited.rs index 622894b93e..9a4ee63abc 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/invited.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/invited.rs @@ -1,4 +1,5 @@ use crate::protocols::connection::invitee::states::requested::RequestedState; +use crate::protocols::connection::trait_bounds::TheirDidDoc; use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::connection::invite::Invitation; use messages::protocols::connection::request::Request; @@ -15,3 +16,9 @@ impl From<(InvitedState, Request, AriesDidDoc)> for RequestedState { RequestedState { request, did_doc } } } + +impl TheirDidDoc for InvitedState { + fn their_did_doc(&self) -> &AriesDidDoc { + &self.did_doc + } +} \ No newline at end of file diff --git a/aries_vcx/src/protocols/connection/invitee/states/mod.rs b/aries_vcx/src/protocols/connection/invitee/states/mod.rs index 2c1b5a715f..25dfdd5482 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/mod.rs @@ -1,5 +1,5 @@ -pub(super) mod complete; -pub(super) mod initial; -pub(super) mod invited; -pub(super) mod requested; -pub(super) mod responded; +pub mod complete; +pub mod initial; +pub mod invited; +pub mod requested; +pub mod responded; \ No newline at end of file diff --git a/aries_vcx/src/protocols/connection/invitee/states/requested.rs b/aries_vcx/src/protocols/connection/invitee/states/requested.rs index d56f47b9f2..17653136e5 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/requested.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/requested.rs @@ -1,5 +1,7 @@ +use crate::errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult}; use crate::protocols::connection::invitee::states::initial::InitialState; use crate::protocols::connection::invitee::states::responded::RespondedState; +use crate::protocols::connection::trait_bounds::TheirDidDoc; use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::connection::problem_report::ProblemReport; use messages::protocols::connection::request::Request; @@ -11,13 +13,39 @@ pub struct RequestedState { pub did_doc: AriesDidDoc, } +impl RequestedState { + /// Attempts to convert [`Self`] based on a [`Response`] into a [`RespondedState`]. + /// + /// # Errors + /// An error is returned if the response has an unexpected thread ID. + pub fn try_into_responded(self, response: Response) -> VcxResult { + if !response.from_thread(&self.request.get_thread_id()) { + let err_msg = format!( + "Cannot handle response: thread id does not match: {:?}", + response.thread + ); + + let err = AriesVcxError::from_msg(AriesVcxErrorKind::InvalidJson, err_msg); + + Err(err) + } else { + let state = RespondedState { + response, + request: self.request, + did_doc: self.did_doc, + }; + Ok(state) + } + } +} + impl From<(RequestedState, ProblemReport)> for InitialState { fn from((_state, problem_report): (RequestedState, ProblemReport)) -> InitialState { trace!( "ConnectionInvitee: transit state from RequestedState to InitialState, problem_report: {:?}", problem_report ); - InitialState::new(Some(problem_report), None) + InitialState::new(Some(problem_report), _state.did_doc) } } @@ -31,3 +59,9 @@ impl From<(RequestedState, Response)> for RespondedState { } } } + +impl TheirDidDoc for RequestedState { + fn their_did_doc(&self) -> &AriesDidDoc { + &self.did_doc + } +} diff --git a/aries_vcx/src/protocols/connection/invitee/states/responded.rs b/aries_vcx/src/protocols/connection/invitee/states/responded.rs index 9d3e2bc28a..f260c81f98 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/responded.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/responded.rs @@ -1,4 +1,5 @@ use crate::protocols::connection::invitee::states::initial::InitialState; +use crate::protocols::connection::trait_bounds::TheirDidDoc; use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::connection::problem_report::ProblemReport; use messages::protocols::connection::request::Request; @@ -17,6 +18,12 @@ impl From<(RespondedState, ProblemReport)> for InitialState { "ConnectionInvitee: transit state from RespondedState to InitialState, problem_report: {:?}", problem_report ); - InitialState::new(Some(problem_report), None) + InitialState::new(Some(problem_report), _state.did_doc) } } + +impl TheirDidDoc for RespondedState { + fn their_did_doc(&self) -> &AriesDidDoc { + &self.did_doc + } +} \ No newline at end of file diff --git a/aries_vcx/src/protocols/connection/inviter/mod.rs b/aries_vcx/src/protocols/connection/inviter/mod.rs index 6b37a228b6..e48c1b29d4 100644 --- a/aries_vcx/src/protocols/connection/inviter/mod.rs +++ b/aries_vcx/src/protocols/connection/inviter/mod.rs @@ -1,2 +1,272 @@ pub mod state_machine; mod states; + +use std::sync::Arc; + +use crate::handlers::util::verify_thread_id; +use crate::{ + common::signing::sign_connection_response, core::profile::profile::Profile, errors::error::VcxResult, + plugins::wallet::base_wallet::BaseWallet, protocols::SendClosureConnection, +}; + +use self::states::complete::CompleteState; +use self::states::initial::InitialState; +use self::states::{invited::InvitedState, requested::RequestedState, responded::RespondedState}; +use super::{initiation_type::Inviter, pairwise_info::PairwiseInfo, Connection}; +use messages::a2a::A2AMessage; +use messages::protocols::connection::invite::PairwiseInvitation; +use messages::protocols::connection::{ + invite::Invitation, + request::Request, + response::{Response, SignedResponse}, +}; +use messages::protocols::discovery::disclose::{ProtocolDescriptor, Disclose}; + +pub type InviterConnection = Connection; + +impl InviterConnection { + pub fn new_inviter( + source_id: String, + pairwise_info: PairwiseInfo, + transport_type: T, + ) -> InviterConnection { + Connection { + source_id, + thread_id: String::new(), + state: InitialState::new(None), + pairwise_info, + initiation_type: Inviter, + transport_type, + } + } +} + +impl InviterConnection { + pub fn create_invitation( + self, + routing_keys: Vec, + service_endpoint: String, + ) -> InviterConnection { + let invite: PairwiseInvitation = PairwiseInvitation::create() + .set_id(&self.thread_id) + .set_label(&self.source_id) + .set_recipient_keys(vec![self.pairwise_info.pw_vk.clone()]) + .set_routing_keys(routing_keys) + .set_service_endpoint(service_endpoint); + + let Self { + source_id, + thread_id, + pairwise_info, + initiation_type, + transport_type, + state, + } = self; + let state = (state, Invitation::Pairwise(invite)).into(); + + Connection { + source_id, + thread_id, + pairwise_info, + initiation_type, + transport_type, + state, + } + } + + pub async fn create_invite( + self, + service_endpoint: String, + routing_keys: Vec, + ) -> InviterConnection { + self.create_invitation(routing_keys, service_endpoint) + } +} + +impl InviterConnection { + pub fn get_invitation(&self) -> &Invitation { + &self.state.invitation + } + + async fn handle_connection_request( + self, + wallet: Arc, + request: Request, + new_pairwise_info: &PairwiseInfo, + new_routing_keys: Vec, + new_service_endpoint: String, + _send_message: SendClosureConnection, + ) -> VcxResult> { + verify_thread_id(self.thread_id(), &A2AMessage::ConnectionRequest(request.clone()))?; + request.connection.did_doc.validate()?; + + let signed_response = self + .build_response( + &wallet, + &request, + new_pairwise_info, + new_routing_keys, + new_service_endpoint, + ) + .await?; + + let state = RequestedState { + signed_response, + did_doc: request.connection.did_doc, + thread_id: request.id.0, + }; + + let Self { + source_id, + thread_id, + pairwise_info, + initiation_type, + transport_type, + .. + } = self; + + Ok(Connection { + source_id, + thread_id, + pairwise_info, + initiation_type, + transport_type, + state, + }) + } + + async fn build_response( + &self, + wallet: &Arc, + request: &Request, + new_pairwise_info: &PairwiseInfo, + new_routing_keys: Vec, + new_service_endpoint: String, + ) -> VcxResult { + let new_recipient_keys = vec![new_pairwise_info.pw_vk.clone()]; + sign_connection_response( + wallet, + &self.pairwise_info.clone().pw_vk, + Response::create() + .set_did(new_pairwise_info.pw_did.to_string()) + .set_service_endpoint(new_service_endpoint) + .set_keys(new_recipient_keys, new_routing_keys) + .ask_for_ack() + .set_thread_id(&request.get_thread_id()) + .set_out_time(), + ) + .await + } + + pub async fn process_request( + self, + profile: &Arc, + request: Request, + service_endpoint: String, + routing_keys: Vec, + send_message: Option, + ) -> VcxResult> { + trace!( + "Connection::process_request >>> request: {:?}, service_endpoint: {}, routing_keys: {:?}", + request, + service_endpoint, + routing_keys, + ); + + let send_message = send_message.unwrap_or(self.send_message_closure_connection(profile)); + let new_pairwise_info = PairwiseInfo::create(&profile.inject_wallet()).await?; + + self.handle_connection_request( + profile.inject_wallet(), + request, + &new_pairwise_info, + routing_keys, + service_endpoint, + send_message, + ) + .await + } +} + +impl InviterConnection { + pub async fn handle_send_response( + self, + send_message: SendClosureConnection, + ) -> VcxResult> { + send_message( + self.state.signed_response.to_a2a_message(), + self.pairwise_info.pw_vk.clone(), + self.state.did_doc.clone(), + ) + .await?; + + let Self { + source_id, + thread_id, + pairwise_info, + initiation_type, + transport_type, + state, + } = self; + + Ok(Connection { + state: state.into(), + source_id, + thread_id, + pairwise_info, + initiation_type, + transport_type, + }) + } + + pub async fn send_response( + self, + profile: &Arc, + send_message: Option, + ) -> VcxResult> { + trace!("Connection::send_response >>>"); + let send_message = send_message.unwrap_or(self.send_message_closure_connection(profile)); + self.handle_send_response(send_message).await + } +} + +impl InviterConnection { + pub fn handle_confirmation_message(self, msg: &A2AMessage) -> VcxResult> { + verify_thread_id(self.thread_id(), msg)?; + + let Self { + source_id, + thread_id, + pairwise_info, + initiation_type, + transport_type, + state, + } = self; + + let state = state.into(); + + Ok(Connection { + source_id, + thread_id, + pairwise_info, + initiation_type, + transport_type, + state, + }) + } + + pub fn process_ack(self, message: &A2AMessage) -> VcxResult> { + self.handle_confirmation_message(message) + } +} + + +impl InviterConnection< T, CompleteState> { + pub fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { + self.state.remote_protocols() + } + + pub fn handle_disclose(&mut self, disclose: Disclose) { + self.state.handle_disclose(disclose) + } +} \ No newline at end of file diff --git a/aries_vcx/src/protocols/connection/inviter/state_machine.rs b/aries_vcx/src/protocols/connection/inviter/state_machine.rs index 89fe3e6d64..794213adad 100644 --- a/aries_vcx/src/protocols/connection/inviter/state_machine.rs +++ b/aries_vcx/src/protocols/connection/inviter/state_machine.rs @@ -132,9 +132,9 @@ impl SmConnectionInviter { ProtocolRegistry::init().protocols() } - pub fn get_remote_protocols(&self) -> Option> { + pub fn get_remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { match self.state { - InviterFullState::Completed(ref state) => state.protocols.clone(), + InviterFullState::Completed(ref state) => state.remote_protocols(), _ => None, } } diff --git a/aries_vcx/src/protocols/connection/inviter/states/complete.rs b/aries_vcx/src/protocols/connection/inviter/states/complete.rs index 5678f3f719..068a84c9ed 100644 --- a/aries_vcx/src/protocols/connection/inviter/states/complete.rs +++ b/aries_vcx/src/protocols/connection/inviter/states/complete.rs @@ -1,7 +1,9 @@ use std::clone::Clone; use messages::diddoc::aries::diddoc::AriesDidDoc; -use messages::protocols::discovery::disclose::ProtocolDescriptor; +use messages::protocols::discovery::disclose::{Disclose, ProtocolDescriptor}; + +use crate::protocols::connection::trait_bounds::TheirDidDoc; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct CompleteState { @@ -10,6 +12,16 @@ pub struct CompleteState { pub thread_id: Option, } +impl CompleteState { + pub fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { + self.protocols.as_deref() + } + + pub fn handle_disclose(&mut self, disclose: Disclose) { + self.protocols = Some(disclose.protocols) + } +} + impl From<(CompleteState, Vec)> for CompleteState { fn from((state, protocols): (CompleteState, Vec)) -> CompleteState { trace!("ConnectionInviter: transit state from CompleteState to CompleteState"); @@ -20,3 +32,9 @@ impl From<(CompleteState, Vec)> for CompleteState { } } } + +impl TheirDidDoc for CompleteState { + fn their_did_doc(&self) -> &AriesDidDoc { + &self.did_doc + } +} diff --git a/aries_vcx/src/protocols/connection/inviter/states/invited.rs b/aries_vcx/src/protocols/connection/inviter/states/invited.rs index 409f0d4269..9a7ed01157 100644 --- a/aries_vcx/src/protocols/connection/inviter/states/invited.rs +++ b/aries_vcx/src/protocols/connection/inviter/states/invited.rs @@ -30,4 +30,4 @@ impl From<(Request, SignedResponse)> for RequestedState { thread_id: request.id.0, } } -} +} \ No newline at end of file diff --git a/aries_vcx/src/protocols/connection/inviter/states/requested.rs b/aries_vcx/src/protocols/connection/inviter/states/requested.rs index 11772b957e..fd3c2545f1 100644 --- a/aries_vcx/src/protocols/connection/inviter/states/requested.rs +++ b/aries_vcx/src/protocols/connection/inviter/states/requested.rs @@ -1,5 +1,6 @@ use crate::protocols::connection::inviter::states::initial::InitialState; use crate::protocols::connection::inviter::states::responded::RespondedState; +use crate::protocols::connection::trait_bounds::TheirDidDoc; use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::connection::problem_report::ProblemReport; use messages::protocols::connection::response::SignedResponse; @@ -30,3 +31,9 @@ impl From for RespondedState { } } } + +impl TheirDidDoc for RequestedState { + fn their_did_doc(&self) -> &AriesDidDoc { + &self.did_doc + } +} \ No newline at end of file diff --git a/aries_vcx/src/protocols/connection/inviter/states/responded.rs b/aries_vcx/src/protocols/connection/inviter/states/responded.rs index 397eb3110d..7ab111889b 100644 --- a/aries_vcx/src/protocols/connection/inviter/states/responded.rs +++ b/aries_vcx/src/protocols/connection/inviter/states/responded.rs @@ -7,6 +7,7 @@ use messages::protocols::connection::response::SignedResponse; use crate::protocols::connection::inviter::states::complete::CompleteState; use crate::protocols::connection::inviter::states::initial::InitialState; +use crate::protocols::connection::trait_bounds::TheirDidDoc; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct RespondedState { @@ -34,3 +35,9 @@ impl From for CompleteState { } } } + +impl TheirDidDoc for RespondedState { + fn their_did_doc(&self) -> &AriesDidDoc { + &self.did_doc + } +} diff --git a/aries_vcx/src/protocols/connection/mod.rs b/aries_vcx/src/protocols/connection/mod.rs index 83222afec8..48c7c890b9 100644 --- a/aries_vcx/src/protocols/connection/mod.rs +++ b/aries_vcx/src/protocols/connection/mod.rs @@ -1,3 +1,112 @@ +pub mod initiation_type; pub mod invitee; pub mod inviter; pub mod pairwise_info; +mod trait_bounds; + +use messages::{ + a2a::{protocol_registry::ProtocolRegistry, A2AMessage}, + diddoc::aries::diddoc::AriesDidDoc, + protocols::discovery::disclose::ProtocolDescriptor, +}; +use std::sync::Arc; + +use crate::{ + core::profile::profile::Profile, + errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult}, + utils::send_message, +}; + +use self::{pairwise_info::PairwiseInfo, trait_bounds::TheirDidDoc}; + +use super::{SendClosure, SendClosureConnection}; + +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +struct SideConnectionInfo { + did: String, + recipient_keys: Vec, + routing_keys: Vec, + service_endpoint: String, + #[serde(skip_serializing_if = "Option::is_none")] + protocols: Option>, +} + +#[derive(Debug, Serialize)] +struct ConnectionInfo { + my: SideConnectionInfo, + their: Option, +} + +pub struct Connection { + source_id: String, + thread_id: String, + pairwise_info: PairwiseInfo, + initiation_type: I, + transport_type: T, + state: S, +} + +impl Connection { + pub fn pairwise_info(&self) -> &PairwiseInfo { + &self.pairwise_info + } + + pub fn source_id(&self) -> &str { + &self.source_id + } + + pub fn thread_id(&self) -> &str { + &self.thread_id + } + + pub fn protocols(&self) -> Vec { + ProtocolRegistry::init().protocols() + } + + fn send_message_closure_connection(&self, profile: &Arc) -> SendClosureConnection { + trace!("send_message_closure_connection >>>"); + let wallet = profile.inject_wallet(); + Box::new(move |message: A2AMessage, sender_vk: String, did_doc: AriesDidDoc| { + Box::pin(send_message(wallet, sender_vk, did_doc, message)) + }) + } +} + +impl Connection +where + S: TheirDidDoc, +{ + pub fn their_did_doc(&self) -> &AriesDidDoc { + self.state.their_did_doc() + } + + pub fn remote_did(&self) -> &str { + &self.their_did_doc().id + } + + pub fn remote_vk(&self) -> VcxResult { + self.their_did_doc() + .recipient_keys()? + .first() + .map(ToOwned::to_owned) + .ok_or(AriesVcxError::from_msg( + AriesVcxErrorKind::NotReady, + "Can't resolve recipient key from the counterparty diddoc.", + )) + } + + pub async fn send_message_closure( + &self, + profile: &Arc, + send_message: Option, + ) -> VcxResult { + trace!("send_message_closure >>>"); + let did_doc = self.their_did_doc().clone(); + let sender_vk = self.pairwise_info().pw_vk.clone(); + let send_message = send_message.unwrap_or(self.send_message_closure_connection(profile)); + Ok(Box::new(move |message: A2AMessage| { + Box::pin(send_message(message, sender_vk, did_doc)) + })) + } +} diff --git a/aries_vcx/src/protocols/connection/trait_bounds.rs b/aries_vcx/src/protocols/connection/trait_bounds.rs new file mode 100644 index 0000000000..48cf8db3ca --- /dev/null +++ b/aries_vcx/src/protocols/connection/trait_bounds.rs @@ -0,0 +1,7 @@ +use messages::diddoc::aries::diddoc::AriesDidDoc; + +/// Trait used for implementing common [`super::Connection`] behavior based +/// on states implementing it. +pub trait TheirDidDoc { + fn their_did_doc(&self) -> &AriesDidDoc; +} \ No newline at end of file diff --git a/aries_vcx/tails.txt/3KQ6Ef6E2LQQb85jb8kATZPHTZwiKBsCC9PAPtr5kbQx b/aries_vcx/tails.txt/3KQ6Ef6E2LQQb85jb8kATZPHTZwiKBsCC9PAPtr5kbQx new file mode 100644 index 0000000000000000000000000000000000000000..fc8be8192083b1835ed8bda13510c70ee647fba8 GIT binary patch literal 642 zcmV-|0)71e0tSUxTmdI~jrsCCgpArkKExM&r9nm*xpC)w+Aw=lLkB)Gf%C(tl&GDe zv#Cq%zfV|HKS2T86N?}9YC}OE(hWKnnqCf`W20Wx;S6>cn`9h4gL@vdVbvz!_G2W9 zrx$QKbbo?+pC|w($$>EQ*CHnN%^6 zc_qFm>B&kpR!kt7 zLspa<_uVw5oB^PJ@7&&({-tGI ztUzfA=m?qL459hQJHoHd@1ZD4HYzA@?Dh&!Lg8Yy=B;o9+TrV41Vg~W788+vivjS><_l$ zD23(8vP*57YYWLV8ILG#6gXF>uU!=whr3pgAxYRJS@-JYQtUfUoRSpt6kY7B3H<^3lCTJVjs)DZ89Cg cr*(tSDN?M8c;+p$hAL%J;ZwIypWnE(I) literal 0 HcmV?d00001 diff --git a/aries_vcx/tails.txt/5b534m78fJiVNAj2q1qBxQPKjmNPhXYjrJyNXLsRP44M b/aries_vcx/tails.txt/5b534m78fJiVNAj2q1qBxQPKjmNPhXYjrJyNXLsRP44M new file mode 100644 index 0000000000000000000000000000000000000000..f579ee4b69173fcef4c4d6b43f7f06359f0b51d5 GIT binary patch literal 642 zcmV-|0)71e0tM)I#t=+vs9~3sYYQd8fN%I$6EDY_*MC<|Zp(MU5*3q-V z*qHGBN6^IlLyxDFs>;;UO?&Dw6dVatF-vrOOnSD$n4}?U!;uITL1l|5_lYa4R;$2% zQ53nCWD^qE#Fa54Xsa*TDqo_9kc}iLeC!!?uR113%>w(4wTiM4DO3W}3C1)yIxngH ze2D=HlVEj5ra?=Zwi^VV3DZpn=XO2UyJ`|WrtlUQG36n!Eh&bd_eAJN!6eDFe7G#B zVzL1`D#C3+Azy8-P`8L(C|GA;3mm*VP7&RGqc5xO_8ec;YM(rHT}U5==^;$QG*DAy zh9F*RmI60@Szgi4C4FA4Ox48b{H1aX5ybH?BfMn8uTgFvh#{0VhNqwDBF=!5QSR*M zera9p1P}Qvg`$hUlGx)XZD*d5A$VURqmhZ9w7So0?WZ%&= ziL;}#V3aDe&KxZu8SbD_2|S?>ipIjRyPszM7C=m&ii00;jHOKy5`$3 zTPSafuTJ3h3H6{%h_Bc|HEtytK?kC7%TzD~Hh`Xj%?hHyujO$B4GB#lG6nIPkHE1O zYXFQ$C*J>ktW&=#mqaJ`wpZWd(u52WLUnAKdRht(Zy!WEEzF c>TVYZ6q;m2F*CN+V#g#u&EhZNW%DF30TBx>^8f$< literal 0 HcmV?d00001 diff --git a/aries_vcx/tails.txt/Azkgu2n6Vu6kPygbNj8z5vxV722opVxnFx7waHRDUcKK b/aries_vcx/tails.txt/Azkgu2n6Vu6kPygbNj8z5vxV722opVxnFx7waHRDUcKK new file mode 100644 index 0000000000000000000000000000000000000000..2f4ab85243e34ba5a9a860d29728fde4577a8541 GIT binary patch literal 642 zcmV-|0)71e0t}29{bb^pkV$dXM&qqR*CMwL%;VrRtoAIiVdwd%76}jiLnZ1OBStnb z*3UXz*r8fW{GSKtTbBi>kX_yg|3ZHHSC$CVj)(G>{nTlIlW3SKeg#T{Y>@0>@VhS{Lv+&FZ4Jwd^? z53A^x@TE-doDB=ds0mk@c`=|aQKt(S!dk0MCyyd8Pawvu!lNO1rdXm@M;!#!|KpMs zN2B(ozO6mU{(<46>B-^z`rFe4m-;@0jRt89S3M(c%!;a3md<*52E07!rs+{7`l8yZ z*9YJf$_N4{I!F@}B&Uq|rP0}BJ5$=GBjJZ-+58V|^+-VFgauUMN^D!r&)45k?INff z>1nFo7nQ>lSmq{F@tjQ=yA_hvqdz~$-E&a~&oS`T^kJB2;n*#VE(`O^{9H*rr6J5P zNgAK3EG%9l0SsnmUe$qmo}8mESWb{V*fxo*h8-Afx$uv@^WtLqm~Bn1UNS*2|jtf&hw zxWuCZ#@yV306`@Oi@E+LHs^dhHwWLehB|cEa@3&!uT3fk`d<@}=@{4g16opCP*m;& zr4G;}i0rr>duuc4-*b|mVr(aVT9CX7(td!#Fo%>xJ|X-@ct5*zI5~aXffKzoIqzxi zV=0Pz+WC^oOnJevff_6TD5ue!FdTu9b#jrWsBRWAwcuRKff6q0d}Qvt>L4a5+3)-$ cI!b1PiP3sYxUBEqqL)1w^K|!z)c}*tdEg^Ct^fc4 literal 0 HcmV?d00001 diff --git a/aries_vcx/tails.txt/BpEM3wbxe1x4GoaX3xyyts6MSDs1ixyYmTQKkE4b7PQ1 b/aries_vcx/tails.txt/BpEM3wbxe1x4GoaX3xyyts6MSDs1ixyYmTQKkE4b7PQ1 new file mode 100644 index 0000000000000000000000000000000000000000..7cd79962d326a5a16e3fd30cc3f043b4d7364293 GIT binary patch literal 642 zcmV-|0)71e0v3bzQ|55Kx9t1)gd8YCS-r&}IW!QRX)szh00o%vG6H>=Dn6FAY%Z6q z8IlT1)qfgJ)f~wO;&R5rm}|m|O$CFNxC#{lKQM#(hwm)c6OM;Jh%u&?6lIVlVSYML z=mjy4f+5)4U5|eT6k5o2`_Uc~^&vH?0&aL;Nhu1Q1S9l>LX`|ek#79kzIU~^_m637 zt4ixJvS^#Ju_9TYHyMOU6VD;uoc3JnI;NPSKVyTmX21^|y|GN7KW6PmlOZNe!jM!h zzut98Ye;6yAv=XL0UhPLQ7yIc;u-wNWd)n%*GKD`i^)Y|>)SgNs>-%h9P*hbc^tqjwS95K;4b?B0@-l#2&b z3R9Z`h4=djP!+53hBYK*zHZ2^GptMJ4X{PmV|?(N3TU`oU)qEBI3(Shj}VT8ee{>K zXbwL1RC^jerqZ0v_zYa;G6NhgrXdKpp31}a>8cp=q)j}Mzo*`n#E`i%TZe&5*Cx{6 zR~bUT4zE^0pw{Uyuka&{5>DkrLJL7jG9*$1?ME4rh8YWdsq|I(FI`bkcmiDyZ|dfe zYYzF$Z}3OQk;VieW*sa~dI|DXEBOwR0f;dz9>_csG3qT#NtM_955k5+&>ff0$guNK c3C*E^LFUQA>vpVb#x{j^OT;X3y8uen36(G{8~^|S literal 0 HcmV?d00001 diff --git a/aries_vcx/tails.txt/HcpMG1o8JK4tkcVyryFuJ73RZ4gShjwEjfNVGccRCckZ b/aries_vcx/tails.txt/HcpMG1o8JK4tkcVyryFuJ73RZ4gShjwEjfNVGccRCckZ new file mode 100644 index 0000000000000000000000000000000000000000..ad8392d01b6729841e90175776e0fa6baaab7d40 GIT binary patch literal 642 zcmV-|0)71e0vvplos)83T9ct$&MiK;3EB_-*y@c8h6n~F9*drPK<=5zu8%8SQKRVW<@fT-`wKPqw zQUb(bF|`X!I>BH=ahoND()*1xvlN`rQy&d(%*C#NyCw!}NHqTY;LS0;sQ)^@QAGK! zRaV%G&lpzn+xU|{QjZvEtXL+-MDdh?Sw`Q^05Q|^1;OG!4jluiL+Ls}KZMF(frZqw zePPxWXzOG+{;||)nduQ7-Up#FMl%NtSRpgNikt|VU{1-f;84l7J?rsNWZ)*`Js&)z z382$|V>hZM(-T{qQ8KH~c%s8EK z5K#d?JgZvL_6;7bKtH{7H{cqP7%V|Jn4xuZ(Sm5>7eccChs)$Oz?Z+;v>G4%Y!cwnO0^pQWe{RE@KSt z%T=FpTMmXkcVHy0Iv0c|%B%mEOk0pUt-iSuG2~Qxu}kHyxhf5Jk3I)j0lV-BcXxe zgp*%7L8Vp?nHv7F2Q3`vGqE;e0|ShPf8;QX;GprB@vd*bJtsU&66c1Qd4;$={*Rz&#tI1GXw=8+h z^e1tugm9=*{IE^g6G!Z!aTA*{+<^`NaKw_j_7-G_%hv45^ti9(g22^IRWv? zP%A<^3fwU0zIw(esS~!kt&uH03|r3?$`JT(Ko+!J=B*6y`Dyt3H&)mxXD8Y=DP*mr zFD`wmb(FKt;tG9F)uX;StTHkmg1lFq3=xL+xksi!8ZCTdk%@w^8x*AY{f0)!@kpO# ze3UMDpEv|BfJcj*7l11gzD-i z!~j!mt; ceHKYPk%Tt{-$awP4B%sMhfBWKnCS^E+7@0kB>(^b literal 0 HcmV?d00001 From d76bf5e6e0e8a8c3b7df4c1e235e97a5b22dbb07 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Tue, 24 Jan 2023 15:24:38 +0200 Subject: [PATCH 02/66] Added dummy, not functional tests, as a mere representation of the transitions between states for the typestate Connection Signed-off-by: Bogdan Mircea --- .../src/protocols/connection/invitee/mod.rs | 15 +++++++- .../src/protocols/connection/inviter/mod.rs | 2 +- aries_vcx/src/protocols/connection/mod.rs | 36 +++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/aries_vcx/src/protocols/connection/invitee/mod.rs b/aries_vcx/src/protocols/connection/invitee/mod.rs index 424496499a..55b95a85f0 100644 --- a/aries_vcx/src/protocols/connection/invitee/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/mod.rs @@ -9,7 +9,7 @@ use messages::{ }, }; -use crate::errors::error::VcxResult; +use crate::{core::profile::profile::Profile, errors::error::VcxResult}; use self::states::{ complete::CompleteState, initial::InitialState, invited::InvitedState, requested::RequestedState, @@ -173,6 +173,19 @@ impl InviteeConnection { transport_type, }) } + + pub async fn send_request( + self, + profile: &Arc, + service_endpoint: String, + routing_keys: Vec, + send_message: Option, + ) -> VcxResult> { + trace!("Connection::send_request"); + let send_message = send_message.unwrap_or(self.send_message_closure_connection(profile)); + self.send_connection_request(routing_keys, service_endpoint, send_message) + .await + } } impl InviteeConnection { diff --git a/aries_vcx/src/protocols/connection/inviter/mod.rs b/aries_vcx/src/protocols/connection/inviter/mod.rs index e48c1b29d4..3cbfec5d90 100644 --- a/aries_vcx/src/protocols/connection/inviter/mod.rs +++ b/aries_vcx/src/protocols/connection/inviter/mod.rs @@ -74,7 +74,7 @@ impl InviterConnection { } } - pub async fn create_invite( + pub fn create_invite( self, service_endpoint: String, routing_keys: Vec, diff --git a/aries_vcx/src/protocols/connection/mod.rs b/aries_vcx/src/protocols/connection/mod.rs index 48c7c890b9..051d39fe4b 100644 --- a/aries_vcx/src/protocols/connection/mod.rs +++ b/aries_vcx/src/protocols/connection/mod.rs @@ -110,3 +110,39 @@ where })) } } + +#[cfg(test)] +/// Only present to illustrate the transition between states for the typestate Connection. +/// Methods are only available to given states (encoded as types) and thus the Connection is guaranteed +/// at compile time not to get into an invalid state. +mod dummy_tests { + use super::*; + + async fn invitee() { + let con = Connection::new_invitee(source_id, pairwise_info, did_doc, transport_type) + .process_invite(invitation) + .unwrap() + .send_request(profile, service_endpoint, routing_keys, None) + .await + .unwrap() + .handle_connection_response(wallet, response, send_message) + .await + .unwrap() + .handle_send_ack(send_message) + .await + .unwrap(); + } + + async fn inviter() { + let con = Connection::new_inviter(source_id, pairwise_info, transport_type) + .create_invite(service_endpoint, routing_keys) + .process_request(profile, request, service_endpoint, routing_keys, send_message) + .await + .unwrap() + .handle_send_response(send_message) + .await + .unwrap() + .handle_confirmation_message(msg) + .unwrap(); + } +} From 598a7bc81f99aa386e211ecdeffa6019e2ed8f21 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Tue, 24 Jan 2023 16:09:56 +0200 Subject: [PATCH 03/66] Remove obsolete structs Signed-off-by: Bogdan Mircea --- aries_vcx/src/protocols/connection/mod.rs | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/aries_vcx/src/protocols/connection/mod.rs b/aries_vcx/src/protocols/connection/mod.rs index 051d39fe4b..dbb46df0e5 100644 --- a/aries_vcx/src/protocols/connection/mod.rs +++ b/aries_vcx/src/protocols/connection/mod.rs @@ -21,23 +21,6 @@ use self::{pairwise_info::PairwiseInfo, trait_bounds::TheirDidDoc}; use super::{SendClosure, SendClosureConnection}; -#[derive(Debug, Serialize)] -#[serde(rename_all = "camelCase")] -struct SideConnectionInfo { - did: String, - recipient_keys: Vec, - routing_keys: Vec, - service_endpoint: String, - #[serde(skip_serializing_if = "Option::is_none")] - protocols: Option>, -} - -#[derive(Debug, Serialize)] -struct ConnectionInfo { - my: SideConnectionInfo, - their: Option, -} - pub struct Connection { source_id: String, thread_id: String, From 76f6c4f06056b69980ff488de21b41bcccb2eaf9 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Tue, 24 Jan 2023 16:11:21 +0200 Subject: [PATCH 04/66] Remove dummy tests. Will properly reimplement them later Signed-off-by: Bogdan Mircea --- aries_vcx/src/protocols/connection/mod.rs | 36 ----------------------- 1 file changed, 36 deletions(-) diff --git a/aries_vcx/src/protocols/connection/mod.rs b/aries_vcx/src/protocols/connection/mod.rs index dbb46df0e5..ffd7442fb4 100644 --- a/aries_vcx/src/protocols/connection/mod.rs +++ b/aries_vcx/src/protocols/connection/mod.rs @@ -93,39 +93,3 @@ where })) } } - -#[cfg(test)] -/// Only present to illustrate the transition between states for the typestate Connection. -/// Methods are only available to given states (encoded as types) and thus the Connection is guaranteed -/// at compile time not to get into an invalid state. -mod dummy_tests { - use super::*; - - async fn invitee() { - let con = Connection::new_invitee(source_id, pairwise_info, did_doc, transport_type) - .process_invite(invitation) - .unwrap() - .send_request(profile, service_endpoint, routing_keys, None) - .await - .unwrap() - .handle_connection_response(wallet, response, send_message) - .await - .unwrap() - .handle_send_ack(send_message) - .await - .unwrap(); - } - - async fn inviter() { - let con = Connection::new_inviter(source_id, pairwise_info, transport_type) - .create_invite(service_endpoint, routing_keys) - .process_request(profile, request, service_endpoint, routing_keys, send_message) - .await - .unwrap() - .handle_send_response(send_message) - .await - .unwrap() - .handle_confirmation_message(msg) - .unwrap(); - } -} From 0295e460273a4e1bc628c98b9253dca6f22865e0 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Wed, 25 Jan 2023 14:08:00 +0200 Subject: [PATCH 05/66] Removed transport type from type state Connection Signed-off-by: Bogdan Mircea --- .../src/protocols/connection/invitee/mod.rs | 44 +++++++------------ .../src/protocols/connection/inviter/mod.rs | 44 +++++++------------ aries_vcx/src/protocols/connection/mod.rs | 7 ++- 3 files changed, 36 insertions(+), 59 deletions(-) diff --git a/aries_vcx/src/protocols/connection/invitee/mod.rs b/aries_vcx/src/protocols/connection/invitee/mod.rs index 55b95a85f0..a8005897d2 100644 --- a/aries_vcx/src/protocols/connection/invitee/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/mod.rs @@ -34,33 +34,31 @@ use crate::{ }; /// Convenience alias -pub type InviteeConnection = Connection; +pub type InviteeConnection = Connection; -impl InviteeConnection { +impl InviteeConnection { pub fn new_invitee( source_id: String, pairwise_info: PairwiseInfo, did_doc: AriesDidDoc, - transport_type: T, - ) -> InviteeConnection { + ) -> InviteeConnection { Connection { source_id, thread_id: String::new(), state: InitialState::new(None, did_doc), pairwise_info, initiation_type: Invitee, - transport_type, } } } -impl InviteeConnection { +impl InviteeConnection { /// Tries to convert [`InviteeNonMediatedConnection`] to [`InviteeNonMediatedConnection`] /// by handling a received invitation. /// /// # Errors /// Will error out if the there's no thread ID in the [`Invitation`]. - pub fn handle_invitation(self, invitation: Invitation) -> VcxResult> { + pub fn handle_invitation(self, invitation: Invitation) -> VcxResult> { let thread_id = invitation.get_id()?; let did_doc = self.state.did_doc; @@ -73,17 +71,16 @@ impl InviteeConnection { source_id: self.source_id, pairwise_info: self.pairwise_info, initiation_type: Invitee, - transport_type: self.transport_type, }) } - pub fn process_invite(self, invitation: Invitation) -> VcxResult> { + pub fn process_invite(self, invitation: Invitation) -> VcxResult> { trace!("Connection::process_invite >>> invitation: {:?}", invitation); self.handle_invitation(invitation) } } -impl InviteeConnection { +impl InviteeConnection { pub fn get_invitation(&self) -> &Invitation { &self.state.invitation } @@ -129,7 +126,7 @@ impl InviteeConnection { routing_keys: Vec, service_endpoint: String, send_message: SendClosureConnection, - ) -> VcxResult> { + ) -> VcxResult> { let (request, thread_id) = self.build_connection_request_msg(routing_keys, service_endpoint)?; let did_doc = self.state.did_doc; @@ -148,16 +145,14 @@ impl InviteeConnection { source_id: self.source_id, pairwise_info: self.pairwise_info, initiation_type: Invitee, - transport_type: self.transport_type, }) } - pub fn handle_problem_report(self, problem_report: ProblemReport) -> VcxResult> { + pub fn handle_problem_report(self, problem_report: ProblemReport) -> VcxResult> { let Self { source_id, thread_id, pairwise_info, - transport_type, state, .. } = self; @@ -170,7 +165,6 @@ impl InviteeConnection { thread_id, pairwise_info, initiation_type: Invitee, - transport_type, }) } @@ -180,7 +174,7 @@ impl InviteeConnection { service_endpoint: String, routing_keys: Vec, send_message: Option, - ) -> VcxResult> { + ) -> VcxResult> { trace!("Connection::send_request"); let send_message = send_message.unwrap_or(self.send_message_closure_connection(profile)); self.send_connection_request(routing_keys, service_endpoint, send_message) @@ -188,7 +182,7 @@ impl InviteeConnection { } } -impl InviteeConnection { +impl InviteeConnection { /// Returns the first entry from the map for which the message indicates a progressable state. pub fn find_message_to_update_state(&self, messages: HashMap) -> Option<(String, A2AMessage)> { messages @@ -218,7 +212,7 @@ impl InviteeConnection { wallet: &Arc, response: SignedResponse, _send_message: SendClosureConnection, - ) -> VcxResult> { + ) -> VcxResult> { verify_thread_id(self.thread_id(), &A2AMessage::ConnectionResponse(response.clone()))?; let remote_vk: String = @@ -237,7 +231,6 @@ impl InviteeConnection { thread_id, pairwise_info, state, - transport_type, .. } = self; @@ -251,16 +244,14 @@ impl InviteeConnection { thread_id, pairwise_info, initiation_type: Invitee, - transport_type, }) } - pub fn handle_problem_report(self, problem_report: ProblemReport) -> VcxResult> { + pub fn handle_problem_report(self, problem_report: ProblemReport) -> VcxResult> { let Self { source_id, thread_id, pairwise_info, - transport_type, state, .. } = self; @@ -273,12 +264,11 @@ impl InviteeConnection { thread_id, pairwise_info, initiation_type: Invitee, - transport_type, }) } } -impl InviteeConnection { +impl InviteeConnection { fn build_connection_ack_msg(&self) -> Ack { Ack::create().set_out_time().set_thread_id(&self.thread_id) } @@ -286,7 +276,7 @@ impl InviteeConnection { pub async fn handle_send_ack( self, send_message: SendClosureConnection, - ) -> VcxResult> { + ) -> VcxResult> { let sender_vk = self.pairwise_info().pw_vk.clone(); let did_doc = self.state.response.connection.did_doc.clone(); @@ -297,7 +287,6 @@ impl InviteeConnection { thread_id, pairwise_info, state, - transport_type, .. } = self; @@ -313,12 +302,11 @@ impl InviteeConnection { thread_id, pairwise_info, initiation_type: Invitee, - transport_type, }) } } -impl InviteeConnection { +impl InviteeConnection { pub fn bootstrap_did_doc(&self) -> &AriesDidDoc { &self.state.bootstrap_did_doc } diff --git a/aries_vcx/src/protocols/connection/inviter/mod.rs b/aries_vcx/src/protocols/connection/inviter/mod.rs index 3cbfec5d90..e459cb76ba 100644 --- a/aries_vcx/src/protocols/connection/inviter/mod.rs +++ b/aries_vcx/src/protocols/connection/inviter/mod.rs @@ -22,31 +22,29 @@ use messages::protocols::connection::{ }; use messages::protocols::discovery::disclose::{ProtocolDescriptor, Disclose}; -pub type InviterConnection = Connection; +pub type InviterConnection = Connection; -impl InviterConnection { +impl InviterConnection { pub fn new_inviter( source_id: String, pairwise_info: PairwiseInfo, - transport_type: T, - ) -> InviterConnection { + ) -> InviterConnection { Connection { source_id, thread_id: String::new(), state: InitialState::new(None), pairwise_info, initiation_type: Inviter, - transport_type, } } } -impl InviterConnection { +impl InviterConnection { pub fn create_invitation( self, routing_keys: Vec, service_endpoint: String, - ) -> InviterConnection { + ) -> InviterConnection { let invite: PairwiseInvitation = PairwiseInvitation::create() .set_id(&self.thread_id) .set_label(&self.source_id) @@ -59,7 +57,6 @@ impl InviterConnection { thread_id, pairwise_info, initiation_type, - transport_type, state, } = self; let state = (state, Invitation::Pairwise(invite)).into(); @@ -69,7 +66,6 @@ impl InviterConnection { thread_id, pairwise_info, initiation_type, - transport_type, state, } } @@ -78,12 +74,12 @@ impl InviterConnection { self, service_endpoint: String, routing_keys: Vec, - ) -> InviterConnection { + ) -> InviterConnection { self.create_invitation(routing_keys, service_endpoint) } } -impl InviterConnection { +impl InviterConnection { pub fn get_invitation(&self) -> &Invitation { &self.state.invitation } @@ -96,7 +92,7 @@ impl InviterConnection { new_routing_keys: Vec, new_service_endpoint: String, _send_message: SendClosureConnection, - ) -> VcxResult> { + ) -> VcxResult> { verify_thread_id(self.thread_id(), &A2AMessage::ConnectionRequest(request.clone()))?; request.connection.did_doc.validate()?; @@ -121,7 +117,6 @@ impl InviterConnection { thread_id, pairwise_info, initiation_type, - transport_type, .. } = self; @@ -130,7 +125,6 @@ impl InviterConnection { thread_id, pairwise_info, initiation_type, - transport_type, state, }) } @@ -165,7 +159,7 @@ impl InviterConnection { service_endpoint: String, routing_keys: Vec, send_message: Option, - ) -> VcxResult> { + ) -> VcxResult> { trace!( "Connection::process_request >>> request: {:?}, service_endpoint: {}, routing_keys: {:?}", request, @@ -188,11 +182,11 @@ impl InviterConnection { } } -impl InviterConnection { +impl InviterConnection { pub async fn handle_send_response( self, send_message: SendClosureConnection, - ) -> VcxResult> { + ) -> VcxResult> { send_message( self.state.signed_response.to_a2a_message(), self.pairwise_info.pw_vk.clone(), @@ -205,7 +199,6 @@ impl InviterConnection { thread_id, pairwise_info, initiation_type, - transport_type, state, } = self; @@ -215,7 +208,6 @@ impl InviterConnection { thread_id, pairwise_info, initiation_type, - transport_type, }) } @@ -223,15 +215,15 @@ impl InviterConnection { self, profile: &Arc, send_message: Option, - ) -> VcxResult> { + ) -> VcxResult> { trace!("Connection::send_response >>>"); let send_message = send_message.unwrap_or(self.send_message_closure_connection(profile)); self.handle_send_response(send_message).await } } -impl InviterConnection { - pub fn handle_confirmation_message(self, msg: &A2AMessage) -> VcxResult> { +impl InviterConnection { + pub fn handle_confirmation_message(self, msg: &A2AMessage) -> VcxResult> { verify_thread_id(self.thread_id(), msg)?; let Self { @@ -239,7 +231,6 @@ impl InviterConnection { thread_id, pairwise_info, initiation_type, - transport_type, state, } = self; @@ -250,18 +241,17 @@ impl InviterConnection { thread_id, pairwise_info, initiation_type, - transport_type, state, }) } - pub fn process_ack(self, message: &A2AMessage) -> VcxResult> { + pub fn process_ack(self, message: &A2AMessage) -> VcxResult> { self.handle_confirmation_message(message) } } -impl InviterConnection< T, CompleteState> { +impl InviterConnection { pub fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { self.state.remote_protocols() } @@ -269,4 +259,4 @@ impl InviterConnection< T, CompleteState> { pub fn handle_disclose(&mut self, disclose: Disclose) { self.state.handle_disclose(disclose) } -} \ No newline at end of file +} diff --git a/aries_vcx/src/protocols/connection/mod.rs b/aries_vcx/src/protocols/connection/mod.rs index ffd7442fb4..9a6e105795 100644 --- a/aries_vcx/src/protocols/connection/mod.rs +++ b/aries_vcx/src/protocols/connection/mod.rs @@ -21,16 +21,15 @@ use self::{pairwise_info::PairwiseInfo, trait_bounds::TheirDidDoc}; use super::{SendClosure, SendClosureConnection}; -pub struct Connection { +pub struct Connection { source_id: String, thread_id: String, pairwise_info: PairwiseInfo, initiation_type: I, - transport_type: T, state: S, } -impl Connection { +impl Connection { pub fn pairwise_info(&self) -> &PairwiseInfo { &self.pairwise_info } @@ -56,7 +55,7 @@ impl Connection { } } -impl Connection +impl Connection where S: TheirDidDoc, { From 63f7d460b60c9ac210f09adcc9c7c5743de957a7 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Wed, 25 Jan 2023 16:33:36 +0200 Subject: [PATCH 06/66] Factored out build_con_request method Signed-off-by: Bogdan Mircea --- .../src/protocols/connection/invitee/mod.rs | 28 +++++++------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/aries_vcx/src/protocols/connection/invitee/mod.rs b/aries_vcx/src/protocols/connection/invitee/mod.rs index a8005897d2..d258329f20 100644 --- a/aries_vcx/src/protocols/connection/invitee/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/mod.rs @@ -85,11 +85,17 @@ impl InviteeConnection { &self.state.invitation } - fn build_connection_request_msg( - &self, + /// Tries to convert [`SmConnectionInvitee2`] to [`SmConnectionInvitee2`] + /// by sending a connection request. + /// + /// # Errors + /// Will error out if building or sending the connection request message fails. + pub async fn send_connection_request( + self, routing_keys: Vec, service_endpoint: String, - ) -> VcxResult<(Request, String)> { + send_message: SendClosureConnection, + ) -> VcxResult> { let recipient_keys = vec![self.pairwise_info.pw_vk.clone()]; let request = Request::create() .set_label(self.source_id.to_string()) @@ -113,21 +119,7 @@ impl InviteeConnection { request_id, ), }; - Ok((request, thread_id)) - } - - /// Tries to convert [`SmConnectionInvitee2`] to [`SmConnectionInvitee2`] - /// by sending a connection request. - /// - /// # Errors - /// Will error out if building or sending the connection request message fails. - pub async fn send_connection_request( - self, - routing_keys: Vec, - service_endpoint: String, - send_message: SendClosureConnection, - ) -> VcxResult> { - let (request, thread_id) = self.build_connection_request_msg(routing_keys, service_endpoint)?; + let did_doc = self.state.did_doc; send_message( From ee571df52be47cbd026381f02cdae960eadd5ace Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Wed, 25 Jan 2023 16:47:02 +0200 Subject: [PATCH 07/66] Moved all typestate connection related code to a different module Signed-off-by: Bogdan Mircea --- .../src/protocols/connection/invitee/mod.rs | 311 ----------------- .../connection/invitee/states/complete.rs | 7 - .../connection/invitee/states/initial.rs | 7 - .../connection/invitee/states/invited.rs | 7 - .../connection/invitee/states/requested.rs | 7 - .../connection/invitee/states/responded.rs | 7 - .../src/protocols/connection/inviter/mod.rs | 260 --------------- .../connection/inviter/states/complete.rs | 8 - .../connection/inviter/states/requested.rs | 7 - .../connection/inviter/states/responded.rs | 7 - aries_vcx/src/protocols/connection/mod.rs | 90 ----- aries_vcx/src/protocols/mod.rs | 1 + .../protocols/typestate_con/invitee/mod.rs | 312 ++++++++++++++++++ .../typestate_con/invitee/states/complete.rs | 57 ++++ .../typestate_con/invitee/states/initial.rs | 26 ++ .../typestate_con/invitee/states/invited.rs | 17 + .../typestate_con/invitee/states/mod.rs | 5 + .../typestate_con/invitee/states/requested.rs | 60 ++++ .../typestate_con/invitee/states/responded.rs | 22 ++ .../protocols/typestate_con/inviter/mod.rs | 261 +++++++++++++++ .../typestate_con/inviter/states/complete.rs | 32 ++ .../typestate_con/inviter/states/initial.rs | 21 ++ .../typestate_con/inviter/states/invited.rs | 33 ++ .../typestate_con/inviter/states/mod.rs | 5 + .../typestate_con/inviter/states/requested.rs | 32 ++ .../typestate_con/inviter/states/responded.rs | 36 ++ aries_vcx/src/protocols/typestate_con/mod.rs | 91 +++++ .../protocols/typestate_con/pairwise_info.rs | 17 + .../trait_bounds.rs | 0 29 files changed, 1028 insertions(+), 718 deletions(-) create mode 100644 aries_vcx/src/protocols/typestate_con/invitee/mod.rs create mode 100644 aries_vcx/src/protocols/typestate_con/invitee/states/complete.rs create mode 100644 aries_vcx/src/protocols/typestate_con/invitee/states/initial.rs create mode 100644 aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs create mode 100644 aries_vcx/src/protocols/typestate_con/invitee/states/mod.rs create mode 100644 aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs create mode 100644 aries_vcx/src/protocols/typestate_con/invitee/states/responded.rs create mode 100644 aries_vcx/src/protocols/typestate_con/inviter/mod.rs create mode 100644 aries_vcx/src/protocols/typestate_con/inviter/states/complete.rs create mode 100644 aries_vcx/src/protocols/typestate_con/inviter/states/initial.rs create mode 100644 aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs create mode 100644 aries_vcx/src/protocols/typestate_con/inviter/states/mod.rs create mode 100644 aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs create mode 100644 aries_vcx/src/protocols/typestate_con/inviter/states/responded.rs create mode 100644 aries_vcx/src/protocols/typestate_con/mod.rs create mode 100644 aries_vcx/src/protocols/typestate_con/pairwise_info.rs rename aries_vcx/src/protocols/{connection => typestate_con}/trait_bounds.rs (100%) diff --git a/aries_vcx/src/protocols/connection/invitee/mod.rs b/aries_vcx/src/protocols/connection/invitee/mod.rs index d258329f20..abe5f05f66 100644 --- a/aries_vcx/src/protocols/connection/invitee/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/mod.rs @@ -1,313 +1,2 @@ pub mod state_machine; pub mod states; - -use messages::{ - diddoc::aries::diddoc::AriesDidDoc, - protocols::{ - connection::invite::Invitation, - discovery::disclose::{Disclose, ProtocolDescriptor}, - }, -}; - -use crate::{core::profile::profile::Profile, errors::error::VcxResult}; - -use self::states::{ - complete::CompleteState, initial::InitialState, invited::InvitedState, requested::RequestedState, - responded::RespondedState, -}; - -use std::{collections::HashMap, sync::Arc}; - -use messages::{ - a2a::A2AMessage, - concepts::ack::Ack, - protocols::connection::{problem_report::ProblemReport, request::Request, response::SignedResponse}, -}; - -use super::{initiation_type::Invitee, Connection}; -use crate::{ - common::signing::decode_signed_connection_response, - errors::error::{AriesVcxError, AriesVcxErrorKind}, - handlers::util::verify_thread_id, - plugins::wallet::base_wallet::BaseWallet, - protocols::{connection::pairwise_info::PairwiseInfo, SendClosureConnection}, -}; - -/// Convenience alias -pub type InviteeConnection = Connection; - -impl InviteeConnection { - pub fn new_invitee( - source_id: String, - pairwise_info: PairwiseInfo, - did_doc: AriesDidDoc, - ) -> InviteeConnection { - Connection { - source_id, - thread_id: String::new(), - state: InitialState::new(None, did_doc), - pairwise_info, - initiation_type: Invitee, - } - } -} - -impl InviteeConnection { - /// Tries to convert [`InviteeNonMediatedConnection`] to [`InviteeNonMediatedConnection`] - /// by handling a received invitation. - /// - /// # Errors - /// Will error out if the there's no thread ID in the [`Invitation`]. - pub fn handle_invitation(self, invitation: Invitation) -> VcxResult> { - let thread_id = invitation.get_id()?; - - let did_doc = self.state.did_doc; - let state = InvitedState { invitation, did_doc }; - - // Convert to `InvitedState` - Ok(Connection { - state, - thread_id, - source_id: self.source_id, - pairwise_info: self.pairwise_info, - initiation_type: Invitee, - }) - } - - pub fn process_invite(self, invitation: Invitation) -> VcxResult> { - trace!("Connection::process_invite >>> invitation: {:?}", invitation); - self.handle_invitation(invitation) - } -} - -impl InviteeConnection { - pub fn get_invitation(&self) -> &Invitation { - &self.state.invitation - } - - /// Tries to convert [`SmConnectionInvitee2`] to [`SmConnectionInvitee2`] - /// by sending a connection request. - /// - /// # Errors - /// Will error out if building or sending the connection request message fails. - pub async fn send_connection_request( - self, - routing_keys: Vec, - service_endpoint: String, - send_message: SendClosureConnection, - ) -> VcxResult> { - let recipient_keys = vec![self.pairwise_info.pw_vk.clone()]; - let request = Request::create() - .set_label(self.source_id.to_string()) - .set_did(self.pairwise_info.pw_did.to_string()) - .set_service_endpoint(service_endpoint) - .set_keys(recipient_keys, routing_keys) - .set_out_time(); - - let request_id = request.id.0.clone(); - - let (request, thread_id) = match &self.state.invitation { - Invitation::Public(_) => ( - request - .set_parent_thread_id(&self.thread_id) - .set_thread_id_matching_id(), - request_id, - ), - Invitation::Pairwise(_) => (request.set_thread_id(&self.thread_id), self.thread_id().to_owned()), - Invitation::OutOfBand(invite) => ( - request.set_parent_thread_id(&invite.id.0).set_thread_id_matching_id(), - request_id, - ), - }; - - let did_doc = self.state.did_doc; - - send_message( - request.to_a2a_message(), - self.pairwise_info.pw_vk.clone(), - did_doc.clone(), - ) - .await?; - - let state = RequestedState { request, did_doc }; - - Ok(Connection { - state, - thread_id, - source_id: self.source_id, - pairwise_info: self.pairwise_info, - initiation_type: Invitee, - }) - } - - pub fn handle_problem_report(self, problem_report: ProblemReport) -> VcxResult> { - let Self { - source_id, - thread_id, - pairwise_info, - state, - .. - } = self; - - let state = InitialState::new(Some(problem_report), state.did_doc); - - Ok(Connection { - state, - source_id, - thread_id, - pairwise_info, - initiation_type: Invitee, - }) - } - - pub async fn send_request( - self, - profile: &Arc, - service_endpoint: String, - routing_keys: Vec, - send_message: Option, - ) -> VcxResult> { - trace!("Connection::send_request"); - let send_message = send_message.unwrap_or(self.send_message_closure_connection(profile)); - self.send_connection_request(routing_keys, service_endpoint, send_message) - .await - } -} - -impl InviteeConnection { - /// Returns the first entry from the map for which the message indicates a progressable state. - pub fn find_message_to_update_state(&self, messages: HashMap) -> Option<(String, A2AMessage)> { - messages - .into_iter() - .find(|(_, message)| Self::can_progress_state(message)) - } - - /// Determines whether the message indicates a progressable state. - pub fn can_progress_state(message: &A2AMessage) -> bool { - matches!( - message, - A2AMessage::ConnectionResponse(_) | A2AMessage::ConnectionProblemReport(_) - ) - } - - /// Tries to convert [`SmConnectionInvitee2`] to [`SmConnectionInvitee2`] - /// by handling a connection response. - /// - /// # Errors - /// Will error out if the thread ID verification fails, there are no keys in the DidDoc - /// or decoding the response fails. - // - // TODO: Why only convert the state to `InitialState` if the decoding fails? - // Why not on any other errors? - pub async fn handle_connection_response( - self, - wallet: &Arc, - response: SignedResponse, - _send_message: SendClosureConnection, - ) -> VcxResult> { - verify_thread_id(self.thread_id(), &A2AMessage::ConnectionResponse(response.clone()))?; - - let remote_vk: String = - self.state - .did_doc - .recipient_keys()? - .first() - .cloned() - .ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidState, - "Cannot handle response: remote verkey not found", - ))?; - - let Self { - source_id, - thread_id, - pairwise_info, - state, - .. - } = self; - - let state = decode_signed_connection_response(wallet, response.clone(), &remote_vk) - .await - .and_then(|response| state.try_into_responded(response))?; - - Ok(Connection { - state, - source_id, - thread_id, - pairwise_info, - initiation_type: Invitee, - }) - } - - pub fn handle_problem_report(self, problem_report: ProblemReport) -> VcxResult> { - let Self { - source_id, - thread_id, - pairwise_info, - state, - .. - } = self; - - let state = InitialState::new(Some(problem_report), state.did_doc); - - Ok(Connection { - state, - source_id, - thread_id, - pairwise_info, - initiation_type: Invitee, - }) - } -} - -impl InviteeConnection { - fn build_connection_ack_msg(&self) -> Ack { - Ack::create().set_out_time().set_thread_id(&self.thread_id) - } - - pub async fn handle_send_ack( - self, - send_message: SendClosureConnection, - ) -> VcxResult> { - let sender_vk = self.pairwise_info().pw_vk.clone(); - let did_doc = self.state.response.connection.did_doc.clone(); - - send_message(self.build_connection_ack_msg().to_a2a_message(), sender_vk, did_doc).await?; - - let Self { - source_id, - thread_id, - pairwise_info, - state, - .. - } = self; - - let state = CompleteState { - did_doc: state.did_doc, - bootstrap_did_doc: state.response.connection.did_doc, - protocols: None, - }; - - Ok(Connection { - state, - source_id, - thread_id, - pairwise_info, - initiation_type: Invitee, - }) - } -} - -impl InviteeConnection { - pub fn bootstrap_did_doc(&self) -> &AriesDidDoc { - &self.state.bootstrap_did_doc - } - - pub fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { - self.state.remote_protocols() - } - - pub fn handle_disclose(&mut self, disclose: Disclose) { - self.state.handle_disclose(disclose) - } -} diff --git a/aries_vcx/src/protocols/connection/invitee/states/complete.rs b/aries_vcx/src/protocols/connection/invitee/states/complete.rs index bf4fa9d8f7..917dc721f6 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/complete.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/complete.rs @@ -2,7 +2,6 @@ use std::clone::Clone; use crate::protocols::connection::invitee::states::requested::RequestedState; use crate::protocols::connection::invitee::states::responded::RespondedState; -use crate::protocols::connection::trait_bounds::{TheirDidDoc}; use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::connection::response::Response; use messages::protocols::discovery::disclose::{ProtocolDescriptor, Disclose}; @@ -56,9 +55,3 @@ impl From for CompleteState { } } } - -impl TheirDidDoc for CompleteState { - fn their_did_doc(&self) -> &AriesDidDoc { - &self.did_doc - } -} \ No newline at end of file diff --git a/aries_vcx/src/protocols/connection/invitee/states/initial.rs b/aries_vcx/src/protocols/connection/invitee/states/initial.rs index 40da42a151..dd60579786 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/initial.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/initial.rs @@ -1,5 +1,4 @@ use crate::protocols::connection::invitee::states::invited::InvitedState; -use crate::protocols::connection::trait_bounds::TheirDidDoc; use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::connection::invite::Invitation; use messages::protocols::connection::problem_report::ProblemReport; @@ -25,9 +24,3 @@ impl InitialState { } } } - -impl TheirDidDoc for InitialState { - fn their_did_doc(&self) -> &AriesDidDoc { - &self.did_doc - } -} \ No newline at end of file diff --git a/aries_vcx/src/protocols/connection/invitee/states/invited.rs b/aries_vcx/src/protocols/connection/invitee/states/invited.rs index 9a4ee63abc..622894b93e 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/invited.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/invited.rs @@ -1,5 +1,4 @@ use crate::protocols::connection::invitee::states::requested::RequestedState; -use crate::protocols::connection::trait_bounds::TheirDidDoc; use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::connection::invite::Invitation; use messages::protocols::connection::request::Request; @@ -16,9 +15,3 @@ impl From<(InvitedState, Request, AriesDidDoc)> for RequestedState { RequestedState { request, did_doc } } } - -impl TheirDidDoc for InvitedState { - fn their_did_doc(&self) -> &AriesDidDoc { - &self.did_doc - } -} \ No newline at end of file diff --git a/aries_vcx/src/protocols/connection/invitee/states/requested.rs b/aries_vcx/src/protocols/connection/invitee/states/requested.rs index 17653136e5..c89f0ee478 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/requested.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/requested.rs @@ -1,7 +1,6 @@ use crate::errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult}; use crate::protocols::connection::invitee::states::initial::InitialState; use crate::protocols::connection::invitee::states::responded::RespondedState; -use crate::protocols::connection::trait_bounds::TheirDidDoc; use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::connection::problem_report::ProblemReport; use messages::protocols::connection::request::Request; @@ -59,9 +58,3 @@ impl From<(RequestedState, Response)> for RespondedState { } } } - -impl TheirDidDoc for RequestedState { - fn their_did_doc(&self) -> &AriesDidDoc { - &self.did_doc - } -} diff --git a/aries_vcx/src/protocols/connection/invitee/states/responded.rs b/aries_vcx/src/protocols/connection/invitee/states/responded.rs index f260c81f98..6d3b282048 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/responded.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/responded.rs @@ -1,5 +1,4 @@ use crate::protocols::connection::invitee::states::initial::InitialState; -use crate::protocols::connection::trait_bounds::TheirDidDoc; use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::connection::problem_report::ProblemReport; use messages::protocols::connection::request::Request; @@ -21,9 +20,3 @@ impl From<(RespondedState, ProblemReport)> for InitialState { InitialState::new(Some(problem_report), _state.did_doc) } } - -impl TheirDidDoc for RespondedState { - fn their_did_doc(&self) -> &AriesDidDoc { - &self.did_doc - } -} \ No newline at end of file diff --git a/aries_vcx/src/protocols/connection/inviter/mod.rs b/aries_vcx/src/protocols/connection/inviter/mod.rs index e459cb76ba..6b37a228b6 100644 --- a/aries_vcx/src/protocols/connection/inviter/mod.rs +++ b/aries_vcx/src/protocols/connection/inviter/mod.rs @@ -1,262 +1,2 @@ pub mod state_machine; mod states; - -use std::sync::Arc; - -use crate::handlers::util::verify_thread_id; -use crate::{ - common::signing::sign_connection_response, core::profile::profile::Profile, errors::error::VcxResult, - plugins::wallet::base_wallet::BaseWallet, protocols::SendClosureConnection, -}; - -use self::states::complete::CompleteState; -use self::states::initial::InitialState; -use self::states::{invited::InvitedState, requested::RequestedState, responded::RespondedState}; -use super::{initiation_type::Inviter, pairwise_info::PairwiseInfo, Connection}; -use messages::a2a::A2AMessage; -use messages::protocols::connection::invite::PairwiseInvitation; -use messages::protocols::connection::{ - invite::Invitation, - request::Request, - response::{Response, SignedResponse}, -}; -use messages::protocols::discovery::disclose::{ProtocolDescriptor, Disclose}; - -pub type InviterConnection = Connection; - -impl InviterConnection { - pub fn new_inviter( - source_id: String, - pairwise_info: PairwiseInfo, - ) -> InviterConnection { - Connection { - source_id, - thread_id: String::new(), - state: InitialState::new(None), - pairwise_info, - initiation_type: Inviter, - } - } -} - -impl InviterConnection { - pub fn create_invitation( - self, - routing_keys: Vec, - service_endpoint: String, - ) -> InviterConnection { - let invite: PairwiseInvitation = PairwiseInvitation::create() - .set_id(&self.thread_id) - .set_label(&self.source_id) - .set_recipient_keys(vec![self.pairwise_info.pw_vk.clone()]) - .set_routing_keys(routing_keys) - .set_service_endpoint(service_endpoint); - - let Self { - source_id, - thread_id, - pairwise_info, - initiation_type, - state, - } = self; - let state = (state, Invitation::Pairwise(invite)).into(); - - Connection { - source_id, - thread_id, - pairwise_info, - initiation_type, - state, - } - } - - pub fn create_invite( - self, - service_endpoint: String, - routing_keys: Vec, - ) -> InviterConnection { - self.create_invitation(routing_keys, service_endpoint) - } -} - -impl InviterConnection { - pub fn get_invitation(&self) -> &Invitation { - &self.state.invitation - } - - async fn handle_connection_request( - self, - wallet: Arc, - request: Request, - new_pairwise_info: &PairwiseInfo, - new_routing_keys: Vec, - new_service_endpoint: String, - _send_message: SendClosureConnection, - ) -> VcxResult> { - verify_thread_id(self.thread_id(), &A2AMessage::ConnectionRequest(request.clone()))?; - request.connection.did_doc.validate()?; - - let signed_response = self - .build_response( - &wallet, - &request, - new_pairwise_info, - new_routing_keys, - new_service_endpoint, - ) - .await?; - - let state = RequestedState { - signed_response, - did_doc: request.connection.did_doc, - thread_id: request.id.0, - }; - - let Self { - source_id, - thread_id, - pairwise_info, - initiation_type, - .. - } = self; - - Ok(Connection { - source_id, - thread_id, - pairwise_info, - initiation_type, - state, - }) - } - - async fn build_response( - &self, - wallet: &Arc, - request: &Request, - new_pairwise_info: &PairwiseInfo, - new_routing_keys: Vec, - new_service_endpoint: String, - ) -> VcxResult { - let new_recipient_keys = vec![new_pairwise_info.pw_vk.clone()]; - sign_connection_response( - wallet, - &self.pairwise_info.clone().pw_vk, - Response::create() - .set_did(new_pairwise_info.pw_did.to_string()) - .set_service_endpoint(new_service_endpoint) - .set_keys(new_recipient_keys, new_routing_keys) - .ask_for_ack() - .set_thread_id(&request.get_thread_id()) - .set_out_time(), - ) - .await - } - - pub async fn process_request( - self, - profile: &Arc, - request: Request, - service_endpoint: String, - routing_keys: Vec, - send_message: Option, - ) -> VcxResult> { - trace!( - "Connection::process_request >>> request: {:?}, service_endpoint: {}, routing_keys: {:?}", - request, - service_endpoint, - routing_keys, - ); - - let send_message = send_message.unwrap_or(self.send_message_closure_connection(profile)); - let new_pairwise_info = PairwiseInfo::create(&profile.inject_wallet()).await?; - - self.handle_connection_request( - profile.inject_wallet(), - request, - &new_pairwise_info, - routing_keys, - service_endpoint, - send_message, - ) - .await - } -} - -impl InviterConnection { - pub async fn handle_send_response( - self, - send_message: SendClosureConnection, - ) -> VcxResult> { - send_message( - self.state.signed_response.to_a2a_message(), - self.pairwise_info.pw_vk.clone(), - self.state.did_doc.clone(), - ) - .await?; - - let Self { - source_id, - thread_id, - pairwise_info, - initiation_type, - state, - } = self; - - Ok(Connection { - state: state.into(), - source_id, - thread_id, - pairwise_info, - initiation_type, - }) - } - - pub async fn send_response( - self, - profile: &Arc, - send_message: Option, - ) -> VcxResult> { - trace!("Connection::send_response >>>"); - let send_message = send_message.unwrap_or(self.send_message_closure_connection(profile)); - self.handle_send_response(send_message).await - } -} - -impl InviterConnection { - pub fn handle_confirmation_message(self, msg: &A2AMessage) -> VcxResult> { - verify_thread_id(self.thread_id(), msg)?; - - let Self { - source_id, - thread_id, - pairwise_info, - initiation_type, - state, - } = self; - - let state = state.into(); - - Ok(Connection { - source_id, - thread_id, - pairwise_info, - initiation_type, - state, - }) - } - - pub fn process_ack(self, message: &A2AMessage) -> VcxResult> { - self.handle_confirmation_message(message) - } -} - - -impl InviterConnection { - pub fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { - self.state.remote_protocols() - } - - pub fn handle_disclose(&mut self, disclose: Disclose) { - self.state.handle_disclose(disclose) - } -} diff --git a/aries_vcx/src/protocols/connection/inviter/states/complete.rs b/aries_vcx/src/protocols/connection/inviter/states/complete.rs index 068a84c9ed..6a0cad7311 100644 --- a/aries_vcx/src/protocols/connection/inviter/states/complete.rs +++ b/aries_vcx/src/protocols/connection/inviter/states/complete.rs @@ -3,8 +3,6 @@ use std::clone::Clone; use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::discovery::disclose::{Disclose, ProtocolDescriptor}; -use crate::protocols::connection::trait_bounds::TheirDidDoc; - #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct CompleteState { pub did_doc: AriesDidDoc, @@ -32,9 +30,3 @@ impl From<(CompleteState, Vec)> for CompleteState { } } } - -impl TheirDidDoc for CompleteState { - fn their_did_doc(&self) -> &AriesDidDoc { - &self.did_doc - } -} diff --git a/aries_vcx/src/protocols/connection/inviter/states/requested.rs b/aries_vcx/src/protocols/connection/inviter/states/requested.rs index fd3c2545f1..11772b957e 100644 --- a/aries_vcx/src/protocols/connection/inviter/states/requested.rs +++ b/aries_vcx/src/protocols/connection/inviter/states/requested.rs @@ -1,6 +1,5 @@ use crate::protocols::connection::inviter::states::initial::InitialState; use crate::protocols::connection::inviter::states::responded::RespondedState; -use crate::protocols::connection::trait_bounds::TheirDidDoc; use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::connection::problem_report::ProblemReport; use messages::protocols::connection::response::SignedResponse; @@ -31,9 +30,3 @@ impl From for RespondedState { } } } - -impl TheirDidDoc for RequestedState { - fn their_did_doc(&self) -> &AriesDidDoc { - &self.did_doc - } -} \ No newline at end of file diff --git a/aries_vcx/src/protocols/connection/inviter/states/responded.rs b/aries_vcx/src/protocols/connection/inviter/states/responded.rs index 7ab111889b..397eb3110d 100644 --- a/aries_vcx/src/protocols/connection/inviter/states/responded.rs +++ b/aries_vcx/src/protocols/connection/inviter/states/responded.rs @@ -7,7 +7,6 @@ use messages::protocols::connection::response::SignedResponse; use crate::protocols::connection::inviter::states::complete::CompleteState; use crate::protocols::connection::inviter::states::initial::InitialState; -use crate::protocols::connection::trait_bounds::TheirDidDoc; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct RespondedState { @@ -35,9 +34,3 @@ impl From for CompleteState { } } } - -impl TheirDidDoc for RespondedState { - fn their_did_doc(&self) -> &AriesDidDoc { - &self.did_doc - } -} diff --git a/aries_vcx/src/protocols/connection/mod.rs b/aries_vcx/src/protocols/connection/mod.rs index 9a6e105795..d282258916 100644 --- a/aries_vcx/src/protocols/connection/mod.rs +++ b/aries_vcx/src/protocols/connection/mod.rs @@ -2,93 +2,3 @@ pub mod initiation_type; pub mod invitee; pub mod inviter; pub mod pairwise_info; -mod trait_bounds; - -use messages::{ - a2a::{protocol_registry::ProtocolRegistry, A2AMessage}, - diddoc::aries::diddoc::AriesDidDoc, - protocols::discovery::disclose::ProtocolDescriptor, -}; -use std::sync::Arc; - -use crate::{ - core::profile::profile::Profile, - errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult}, - utils::send_message, -}; - -use self::{pairwise_info::PairwiseInfo, trait_bounds::TheirDidDoc}; - -use super::{SendClosure, SendClosureConnection}; - -pub struct Connection { - source_id: String, - thread_id: String, - pairwise_info: PairwiseInfo, - initiation_type: I, - state: S, -} - -impl Connection { - pub fn pairwise_info(&self) -> &PairwiseInfo { - &self.pairwise_info - } - - pub fn source_id(&self) -> &str { - &self.source_id - } - - pub fn thread_id(&self) -> &str { - &self.thread_id - } - - pub fn protocols(&self) -> Vec { - ProtocolRegistry::init().protocols() - } - - fn send_message_closure_connection(&self, profile: &Arc) -> SendClosureConnection { - trace!("send_message_closure_connection >>>"); - let wallet = profile.inject_wallet(); - Box::new(move |message: A2AMessage, sender_vk: String, did_doc: AriesDidDoc| { - Box::pin(send_message(wallet, sender_vk, did_doc, message)) - }) - } -} - -impl Connection -where - S: TheirDidDoc, -{ - pub fn their_did_doc(&self) -> &AriesDidDoc { - self.state.their_did_doc() - } - - pub fn remote_did(&self) -> &str { - &self.their_did_doc().id - } - - pub fn remote_vk(&self) -> VcxResult { - self.their_did_doc() - .recipient_keys()? - .first() - .map(ToOwned::to_owned) - .ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::NotReady, - "Can't resolve recipient key from the counterparty diddoc.", - )) - } - - pub async fn send_message_closure( - &self, - profile: &Arc, - send_message: Option, - ) -> VcxResult { - trace!("send_message_closure >>>"); - let did_doc = self.their_did_doc().clone(); - let sender_vk = self.pairwise_info().pw_vk.clone(); - let send_message = send_message.unwrap_or(self.send_message_closure_connection(profile)); - Ok(Box::new(move |message: A2AMessage| { - Box::pin(send_message(message, sender_vk, did_doc)) - })) - } -} diff --git a/aries_vcx/src/protocols/mod.rs b/aries_vcx/src/protocols/mod.rs index 0558925b22..c0328e1569 100644 --- a/aries_vcx/src/protocols/mod.rs +++ b/aries_vcx/src/protocols/mod.rs @@ -11,6 +11,7 @@ pub mod oob; pub mod proof_presentation; pub mod revocation_notification; pub mod trustping; +mod typestate_con; pub type SendClosure = Box BoxFuture<'static, VcxResult<()>> + Send + Sync>; pub type SendClosureConnection = diff --git a/aries_vcx/src/protocols/typestate_con/invitee/mod.rs b/aries_vcx/src/protocols/typestate_con/invitee/mod.rs new file mode 100644 index 0000000000..9f6a31687f --- /dev/null +++ b/aries_vcx/src/protocols/typestate_con/invitee/mod.rs @@ -0,0 +1,312 @@ +pub mod states; + +use messages::{ + diddoc::aries::diddoc::AriesDidDoc, + protocols::{ + connection::invite::Invitation, + discovery::disclose::{Disclose, ProtocolDescriptor}, + }, +}; + +use crate::{core::profile::profile::Profile, errors::error::VcxResult}; + +use self::states::{ + complete::CompleteState, initial::InitialState, invited::InvitedState, requested::RequestedState, + responded::RespondedState, +}; + +use std::{collections::HashMap, sync::Arc}; + +use messages::{ + a2a::A2AMessage, + concepts::ack::Ack, + protocols::connection::{problem_report::ProblemReport, request::Request, response::SignedResponse}, +}; + +use super::{initiation_type::Invitee, Connection}; +use crate::{ + common::signing::decode_signed_connection_response, + errors::error::{AriesVcxError, AriesVcxErrorKind}, + handlers::util::verify_thread_id, + plugins::wallet::base_wallet::BaseWallet, + protocols::{connection::pairwise_info::PairwiseInfo, SendClosureConnection}, +}; + +/// Convenience alias +pub type InviteeConnection = Connection; + +impl InviteeConnection { + pub fn new_invitee( + source_id: String, + pairwise_info: PairwiseInfo, + did_doc: AriesDidDoc, + ) -> InviteeConnection { + Connection { + source_id, + thread_id: String::new(), + state: InitialState::new(None, did_doc), + pairwise_info, + initiation_type: Invitee, + } + } +} + +impl InviteeConnection { + /// Tries to convert [`InviteeNonMediatedConnection`] to [`InviteeNonMediatedConnection`] + /// by handling a received invitation. + /// + /// # Errors + /// Will error out if the there's no thread ID in the [`Invitation`]. + pub fn handle_invitation(self, invitation: Invitation) -> VcxResult> { + let thread_id = invitation.get_id()?; + + let did_doc = self.state.did_doc; + let state = InvitedState { invitation, did_doc }; + + // Convert to `InvitedState` + Ok(Connection { + state, + thread_id, + source_id: self.source_id, + pairwise_info: self.pairwise_info, + initiation_type: Invitee, + }) + } + + pub fn process_invite(self, invitation: Invitation) -> VcxResult> { + trace!("Connection::process_invite >>> invitation: {:?}", invitation); + self.handle_invitation(invitation) + } +} + +impl InviteeConnection { + pub fn get_invitation(&self) -> &Invitation { + &self.state.invitation + } + + /// Tries to convert [`SmConnectionInvitee2`] to [`SmConnectionInvitee2`] + /// by sending a connection request. + /// + /// # Errors + /// Will error out if building or sending the connection request message fails. + pub async fn send_connection_request( + self, + routing_keys: Vec, + service_endpoint: String, + send_message: SendClosureConnection, + ) -> VcxResult> { + let recipient_keys = vec![self.pairwise_info.pw_vk.clone()]; + let request = Request::create() + .set_label(self.source_id.to_string()) + .set_did(self.pairwise_info.pw_did.to_string()) + .set_service_endpoint(service_endpoint) + .set_keys(recipient_keys, routing_keys) + .set_out_time(); + + let request_id = request.id.0.clone(); + + let (request, thread_id) = match &self.state.invitation { + Invitation::Public(_) => ( + request + .set_parent_thread_id(&self.thread_id) + .set_thread_id_matching_id(), + request_id, + ), + Invitation::Pairwise(_) => (request.set_thread_id(&self.thread_id), self.thread_id().to_owned()), + Invitation::OutOfBand(invite) => ( + request.set_parent_thread_id(&invite.id.0).set_thread_id_matching_id(), + request_id, + ), + }; + + let did_doc = self.state.did_doc; + + send_message( + request.to_a2a_message(), + self.pairwise_info.pw_vk.clone(), + did_doc.clone(), + ) + .await?; + + let state = RequestedState { request, did_doc }; + + Ok(Connection { + state, + thread_id, + source_id: self.source_id, + pairwise_info: self.pairwise_info, + initiation_type: Invitee, + }) + } + + pub fn handle_problem_report(self, problem_report: ProblemReport) -> VcxResult> { + let Self { + source_id, + thread_id, + pairwise_info, + state, + .. + } = self; + + let state = InitialState::new(Some(problem_report), state.did_doc); + + Ok(Connection { + state, + source_id, + thread_id, + pairwise_info, + initiation_type: Invitee, + }) + } + + pub async fn send_request( + self, + profile: &Arc, + service_endpoint: String, + routing_keys: Vec, + send_message: Option, + ) -> VcxResult> { + trace!("Connection::send_request"); + let send_message = send_message.unwrap_or(self.send_message_closure_connection(profile)); + self.send_connection_request(routing_keys, service_endpoint, send_message) + .await + } +} + +impl InviteeConnection { + /// Returns the first entry from the map for which the message indicates a progressable state. + pub fn find_message_to_update_state(&self, messages: HashMap) -> Option<(String, A2AMessage)> { + messages + .into_iter() + .find(|(_, message)| Self::can_progress_state(message)) + } + + /// Determines whether the message indicates a progressable state. + pub fn can_progress_state(message: &A2AMessage) -> bool { + matches!( + message, + A2AMessage::ConnectionResponse(_) | A2AMessage::ConnectionProblemReport(_) + ) + } + + /// Tries to convert [`SmConnectionInvitee2`] to [`SmConnectionInvitee2`] + /// by handling a connection response. + /// + /// # Errors + /// Will error out if the thread ID verification fails, there are no keys in the DidDoc + /// or decoding the response fails. + // + // TODO: Why only convert the state to `InitialState` if the decoding fails? + // Why not on any other errors? + pub async fn handle_connection_response( + self, + wallet: &Arc, + response: SignedResponse, + _send_message: SendClosureConnection, + ) -> VcxResult> { + verify_thread_id(self.thread_id(), &A2AMessage::ConnectionResponse(response.clone()))?; + + let remote_vk: String = + self.state + .did_doc + .recipient_keys()? + .first() + .cloned() + .ok_or(AriesVcxError::from_msg( + AriesVcxErrorKind::InvalidState, + "Cannot handle response: remote verkey not found", + ))?; + + let Self { + source_id, + thread_id, + pairwise_info, + state, + .. + } = self; + + let state = decode_signed_connection_response(wallet, response.clone(), &remote_vk) + .await + .and_then(|response| state.try_into_responded(response))?; + + Ok(Connection { + state, + source_id, + thread_id, + pairwise_info, + initiation_type: Invitee, + }) + } + + pub fn handle_problem_report(self, problem_report: ProblemReport) -> VcxResult> { + let Self { + source_id, + thread_id, + pairwise_info, + state, + .. + } = self; + + let state = InitialState::new(Some(problem_report), state.did_doc); + + Ok(Connection { + state, + source_id, + thread_id, + pairwise_info, + initiation_type: Invitee, + }) + } +} + +impl InviteeConnection { + fn build_connection_ack_msg(&self) -> Ack { + Ack::create().set_out_time().set_thread_id(&self.thread_id) + } + + pub async fn handle_send_ack( + self, + send_message: SendClosureConnection, + ) -> VcxResult> { + let sender_vk = self.pairwise_info().pw_vk.clone(); + let did_doc = self.state.response.connection.did_doc.clone(); + + send_message(self.build_connection_ack_msg().to_a2a_message(), sender_vk, did_doc).await?; + + let Self { + source_id, + thread_id, + pairwise_info, + state, + .. + } = self; + + let state = CompleteState { + did_doc: state.did_doc, + bootstrap_did_doc: state.response.connection.did_doc, + protocols: None, + }; + + Ok(Connection { + state, + source_id, + thread_id, + pairwise_info, + initiation_type: Invitee, + }) + } +} + +impl InviteeConnection { + pub fn bootstrap_did_doc(&self) -> &AriesDidDoc { + &self.state.bootstrap_did_doc + } + + pub fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { + self.state.remote_protocols() + } + + pub fn handle_disclose(&mut self, disclose: Disclose) { + self.state.handle_disclose(disclose) + } +} diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/complete.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/complete.rs new file mode 100644 index 0000000000..917dc721f6 --- /dev/null +++ b/aries_vcx/src/protocols/typestate_con/invitee/states/complete.rs @@ -0,0 +1,57 @@ +use std::clone::Clone; + +use crate::protocols::connection::invitee::states::requested::RequestedState; +use crate::protocols::connection::invitee::states::responded::RespondedState; +use messages::diddoc::aries::diddoc::AriesDidDoc; +use messages::protocols::connection::response::Response; +use messages::protocols::discovery::disclose::{ProtocolDescriptor, Disclose}; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct CompleteState { + pub did_doc: AriesDidDoc, + pub bootstrap_did_doc: AriesDidDoc, + pub protocols: Option>, +} + +impl CompleteState { + pub fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { + self.protocols.as_deref() + } + + pub fn handle_disclose(&mut self, disclose: Disclose) { + self.protocols = Some(disclose.protocols) + } +} + +impl From<(CompleteState, Vec)> for CompleteState { + fn from((state, protocols): (CompleteState, Vec)) -> CompleteState { + trace!("ConnectionInvitee: transit state from CompleteState to CompleteState"); + CompleteState { + bootstrap_did_doc: state.bootstrap_did_doc, + did_doc: state.did_doc, + protocols: Some(protocols), + } + } +} + +impl From<(RequestedState, Response)> for CompleteState { + fn from((state, response): (RequestedState, Response)) -> CompleteState { + trace!("ConnectionInvitee: transit state from RequestedState to CompleteState"); + CompleteState { + bootstrap_did_doc: state.did_doc, + did_doc: response.connection.did_doc, + protocols: None, + } + } +} + +impl From for CompleteState { + fn from(state: RespondedState) -> CompleteState { + trace!("ConnectionInvitee: transit state from RespondedState to CompleteState"); + CompleteState { + bootstrap_did_doc: state.did_doc, + did_doc: state.response.connection.did_doc, + protocols: None, + } + } +} diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/initial.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/initial.rs new file mode 100644 index 0000000000..dd60579786 --- /dev/null +++ b/aries_vcx/src/protocols/typestate_con/invitee/states/initial.rs @@ -0,0 +1,26 @@ +use crate::protocols::connection::invitee::states::invited::InvitedState; +use messages::diddoc::aries::diddoc::AriesDidDoc; +use messages::protocols::connection::invite::Invitation; +use messages::protocols::connection::problem_report::ProblemReport; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct InitialState { + pub problem_report: Option, + pub did_doc: AriesDidDoc, +} + +impl From<(InitialState, Invitation, AriesDidDoc)> for InvitedState { + fn from((_state, invitation, did_doc): (InitialState, Invitation, AriesDidDoc)) -> InvitedState { + trace!("ConnectionInvitee: transit state from InitialState to InvitedState"); + InvitedState { invitation, did_doc } + } +} + +impl InitialState { + pub fn new(problem_report: Option, did_doc: AriesDidDoc) -> Self { + InitialState { + problem_report, + did_doc, + } + } +} diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs new file mode 100644 index 0000000000..622894b93e --- /dev/null +++ b/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs @@ -0,0 +1,17 @@ +use crate::protocols::connection::invitee::states::requested::RequestedState; +use messages::diddoc::aries::diddoc::AriesDidDoc; +use messages::protocols::connection::invite::Invitation; +use messages::protocols::connection::request::Request; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct InvitedState { + pub invitation: Invitation, + pub did_doc: AriesDidDoc, +} + +impl From<(InvitedState, Request, AriesDidDoc)> for RequestedState { + fn from((_state, request, did_doc): (InvitedState, Request, AriesDidDoc)) -> RequestedState { + trace!("ConnectionInvitee: transit state from InvitedState to RequestedState"); + RequestedState { request, did_doc } + } +} diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/mod.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/mod.rs new file mode 100644 index 0000000000..25dfdd5482 --- /dev/null +++ b/aries_vcx/src/protocols/typestate_con/invitee/states/mod.rs @@ -0,0 +1,5 @@ +pub mod complete; +pub mod initial; +pub mod invited; +pub mod requested; +pub mod responded; \ No newline at end of file diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs new file mode 100644 index 0000000000..c89f0ee478 --- /dev/null +++ b/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs @@ -0,0 +1,60 @@ +use crate::errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult}; +use crate::protocols::connection::invitee::states::initial::InitialState; +use crate::protocols::connection::invitee::states::responded::RespondedState; +use messages::diddoc::aries::diddoc::AriesDidDoc; +use messages::protocols::connection::problem_report::ProblemReport; +use messages::protocols::connection::request::Request; +use messages::protocols::connection::response::Response; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct RequestedState { + pub request: Request, + pub did_doc: AriesDidDoc, +} + +impl RequestedState { + /// Attempts to convert [`Self`] based on a [`Response`] into a [`RespondedState`]. + /// + /// # Errors + /// An error is returned if the response has an unexpected thread ID. + pub fn try_into_responded(self, response: Response) -> VcxResult { + if !response.from_thread(&self.request.get_thread_id()) { + let err_msg = format!( + "Cannot handle response: thread id does not match: {:?}", + response.thread + ); + + let err = AriesVcxError::from_msg(AriesVcxErrorKind::InvalidJson, err_msg); + + Err(err) + } else { + let state = RespondedState { + response, + request: self.request, + did_doc: self.did_doc, + }; + Ok(state) + } + } +} + +impl From<(RequestedState, ProblemReport)> for InitialState { + fn from((_state, problem_report): (RequestedState, ProblemReport)) -> InitialState { + trace!( + "ConnectionInvitee: transit state from RequestedState to InitialState, problem_report: {:?}", + problem_report + ); + InitialState::new(Some(problem_report), _state.did_doc) + } +} + +impl From<(RequestedState, Response)> for RespondedState { + fn from((state, response): (RequestedState, Response)) -> RespondedState { + trace!("ConnectionInvitee: transit state from RequestedState to RespondedState"); + RespondedState { + response, + did_doc: state.did_doc, + request: state.request, + } + } +} diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/responded.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/responded.rs new file mode 100644 index 0000000000..6d3b282048 --- /dev/null +++ b/aries_vcx/src/protocols/typestate_con/invitee/states/responded.rs @@ -0,0 +1,22 @@ +use crate::protocols::connection::invitee::states::initial::InitialState; +use messages::diddoc::aries::diddoc::AriesDidDoc; +use messages::protocols::connection::problem_report::ProblemReport; +use messages::protocols::connection::request::Request; +use messages::protocols::connection::response::Response; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct RespondedState { + pub response: Response, + pub request: Request, + pub did_doc: AriesDidDoc, +} + +impl From<(RespondedState, ProblemReport)> for InitialState { + fn from((_state, problem_report): (RespondedState, ProblemReport)) -> InitialState { + trace!( + "ConnectionInvitee: transit state from RespondedState to InitialState, problem_report: {:?}", + problem_report + ); + InitialState::new(Some(problem_report), _state.did_doc) + } +} diff --git a/aries_vcx/src/protocols/typestate_con/inviter/mod.rs b/aries_vcx/src/protocols/typestate_con/inviter/mod.rs new file mode 100644 index 0000000000..c3d0967e3c --- /dev/null +++ b/aries_vcx/src/protocols/typestate_con/inviter/mod.rs @@ -0,0 +1,261 @@ +pub mod states; + +use std::sync::Arc; + +use crate::handlers::util::verify_thread_id; +use crate::{ + common::signing::sign_connection_response, core::profile::profile::Profile, errors::error::VcxResult, + plugins::wallet::base_wallet::BaseWallet, protocols::SendClosureConnection, +}; + +use self::states::complete::CompleteState; +use self::states::initial::InitialState; +use self::states::{invited::InvitedState, requested::RequestedState, responded::RespondedState}; +use super::{initiation_type::Inviter, pairwise_info::PairwiseInfo, Connection}; +use messages::a2a::A2AMessage; +use messages::protocols::connection::invite::PairwiseInvitation; +use messages::protocols::connection::{ + invite::Invitation, + request::Request, + response::{Response, SignedResponse}, +}; +use messages::protocols::discovery::disclose::{ProtocolDescriptor, Disclose}; + +pub type InviterConnection = Connection; + +impl InviterConnection { + pub fn new_inviter( + source_id: String, + pairwise_info: PairwiseInfo, + ) -> InviterConnection { + Connection { + source_id, + thread_id: String::new(), + state: InitialState::new(None), + pairwise_info, + initiation_type: Inviter, + } + } +} + +impl InviterConnection { + pub fn create_invitation( + self, + routing_keys: Vec, + service_endpoint: String, + ) -> InviterConnection { + let invite: PairwiseInvitation = PairwiseInvitation::create() + .set_id(&self.thread_id) + .set_label(&self.source_id) + .set_recipient_keys(vec![self.pairwise_info.pw_vk.clone()]) + .set_routing_keys(routing_keys) + .set_service_endpoint(service_endpoint); + + let Self { + source_id, + thread_id, + pairwise_info, + initiation_type, + state, + } = self; + let state = (state, Invitation::Pairwise(invite)).into(); + + Connection { + source_id, + thread_id, + pairwise_info, + initiation_type, + state, + } + } + + pub fn create_invite( + self, + service_endpoint: String, + routing_keys: Vec, + ) -> InviterConnection { + self.create_invitation(routing_keys, service_endpoint) + } +} + +impl InviterConnection { + pub fn get_invitation(&self) -> &Invitation { + &self.state.invitation + } + + async fn handle_connection_request( + self, + wallet: Arc, + request: Request, + new_pairwise_info: &PairwiseInfo, + new_routing_keys: Vec, + new_service_endpoint: String, + _send_message: SendClosureConnection, + ) -> VcxResult> { + verify_thread_id(self.thread_id(), &A2AMessage::ConnectionRequest(request.clone()))?; + request.connection.did_doc.validate()?; + + let signed_response = self + .build_response( + &wallet, + &request, + new_pairwise_info, + new_routing_keys, + new_service_endpoint, + ) + .await?; + + let state = RequestedState { + signed_response, + did_doc: request.connection.did_doc, + thread_id: request.id.0, + }; + + let Self { + source_id, + thread_id, + pairwise_info, + initiation_type, + .. + } = self; + + Ok(Connection { + source_id, + thread_id, + pairwise_info, + initiation_type, + state, + }) + } + + async fn build_response( + &self, + wallet: &Arc, + request: &Request, + new_pairwise_info: &PairwiseInfo, + new_routing_keys: Vec, + new_service_endpoint: String, + ) -> VcxResult { + let new_recipient_keys = vec![new_pairwise_info.pw_vk.clone()]; + sign_connection_response( + wallet, + &self.pairwise_info.clone().pw_vk, + Response::create() + .set_did(new_pairwise_info.pw_did.to_string()) + .set_service_endpoint(new_service_endpoint) + .set_keys(new_recipient_keys, new_routing_keys) + .ask_for_ack() + .set_thread_id(&request.get_thread_id()) + .set_out_time(), + ) + .await + } + + pub async fn process_request( + self, + profile: &Arc, + request: Request, + service_endpoint: String, + routing_keys: Vec, + send_message: Option, + ) -> VcxResult> { + trace!( + "Connection::process_request >>> request: {:?}, service_endpoint: {}, routing_keys: {:?}", + request, + service_endpoint, + routing_keys, + ); + + let send_message = send_message.unwrap_or(self.send_message_closure_connection(profile)); + let new_pairwise_info = PairwiseInfo::create(&profile.inject_wallet()).await?; + + self.handle_connection_request( + profile.inject_wallet(), + request, + &new_pairwise_info, + routing_keys, + service_endpoint, + send_message, + ) + .await + } +} + +impl InviterConnection { + pub async fn handle_send_response( + self, + send_message: SendClosureConnection, + ) -> VcxResult> { + send_message( + self.state.signed_response.to_a2a_message(), + self.pairwise_info.pw_vk.clone(), + self.state.did_doc.clone(), + ) + .await?; + + let Self { + source_id, + thread_id, + pairwise_info, + initiation_type, + state, + } = self; + + Ok(Connection { + state: state.into(), + source_id, + thread_id, + pairwise_info, + initiation_type, + }) + } + + pub async fn send_response( + self, + profile: &Arc, + send_message: Option, + ) -> VcxResult> { + trace!("Connection::send_response >>>"); + let send_message = send_message.unwrap_or(self.send_message_closure_connection(profile)); + self.handle_send_response(send_message).await + } +} + +impl InviterConnection { + pub fn handle_confirmation_message(self, msg: &A2AMessage) -> VcxResult> { + verify_thread_id(self.thread_id(), msg)?; + + let Self { + source_id, + thread_id, + pairwise_info, + initiation_type, + state, + } = self; + + let state = state.into(); + + Ok(Connection { + source_id, + thread_id, + pairwise_info, + initiation_type, + state, + }) + } + + pub fn process_ack(self, message: &A2AMessage) -> VcxResult> { + self.handle_confirmation_message(message) + } +} + + +impl InviterConnection { + pub fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { + self.state.remote_protocols() + } + + pub fn handle_disclose(&mut self, disclose: Disclose) { + self.state.handle_disclose(disclose) + } +} diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/complete.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/complete.rs new file mode 100644 index 0000000000..6a0cad7311 --- /dev/null +++ b/aries_vcx/src/protocols/typestate_con/inviter/states/complete.rs @@ -0,0 +1,32 @@ +use std::clone::Clone; + +use messages::diddoc::aries::diddoc::AriesDidDoc; +use messages::protocols::discovery::disclose::{Disclose, ProtocolDescriptor}; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct CompleteState { + pub did_doc: AriesDidDoc, + pub protocols: Option>, + pub thread_id: Option, +} + +impl CompleteState { + pub fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { + self.protocols.as_deref() + } + + pub fn handle_disclose(&mut self, disclose: Disclose) { + self.protocols = Some(disclose.protocols) + } +} + +impl From<(CompleteState, Vec)> for CompleteState { + fn from((state, protocols): (CompleteState, Vec)) -> CompleteState { + trace!("ConnectionInviter: transit state from CompleteState to CompleteState"); + CompleteState { + did_doc: state.did_doc, + thread_id: state.thread_id, + protocols: Some(protocols), + } + } +} diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/initial.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/initial.rs new file mode 100644 index 0000000000..ffb41f66ab --- /dev/null +++ b/aries_vcx/src/protocols/typestate_con/inviter/states/initial.rs @@ -0,0 +1,21 @@ +use crate::protocols::connection::inviter::states::invited::InvitedState; +use messages::protocols::connection::invite::Invitation; +use messages::protocols::connection::problem_report::ProblemReport; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct InitialState { + problem_report: Option, +} + +impl From<(InitialState, Invitation)> for InvitedState { + fn from((_state, invitation): (InitialState, Invitation)) -> InvitedState { + trace!("ConnectionInviter: transit state from InitialState to InvitedState"); + InvitedState { invitation } + } +} + +impl InitialState { + pub fn new(problem_report: Option) -> Self { + InitialState { problem_report } + } +} diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs new file mode 100644 index 0000000000..9a7ed01157 --- /dev/null +++ b/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs @@ -0,0 +1,33 @@ +use crate::protocols::connection::inviter::states::initial::InitialState; +use crate::protocols::connection::inviter::states::requested::RequestedState; +use messages::protocols::connection::invite::Invitation; +use messages::protocols::connection::problem_report::ProblemReport; +use messages::protocols::connection::request::Request; +use messages::protocols::connection::response::SignedResponse; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct InvitedState { + pub invitation: Invitation, +} + +// TODO: These have no justification for being here anymore +impl From for InitialState { + fn from(problem_report: ProblemReport) -> InitialState { + trace!( + "ConnectionInviter: transit state to InitialState, problem_report: {:?}", + problem_report + ); + InitialState::new(Some(problem_report)) + } +} + +impl From<(Request, SignedResponse)> for RequestedState { + fn from((request, signed_response): (Request, SignedResponse)) -> RequestedState { + trace!("ConnectionInviter: transit state to RespondedState"); + RequestedState { + signed_response, + did_doc: request.connection.did_doc, + thread_id: request.id.0, + } + } +} \ No newline at end of file diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/mod.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/mod.rs new file mode 100644 index 0000000000..2c1b5a715f --- /dev/null +++ b/aries_vcx/src/protocols/typestate_con/inviter/states/mod.rs @@ -0,0 +1,5 @@ +pub(super) mod complete; +pub(super) mod initial; +pub(super) mod invited; +pub(super) mod requested; +pub(super) mod responded; diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs new file mode 100644 index 0000000000..11772b957e --- /dev/null +++ b/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs @@ -0,0 +1,32 @@ +use crate::protocols::connection::inviter::states::initial::InitialState; +use crate::protocols::connection::inviter::states::responded::RespondedState; +use messages::diddoc::aries::diddoc::AriesDidDoc; +use messages::protocols::connection::problem_report::ProblemReport; +use messages::protocols::connection::response::SignedResponse; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct RequestedState { + pub signed_response: SignedResponse, + pub did_doc: AriesDidDoc, + pub thread_id: String, +} + +impl From<(RequestedState, ProblemReport)> for InitialState { + fn from((_state, problem_report): (RequestedState, ProblemReport)) -> InitialState { + trace!( + "ConnectionInviter: transit state from RequestedState to InitialState, problem_report: {:?}", + problem_report + ); + InitialState::new(Some(problem_report)) + } +} + +impl From for RespondedState { + fn from(state: RequestedState) -> RespondedState { + trace!("ConnectionInviter: transit state from RequestedState to RespondedState"); + RespondedState { + signed_response: state.signed_response, + did_doc: state.did_doc, + } + } +} diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/responded.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/responded.rs new file mode 100644 index 0000000000..397eb3110d --- /dev/null +++ b/aries_vcx/src/protocols/typestate_con/inviter/states/responded.rs @@ -0,0 +1,36 @@ +use std::clone::Clone; + +use messages::diddoc::aries::diddoc::AriesDidDoc; + +use messages::protocols::connection::problem_report::ProblemReport; +use messages::protocols::connection::response::SignedResponse; + +use crate::protocols::connection::inviter::states::complete::CompleteState; +use crate::protocols::connection::inviter::states::initial::InitialState; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct RespondedState { + pub signed_response: SignedResponse, + pub did_doc: AriesDidDoc, +} + +impl From<(RespondedState, ProblemReport)> for InitialState { + fn from((_state, problem_report): (RespondedState, ProblemReport)) -> InitialState { + trace!( + "ConnectionInviter: transit state from RespondedState to InitialState, problem_report: {:?}", + problem_report + ); + InitialState::new(Some(problem_report)) + } +} + +impl From for CompleteState { + fn from(state: RespondedState) -> CompleteState { + trace!("ConnectionInviter: transit state from RespondedState to CompleteState"); + CompleteState { + did_doc: state.did_doc, + thread_id: Some(state.signed_response.get_thread_id()), + protocols: None, + } + } +} diff --git a/aries_vcx/src/protocols/typestate_con/mod.rs b/aries_vcx/src/protocols/typestate_con/mod.rs new file mode 100644 index 0000000000..39ce86a66d --- /dev/null +++ b/aries_vcx/src/protocols/typestate_con/mod.rs @@ -0,0 +1,91 @@ +mod trait_bounds; +mod pairwise_info; + +use messages::{ + a2a::{protocol_registry::ProtocolRegistry, A2AMessage}, + diddoc::aries::diddoc::AriesDidDoc, + protocols::discovery::disclose::ProtocolDescriptor, +}; +use std::sync::Arc; + +use crate::{ + core::profile::profile::Profile, + errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult}, + utils::send_message, +}; + +use self::{pairwise_info::PairwiseInfo, trait_bounds::TheirDidDoc}; + +use super::{SendClosure, SendClosureConnection}; + +pub struct Connection { + source_id: String, + thread_id: String, + pairwise_info: PairwiseInfo, + initiation_type: I, + state: S, +} + +impl Connection { + pub fn pairwise_info(&self) -> &PairwiseInfo { + &self.pairwise_info + } + + pub fn source_id(&self) -> &str { + &self.source_id + } + + pub fn thread_id(&self) -> &str { + &self.thread_id + } + + pub fn protocols(&self) -> Vec { + ProtocolRegistry::init().protocols() + } + + fn send_message_closure_connection(&self, profile: &Arc) -> SendClosureConnection { + trace!("send_message_closure_connection >>>"); + let wallet = profile.inject_wallet(); + Box::new(move |message: A2AMessage, sender_vk: String, did_doc: AriesDidDoc| { + Box::pin(send_message(wallet, sender_vk, did_doc, message)) + }) + } +} + +impl Connection +where + S: TheirDidDoc, +{ + pub fn their_did_doc(&self) -> &AriesDidDoc { + self.state.their_did_doc() + } + + pub fn remote_did(&self) -> &str { + &self.their_did_doc().id + } + + pub fn remote_vk(&self) -> VcxResult { + self.their_did_doc() + .recipient_keys()? + .first() + .map(ToOwned::to_owned) + .ok_or(AriesVcxError::from_msg( + AriesVcxErrorKind::NotReady, + "Can't resolve recipient key from the counterparty diddoc.", + )) + } + + pub async fn send_message_closure( + &self, + profile: &Arc, + send_message: Option, + ) -> VcxResult { + trace!("send_message_closure >>>"); + let did_doc = self.their_did_doc().clone(); + let sender_vk = self.pairwise_info().pw_vk.clone(); + let send_message = send_message.unwrap_or(self.send_message_closure_connection(profile)); + Ok(Box::new(move |message: A2AMessage| { + Box::pin(send_message(message, sender_vk, did_doc)) + })) + } +} diff --git a/aries_vcx/src/protocols/typestate_con/pairwise_info.rs b/aries_vcx/src/protocols/typestate_con/pairwise_info.rs new file mode 100644 index 0000000000..4c1821a73b --- /dev/null +++ b/aries_vcx/src/protocols/typestate_con/pairwise_info.rs @@ -0,0 +1,17 @@ +use std::sync::Arc; + +use crate::errors::error::VcxResult; +use crate::plugins::wallet::base_wallet::BaseWallet; + +#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct PairwiseInfo { + pub pw_did: String, + pub pw_vk: String, +} + +impl PairwiseInfo { + pub async fn create(wallet: &Arc) -> VcxResult { + let (pw_did, pw_vk) = wallet.create_and_store_my_did(None, None).await?; + Ok(PairwiseInfo { pw_did, pw_vk }) + } +} diff --git a/aries_vcx/src/protocols/connection/trait_bounds.rs b/aries_vcx/src/protocols/typestate_con/trait_bounds.rs similarity index 100% rename from aries_vcx/src/protocols/connection/trait_bounds.rs rename to aries_vcx/src/protocols/typestate_con/trait_bounds.rs From 8fff813f037af6ac4371a2fdf434efe610d289eb Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Wed, 25 Jan 2023 20:28:31 +0200 Subject: [PATCH 08/66] Refactored inner methods and simplified them Signed-off-by: Bogdan Mircea --- .../connection/invitee/states/requested.rs | 27 -- aries_vcx/src/protocols/connection/mod.rs | 1 - aries_vcx/src/protocols/mod.rs | 2 +- .../src/protocols/typestate_con/common/mod.rs | 1 + .../{inviter => common}/states/complete.rs | 25 +- .../typestate_con/common/states/mod.rs | 2 + .../typestate_con/common/states/responded.rs | 21 ++ .../initiation_type.rs | 0 .../protocols/typestate_con/invitee/mod.rs | 321 ++++++------------ .../typestate_con/invitee/states/complete.rs | 57 ---- .../typestate_con/invitee/states/initial.rs | 26 +- .../typestate_con/invitee/states/invited.rs | 20 +- .../typestate_con/invitee/states/mod.rs | 4 +- .../typestate_con/invitee/states/requested.rs | 57 +--- .../typestate_con/invitee/states/responded.rs | 22 -- .../protocols/typestate_con/inviter/mod.rs | 278 ++++++--------- .../typestate_con/inviter/states/initial.rs | 15 +- .../typestate_con/inviter/states/invited.rs | 31 +- .../typestate_con/inviter/states/mod.rs | 8 +- .../typestate_con/inviter/states/requested.rs | 32 +- .../typestate_con/inviter/states/responded.rs | 36 -- aries_vcx/src/protocols/typestate_con/mod.rs | 65 ++-- .../protocols/typestate_con/trait_bounds.rs | 10 +- 23 files changed, 327 insertions(+), 734 deletions(-) create mode 100644 aries_vcx/src/protocols/typestate_con/common/mod.rs rename aries_vcx/src/protocols/typestate_con/{inviter => common}/states/complete.rs (57%) create mode 100644 aries_vcx/src/protocols/typestate_con/common/states/mod.rs create mode 100644 aries_vcx/src/protocols/typestate_con/common/states/responded.rs rename aries_vcx/src/protocols/{connection => typestate_con}/initiation_type.rs (100%) delete mode 100644 aries_vcx/src/protocols/typestate_con/invitee/states/complete.rs delete mode 100644 aries_vcx/src/protocols/typestate_con/invitee/states/responded.rs delete mode 100644 aries_vcx/src/protocols/typestate_con/inviter/states/responded.rs diff --git a/aries_vcx/src/protocols/connection/invitee/states/requested.rs b/aries_vcx/src/protocols/connection/invitee/states/requested.rs index c89f0ee478..779351df11 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/requested.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/requested.rs @@ -1,4 +1,3 @@ -use crate::errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult}; use crate::protocols::connection::invitee::states::initial::InitialState; use crate::protocols::connection::invitee::states::responded::RespondedState; use messages::diddoc::aries::diddoc::AriesDidDoc; @@ -12,32 +11,6 @@ pub struct RequestedState { pub did_doc: AriesDidDoc, } -impl RequestedState { - /// Attempts to convert [`Self`] based on a [`Response`] into a [`RespondedState`]. - /// - /// # Errors - /// An error is returned if the response has an unexpected thread ID. - pub fn try_into_responded(self, response: Response) -> VcxResult { - if !response.from_thread(&self.request.get_thread_id()) { - let err_msg = format!( - "Cannot handle response: thread id does not match: {:?}", - response.thread - ); - - let err = AriesVcxError::from_msg(AriesVcxErrorKind::InvalidJson, err_msg); - - Err(err) - } else { - let state = RespondedState { - response, - request: self.request, - did_doc: self.did_doc, - }; - Ok(state) - } - } -} - impl From<(RequestedState, ProblemReport)> for InitialState { fn from((_state, problem_report): (RequestedState, ProblemReport)) -> InitialState { trace!( diff --git a/aries_vcx/src/protocols/connection/mod.rs b/aries_vcx/src/protocols/connection/mod.rs index d282258916..83222afec8 100644 --- a/aries_vcx/src/protocols/connection/mod.rs +++ b/aries_vcx/src/protocols/connection/mod.rs @@ -1,4 +1,3 @@ -pub mod initiation_type; pub mod invitee; pub mod inviter; pub mod pairwise_info; diff --git a/aries_vcx/src/protocols/mod.rs b/aries_vcx/src/protocols/mod.rs index c0328e1569..49693fb554 100644 --- a/aries_vcx/src/protocols/mod.rs +++ b/aries_vcx/src/protocols/mod.rs @@ -11,7 +11,7 @@ pub mod oob; pub mod proof_presentation; pub mod revocation_notification; pub mod trustping; -mod typestate_con; +pub mod typestate_con; pub type SendClosure = Box BoxFuture<'static, VcxResult<()>> + Send + Sync>; pub type SendClosureConnection = diff --git a/aries_vcx/src/protocols/typestate_con/common/mod.rs b/aries_vcx/src/protocols/typestate_con/common/mod.rs new file mode 100644 index 0000000000..ad079970d7 --- /dev/null +++ b/aries_vcx/src/protocols/typestate_con/common/mod.rs @@ -0,0 +1 @@ +pub mod states; \ No newline at end of file diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/complete.rs b/aries_vcx/src/protocols/typestate_con/common/states/complete.rs similarity index 57% rename from aries_vcx/src/protocols/typestate_con/inviter/states/complete.rs rename to aries_vcx/src/protocols/typestate_con/common/states/complete.rs index 6a0cad7311..4349014263 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/states/complete.rs +++ b/aries_vcx/src/protocols/typestate_con/common/states/complete.rs @@ -3,14 +3,24 @@ use std::clone::Clone; use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::discovery::disclose::{Disclose, ProtocolDescriptor}; +use crate::protocols::typestate_con::trait_bounds::TheirDidDoc; + #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct CompleteState { pub did_doc: AriesDidDoc, + pub thread_id: String, pub protocols: Option>, - pub thread_id: Option, } impl CompleteState { + pub fn new(did_doc: AriesDidDoc, thread_id: String, protocols: Option>) -> Self { + Self { + did_doc, + thread_id, + protocols, + } + } + pub fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { self.protocols.as_deref() } @@ -20,13 +30,8 @@ impl CompleteState { } } -impl From<(CompleteState, Vec)> for CompleteState { - fn from((state, protocols): (CompleteState, Vec)) -> CompleteState { - trace!("ConnectionInviter: transit state from CompleteState to CompleteState"); - CompleteState { - did_doc: state.did_doc, - thread_id: state.thread_id, - protocols: Some(protocols), - } +impl TheirDidDoc for CompleteState { + fn their_did_doc(&self) -> &AriesDidDoc { + &self.did_doc } -} +} \ No newline at end of file diff --git a/aries_vcx/src/protocols/typestate_con/common/states/mod.rs b/aries_vcx/src/protocols/typestate_con/common/states/mod.rs new file mode 100644 index 0000000000..77cc20b701 --- /dev/null +++ b/aries_vcx/src/protocols/typestate_con/common/states/mod.rs @@ -0,0 +1,2 @@ +pub mod complete; +pub mod responded; \ No newline at end of file diff --git a/aries_vcx/src/protocols/typestate_con/common/states/responded.rs b/aries_vcx/src/protocols/typestate_con/common/states/responded.rs new file mode 100644 index 0000000000..0d68f9c214 --- /dev/null +++ b/aries_vcx/src/protocols/typestate_con/common/states/responded.rs @@ -0,0 +1,21 @@ +use messages::diddoc::aries::diddoc::AriesDidDoc; + +use crate::protocols::typestate_con::trait_bounds::TheirDidDoc; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct RespondedState { + pub did_doc: AriesDidDoc, + pub thread_id: String +} + +impl RespondedState { + pub fn new(did_doc: AriesDidDoc, thread_id: String) -> Self { + Self { did_doc, thread_id } + } +} + +impl TheirDidDoc for RespondedState { + fn their_did_doc(&self) -> &AriesDidDoc { + &self.did_doc + } +} \ No newline at end of file diff --git a/aries_vcx/src/protocols/connection/initiation_type.rs b/aries_vcx/src/protocols/typestate_con/initiation_type.rs similarity index 100% rename from aries_vcx/src/protocols/connection/initiation_type.rs rename to aries_vcx/src/protocols/typestate_con/initiation_type.rs diff --git a/aries_vcx/src/protocols/typestate_con/invitee/mod.rs b/aries_vcx/src/protocols/typestate_con/invitee/mod.rs index 9f6a31687f..f0033b6aaf 100644 --- a/aries_vcx/src/protocols/typestate_con/invitee/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/invitee/mod.rs @@ -1,50 +1,41 @@ pub mod states; -use messages::{ - diddoc::aries::diddoc::AriesDidDoc, - protocols::{ - connection::invite::Invitation, - discovery::disclose::{Disclose, ProtocolDescriptor}, - }, -}; +use std::sync::Arc; -use crate::{core::profile::profile::Profile, errors::error::VcxResult}; +use messages::diddoc::aries::diddoc::AriesDidDoc; -use self::states::{ - complete::CompleteState, initial::InitialState, invited::InvitedState, requested::RequestedState, - responded::RespondedState, -}; +use crate::{errors::error::VcxResult, utils::uuid}; -use std::{collections::HashMap, sync::Arc}; +use self::states::{initial::InitialState, invited::InvitedState, requested::RequestedState}; use messages::{ a2a::A2AMessage, concepts::ack::Ack, - protocols::connection::{problem_report::ProblemReport, request::Request, response::SignedResponse}, + protocols::connection::{request::Request, response::SignedResponse}, }; -use super::{initiation_type::Invitee, Connection}; +use super::{ + common::states::{complete::CompleteState, responded::RespondedState}, + initiation_type::Invitee, + pairwise_info::PairwiseInfo, + trait_bounds::Transport, + Connection, +}; use crate::{ common::signing::decode_signed_connection_response, errors::error::{AriesVcxError, AriesVcxErrorKind}, handlers::util::verify_thread_id, plugins::wallet::base_wallet::BaseWallet, - protocols::{connection::pairwise_info::PairwiseInfo, SendClosureConnection}, }; /// Convenience alias pub type InviteeConnection = Connection; impl InviteeConnection { - pub fn new_invitee( - source_id: String, - pairwise_info: PairwiseInfo, - did_doc: AriesDidDoc, - ) -> InviteeConnection { + pub fn new(source_id: String, pairwise_info: PairwiseInfo) -> InviteeConnection { Connection { source_id, - thread_id: String::new(), - state: InitialState::new(None, did_doc), + state: InitialState, pairwise_info, initiation_type: Invitee, } @@ -52,50 +43,42 @@ impl InviteeConnection { } impl InviteeConnection { - /// Tries to convert [`InviteeNonMediatedConnection`] to [`InviteeNonMediatedConnection`] - /// by handling a received invitation. - /// - /// # Errors - /// Will error out if the there's no thread ID in the [`Invitation`]. - pub fn handle_invitation(self, invitation: Invitation) -> VcxResult> { - let thread_id = invitation.get_id()?; + // This should take an Invitation, but that also implies a DDO resolver + // for public invitations. + // Proper signature: + // pub fn into_invited(self, invitation: Invitation) -> VcxResult> { - let did_doc = self.state.did_doc; - let state = InvitedState { invitation, did_doc }; + // We'll accept a DidDoc for now. + pub fn into_invited(self, did_doc: AriesDidDoc) -> VcxResult> { + trace!("Connection::into_invited >>> did_doc: {:?}", &did_doc); + let thread_id = uuid::uuid(); + let state = InvitedState { did_doc, thread_id }; // Convert to `InvitedState` Ok(Connection { state, - thread_id, source_id: self.source_id, pairwise_info: self.pairwise_info, initiation_type: Invitee, }) } - - pub fn process_invite(self, invitation: Invitation) -> VcxResult> { - trace!("Connection::process_invite >>> invitation: {:?}", invitation); - self.handle_invitation(invitation) - } } impl InviteeConnection { - pub fn get_invitation(&self) -> &Invitation { - &self.state.invitation - } - - /// Tries to convert [`SmConnectionInvitee2`] to [`SmConnectionInvitee2`] - /// by sending a connection request. - /// - /// # Errors - /// Will error out if building or sending the connection request message fails. - pub async fn send_connection_request( + pub async fn send_request( self, - routing_keys: Vec, + wallet: &Arc, service_endpoint: String, - send_message: SendClosureConnection, - ) -> VcxResult> { + routing_keys: Vec, + transport: &T, + ) -> VcxResult> + where + T: Transport, + { + trace!("Connection::send_request"); + let recipient_keys = vec![self.pairwise_info.pw_vk.clone()]; + let request = Request::create() .set_label(self.source_id.to_string()) .set_did(self.pairwise_info.pw_did.to_string()) @@ -103,210 +86,104 @@ impl InviteeConnection { .set_keys(recipient_keys, routing_keys) .set_out_time(); - let request_id = request.id.0.clone(); - - let (request, thread_id) = match &self.state.invitation { - Invitation::Public(_) => ( - request - .set_parent_thread_id(&self.thread_id) - .set_thread_id_matching_id(), - request_id, - ), - Invitation::Pairwise(_) => (request.set_thread_id(&self.thread_id), self.thread_id().to_owned()), - Invitation::OutOfBand(invite) => ( - request.set_parent_thread_id(&invite.id.0).set_thread_id_matching_id(), - request_id, - ), - }; - - let did_doc = self.state.did_doc; - - send_message( - request.to_a2a_message(), - self.pairwise_info.pw_vk.clone(), - did_doc.clone(), + // Should be properly retrieved from Invitation. + // Also there's if this Request will just be serialized, it might as well take references. + let request = request.set_parent_thread_id(&self.state.thread_id); + + // The Invitation gets lost along the way when converting from Invited to Requested + // in previous implementations. Apart from these thread ID's, it's not used at all. + // + // Might as well implement it properly when accepting an Invitation in the `into_invited` method. + // + // let request_id = request.id.0.clone(); + // + // let (request, thread_id) = match &self.state.invitation { + // Invitation::Public(_) => ( + // request + // .set_parent_thread_id(&self.thread_id) + // .set_thread_id_matching_id(), + // request_id, + // ), + // Invitation::Pairwise(_) => (request.set_thread_id(&self.thread_id), self.thread_id().to_owned()), + // Invitation::OutOfBand(invite) => ( + // request.set_parent_thread_id(&invite.id.0).set_thread_id_matching_id(), + // request_id, + // ), + // }; + + Self::send_message( + wallet, + &self.state.did_doc, + &request.to_a2a_message(), + &self.pairwise_info.pw_vk, + transport, ) .await?; - let state = RequestedState { request, did_doc }; - Ok(Connection { - state, - thread_id, + state: RequestedState::new(self.state.did_doc, self.state.thread_id), source_id: self.source_id, pairwise_info: self.pairwise_info, initiation_type: Invitee, }) } - - pub fn handle_problem_report(self, problem_report: ProblemReport) -> VcxResult> { - let Self { - source_id, - thread_id, - pairwise_info, - state, - .. - } = self; - - let state = InitialState::new(Some(problem_report), state.did_doc); - - Ok(Connection { - state, - source_id, - thread_id, - pairwise_info, - initiation_type: Invitee, - }) - } - - pub async fn send_request( - self, - profile: &Arc, - service_endpoint: String, - routing_keys: Vec, - send_message: Option, - ) -> VcxResult> { - trace!("Connection::send_request"); - let send_message = send_message.unwrap_or(self.send_message_closure_connection(profile)); - self.send_connection_request(routing_keys, service_endpoint, send_message) - .await - } } impl InviteeConnection { - /// Returns the first entry from the map for which the message indicates a progressable state. - pub fn find_message_to_update_state(&self, messages: HashMap) -> Option<(String, A2AMessage)> { - messages - .into_iter() - .find(|(_, message)| Self::can_progress_state(message)) - } - - /// Determines whether the message indicates a progressable state. - pub fn can_progress_state(message: &A2AMessage) -> bool { - matches!( - message, - A2AMessage::ConnectionResponse(_) | A2AMessage::ConnectionProblemReport(_) - ) - } - - /// Tries to convert [`SmConnectionInvitee2`] to [`SmConnectionInvitee2`] - /// by handling a connection response. - /// - /// # Errors - /// Will error out if the thread ID verification fails, there are no keys in the DidDoc - /// or decoding the response fails. - // - // TODO: Why only convert the state to `InitialState` if the decoding fails? - // Why not on any other errors? - pub async fn handle_connection_response( + pub async fn handle_response( self, wallet: &Arc, response: SignedResponse, - _send_message: SendClosureConnection, - ) -> VcxResult> { - verify_thread_id(self.thread_id(), &A2AMessage::ConnectionResponse(response.clone()))?; - - let remote_vk: String = - self.state - .did_doc - .recipient_keys()? - .first() - .cloned() - .ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidState, - "Cannot handle response: remote verkey not found", - ))?; - - let Self { - source_id, - thread_id, - pairwise_info, - state, - .. - } = self; - - let state = decode_signed_connection_response(wallet, response.clone(), &remote_vk) + ) -> VcxResult> + where + T: Transport, + { + verify_thread_id(&self.state.thread_id, &A2AMessage::ConnectionResponse(response.clone()))?; + + let keys = &self.state.did_doc.recipient_keys()?; + let remote_vk = keys.first().ok_or(AriesVcxError::from_msg( + AriesVcxErrorKind::InvalidState, + "Cannot handle response: remote verkey not found", + ))?; + + let did_doc = decode_signed_connection_response(wallet, response, remote_vk) .await - .and_then(|response| state.try_into_responded(response))?; + .map(|response| response.connection.did_doc)?; - Ok(Connection { - state, - source_id, - thread_id, - pairwise_info, - initiation_type: Invitee, - }) - } - - pub fn handle_problem_report(self, problem_report: ProblemReport) -> VcxResult> { - let Self { - source_id, - thread_id, - pairwise_info, - state, - .. - } = self; - - let state = InitialState::new(Some(problem_report), state.did_doc); + let state = RespondedState::new(did_doc, self.state.thread_id); Ok(Connection { state, - source_id, - thread_id, - pairwise_info, + source_id: self.source_id, + pairwise_info: self.pairwise_info, initiation_type: Invitee, }) } } impl InviteeConnection { - fn build_connection_ack_msg(&self) -> Ack { - Ack::create().set_out_time().set_thread_id(&self.thread_id) - } - - pub async fn handle_send_ack( + pub async fn send_ack( self, - send_message: SendClosureConnection, - ) -> VcxResult> { - let sender_vk = self.pairwise_info().pw_vk.clone(); - let did_doc = self.state.response.connection.did_doc.clone(); - - send_message(self.build_connection_ack_msg().to_a2a_message(), sender_vk, did_doc).await?; + wallet: &Arc, + transport: &T, + ) -> VcxResult> + where + T: Transport, + { + let msg = Ack::create() + .set_out_time() + .set_thread_id(&self.state.thread_id) + .to_a2a_message(); - let Self { - source_id, - thread_id, - pairwise_info, - state, - .. - } = self; + Self::send_message(wallet, &self.state.did_doc, &msg, &self.pairwise_info.pw_vk, transport).await?; - let state = CompleteState { - did_doc: state.did_doc, - bootstrap_did_doc: state.response.connection.did_doc, - protocols: None, - }; + let state = CompleteState::new(self.state.did_doc, self.state.thread_id, None); Ok(Connection { state, - source_id, - thread_id, - pairwise_info, + source_id: self.source_id, + pairwise_info: self.pairwise_info, initiation_type: Invitee, }) } } - -impl InviteeConnection { - pub fn bootstrap_did_doc(&self) -> &AriesDidDoc { - &self.state.bootstrap_did_doc - } - - pub fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { - self.state.remote_protocols() - } - - pub fn handle_disclose(&mut self, disclose: Disclose) { - self.state.handle_disclose(disclose) - } -} diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/complete.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/complete.rs deleted file mode 100644 index 917dc721f6..0000000000 --- a/aries_vcx/src/protocols/typestate_con/invitee/states/complete.rs +++ /dev/null @@ -1,57 +0,0 @@ -use std::clone::Clone; - -use crate::protocols::connection::invitee::states::requested::RequestedState; -use crate::protocols::connection::invitee::states::responded::RespondedState; -use messages::diddoc::aries::diddoc::AriesDidDoc; -use messages::protocols::connection::response::Response; -use messages::protocols::discovery::disclose::{ProtocolDescriptor, Disclose}; - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct CompleteState { - pub did_doc: AriesDidDoc, - pub bootstrap_did_doc: AriesDidDoc, - pub protocols: Option>, -} - -impl CompleteState { - pub fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { - self.protocols.as_deref() - } - - pub fn handle_disclose(&mut self, disclose: Disclose) { - self.protocols = Some(disclose.protocols) - } -} - -impl From<(CompleteState, Vec)> for CompleteState { - fn from((state, protocols): (CompleteState, Vec)) -> CompleteState { - trace!("ConnectionInvitee: transit state from CompleteState to CompleteState"); - CompleteState { - bootstrap_did_doc: state.bootstrap_did_doc, - did_doc: state.did_doc, - protocols: Some(protocols), - } - } -} - -impl From<(RequestedState, Response)> for CompleteState { - fn from((state, response): (RequestedState, Response)) -> CompleteState { - trace!("ConnectionInvitee: transit state from RequestedState to CompleteState"); - CompleteState { - bootstrap_did_doc: state.did_doc, - did_doc: response.connection.did_doc, - protocols: None, - } - } -} - -impl From for CompleteState { - fn from(state: RespondedState) -> CompleteState { - trace!("ConnectionInvitee: transit state from RespondedState to CompleteState"); - CompleteState { - bootstrap_did_doc: state.did_doc, - did_doc: state.response.connection.did_doc, - protocols: None, - } - } -} diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/initial.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/initial.rs index dd60579786..88d0537111 100644 --- a/aries_vcx/src/protocols/typestate_con/invitee/states/initial.rs +++ b/aries_vcx/src/protocols/typestate_con/invitee/states/initial.rs @@ -1,26 +1,2 @@ -use crate::protocols::connection::invitee::states::invited::InvitedState; -use messages::diddoc::aries::diddoc::AriesDidDoc; -use messages::protocols::connection::invite::Invitation; -use messages::protocols::connection::problem_report::ProblemReport; - #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct InitialState { - pub problem_report: Option, - pub did_doc: AriesDidDoc, -} - -impl From<(InitialState, Invitation, AriesDidDoc)> for InvitedState { - fn from((_state, invitation, did_doc): (InitialState, Invitation, AriesDidDoc)) -> InvitedState { - trace!("ConnectionInvitee: transit state from InitialState to InvitedState"); - InvitedState { invitation, did_doc } - } -} - -impl InitialState { - pub fn new(problem_report: Option, did_doc: AriesDidDoc) -> Self { - InitialState { - problem_report, - did_doc, - } - } -} +pub struct InitialState; diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs index 622894b93e..b0636764fe 100644 --- a/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs +++ b/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs @@ -1,17 +1,21 @@ -use crate::protocols::connection::invitee::states::requested::RequestedState; use messages::diddoc::aries::diddoc::AriesDidDoc; -use messages::protocols::connection::invite::Invitation; -use messages::protocols::connection::request::Request; + +use crate::protocols::typestate_con::trait_bounds::TheirDidDoc; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct InvitedState { - pub invitation: Invitation, pub did_doc: AriesDidDoc, + pub thread_id: String } -impl From<(InvitedState, Request, AriesDidDoc)> for RequestedState { - fn from((_state, request, did_doc): (InvitedState, Request, AriesDidDoc)) -> RequestedState { - trace!("ConnectionInvitee: transit state from InvitedState to RequestedState"); - RequestedState { request, did_doc } +impl InvitedState { + pub fn new(did_doc: AriesDidDoc, thread_id: String) -> Self { + Self { did_doc, thread_id } } } + +impl TheirDidDoc for InvitedState { + fn their_did_doc(&self) -> &AriesDidDoc { + &self.did_doc + } +} \ No newline at end of file diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/mod.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/mod.rs index 25dfdd5482..d4151d969c 100644 --- a/aries_vcx/src/protocols/typestate_con/invitee/states/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/invitee/states/mod.rs @@ -1,5 +1,3 @@ -pub mod complete; -pub mod initial; pub mod invited; pub mod requested; -pub mod responded; \ No newline at end of file +pub mod initial; \ No newline at end of file diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs index c89f0ee478..639c0fa8a4 100644 --- a/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs +++ b/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs @@ -1,60 +1,21 @@ -use crate::errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult}; -use crate::protocols::connection::invitee::states::initial::InitialState; -use crate::protocols::connection::invitee::states::responded::RespondedState; use messages::diddoc::aries::diddoc::AriesDidDoc; -use messages::protocols::connection::problem_report::ProblemReport; -use messages::protocols::connection::request::Request; -use messages::protocols::connection::response::Response; + +use crate::protocols::typestate_con::trait_bounds::TheirDidDoc; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct RequestedState { - pub request: Request, pub did_doc: AriesDidDoc, + pub thread_id: String } impl RequestedState { - /// Attempts to convert [`Self`] based on a [`Response`] into a [`RespondedState`]. - /// - /// # Errors - /// An error is returned if the response has an unexpected thread ID. - pub fn try_into_responded(self, response: Response) -> VcxResult { - if !response.from_thread(&self.request.get_thread_id()) { - let err_msg = format!( - "Cannot handle response: thread id does not match: {:?}", - response.thread - ); - - let err = AriesVcxError::from_msg(AriesVcxErrorKind::InvalidJson, err_msg); - - Err(err) - } else { - let state = RespondedState { - response, - request: self.request, - did_doc: self.did_doc, - }; - Ok(state) - } + pub fn new(did_doc: AriesDidDoc, thread_id: String) -> Self { + Self { did_doc, thread_id } } } -impl From<(RequestedState, ProblemReport)> for InitialState { - fn from((_state, problem_report): (RequestedState, ProblemReport)) -> InitialState { - trace!( - "ConnectionInvitee: transit state from RequestedState to InitialState, problem_report: {:?}", - problem_report - ); - InitialState::new(Some(problem_report), _state.did_doc) +impl TheirDidDoc for RequestedState { + fn their_did_doc(&self) -> &AriesDidDoc { + &self.did_doc } -} - -impl From<(RequestedState, Response)> for RespondedState { - fn from((state, response): (RequestedState, Response)) -> RespondedState { - trace!("ConnectionInvitee: transit state from RequestedState to RespondedState"); - RespondedState { - response, - did_doc: state.did_doc, - request: state.request, - } - } -} +} \ No newline at end of file diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/responded.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/responded.rs deleted file mode 100644 index 6d3b282048..0000000000 --- a/aries_vcx/src/protocols/typestate_con/invitee/states/responded.rs +++ /dev/null @@ -1,22 +0,0 @@ -use crate::protocols::connection::invitee::states::initial::InitialState; -use messages::diddoc::aries::diddoc::AriesDidDoc; -use messages::protocols::connection::problem_report::ProblemReport; -use messages::protocols::connection::request::Request; -use messages::protocols::connection::response::Response; - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct RespondedState { - pub response: Response, - pub request: Request, - pub did_doc: AriesDidDoc, -} - -impl From<(RespondedState, ProblemReport)> for InitialState { - fn from((_state, problem_report): (RespondedState, ProblemReport)) -> InitialState { - trace!( - "ConnectionInvitee: transit state from RespondedState to InitialState, problem_report: {:?}", - problem_report - ); - InitialState::new(Some(problem_report), _state.did_doc) - } -} diff --git a/aries_vcx/src/protocols/typestate_con/inviter/mod.rs b/aries_vcx/src/protocols/typestate_con/inviter/mod.rs index c3d0967e3c..0336511091 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/mod.rs @@ -2,15 +2,18 @@ pub mod states; use std::sync::Arc; +use crate::errors::error::{AriesVcxError, AriesVcxErrorKind}; use crate::handlers::util::verify_thread_id; +use crate::utils::uuid; use crate::{ - common::signing::sign_connection_response, core::profile::profile::Profile, errors::error::VcxResult, - plugins::wallet::base_wallet::BaseWallet, protocols::SendClosureConnection, + common::signing::sign_connection_response, errors::error::VcxResult, plugins::wallet::base_wallet::BaseWallet, }; -use self::states::complete::CompleteState; use self::states::initial::InitialState; -use self::states::{invited::InvitedState, requested::RequestedState, responded::RespondedState}; +use self::states::{invited::InvitedState, requested::RequestedState}; +use super::common::states::complete::CompleteState; +use super::common::states::responded::RespondedState; +use super::trait_bounds::Transport; use super::{initiation_type::Inviter, pairwise_info::PairwiseInfo, Connection}; use messages::a2a::A2AMessage; use messages::protocols::connection::invite::PairwiseInvitation; @@ -19,243 +22,164 @@ use messages::protocols::connection::{ request::Request, response::{Response, SignedResponse}, }; -use messages::protocols::discovery::disclose::{ProtocolDescriptor, Disclose}; pub type InviterConnection = Connection; impl InviterConnection { - pub fn new_inviter( + pub fn new( source_id: String, pairwise_info: PairwiseInfo, - ) -> InviterConnection { - Connection { - source_id, - thread_id: String::new(), - state: InitialState::new(None), - pairwise_info, - initiation_type: Inviter, - } - } -} - -impl InviterConnection { - pub fn create_invitation( - self, routing_keys: Vec, service_endpoint: String, - ) -> InviterConnection { + ) -> InviterConnection { let invite: PairwiseInvitation = PairwiseInvitation::create() - .set_id(&self.thread_id) - .set_label(&self.source_id) - .set_recipient_keys(vec![self.pairwise_info.pw_vk.clone()]) + .set_id(&uuid::uuid()) + .set_label(&source_id) + .set_recipient_keys(vec![pairwise_info.pw_vk.clone()]) .set_routing_keys(routing_keys) .set_service_endpoint(service_endpoint); - let Self { - source_id, - thread_id, - pairwise_info, - initiation_type, - state, - } = self; - let state = (state, Invitation::Pairwise(invite)).into(); + let invitation = Invitation::Pairwise(invite); Connection { source_id, - thread_id, + state: InitialState::new(invitation), pairwise_info, - initiation_type, - state, + initiation_type: Inviter, } } - pub fn create_invite( - self, - service_endpoint: String, - routing_keys: Vec, - ) -> InviterConnection { - self.create_invitation(routing_keys, service_endpoint) + pub fn new_invited(source_id: String, pairwise_info: PairwiseInfo) -> InviterConnection { + Connection { + source_id, + state: InvitedState::new(None), // what should the thread ID be in this case??? + pairwise_info, + initiation_type: Inviter, + } } } -impl InviterConnection { +impl InviterConnection { pub fn get_invitation(&self) -> &Invitation { &self.state.invitation } - async fn handle_connection_request( - self, - wallet: Arc, - request: Request, - new_pairwise_info: &PairwiseInfo, - new_routing_keys: Vec, - new_service_endpoint: String, - _send_message: SendClosureConnection, - ) -> VcxResult> { - verify_thread_id(self.thread_id(), &A2AMessage::ConnectionRequest(request.clone()))?; - request.connection.did_doc.validate()?; + pub fn send_invitation(self, _transport: &T) -> VcxResult> { + // Implement some way to actually send the invitation + Err(AriesVcxError::from_msg( + AriesVcxErrorKind::ActionNotSupported, + "sending invites isn't yet supported!", + )) + } +} - let signed_response = self - .build_response( - &wallet, - &request, - new_pairwise_info, - new_routing_keys, - new_service_endpoint, - ) - .await?; +impl InviterConnection { + pub async fn handle_request(self, request: Request) -> VcxResult> + where + T: Transport, + { + trace!("Connection::process_request >>> request: {:?}", request,); + + // There must be some other way to validate the thread ID other than cloning the entire Request + self.state + .thread_id + .as_ref() + .map(|thread_id| verify_thread_id(thread_id, &A2AMessage::ConnectionRequest(request.clone()))) + .unwrap_or(Ok(()))?; - let state = RequestedState { - signed_response, - did_doc: request.connection.did_doc, - thread_id: request.id.0, - }; + request.connection.did_doc.validate()?; - let Self { - source_id, - thread_id, - pairwise_info, - initiation_type, - .. - } = self; + let state = RequestedState::new(request); Ok(Connection { - source_id, - thread_id, - pairwise_info, - initiation_type, + source_id: self.source_id, + pairwise_info: self.pairwise_info, + initiation_type: self.initiation_type, state, }) } +} +impl InviterConnection { async fn build_response( &self, wallet: &Arc, request: &Request, new_pairwise_info: &PairwiseInfo, - new_routing_keys: Vec, new_service_endpoint: String, + new_routing_keys: Vec, ) -> VcxResult { let new_recipient_keys = vec![new_pairwise_info.pw_vk.clone()]; - sign_connection_response( - wallet, - &self.pairwise_info.clone().pw_vk, - Response::create() - .set_did(new_pairwise_info.pw_did.to_string()) - .set_service_endpoint(new_service_endpoint) - .set_keys(new_recipient_keys, new_routing_keys) - .ask_for_ack() - .set_thread_id(&request.get_thread_id()) - .set_out_time(), - ) - .await + let response = Response::create() + .set_did(new_pairwise_info.pw_did.to_string()) + .set_service_endpoint(new_service_endpoint) + .set_keys(new_recipient_keys, new_routing_keys) + .ask_for_ack() + .set_thread_id(&request.get_thread_id()) + .set_out_time(); + + sign_connection_response(wallet, &self.pairwise_info.pw_vk, response).await } - pub async fn process_request( + pub async fn send_response( self, - profile: &Arc, - request: Request, - service_endpoint: String, - routing_keys: Vec, - send_message: Option, - ) -> VcxResult> { + wallet: &Arc, + new_service_endpoint: String, + new_routing_keys: Vec, + transport: &T, + ) -> VcxResult> + where + T: Transport, + { trace!( - "Connection::process_request >>> request: {:?}, service_endpoint: {}, routing_keys: {:?}", - request, - service_endpoint, - routing_keys, + "Connection::send_response >>> service_endpoint: {}, routing_keys: {:?}", + new_service_endpoint, + new_routing_keys, ); - let send_message = send_message.unwrap_or(self.send_message_closure_connection(profile)); - let new_pairwise_info = PairwiseInfo::create(&profile.inject_wallet()).await?; + let new_pairwise_info = PairwiseInfo::create(wallet).await?; + let thread_id = self.state.request.get_thread_id(); - self.handle_connection_request( - profile.inject_wallet(), - request, - &new_pairwise_info, - routing_keys, - service_endpoint, - send_message, - ) - .await - } -} + let signed_response = self + .build_response( + wallet, + &self.state.request, + &new_pairwise_info, + new_service_endpoint, + new_routing_keys, + ) + .await?; -impl InviterConnection { - pub async fn handle_send_response( - self, - send_message: SendClosureConnection, - ) -> VcxResult> { - send_message( - self.state.signed_response.to_a2a_message(), - self.pairwise_info.pw_vk.clone(), - self.state.did_doc.clone(), + Self::send_message( + wallet, + self.their_did_doc(), + &signed_response.to_a2a_message(), + &self.pairwise_info.pw_vk, + transport, ) .await?; - let Self { - source_id, - thread_id, - pairwise_info, - initiation_type, - state, - } = self; + let state = RespondedState::new(self.state.request.connection.did_doc, thread_id); Ok(Connection { - state: state.into(), - source_id, - thread_id, - pairwise_info, - initiation_type, + state, + source_id: self.source_id, + pairwise_info: new_pairwise_info, + initiation_type: self.initiation_type, }) } - - pub async fn send_response( - self, - profile: &Arc, - send_message: Option, - ) -> VcxResult> { - trace!("Connection::send_response >>>"); - let send_message = send_message.unwrap_or(self.send_message_closure_connection(profile)); - self.handle_send_response(send_message).await - } } impl InviterConnection { - pub fn handle_confirmation_message(self, msg: &A2AMessage) -> VcxResult> { - verify_thread_id(self.thread_id(), msg)?; - - let Self { - source_id, - thread_id, - pairwise_info, - initiation_type, - state, - } = self; - - let state = state.into(); + pub fn acknowledge_connection(self, msg: &A2AMessage) -> VcxResult> { + verify_thread_id(&self.state.thread_id, msg)?; + let state = CompleteState::new(self.state.did_doc, self.state.thread_id, None); Ok(Connection { - source_id, - thread_id, - pairwise_info, - initiation_type, + source_id: self.source_id, + pairwise_info: self.pairwise_info, + initiation_type: self.initiation_type, state, }) } - - pub fn process_ack(self, message: &A2AMessage) -> VcxResult> { - self.handle_confirmation_message(message) - } -} - - -impl InviterConnection { - pub fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { - self.state.remote_protocols() - } - - pub fn handle_disclose(&mut self, disclose: Disclose) { - self.state.handle_disclose(disclose) - } } diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/initial.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/initial.rs index ffb41f66ab..c59c5cf20a 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/states/initial.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/states/initial.rs @@ -1,21 +1,12 @@ -use crate::protocols::connection::inviter::states::invited::InvitedState; use messages::protocols::connection::invite::Invitation; -use messages::protocols::connection::problem_report::ProblemReport; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct InitialState { - problem_report: Option, -} - -impl From<(InitialState, Invitation)> for InvitedState { - fn from((_state, invitation): (InitialState, Invitation)) -> InvitedState { - trace!("ConnectionInviter: transit state from InitialState to InvitedState"); - InvitedState { invitation } - } + pub invitation: Invitation, } impl InitialState { - pub fn new(problem_report: Option) -> Self { - InitialState { problem_report } + pub fn new(invitation: Invitation) -> Self { + Self { invitation } } } diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs index 9a7ed01157..687ec40262 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs @@ -1,33 +1,10 @@ -use crate::protocols::connection::inviter::states::initial::InitialState; -use crate::protocols::connection::inviter::states::requested::RequestedState; -use messages::protocols::connection::invite::Invitation; -use messages::protocols::connection::problem_report::ProblemReport; -use messages::protocols::connection::request::Request; -use messages::protocols::connection::response::SignedResponse; - #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct InvitedState { - pub invitation: Invitation, + pub thread_id: Option, } -// TODO: These have no justification for being here anymore -impl From for InitialState { - fn from(problem_report: ProblemReport) -> InitialState { - trace!( - "ConnectionInviter: transit state to InitialState, problem_report: {:?}", - problem_report - ); - InitialState::new(Some(problem_report)) +impl InvitedState { + pub fn new(thread_id: Option) -> Self { + Self { thread_id } } } - -impl From<(Request, SignedResponse)> for RequestedState { - fn from((request, signed_response): (Request, SignedResponse)) -> RequestedState { - trace!("ConnectionInviter: transit state to RespondedState"); - RequestedState { - signed_response, - did_doc: request.connection.did_doc, - thread_id: request.id.0, - } - } -} \ No newline at end of file diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/mod.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/mod.rs index 2c1b5a715f..d4151d969c 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/states/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/states/mod.rs @@ -1,5 +1,3 @@ -pub(super) mod complete; -pub(super) mod initial; -pub(super) mod invited; -pub(super) mod requested; -pub(super) mod responded; +pub mod invited; +pub mod requested; +pub mod initial; \ No newline at end of file diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs index 11772b957e..99823f7b5f 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs @@ -1,32 +1,20 @@ -use crate::protocols::connection::inviter::states::initial::InitialState; -use crate::protocols::connection::inviter::states::responded::RespondedState; -use messages::diddoc::aries::diddoc::AriesDidDoc; -use messages::protocols::connection::problem_report::ProblemReport; -use messages::protocols::connection::response::SignedResponse; +use messages::{protocols::connection::request::Request, diddoc::aries::diddoc::AriesDidDoc}; + +use crate::protocols::typestate_con::trait_bounds::TheirDidDoc; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct RequestedState { - pub signed_response: SignedResponse, - pub did_doc: AriesDidDoc, - pub thread_id: String, + pub request: Request, } -impl From<(RequestedState, ProblemReport)> for InitialState { - fn from((_state, problem_report): (RequestedState, ProblemReport)) -> InitialState { - trace!( - "ConnectionInviter: transit state from RequestedState to InitialState, problem_report: {:?}", - problem_report - ); - InitialState::new(Some(problem_report)) +impl RequestedState { + pub fn new(request: Request) -> Self { + Self { request } } } -impl From for RespondedState { - fn from(state: RequestedState) -> RespondedState { - trace!("ConnectionInviter: transit state from RequestedState to RespondedState"); - RespondedState { - signed_response: state.signed_response, - did_doc: state.did_doc, - } +impl TheirDidDoc for RequestedState { + fn their_did_doc(&self) -> &AriesDidDoc { + &self.request.connection.did_doc } } diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/responded.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/responded.rs deleted file mode 100644 index 397eb3110d..0000000000 --- a/aries_vcx/src/protocols/typestate_con/inviter/states/responded.rs +++ /dev/null @@ -1,36 +0,0 @@ -use std::clone::Clone; - -use messages::diddoc::aries::diddoc::AriesDidDoc; - -use messages::protocols::connection::problem_report::ProblemReport; -use messages::protocols::connection::response::SignedResponse; - -use crate::protocols::connection::inviter::states::complete::CompleteState; -use crate::protocols::connection::inviter::states::initial::InitialState; - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct RespondedState { - pub signed_response: SignedResponse, - pub did_doc: AriesDidDoc, -} - -impl From<(RespondedState, ProblemReport)> for InitialState { - fn from((_state, problem_report): (RespondedState, ProblemReport)) -> InitialState { - trace!( - "ConnectionInviter: transit state from RespondedState to InitialState, problem_report: {:?}", - problem_report - ); - InitialState::new(Some(problem_report)) - } -} - -impl From for CompleteState { - fn from(state: RespondedState) -> CompleteState { - trace!("ConnectionInviter: transit state from RespondedState to CompleteState"); - CompleteState { - did_doc: state.did_doc, - thread_id: Some(state.signed_response.get_thread_id()), - protocols: None, - } - } -} diff --git a/aries_vcx/src/protocols/typestate_con/mod.rs b/aries_vcx/src/protocols/typestate_con/mod.rs index 39ce86a66d..80f38daa21 100644 --- a/aries_vcx/src/protocols/typestate_con/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/mod.rs @@ -1,26 +1,31 @@ -mod trait_bounds; +mod common; +mod initiation_type; +mod invitee; +mod inviter; mod pairwise_info; +mod trait_bounds; use messages::{ a2a::{protocol_registry::ProtocolRegistry, A2AMessage}, diddoc::aries::diddoc::AriesDidDoc, - protocols::discovery::disclose::ProtocolDescriptor, + protocols::discovery::disclose::{Disclose, ProtocolDescriptor}, }; use std::sync::Arc; use crate::{ - core::profile::profile::Profile, errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult}, - utils::send_message, + plugins::wallet::base_wallet::BaseWallet, + utils::encryption_envelope::EncryptionEnvelope, }; -use self::{pairwise_info::PairwiseInfo, trait_bounds::TheirDidDoc}; - -use super::{SendClosure, SendClosureConnection}; +use self::{ + common::states::complete::CompleteState, + pairwise_info::PairwiseInfo, + trait_bounds::{TheirDidDoc, Transport}, +}; pub struct Connection { source_id: String, - thread_id: String, pairwise_info: PairwiseInfo, initiation_type: I, state: S, @@ -35,20 +40,24 @@ impl Connection { &self.source_id } - pub fn thread_id(&self) -> &str { - &self.thread_id - } - pub fn protocols(&self) -> Vec { ProtocolRegistry::init().protocols() } - fn send_message_closure_connection(&self, profile: &Arc) -> SendClosureConnection { - trace!("send_message_closure_connection >>>"); - let wallet = profile.inject_wallet(); - Box::new(move |message: A2AMessage, sender_vk: String, did_doc: AriesDidDoc| { - Box::pin(send_message(wallet, sender_vk, did_doc, message)) - }) + pub async fn send_message( + wallet: &Arc, + did_doc: &AriesDidDoc, + message: &A2AMessage, + sender_verkey: &str, + transport: &T, + ) -> VcxResult<()> + where + T: Transport, + { + let env = EncryptionEnvelope::create(wallet, message, Some(sender_verkey), did_doc).await?; + let msg = env.0; + let service_endpoint = did_doc.get_endpoint(); // This, like many other things, shouldn't clone... + transport.send_message(msg, &service_endpoint).await } } @@ -74,18 +83,14 @@ where "Can't resolve recipient key from the counterparty diddoc.", )) } +} + +impl Connection { + pub fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { + self.state.remote_protocols() + } - pub async fn send_message_closure( - &self, - profile: &Arc, - send_message: Option, - ) -> VcxResult { - trace!("send_message_closure >>>"); - let did_doc = self.their_did_doc().clone(); - let sender_vk = self.pairwise_info().pw_vk.clone(); - let send_message = send_message.unwrap_or(self.send_message_closure_connection(profile)); - Ok(Box::new(move |message: A2AMessage| { - Box::pin(send_message(message, sender_vk, did_doc)) - })) + pub fn handle_disclose(&mut self, disclose: Disclose) { + self.state.handle_disclose(disclose) } } diff --git a/aries_vcx/src/protocols/typestate_con/trait_bounds.rs b/aries_vcx/src/protocols/typestate_con/trait_bounds.rs index 48cf8db3ca..3dfb3119b7 100644 --- a/aries_vcx/src/protocols/typestate_con/trait_bounds.rs +++ b/aries_vcx/src/protocols/typestate_con/trait_bounds.rs @@ -1,7 +1,15 @@ -use messages::diddoc::aries::diddoc::AriesDidDoc; +use async_trait::async_trait; +use messages::{diddoc::aries::diddoc::AriesDidDoc}; + +use crate::errors::error::VcxResult; /// Trait used for implementing common [`super::Connection`] behavior based /// on states implementing it. pub trait TheirDidDoc { fn their_did_doc(&self) -> &AriesDidDoc; +} + +#[async_trait] +pub trait Transport { + async fn send_message(&self, msg: Vec, service_endpoint: &str) -> VcxResult<()>; } \ No newline at end of file From ad9a6fe5ae6a5e0a35bcb74a1544318ca83b6b36 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Thu, 26 Jan 2023 08:34:32 +0200 Subject: [PATCH 09/66] Reverted changes on current code as the typestate_con is separated into a different module Signed-off-by: Bogdan Mircea --- .../connection/mediated_connection.rs | 4 +-- .../src/protocols/connection/invitee/mod.rs | 2 +- .../connection/invitee/state_machine.rs | 28 ++++++++++++------- .../connection/invitee/states/complete.rs | 12 +------- .../connection/invitee/states/initial.rs | 6 ++-- .../connection/invitee/states/mod.rs | 10 +++---- .../connection/invitee/states/requested.rs | 2 +- .../connection/invitee/states/responded.rs | 2 +- .../connection/inviter/state_machine.rs | 4 +-- .../connection/inviter/states/complete.rs | 12 +------- .../connection/inviter/states/invited.rs | 2 +- 11 files changed, 36 insertions(+), 48 deletions(-) diff --git a/aries_vcx/src/handlers/connection/mediated_connection.rs b/aries_vcx/src/handlers/connection/mediated_connection.rs index 08f6a6cccf..c5a6247891 100644 --- a/aries_vcx/src/handlers/connection/mediated_connection.rs +++ b/aries_vcx/src/handlers/connection/mediated_connection.rs @@ -245,7 +245,7 @@ impl MediatedConnection { } } - pub fn get_remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { + pub fn get_remote_protocols(&self) -> Option> { match &self.connection_sm { SmConnection::Inviter(sm_inviter) => sm_inviter.get_remote_protocols(), SmConnection::Invitee(sm_invitee) => sm_invitee.get_remote_protocols(), @@ -898,7 +898,7 @@ impl MediatedConnection { recipient_keys: did_doc.recipient_keys()?, routing_keys: did_doc.routing_keys(), service_endpoint: did_doc.get_endpoint(), - protocols: self.get_remote_protocols().map(ToOwned::to_owned), + protocols: self.get_remote_protocols(), }), None => None, }; diff --git a/aries_vcx/src/protocols/connection/invitee/mod.rs b/aries_vcx/src/protocols/connection/invitee/mod.rs index abe5f05f66..6b37a228b6 100644 --- a/aries_vcx/src/protocols/connection/invitee/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/mod.rs @@ -1,2 +1,2 @@ pub mod state_machine; -pub mod states; +mod states; diff --git a/aries_vcx/src/protocols/connection/invitee/state_machine.rs b/aries_vcx/src/protocols/connection/invitee/state_machine.rs index 18fe9f4a2a..2fc959b035 100644 --- a/aries_vcx/src/protocols/connection/invitee/state_machine.rs +++ b/aries_vcx/src/protocols/connection/invitee/state_machine.rs @@ -72,7 +72,7 @@ impl SmConnectionInvitee { SmConnectionInvitee { source_id: source_id.to_string(), thread_id: String::new(), - state: InviteeFullState::Initial(InitialState::new(None, did_doc)), + state: InviteeFullState::Initial(InitialState::new(None, Some(did_doc))), pairwise_info, } } @@ -112,7 +112,7 @@ impl SmConnectionInvitee { pub fn their_did_doc(&self) -> Option { match self.state { - InviteeFullState::Initial(ref state) => Some(state.did_doc.clone()), + InviteeFullState::Initial(ref state) => state.did_doc.clone(), InviteeFullState::Invited(ref state) => Some(state.did_doc.clone()), InviteeFullState::Requested(ref state) => Some(state.did_doc.clone()), InviteeFullState::Responded(ref state) => Some(state.did_doc.clone()), @@ -122,7 +122,7 @@ impl SmConnectionInvitee { pub async fn bootstrap_did_doc(&self) -> Option { match self.state { - InviteeFullState::Initial(ref state) => Some(state.did_doc.clone()), + InviteeFullState::Initial(ref state) => state.did_doc.clone(), InviteeFullState::Invited(ref state) => Some(state.did_doc.clone()), InviteeFullState::Requested(ref state) => Some(state.did_doc.clone()), InviteeFullState::Responded(ref state) => Some(state.did_doc.clone()), @@ -150,9 +150,9 @@ impl SmConnectionInvitee { ProtocolRegistry::init().protocols() } - pub fn get_remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { + pub fn get_remote_protocols(&self) -> Option> { match self.state { - InviteeFullState::Completed(ref state) => state.remote_protocols(), + InviteeFullState::Completed(ref state) => state.protocols.clone(), _ => None, } } @@ -242,9 +242,17 @@ impl SmConnectionInvitee { let Self { state, .. } = self; let thread_id = invitation.get_id()?; let state = match state { - InviteeFullState::Initial(state) => { - InviteeFullState::Invited((state.clone(), invitation, state.did_doc).into()) - } + InviteeFullState::Initial(state) => InviteeFullState::Invited( + ( + state.clone(), + invitation, + state.did_doc.ok_or(AriesVcxError::from_msg( + AriesVcxErrorKind::InvalidState, + "Expected none None state.did_doc result given current state", + ))?, + ) + .into(), + ), s => { return Err(AriesVcxError::from_msg( AriesVcxErrorKind::InvalidState, @@ -365,8 +373,8 @@ impl SmConnectionInvitee { pub fn handle_problem_report(self, _problem_report: ProblemReport) -> VcxResult { let state = match self.state { - InviteeFullState::Requested(_state) => InviteeFullState::Initial(InitialState::new(None, _state.did_doc)), - InviteeFullState::Invited(_state) => InviteeFullState::Initial(InitialState::new(None, _state.did_doc)), + InviteeFullState::Requested(_state) => InviteeFullState::Initial(InitialState::new(None, None)), + InviteeFullState::Invited(_state) => InviteeFullState::Initial(InitialState::new(None, None)), _ => self.state.clone(), }; Ok(Self { state, ..self }) diff --git a/aries_vcx/src/protocols/connection/invitee/states/complete.rs b/aries_vcx/src/protocols/connection/invitee/states/complete.rs index 917dc721f6..fed457c333 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/complete.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/complete.rs @@ -4,7 +4,7 @@ use crate::protocols::connection::invitee::states::requested::RequestedState; use crate::protocols::connection::invitee::states::responded::RespondedState; use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::connection::response::Response; -use messages::protocols::discovery::disclose::{ProtocolDescriptor, Disclose}; +use messages::protocols::discovery::disclose::ProtocolDescriptor; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct CompleteState { @@ -13,16 +13,6 @@ pub struct CompleteState { pub protocols: Option>, } -impl CompleteState { - pub fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { - self.protocols.as_deref() - } - - pub fn handle_disclose(&mut self, disclose: Disclose) { - self.protocols = Some(disclose.protocols) - } -} - impl From<(CompleteState, Vec)> for CompleteState { fn from((state, protocols): (CompleteState, Vec)) -> CompleteState { trace!("ConnectionInvitee: transit state from CompleteState to CompleteState"); diff --git a/aries_vcx/src/protocols/connection/invitee/states/initial.rs b/aries_vcx/src/protocols/connection/invitee/states/initial.rs index dd60579786..7522e6afc6 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/initial.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/initial.rs @@ -5,8 +5,8 @@ use messages::protocols::connection::problem_report::ProblemReport; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct InitialState { - pub problem_report: Option, - pub did_doc: AriesDidDoc, + problem_report: Option, + pub did_doc: Option, } impl From<(InitialState, Invitation, AriesDidDoc)> for InvitedState { @@ -17,7 +17,7 @@ impl From<(InitialState, Invitation, AriesDidDoc)> for InvitedState { } impl InitialState { - pub fn new(problem_report: Option, did_doc: AriesDidDoc) -> Self { + pub fn new(problem_report: Option, did_doc: Option) -> Self { InitialState { problem_report, did_doc, diff --git a/aries_vcx/src/protocols/connection/invitee/states/mod.rs b/aries_vcx/src/protocols/connection/invitee/states/mod.rs index 25dfdd5482..2c1b5a715f 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/mod.rs @@ -1,5 +1,5 @@ -pub mod complete; -pub mod initial; -pub mod invited; -pub mod requested; -pub mod responded; \ No newline at end of file +pub(super) mod complete; +pub(super) mod initial; +pub(super) mod invited; +pub(super) mod requested; +pub(super) mod responded; diff --git a/aries_vcx/src/protocols/connection/invitee/states/requested.rs b/aries_vcx/src/protocols/connection/invitee/states/requested.rs index 779351df11..d56f47b9f2 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/requested.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/requested.rs @@ -17,7 +17,7 @@ impl From<(RequestedState, ProblemReport)> for InitialState { "ConnectionInvitee: transit state from RequestedState to InitialState, problem_report: {:?}", problem_report ); - InitialState::new(Some(problem_report), _state.did_doc) + InitialState::new(Some(problem_report), None) } } diff --git a/aries_vcx/src/protocols/connection/invitee/states/responded.rs b/aries_vcx/src/protocols/connection/invitee/states/responded.rs index 6d3b282048..9d3e2bc28a 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/responded.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/responded.rs @@ -17,6 +17,6 @@ impl From<(RespondedState, ProblemReport)> for InitialState { "ConnectionInvitee: transit state from RespondedState to InitialState, problem_report: {:?}", problem_report ); - InitialState::new(Some(problem_report), _state.did_doc) + InitialState::new(Some(problem_report), None) } } diff --git a/aries_vcx/src/protocols/connection/inviter/state_machine.rs b/aries_vcx/src/protocols/connection/inviter/state_machine.rs index 794213adad..89fe3e6d64 100644 --- a/aries_vcx/src/protocols/connection/inviter/state_machine.rs +++ b/aries_vcx/src/protocols/connection/inviter/state_machine.rs @@ -132,9 +132,9 @@ impl SmConnectionInviter { ProtocolRegistry::init().protocols() } - pub fn get_remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { + pub fn get_remote_protocols(&self) -> Option> { match self.state { - InviterFullState::Completed(ref state) => state.remote_protocols(), + InviterFullState::Completed(ref state) => state.protocols.clone(), _ => None, } } diff --git a/aries_vcx/src/protocols/connection/inviter/states/complete.rs b/aries_vcx/src/protocols/connection/inviter/states/complete.rs index 6a0cad7311..5678f3f719 100644 --- a/aries_vcx/src/protocols/connection/inviter/states/complete.rs +++ b/aries_vcx/src/protocols/connection/inviter/states/complete.rs @@ -1,7 +1,7 @@ use std::clone::Clone; use messages::diddoc::aries::diddoc::AriesDidDoc; -use messages::protocols::discovery::disclose::{Disclose, ProtocolDescriptor}; +use messages::protocols::discovery::disclose::ProtocolDescriptor; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct CompleteState { @@ -10,16 +10,6 @@ pub struct CompleteState { pub thread_id: Option, } -impl CompleteState { - pub fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { - self.protocols.as_deref() - } - - pub fn handle_disclose(&mut self, disclose: Disclose) { - self.protocols = Some(disclose.protocols) - } -} - impl From<(CompleteState, Vec)> for CompleteState { fn from((state, protocols): (CompleteState, Vec)) -> CompleteState { trace!("ConnectionInviter: transit state from CompleteState to CompleteState"); diff --git a/aries_vcx/src/protocols/connection/inviter/states/invited.rs b/aries_vcx/src/protocols/connection/inviter/states/invited.rs index 9a7ed01157..409f0d4269 100644 --- a/aries_vcx/src/protocols/connection/inviter/states/invited.rs +++ b/aries_vcx/src/protocols/connection/inviter/states/invited.rs @@ -30,4 +30,4 @@ impl From<(Request, SignedResponse)> for RequestedState { thread_id: request.id.0, } } -} \ No newline at end of file +} From fb1260ae841746534799ff8caaf771505d088796 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Thu, 26 Jan 2023 09:53:07 +0200 Subject: [PATCH 10/66] Added serde capabilities to typestate Connection Signed-off-by: Bogdan Mircea --- .../typestate_con/initiation_type.rs | 2 + .../typestate_con/invitee/states/initial.rs | 2 +- aries_vcx/src/protocols/typestate_con/mod.rs | 13 ++ .../src/protocols/typestate_con/serde.rs | 147 ++++++++++++++++++ 4 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 aries_vcx/src/protocols/typestate_con/serde.rs diff --git a/aries_vcx/src/protocols/typestate_con/initiation_type.rs b/aries_vcx/src/protocols/typestate_con/initiation_type.rs index 597c16e747..55ae03af9a 100644 --- a/aries_vcx/src/protocols/typestate_con/initiation_type.rs +++ b/aries_vcx/src/protocols/typestate_con/initiation_type.rs @@ -1,6 +1,8 @@ /// Unit struct illustrating that the connection was initiated by an inviter. +#[derive(Clone, Copy)] pub struct Inviter; /// Unit struct illustrating that the connection was initiated by an invitee. +#[derive(Clone, Copy)] pub struct Invitee; \ No newline at end of file diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/initial.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/initial.rs index 88d0537111..88fb901100 100644 --- a/aries_vcx/src/protocols/typestate_con/invitee/states/initial.rs +++ b/aries_vcx/src/protocols/typestate_con/invitee/states/initial.rs @@ -1,2 +1,2 @@ -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq)] pub struct InitialState; diff --git a/aries_vcx/src/protocols/typestate_con/mod.rs b/aries_vcx/src/protocols/typestate_con/mod.rs index 80f38daa21..d987f57e45 100644 --- a/aries_vcx/src/protocols/typestate_con/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/mod.rs @@ -3,6 +3,7 @@ mod initiation_type; mod invitee; mod inviter; mod pairwise_info; +pub mod serde; mod trait_bounds; use messages::{ @@ -21,9 +22,21 @@ use crate::{ use self::{ common::states::complete::CompleteState, pairwise_info::PairwiseInfo, + serde::{SerdeCon, SerdeState}, trait_bounds::{TheirDidDoc, Transport}, }; +// The serialization will first convert into the serializable connection type +// but will do that by cloning, which is fairly unfortunate and unnecessary. +// +// We can theoretically serialize this type as well directly, through a reference, +// but we must align the deserialization to be to the serializable connection +// and ensure the format matches. +// +// Can definitely be done, but just requires a bit of work put into it. +#[derive(Clone, Serialize)] +#[serde(into = "SerdeCon")] +#[serde(bound(serialize = "SerdeState: From<(I, S)>, I: Clone, S: Clone"))] pub struct Connection { source_id: String, pairwise_info: PairwiseInfo, diff --git a/aries_vcx/src/protocols/typestate_con/serde.rs b/aries_vcx/src/protocols/typestate_con/serde.rs new file mode 100644 index 0000000000..04cf3cc02b --- /dev/null +++ b/aries_vcx/src/protocols/typestate_con/serde.rs @@ -0,0 +1,147 @@ +use super::{ + common::states::{complete::CompleteState, responded::RespondedState}, + initiation_type::{Invitee, Inviter}, + invitee::states::{ + initial::InitialState as InviteeInitial, invited::InvitedState as InviteeInvited, + requested::RequestedState as InviteeRequested, + }, + inviter::states::{ + initial::InitialState as InviterInitial, invited::InvitedState as InviterInvited, + requested::RequestedState as InviterRequested, + }, + pairwise_info::PairwiseInfo, + Connection, +}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct SerdeCon { + source_id: String, + pairwise_info: PairwiseInfo, + state: SerdeState, +} + +impl SerdeCon { + fn new(source_id: String, pairwise_info: PairwiseInfo, state: SerdeState) -> Self { + Self { + source_id, + pairwise_info, + state, + } + } +} + +impl From> for SerdeCon +where + SerdeState: From<(I, S)>, +{ + fn from(value: Connection) -> Self { + let state = From::from((value.initiation_type, value.state)); + Self::new(value.source_id, value.pairwise_info, state) + } +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum SerdeState { + Inviter(SerdeInviterState), + Invitee(SerdeInviteeState), +} + +impl From<(Inviter, S)> for SerdeState +where + SerdeInviterState: From, +{ + fn from(value: (Inviter, S)) -> Self { + let (_, state) = value; + let serde_state = From::from(state); + Self::Inviter(serde_state) + } +} + +impl From<(Invitee, S)> for SerdeState +where + SerdeInviteeState: From, +{ + fn from(value: (Invitee, S)) -> Self { + let (_, state) = value; + let serde_state = From::from(state); + Self::Invitee(serde_state) + } +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum SerdeInviterState { + Initial(InviterInitial), + Invited(InviterInvited), + Requested(InviterRequested), + Responded(RespondedState), + Complete(CompleteState), +} + +impl From for SerdeInviterState { + fn from(value: InviterInitial) -> Self { + Self::Initial(value) + } +} + +impl From for SerdeInviterState { + fn from(value: InviterInvited) -> Self { + Self::Invited(value) + } +} + +impl From for SerdeInviterState { + fn from(value: InviterRequested) -> Self { + Self::Requested(value) + } +} + +impl From for SerdeInviterState { + fn from(value: RespondedState) -> Self { + Self::Responded(value) + } +} + +impl From for SerdeInviterState { + fn from(value: CompleteState) -> Self { + Self::Complete(value) + } +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum SerdeInviteeState { + Initial(InviteeInitial), + Invited(InviteeInvited), + Requested(InviteeRequested), + Responded(RespondedState), + Complete(CompleteState), +} + +impl From for SerdeInviteeState { + fn from(value: InviteeInitial) -> Self { + Self::Initial(value) + } +} + +impl From for SerdeInviteeState { + fn from(value: InviteeInvited) -> Self { + Self::Invited(value) + } +} + +impl From for SerdeInviteeState { + fn from(value: InviteeRequested) -> Self { + Self::Requested(value) + } +} + +impl From for SerdeInviteeState { + fn from(value: RespondedState) -> Self { + Self::Responded(value) + } +} + +impl From for SerdeInviteeState { + fn from(value: CompleteState) -> Self { + Self::Complete(value) + } +} From f48c42983fdf121fd82ad583c6623d74ea8bc873 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Fri, 27 Jan 2023 09:12:49 +0200 Subject: [PATCH 11/66] Added invitation processing to Invitee and moved some Connection methods to their appropriate types Signed-off-by: Bogdan Mircea --- .../protocols/typestate_con/invitee/mod.rs | 52 ++++++++----------- .../protocols/typestate_con/inviter/mod.rs | 41 ++++++--------- aries_vcx/src/protocols/typestate_con/mod.rs | 40 +++++++------- 3 files changed, 58 insertions(+), 75 deletions(-) diff --git a/aries_vcx/src/protocols/typestate_con/invitee/mod.rs b/aries_vcx/src/protocols/typestate_con/invitee/mod.rs index f0033b6aaf..bdb11a5ab4 100644 --- a/aries_vcx/src/protocols/typestate_con/invitee/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/invitee/mod.rs @@ -2,9 +2,9 @@ pub mod states; use std::sync::Arc; -use messages::diddoc::aries::diddoc::AriesDidDoc; +use messages::protocols::connection::invite::Invitation; -use crate::{errors::error::VcxResult, utils::uuid}; +use crate::{common::ledger::transactions::into_did_doc, core::profile::profile::Profile, errors::error::VcxResult, utils}; use self::states::{initial::InitialState, invited::InvitedState, requested::RequestedState}; @@ -31,27 +31,29 @@ use crate::{ /// Convenience alias pub type InviteeConnection = Connection; -impl InviteeConnection { - pub fn new(source_id: String, pairwise_info: PairwiseInfo) -> InviteeConnection { - Connection { +impl InviteeConnection { + pub fn new(source_id: String, pairwise_info: PairwiseInfo) -> Self { + Self { source_id, state: InitialState, pairwise_info, initiation_type: Invitee, } } -} -impl InviteeConnection { - // This should take an Invitation, but that also implies a DDO resolver - // for public invitations. - // Proper signature: - // pub fn into_invited(self, invitation: Invitation) -> VcxResult> { - - // We'll accept a DidDoc for now. - pub fn into_invited(self, did_doc: AriesDidDoc) -> VcxResult> { - trace!("Connection::into_invited >>> did_doc: {:?}", &did_doc); - let thread_id = uuid::uuid(); + pub async fn accept_invitation( + self, + profile: &Arc, + invitation: &Invitation, + ) -> VcxResult> { + trace!("Connection::into_invited >>> invitation: {:?}", &invitation); + + // Why would all inviters that accept an + // invitation use the same thread ID? + // + // let thread_id = invitation.get_id()?; + let thread_id = utils::uuid::uuid(); + let did_doc = into_did_doc(profile, invitation).await?; let state = InvitedState { did_doc, thread_id }; // Convert to `InvitedState` @@ -111,14 +113,7 @@ impl InviteeConnection { // ), // }; - Self::send_message( - wallet, - &self.state.did_doc, - &request.to_a2a_message(), - &self.pairwise_info.pw_vk, - transport, - ) - .await?; + self.send_message(wallet, &request.to_a2a_message(), transport).await?; Ok(Connection { state: RequestedState::new(self.state.did_doc, self.state.thread_id), @@ -130,14 +125,11 @@ impl InviteeConnection { } impl InviteeConnection { - pub async fn handle_response( + pub async fn handle_response( self, wallet: &Arc, response: SignedResponse, - ) -> VcxResult> - where - T: Transport, - { + ) -> VcxResult> { verify_thread_id(&self.state.thread_id, &A2AMessage::ConnectionResponse(response.clone()))?; let keys = &self.state.did_doc.recipient_keys()?; @@ -175,7 +167,7 @@ impl InviteeConnection { .set_thread_id(&self.state.thread_id) .to_a2a_message(); - Self::send_message(wallet, &self.state.did_doc, &msg, &self.pairwise_info.pw_vk, transport).await?; + self.send_message(wallet, &msg, transport).await?; let state = CompleteState::new(self.state.did_doc, self.state.thread_id, None); diff --git a/aries_vcx/src/protocols/typestate_con/inviter/mod.rs b/aries_vcx/src/protocols/typestate_con/inviter/mod.rs index 0336511091..17a1ca7c6d 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/mod.rs @@ -25,13 +25,13 @@ use messages::protocols::connection::{ pub type InviterConnection = Connection; -impl InviterConnection { +impl InviterConnection { pub fn new( source_id: String, pairwise_info: PairwiseInfo, routing_keys: Vec, service_endpoint: String, - ) -> InviterConnection { + ) -> Self { let invite: PairwiseInvitation = PairwiseInvitation::create() .set_id(&uuid::uuid()) .set_label(&source_id) @@ -41,7 +41,7 @@ impl InviterConnection { let invitation = Invitation::Pairwise(invite); - Connection { + Self { source_id, state: InitialState::new(invitation), pairwise_info, @@ -49,17 +49,6 @@ impl InviterConnection { } } - pub fn new_invited(source_id: String, pairwise_info: PairwiseInfo) -> InviterConnection { - Connection { - source_id, - state: InvitedState::new(None), // what should the thread ID be in this case??? - pairwise_info, - initiation_type: Inviter, - } - } -} - -impl InviterConnection { pub fn get_invitation(&self) -> &Invitation { &self.state.invitation } @@ -74,10 +63,16 @@ impl InviterConnection { } impl InviterConnection { - pub async fn handle_request(self, request: Request) -> VcxResult> - where - T: Transport, - { + pub fn new_invited(source_id: String, pairwise_info: PairwiseInfo) -> Self { + Self { + source_id, + state: InvitedState::new(None), // what should the thread ID be in this case??? + pairwise_info, + initiation_type: Inviter, + } + } + + pub async fn handle_request(self, request: Request) -> VcxResult> { trace!("Connection::process_request >>> request: {:?}", request,); // There must be some other way to validate the thread ID other than cloning the entire Request @@ -150,14 +145,8 @@ impl InviterConnection { ) .await?; - Self::send_message( - wallet, - self.their_did_doc(), - &signed_response.to_a2a_message(), - &self.pairwise_info.pw_vk, - transport, - ) - .await?; + self.send_message(wallet, &signed_response.to_a2a_message(), transport) + .await?; let state = RespondedState::new(self.state.request.connection.did_doc, thread_id); diff --git a/aries_vcx/src/protocols/typestate_con/mod.rs b/aries_vcx/src/protocols/typestate_con/mod.rs index d987f57e45..4111a93a8d 100644 --- a/aries_vcx/src/protocols/typestate_con/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/mod.rs @@ -1,8 +1,8 @@ mod common; mod initiation_type; -mod invitee; -mod inviter; -mod pairwise_info; +pub mod invitee; +pub mod inviter; +pub mod pairwise_info; pub mod serde; mod trait_bounds; @@ -56,22 +56,6 @@ impl Connection { pub fn protocols(&self) -> Vec { ProtocolRegistry::init().protocols() } - - pub async fn send_message( - wallet: &Arc, - did_doc: &AriesDidDoc, - message: &A2AMessage, - sender_verkey: &str, - transport: &T, - ) -> VcxResult<()> - where - T: Transport, - { - let env = EncryptionEnvelope::create(wallet, message, Some(sender_verkey), did_doc).await?; - let msg = env.0; - let service_endpoint = did_doc.get_endpoint(); // This, like many other things, shouldn't clone... - transport.send_message(msg, &service_endpoint).await - } } impl Connection @@ -96,6 +80,24 @@ where "Can't resolve recipient key from the counterparty diddoc.", )) } + + pub async fn send_message( + &self, + wallet: &Arc, + message: &A2AMessage, + transport: &T, + ) -> VcxResult<()> + where + T: Transport, + { + let sender_verkey = &self.pairwise_info.pw_vk; + let did_doc = self.their_did_doc(); + let env = EncryptionEnvelope::create(wallet, message, Some(sender_verkey), did_doc).await?; + let msg = env.0; + let service_endpoint = did_doc.get_endpoint(); // This, like many other things, shouldn't clone... + + transport.send_message(msg, &service_endpoint).await + } } impl Connection { From 18b0f4c7858ce8de169f2ed175ce3f70e7f17a19 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Fri, 27 Jan 2023 09:28:07 +0200 Subject: [PATCH 12/66] Renamed SerdeCon to VagueConnection. This will be used for deserialization only Signed-off-by: Bogdan Mircea --- .../typestate_con/initiation_type.rs | 4 +- aries_vcx/src/protocols/typestate_con/mod.rs | 6 +- .../typestate_con/{serde.rs => serde/de.rs} | 63 ++++++++++--------- .../src/protocols/typestate_con/serde/mod.rs | 2 + .../src/protocols/typestate_con/serde/ser.rs | 0 5 files changed, 38 insertions(+), 37 deletions(-) rename aries_vcx/src/protocols/typestate_con/{serde.rs => serde/de.rs} (66%) create mode 100644 aries_vcx/src/protocols/typestate_con/serde/mod.rs create mode 100644 aries_vcx/src/protocols/typestate_con/serde/ser.rs diff --git a/aries_vcx/src/protocols/typestate_con/initiation_type.rs b/aries_vcx/src/protocols/typestate_con/initiation_type.rs index 55ae03af9a..eda8e75cd2 100644 --- a/aries_vcx/src/protocols/typestate_con/initiation_type.rs +++ b/aries_vcx/src/protocols/typestate_con/initiation_type.rs @@ -1,8 +1,8 @@ /// Unit struct illustrating that the connection was initiated by an inviter. -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] pub struct Inviter; /// Unit struct illustrating that the connection was initiated by an invitee. -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] pub struct Invitee; \ No newline at end of file diff --git a/aries_vcx/src/protocols/typestate_con/mod.rs b/aries_vcx/src/protocols/typestate_con/mod.rs index 4111a93a8d..894a344350 100644 --- a/aries_vcx/src/protocols/typestate_con/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/mod.rs @@ -22,7 +22,6 @@ use crate::{ use self::{ common::states::complete::CompleteState, pairwise_info::PairwiseInfo, - serde::{SerdeCon, SerdeState}, trait_bounds::{TheirDidDoc, Transport}, }; @@ -34,9 +33,6 @@ use self::{ // and ensure the format matches. // // Can definitely be done, but just requires a bit of work put into it. -#[derive(Clone, Serialize)] -#[serde(into = "SerdeCon")] -#[serde(bound(serialize = "SerdeState: From<(I, S)>, I: Clone, S: Clone"))] pub struct Connection { source_id: String, pairwise_info: PairwiseInfo, @@ -95,7 +91,7 @@ where let env = EncryptionEnvelope::create(wallet, message, Some(sender_verkey), did_doc).await?; let msg = env.0; let service_endpoint = did_doc.get_endpoint(); // This, like many other things, shouldn't clone... - + transport.send_message(msg, &service_endpoint).await } } diff --git a/aries_vcx/src/protocols/typestate_con/serde.rs b/aries_vcx/src/protocols/typestate_con/serde/de.rs similarity index 66% rename from aries_vcx/src/protocols/typestate_con/serde.rs rename to aries_vcx/src/protocols/typestate_con/serde/de.rs index 04cf3cc02b..dfe7111fc6 100644 --- a/aries_vcx/src/protocols/typestate_con/serde.rs +++ b/aries_vcx/src/protocols/typestate_con/serde/de.rs @@ -1,4 +1,4 @@ -use super::{ +use crate::protocols::typestate_con::{ common::states::{complete::CompleteState, responded::RespondedState}, initiation_type::{Invitee, Inviter}, invitee::states::{ @@ -13,15 +13,18 @@ use super::{ Connection, }; -#[derive(Debug, Serialize, Deserialize)] -pub struct SerdeCon { +/// Type used for deserialization of a [`Connection`]. +/// This struct cannot be used for anything useful directly, +/// but the inner `state` has to be matched to get the concrete [`Connection`] type. +#[derive(Debug, Deserialize)] +pub struct VagueConnection { source_id: String, pairwise_info: PairwiseInfo, - state: SerdeState, + pub state: State, } -impl SerdeCon { - fn new(source_id: String, pairwise_info: PairwiseInfo, state: SerdeState) -> Self { +impl VagueConnection { + fn new(source_id: String, pairwise_info: PairwiseInfo, state: State) -> Self { Self { source_id, pairwise_info, @@ -30,9 +33,9 @@ impl SerdeCon { } } -impl From> for SerdeCon +impl From> for VagueConnection where - SerdeState: From<(I, S)>, + State: From<(I, S)>, { fn from(value: Connection) -> Self { let state = From::from((value.initiation_type, value.state)); @@ -40,15 +43,15 @@ where } } -#[derive(Debug, Serialize, Deserialize)] -pub enum SerdeState { - Inviter(SerdeInviterState), - Invitee(SerdeInviteeState), +#[derive(Debug, Deserialize)] +pub enum State { + Inviter(InviterState), + Invitee(InviteeState), } -impl From<(Inviter, S)> for SerdeState +impl From<(Inviter, S)> for State where - SerdeInviterState: From, + InviterState: From, { fn from(value: (Inviter, S)) -> Self { let (_, state) = value; @@ -57,9 +60,9 @@ where } } -impl From<(Invitee, S)> for SerdeState +impl From<(Invitee, S)> for State where - SerdeInviteeState: From, + InviteeState: From, { fn from(value: (Invitee, S)) -> Self { let (_, state) = value; @@ -68,8 +71,8 @@ where } } -#[derive(Debug, Serialize, Deserialize)] -pub enum SerdeInviterState { +#[derive(Debug, Deserialize)] +pub enum InviterState { Initial(InviterInitial), Invited(InviterInvited), Requested(InviterRequested), @@ -77,38 +80,38 @@ pub enum SerdeInviterState { Complete(CompleteState), } -impl From for SerdeInviterState { +impl From for InviterState { fn from(value: InviterInitial) -> Self { Self::Initial(value) } } -impl From for SerdeInviterState { +impl From for InviterState { fn from(value: InviterInvited) -> Self { Self::Invited(value) } } -impl From for SerdeInviterState { +impl From for InviterState { fn from(value: InviterRequested) -> Self { Self::Requested(value) } } -impl From for SerdeInviterState { +impl From for InviterState { fn from(value: RespondedState) -> Self { Self::Responded(value) } } -impl From for SerdeInviterState { +impl From for InviterState { fn from(value: CompleteState) -> Self { Self::Complete(value) } } -#[derive(Debug, Serialize, Deserialize)] -pub enum SerdeInviteeState { +#[derive(Debug, Deserialize)] +pub enum InviteeState { Initial(InviteeInitial), Invited(InviteeInvited), Requested(InviteeRequested), @@ -116,31 +119,31 @@ pub enum SerdeInviteeState { Complete(CompleteState), } -impl From for SerdeInviteeState { +impl From for InviteeState { fn from(value: InviteeInitial) -> Self { Self::Initial(value) } } -impl From for SerdeInviteeState { +impl From for InviteeState { fn from(value: InviteeInvited) -> Self { Self::Invited(value) } } -impl From for SerdeInviteeState { +impl From for InviteeState { fn from(value: InviteeRequested) -> Self { Self::Requested(value) } } -impl From for SerdeInviteeState { +impl From for InviteeState { fn from(value: RespondedState) -> Self { Self::Responded(value) } } -impl From for SerdeInviteeState { +impl From for InviteeState { fn from(value: CompleteState) -> Self { Self::Complete(value) } diff --git a/aries_vcx/src/protocols/typestate_con/serde/mod.rs b/aries_vcx/src/protocols/typestate_con/serde/mod.rs new file mode 100644 index 0000000000..2e6ab62c61 --- /dev/null +++ b/aries_vcx/src/protocols/typestate_con/serde/mod.rs @@ -0,0 +1,2 @@ +pub mod de; +pub mod ser; diff --git a/aries_vcx/src/protocols/typestate_con/serde/ser.rs b/aries_vcx/src/protocols/typestate_con/serde/ser.rs new file mode 100644 index 0000000000..e69de29bb2 From 6ea03e70cb8e3af39cd9e8298c09f0f99aec9ee4 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Fri, 27 Jan 2023 10:02:13 +0200 Subject: [PATCH 13/66] Added dedicated serialization types for borrowed serialization of Connection and implemented Serialize Signed-off-by: Bogdan Mircea --- aries_vcx/src/protocols/typestate_con/mod.rs | 8 - .../src/protocols/typestate_con/serde/ser.rs | 170 ++++++++++++++++++ 2 files changed, 170 insertions(+), 8 deletions(-) diff --git a/aries_vcx/src/protocols/typestate_con/mod.rs b/aries_vcx/src/protocols/typestate_con/mod.rs index 894a344350..3468c97520 100644 --- a/aries_vcx/src/protocols/typestate_con/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/mod.rs @@ -25,14 +25,6 @@ use self::{ trait_bounds::{TheirDidDoc, Transport}, }; -// The serialization will first convert into the serializable connection type -// but will do that by cloning, which is fairly unfortunate and unnecessary. -// -// We can theoretically serialize this type as well directly, through a reference, -// but we must align the deserialization to be to the serializable connection -// and ensure the format matches. -// -// Can definitely be done, but just requires a bit of work put into it. pub struct Connection { source_id: String, pairwise_info: PairwiseInfo, diff --git a/aries_vcx/src/protocols/typestate_con/serde/ser.rs b/aries_vcx/src/protocols/typestate_con/serde/ser.rs index e69de29bb2..d1faddc443 100644 --- a/aries_vcx/src/protocols/typestate_con/serde/ser.rs +++ b/aries_vcx/src/protocols/typestate_con/serde/ser.rs @@ -0,0 +1,170 @@ +use serde::Serialize; + +use crate::protocols::typestate_con::{ + common::states::{complete::CompleteState, responded::RespondedState}, + initiation_type::{Invitee, Inviter}, + invitee::states::{ + initial::InitialState as InviteeInitial, invited::InvitedState as InviteeInvited, + requested::RequestedState as InviteeRequested, + }, + inviter::states::{ + initial::InitialState as InviterInitial, invited::InvitedState as InviterInvited, + requested::RequestedState as InviterRequested, + }, + pairwise_info::PairwiseInfo, + Connection, +}; + +impl Serialize for Connection +where + I: Serialize, + S: Serialize, + for<'a> SerializableConnection<'a>: From<&'a Connection>, +{ + fn serialize(&self, serializer: Serializer) -> Result + where + Serializer: ::serde::Serializer, + { + SerializableConnection::from(self).serialize(serializer) + } +} + +/// Type used for serialization of a [`Connection`]. +/// This struct is used transparently, under the hood, to convert a reference +/// of a [`Connection`] (so we don't clone unnecessarily) to itself and then serialize it. +#[derive(Debug, Serialize)] +pub struct SerializableConnection<'a> { + source_id: &'a str, + pairwise_info: &'a PairwiseInfo, + pub state: RefState<'a>, +} + +impl<'a> SerializableConnection<'a> { + fn new(source_id: &'a str, pairwise_info: &'a PairwiseInfo, state: RefState<'a>) -> Self { + Self { + source_id, + pairwise_info, + state, + } + } +} + +impl<'a, I, S> From<&'a Connection> for SerializableConnection<'a> +where + RefState<'a>: From<(&'a I, &'a S)>, + I: 'a, + S: 'a, +{ + fn from(value: &'a Connection) -> Self { + let state = From::from((&value.initiation_type, &value.state)); + Self::new(&value.source_id, &value.pairwise_info, state) + } +} + +#[derive(Debug, Serialize)] +pub enum RefState<'a> { + Inviter(RefInviterState<'a>), + Invitee(RefInviteeState<'a>), +} + +impl<'a, S> From<(&'a Inviter, &'a S)> for RefState<'a> +where + RefInviterState<'a>: From<&'a S>, + S: 'a, +{ + fn from(value: (&'a Inviter, &'a S)) -> Self { + let (_, state) = value; + let serde_state = From::from(state); + Self::Inviter(serde_state) + } +} + +impl<'a, S> From<(&'a Invitee, &'a S)> for RefState<'a> +where + RefInviteeState<'a>: From<&'a S>, + S: 'a, +{ + fn from(value: (&'a Invitee, &'a S)) -> Self { + let (_, state) = value; + let serde_state = From::from(state); + Self::Invitee(serde_state) + } +} + +#[derive(Debug, Serialize)] +pub enum RefInviterState<'a> { + Initial(&'a InviterInitial), + Invited(&'a InviterInvited), + Requested(&'a InviterRequested), + Responded(&'a RespondedState), + Complete(&'a CompleteState), +} + +impl<'a> From<&'a InviterInitial> for RefInviterState<'a> { + fn from(value: &'a InviterInitial) -> Self { + Self::Initial(value) + } +} + +impl<'a> From<&'a InviterInvited> for RefInviterState<'a> { + fn from(value: &'a InviterInvited) -> Self { + Self::Invited(value) + } +} + +impl<'a> From<&'a InviterRequested> for RefInviterState<'a> { + fn from(value: &'a InviterRequested) -> Self { + Self::Requested(value) + } +} + +impl<'a> From<&'a RespondedState> for RefInviterState<'a> { + fn from(value: &'a RespondedState) -> Self { + Self::Responded(value) + } +} + +impl<'a> From<&'a CompleteState> for RefInviterState<'a> { + fn from(value: &'a CompleteState) -> Self { + Self::Complete(value) + } +} + +#[derive(Debug, Serialize)] +pub enum RefInviteeState<'a> { + Initial(&'a InviteeInitial), + Invited(&'a InviteeInvited), + Requested(&'a InviteeRequested), + Responded(&'a RespondedState), + Complete(&'a CompleteState), +} + +impl<'a> From<&'a InviteeInitial> for RefInviteeState<'a> { + fn from(value: &'a InviteeInitial) -> Self { + Self::Initial(value) + } +} + +impl<'a> From<&'a InviteeInvited> for RefInviteeState<'a> { + fn from(value: &'a InviteeInvited) -> Self { + Self::Invited(value) + } +} + +impl<'a> From<&'a InviteeRequested> for RefInviteeState<'a> { + fn from(value: &'a InviteeRequested) -> Self { + Self::Requested(value) + } +} + +impl<'a> From<&'a RespondedState> for RefInviteeState<'a> { + fn from(value: &'a RespondedState) -> Self { + Self::Responded(value) + } +} + +impl<'a> From<&'a CompleteState> for RefInviteeState<'a> { + fn from(value: &'a CompleteState) -> Self { + Self::Complete(value) + } +} From 3b5158645e014c1554760c436cd1bc90b131ad91 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Fri, 27 Jan 2023 10:21:48 +0200 Subject: [PATCH 14/66] Fixed Connection serialization trait bounds Signed-off-by: Bogdan Mircea --- aries_vcx/src/protocols/typestate_con/serde/mod.rs | 2 +- aries_vcx/src/protocols/typestate_con/serde/ser.rs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/aries_vcx/src/protocols/typestate_con/serde/mod.rs b/aries_vcx/src/protocols/typestate_con/serde/mod.rs index 2e6ab62c61..4397947172 100644 --- a/aries_vcx/src/protocols/typestate_con/serde/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/serde/mod.rs @@ -1,2 +1,2 @@ pub mod de; -pub mod ser; +mod ser; diff --git a/aries_vcx/src/protocols/typestate_con/serde/ser.rs b/aries_vcx/src/protocols/typestate_con/serde/ser.rs index d1faddc443..063983280f 100644 --- a/aries_vcx/src/protocols/typestate_con/serde/ser.rs +++ b/aries_vcx/src/protocols/typestate_con/serde/ser.rs @@ -17,8 +17,6 @@ use crate::protocols::typestate_con::{ impl Serialize for Connection where - I: Serialize, - S: Serialize, for<'a> SerializableConnection<'a>: From<&'a Connection>, { fn serialize(&self, serializer: Serializer) -> Result From 928063311c0e4834e4c33872dbe00dc1c95e22ba Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Fri, 27 Jan 2023 11:46:29 +0200 Subject: [PATCH 15/66] Reverted to using invitation ID as thread ID Signed-off-by: Bogdan Mircea --- aries_vcx/src/protocols/typestate_con/invitee/mod.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/aries_vcx/src/protocols/typestate_con/invitee/mod.rs b/aries_vcx/src/protocols/typestate_con/invitee/mod.rs index bdb11a5ab4..16c3146838 100644 --- a/aries_vcx/src/protocols/typestate_con/invitee/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/invitee/mod.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use messages::protocols::connection::invite::Invitation; -use crate::{common::ledger::transactions::into_did_doc, core::profile::profile::Profile, errors::error::VcxResult, utils}; +use crate::{common::ledger::transactions::into_did_doc, core::profile::profile::Profile, errors::error::VcxResult}; use self::states::{initial::InitialState, invited::InvitedState, requested::RequestedState}; @@ -48,11 +48,7 @@ impl InviteeConnection { ) -> VcxResult> { trace!("Connection::into_invited >>> invitation: {:?}", &invitation); - // Why would all inviters that accept an - // invitation use the same thread ID? - // - // let thread_id = invitation.get_id()?; - let thread_id = utils::uuid::uuid(); + let thread_id = invitation.get_id()?; let did_doc = into_did_doc(profile, invitation).await?; let state = InvitedState { did_doc, thread_id }; From 1927b5e6b5f130a11ed7a78236df759d3fe89c1e Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Fri, 27 Jan 2023 14:19:42 +0200 Subject: [PATCH 16/66] Added direct deserialization support to Connection through try_from impl of VagueConnection Signed-off-by: Bogdan Mircea --- aries_vcx/src/protocols/typestate_con/mod.rs | 17 +- .../src/protocols/typestate_con/serde/de.rs | 249 ++++++++++-------- 2 files changed, 154 insertions(+), 112 deletions(-) diff --git a/aries_vcx/src/protocols/typestate_con/mod.rs b/aries_vcx/src/protocols/typestate_con/mod.rs index 3468c97520..2a0fc9aad5 100644 --- a/aries_vcx/src/protocols/typestate_con/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/mod.rs @@ -3,7 +3,7 @@ mod initiation_type; pub mod invitee; pub mod inviter; pub mod pairwise_info; -pub mod serde; +mod serde; mod trait_bounds; use messages::{ @@ -22,9 +22,15 @@ use crate::{ use self::{ common::states::complete::CompleteState, pairwise_info::PairwiseInfo, + serde::de::VagueState, trait_bounds::{TheirDidDoc, Transport}, }; +pub use self::serde::de::VagueConnection; + +#[derive(Clone, Deserialize)] +#[serde(try_from = "VagueConnection")] +#[serde(bound = "(I, S): TryFrom")] pub struct Connection { source_id: String, pairwise_info: PairwiseInfo, @@ -33,6 +39,15 @@ pub struct Connection { } impl Connection { + pub(crate) fn from_parts(source_id: String, pairwise_info: PairwiseInfo, initiation_type: I, state: S) -> Self { + Self { + source_id, + pairwise_info, + initiation_type, + state, + } + } + pub fn pairwise_info(&self) -> &PairwiseInfo { &self.pairwise_info } diff --git a/aries_vcx/src/protocols/typestate_con/serde/de.rs b/aries_vcx/src/protocols/typestate_con/serde/de.rs index dfe7111fc6..f0d9b81ea8 100644 --- a/aries_vcx/src/protocols/typestate_con/serde/de.rs +++ b/aries_vcx/src/protocols/typestate_con/serde/de.rs @@ -1,18 +1,90 @@ -use crate::protocols::typestate_con::{ - common::states::{complete::CompleteState, responded::RespondedState}, - initiation_type::{Invitee, Inviter}, - invitee::states::{ - initial::InitialState as InviteeInitial, invited::InvitedState as InviteeInvited, - requested::RequestedState as InviteeRequested, +use crate::{ + errors::error::{AriesVcxError, AriesVcxErrorKind}, + protocols::typestate_con::{ + common::states::{complete::CompleteState, responded::RespondedState}, + initiation_type::{Invitee, Inviter}, + invitee::states::{ + initial::InitialState as InviteeInitial, invited::InvitedState as InviteeInvited, + requested::RequestedState as InviteeRequested, + }, + inviter::states::{ + initial::InitialState as InviterInitial, invited::InvitedState as InviterInvited, + requested::RequestedState as InviterRequested, + }, + pairwise_info::PairwiseInfo, + Connection, }, - inviter::states::{ - initial::InitialState as InviterInitial, invited::InvitedState as InviterInvited, - requested::RequestedState as InviterRequested, - }, - pairwise_info::PairwiseInfo, - Connection, }; +/// Macro used for boilerplace implementation of the +/// [`From`] trait from a concrete connection state to the vague state. +macro_rules! from_concrete_to_vague { + ($from:ident, $var:ident, $to:ident) => { + impl From<$from> for $to { + fn from(value: $from) -> Self { + Self::$var(value) + } + } + }; + + ($init_type:ident, $state:ident, $var:ident, $to:ident) => { + impl From<($init_type, S)> for $to + where + $state: From, + { + fn from(value: ($init_type, S)) -> Self { + let (_, state) = value; + let serde_state = From::from(state); + Self::$var(serde_state) + } + } + }; +} + +/// Macro used for boilerplace implementation of the +/// [`TryFrom`] trait from a vague connection state to a concrete state. +macro_rules! try_from_vague_to_concrete { + ($from:ident, $var:ident, $to:ident) => { + impl TryFrom<$from> for $to { + type Error = AriesVcxError; + + fn try_from(value: $from) -> Result { + match value { + $from::$var(s) => Ok(s), + _ => Err(AriesVcxError::from_msg( + AriesVcxErrorKind::InvalidState, + format!("unexpected connection state: {:?}!", value), + )), + } + } + } + }; + + ($state:ident, $good_var:ident, $bad_var:ident, $init_type:ident) => { + impl TryFrom for ($init_type, S) + where + S: TryFrom<$state, Error = AriesVcxError>, + { + type Error = AriesVcxError; + + fn try_from(value: VagueState) -> Result { + match value { + VagueState::$good_var(s) => S::try_from(s).map(|s| ($init_type, s)), + VagueState::$bad_var(_) => Err(AriesVcxError::from_msg( + AriesVcxErrorKind::InvalidState, + concat!( + "Expected ", + stringify!(VagueState::$good_var), + "connection state, found ", + stringify!(VagueState::$bad_var), + ), + )), + } + } + } + }; +} + /// Type used for deserialization of a [`Connection`]. /// This struct cannot be used for anything useful directly, /// but the inner `state` has to be matched to get the concrete [`Connection`] type. @@ -20,59 +92,17 @@ use crate::protocols::typestate_con::{ pub struct VagueConnection { source_id: String, pairwise_info: PairwiseInfo, - pub state: State, -} - -impl VagueConnection { - fn new(source_id: String, pairwise_info: PairwiseInfo, state: State) -> Self { - Self { - source_id, - pairwise_info, - state, - } - } -} - -impl From> for VagueConnection -where - State: From<(I, S)>, -{ - fn from(value: Connection) -> Self { - let state = From::from((value.initiation_type, value.state)); - Self::new(value.source_id, value.pairwise_info, state) - } + state: VagueState, } #[derive(Debug, Deserialize)] -pub enum State { - Inviter(InviterState), - Invitee(InviteeState), -} - -impl From<(Inviter, S)> for State -where - InviterState: From, -{ - fn from(value: (Inviter, S)) -> Self { - let (_, state) = value; - let serde_state = From::from(state); - Self::Inviter(serde_state) - } -} - -impl From<(Invitee, S)> for State -where - InviteeState: From, -{ - fn from(value: (Invitee, S)) -> Self { - let (_, state) = value; - let serde_state = From::from(state); - Self::Invitee(serde_state) - } +pub enum VagueState { + Inviter(VagueInviterState), + Invitee(VagueInviteeState), } #[derive(Debug, Deserialize)] -pub enum InviterState { +pub enum VagueInviterState { Initial(InviterInitial), Invited(InviterInvited), Requested(InviterRequested), @@ -80,38 +110,8 @@ pub enum InviterState { Complete(CompleteState), } -impl From for InviterState { - fn from(value: InviterInitial) -> Self { - Self::Initial(value) - } -} - -impl From for InviterState { - fn from(value: InviterInvited) -> Self { - Self::Invited(value) - } -} - -impl From for InviterState { - fn from(value: InviterRequested) -> Self { - Self::Requested(value) - } -} - -impl From for InviterState { - fn from(value: RespondedState) -> Self { - Self::Responded(value) - } -} - -impl From for InviterState { - fn from(value: CompleteState) -> Self { - Self::Complete(value) - } -} - #[derive(Debug, Deserialize)] -pub enum InviteeState { +pub enum VagueInviteeState { Initial(InviteeInitial), Invited(InviteeInvited), Requested(InviteeRequested), @@ -119,32 +119,59 @@ pub enum InviteeState { Complete(CompleteState), } -impl From for InviteeState { - fn from(value: InviteeInitial) -> Self { - Self::Initial(value) +impl From> for VagueConnection +where + VagueState: From<(I, S)>, +{ + fn from(value: Connection) -> Self { + let state = From::from((value.initiation_type, value.state)); + Self { + source_id: value.source_id, + pairwise_info: value.pairwise_info, + state, + } } } -impl From for InviteeState { - fn from(value: InviteeInvited) -> Self { - Self::Invited(value) - } -} +from_concrete_to_vague!(Inviter, VagueInviterState, Inviter, VagueState); +from_concrete_to_vague!(Invitee, VagueInviteeState, Invitee, VagueState); -impl From for InviteeState { - fn from(value: InviteeRequested) -> Self { - Self::Requested(value) - } -} +from_concrete_to_vague!(InviterInitial, Initial, VagueInviterState); +from_concrete_to_vague!(InviterInvited, Invited, VagueInviterState); +from_concrete_to_vague!(InviterRequested, Requested, VagueInviterState); +from_concrete_to_vague!(RespondedState, Responded, VagueInviterState); +from_concrete_to_vague!(CompleteState, Complete, VagueInviterState); -impl From for InviteeState { - fn from(value: RespondedState) -> Self { - Self::Responded(value) - } -} +from_concrete_to_vague!(InviteeInitial, Initial, VagueInviteeState); +from_concrete_to_vague!(InviteeInvited, Invited, VagueInviteeState); +from_concrete_to_vague!(InviteeRequested, Requested, VagueInviteeState); +from_concrete_to_vague!(RespondedState, Responded, VagueInviteeState); +from_concrete_to_vague!(CompleteState, Complete, VagueInviteeState); + +impl TryFrom for Connection +where + (I, S): TryFrom, +{ + type Error = AriesVcxError; -impl From for InviteeState { - fn from(value: CompleteState) -> Self { - Self::Complete(value) + fn try_from(value: VagueConnection) -> Result { + let (initiation_type, state) = TryFrom::try_from(value.state)?; + let con = Connection::from_parts(value.source_id, value.pairwise_info, initiation_type, state); + Ok(con) } } + +try_from_vague_to_concrete!(VagueInviterState, Inviter, Invitee, Inviter); +try_from_vague_to_concrete!(VagueInviteeState, Invitee, Inviter, Invitee); + +try_from_vague_to_concrete!(VagueInviterState, Initial, InviterInitial); +try_from_vague_to_concrete!(VagueInviterState, Invited, InviterInvited); +try_from_vague_to_concrete!(VagueInviterState, Requested, InviterRequested); +try_from_vague_to_concrete!(VagueInviterState, Responded, RespondedState); +try_from_vague_to_concrete!(VagueInviterState, Complete, CompleteState); + +try_from_vague_to_concrete!(VagueInviteeState, Initial, InviteeInitial); +try_from_vague_to_concrete!(VagueInviteeState, Invited, InviteeInvited); +try_from_vague_to_concrete!(VagueInviteeState, Requested, InviteeRequested); +try_from_vague_to_concrete!(VagueInviteeState, Responded, RespondedState); +try_from_vague_to_concrete!(VagueInviteeState, Complete, CompleteState); From ccbdb78c098a854bb745ddc8f1813adac33074a2 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Fri, 27 Jan 2023 14:21:47 +0200 Subject: [PATCH 17/66] Set typestate_con states attributes pub(crate) Signed-off-by: Bogdan Mircea --- .../src/protocols/typestate_con/common/states/complete.rs | 6 +++--- .../src/protocols/typestate_con/common/states/responded.rs | 4 ++-- .../src/protocols/typestate_con/invitee/states/invited.rs | 4 ++-- .../src/protocols/typestate_con/invitee/states/requested.rs | 4 ++-- .../src/protocols/typestate_con/inviter/states/initial.rs | 2 +- .../src/protocols/typestate_con/inviter/states/invited.rs | 2 +- .../src/protocols/typestate_con/inviter/states/requested.rs | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/aries_vcx/src/protocols/typestate_con/common/states/complete.rs b/aries_vcx/src/protocols/typestate_con/common/states/complete.rs index 4349014263..0f586031ef 100644 --- a/aries_vcx/src/protocols/typestate_con/common/states/complete.rs +++ b/aries_vcx/src/protocols/typestate_con/common/states/complete.rs @@ -7,9 +7,9 @@ use crate::protocols::typestate_con::trait_bounds::TheirDidDoc; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct CompleteState { - pub did_doc: AriesDidDoc, - pub thread_id: String, - pub protocols: Option>, + pub(crate) did_doc: AriesDidDoc, + pub(crate) thread_id: String, + pub(crate) protocols: Option>, } impl CompleteState { diff --git a/aries_vcx/src/protocols/typestate_con/common/states/responded.rs b/aries_vcx/src/protocols/typestate_con/common/states/responded.rs index 0d68f9c214..04bd336236 100644 --- a/aries_vcx/src/protocols/typestate_con/common/states/responded.rs +++ b/aries_vcx/src/protocols/typestate_con/common/states/responded.rs @@ -4,8 +4,8 @@ use crate::protocols::typestate_con::trait_bounds::TheirDidDoc; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct RespondedState { - pub did_doc: AriesDidDoc, - pub thread_id: String + pub(crate) did_doc: AriesDidDoc, + pub(crate) thread_id: String } impl RespondedState { diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs index b0636764fe..6445314947 100644 --- a/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs +++ b/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs @@ -4,8 +4,8 @@ use crate::protocols::typestate_con::trait_bounds::TheirDidDoc; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct InvitedState { - pub did_doc: AriesDidDoc, - pub thread_id: String + pub(crate) did_doc: AriesDidDoc, + pub(crate) thread_id: String } impl InvitedState { diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs index 639c0fa8a4..0acaba63c9 100644 --- a/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs +++ b/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs @@ -4,8 +4,8 @@ use crate::protocols::typestate_con::trait_bounds::TheirDidDoc; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct RequestedState { - pub did_doc: AriesDidDoc, - pub thread_id: String + pub(crate) did_doc: AriesDidDoc, + pub(crate) thread_id: String } impl RequestedState { diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/initial.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/initial.rs index c59c5cf20a..a9e2809806 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/states/initial.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/states/initial.rs @@ -2,7 +2,7 @@ use messages::protocols::connection::invite::Invitation; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct InitialState { - pub invitation: Invitation, + pub(crate) invitation: Invitation, } impl InitialState { diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs index 687ec40262..3f4e211f93 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs @@ -1,6 +1,6 @@ #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct InvitedState { - pub thread_id: Option, + pub(crate) thread_id: Option, } impl InvitedState { diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs index 99823f7b5f..6c9a2a733f 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs @@ -4,7 +4,7 @@ use crate::protocols::typestate_con::trait_bounds::TheirDidDoc; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct RequestedState { - pub request: Request, + pub(crate) request: Request, } impl RequestedState { From 792c4a677efe43e92c2b010e829a6b57d64a9e06 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Fri, 27 Jan 2023 17:07:37 +0200 Subject: [PATCH 18/66] Added typestate_con libvcx implementation draft Signed-off-by: Bogdan Mircea --- Cargo.lock | 6 +- .../typestate_con/common/states/complete.rs | 2 +- .../typestate_con/common/states/responded.rs | 2 +- .../protocols/typestate_con/invitee/mod.rs | 2 +- .../typestate_con/invitee/states/invited.rs | 2 +- .../typestate_con/invitee/states/requested.rs | 2 +- .../protocols/typestate_con/inviter/mod.rs | 2 +- .../typestate_con/inviter/states/requested.rs | 2 +- aries_vcx/src/protocols/typestate_con/mod.rs | 8 +- .../src/protocols/typestate_con/serde/de.rs | 83 ++++- .../{trait_bounds.rs => traits.rs} | 5 +- libvcx/Cargo.toml | 2 + libvcx/src/api_vcx/api_handle/mod.rs | 1 + .../src/api_vcx/api_handle/typestate_con.rs | 289 ++++++++++++++++++ 14 files changed, 385 insertions(+), 23 deletions(-) rename aries_vcx/src/protocols/typestate_con/{trait_bounds.rs => traits.rs} (71%) create mode 100644 libvcx/src/api_vcx/api_handle/typestate_con.rs diff --git a/Cargo.lock b/Cargo.lock index a679126905..296946323d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -335,9 +335,9 @@ checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" [[package]] name = "async-trait" -version = "0.1.59" +version = "0.1.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6e93155431f3931513b243d371981bb2770112b370c82745a1d19d2f99364" +checksum = "eff18d764974428cf3a9328e23fc5c986f5fbed46e6cd4cdf42544df5d297ec1" dependencies = [ "proc-macro2", "quote", @@ -2231,8 +2231,10 @@ dependencies = [ name = "libvcx" version = "0.51.1" dependencies = [ + "agency_client", "android_logger", "aries-vcx", + "async-trait", "cfg-if 1.0.0", "chrono", "env_logger 0.9.3", diff --git a/aries_vcx/src/protocols/typestate_con/common/states/complete.rs b/aries_vcx/src/protocols/typestate_con/common/states/complete.rs index 0f586031ef..1387ca75c6 100644 --- a/aries_vcx/src/protocols/typestate_con/common/states/complete.rs +++ b/aries_vcx/src/protocols/typestate_con/common/states/complete.rs @@ -3,7 +3,7 @@ use std::clone::Clone; use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::discovery::disclose::{Disclose, ProtocolDescriptor}; -use crate::protocols::typestate_con::trait_bounds::TheirDidDoc; +use crate::protocols::typestate_con::traits::TheirDidDoc; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct CompleteState { diff --git a/aries_vcx/src/protocols/typestate_con/common/states/responded.rs b/aries_vcx/src/protocols/typestate_con/common/states/responded.rs index 04bd336236..d2c0ebaca3 100644 --- a/aries_vcx/src/protocols/typestate_con/common/states/responded.rs +++ b/aries_vcx/src/protocols/typestate_con/common/states/responded.rs @@ -1,6 +1,6 @@ use messages::diddoc::aries::diddoc::AriesDidDoc; -use crate::protocols::typestate_con::trait_bounds::TheirDidDoc; +use crate::protocols::typestate_con::traits::TheirDidDoc; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct RespondedState { diff --git a/aries_vcx/src/protocols/typestate_con/invitee/mod.rs b/aries_vcx/src/protocols/typestate_con/invitee/mod.rs index 16c3146838..9954f8cb2c 100644 --- a/aries_vcx/src/protocols/typestate_con/invitee/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/invitee/mod.rs @@ -18,7 +18,7 @@ use super::{ common::states::{complete::CompleteState, responded::RespondedState}, initiation_type::Invitee, pairwise_info::PairwiseInfo, - trait_bounds::Transport, + traits::Transport, Connection, }; use crate::{ diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs index 6445314947..31ec2993d4 100644 --- a/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs +++ b/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs @@ -1,6 +1,6 @@ use messages::diddoc::aries::diddoc::AriesDidDoc; -use crate::protocols::typestate_con::trait_bounds::TheirDidDoc; +use crate::protocols::typestate_con::traits::TheirDidDoc; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct InvitedState { diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs index 0acaba63c9..86d82a253a 100644 --- a/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs +++ b/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs @@ -1,6 +1,6 @@ use messages::diddoc::aries::diddoc::AriesDidDoc; -use crate::protocols::typestate_con::trait_bounds::TheirDidDoc; +use crate::protocols::typestate_con::traits::TheirDidDoc; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct RequestedState { diff --git a/aries_vcx/src/protocols/typestate_con/inviter/mod.rs b/aries_vcx/src/protocols/typestate_con/inviter/mod.rs index 17a1ca7c6d..12c6824fd8 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/mod.rs @@ -13,7 +13,7 @@ use self::states::initial::InitialState; use self::states::{invited::InvitedState, requested::RequestedState}; use super::common::states::complete::CompleteState; use super::common::states::responded::RespondedState; -use super::trait_bounds::Transport; +use super::traits::Transport; use super::{initiation_type::Inviter, pairwise_info::PairwiseInfo, Connection}; use messages::a2a::A2AMessage; use messages::protocols::connection::invite::PairwiseInvitation; diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs index 6c9a2a733f..ba55a82c01 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs @@ -1,6 +1,6 @@ use messages::{protocols::connection::request::Request, diddoc::aries::diddoc::AriesDidDoc}; -use crate::protocols::typestate_con::trait_bounds::TheirDidDoc; +use crate::protocols::typestate_con::traits::TheirDidDoc; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct RequestedState { diff --git a/aries_vcx/src/protocols/typestate_con/mod.rs b/aries_vcx/src/protocols/typestate_con/mod.rs index 2a0fc9aad5..f3e1d355bf 100644 --- a/aries_vcx/src/protocols/typestate_con/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/mod.rs @@ -4,7 +4,7 @@ pub mod invitee; pub mod inviter; pub mod pairwise_info; mod serde; -mod trait_bounds; +mod traits; use messages::{ a2a::{protocol_registry::ProtocolRegistry, A2AMessage}, @@ -20,13 +20,11 @@ use crate::{ }; use self::{ - common::states::complete::CompleteState, - pairwise_info::PairwiseInfo, - serde::de::VagueState, - trait_bounds::{TheirDidDoc, Transport}, + common::states::complete::CompleteState, pairwise_info::PairwiseInfo, serde::de::VagueState, traits::TheirDidDoc, }; pub use self::serde::de::VagueConnection; +pub use self::traits::Transport; #[derive(Clone, Deserialize)] #[serde(try_from = "VagueConnection")] diff --git a/aries_vcx/src/protocols/typestate_con/serde/de.rs b/aries_vcx/src/protocols/typestate_con/serde/de.rs index f0d9b81ea8..20f60ae636 100644 --- a/aries_vcx/src/protocols/typestate_con/serde/de.rs +++ b/aries_vcx/src/protocols/typestate_con/serde/de.rs @@ -85,23 +85,23 @@ macro_rules! try_from_vague_to_concrete { }; } -/// Type used for deserialization of a [`Connection`]. -/// This struct cannot be used for anything useful directly, -/// but the inner `state` has to be matched to get the concrete [`Connection`] type. -#[derive(Debug, Deserialize)] +/// Helper type mainly used for deserialization of a [`Connection`]. +/// It does not expose methods to advance the connection protocol +/// It does, however, expose some methods agnostic to the [`Connection`] type. +#[derive(Debug, Serialize, Deserialize)] pub struct VagueConnection { source_id: String, pairwise_info: PairwiseInfo, state: VagueState, } -#[derive(Debug, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] pub enum VagueState { Inviter(VagueInviterState), Invitee(VagueInviteeState), } -#[derive(Debug, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] pub enum VagueInviterState { Initial(InviterInitial), Invited(InviterInvited), @@ -110,7 +110,7 @@ pub enum VagueInviterState { Complete(CompleteState), } -#[derive(Debug, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] pub enum VagueInviteeState { Initial(InviteeInitial), Invited(InviteeInvited), @@ -119,6 +119,7 @@ pub enum VagueInviteeState { Complete(CompleteState), } +// ---------------------------- From Concrete State to Vague State implementations ---------------------------- impl From> for VagueConnection where VagueState: From<(I, S)>, @@ -148,6 +149,7 @@ from_concrete_to_vague!(InviteeRequested, Requested, VagueInviteeState); from_concrete_to_vague!(RespondedState, Responded, VagueInviteeState); from_concrete_to_vague!(CompleteState, Complete, VagueInviteeState); +// ---------------------------- Try From Vague State to Concrete State implementations ---------------------------- impl TryFrom for Connection where (I, S): TryFrom, @@ -175,3 +177,70 @@ try_from_vague_to_concrete!(VagueInviteeState, Invited, InviteeInvited); try_from_vague_to_concrete!(VagueInviteeState, Requested, InviteeRequested); try_from_vague_to_concrete!(VagueInviteeState, Responded, RespondedState); try_from_vague_to_concrete!(VagueInviteeState, Complete, CompleteState); + +/// Small sized enum used for determining +/// a connection's state in terms of initiation type. +#[derive(Clone, Copy, Debug)] +pub enum State { + Invitee(ConState), + Inviter(ConState), +} + +/// Small sized enum used for determining +/// a connection's state in terms of connection stage. +#[derive(Clone, Copy, Debug)] +pub enum ConState { + Initial, + Invited, + Requested, + Responded, + Complete, +} + +impl From for u32 { + fn from(value: State) -> Self { + match value { + State::Invitee(v) => v as u32, + State::Inviter(v) => v as u32, + } + } +} + +impl From<&VagueState> for State { + fn from(value: &VagueState) -> Self { + match value { + VagueState::Invitee(v) => Self::Invitee(v.into()), + VagueState::Inviter(v) => Self::Inviter(v.into()), + } + } +} + +impl From<&VagueInviterState> for ConState { + fn from(value: &VagueInviterState) -> Self { + match value { + VagueInviterState::Initial(_) => Self::Initial, + VagueInviterState::Invited(_) => Self::Invited, + VagueInviterState::Requested(_) => Self::Requested, + VagueInviterState::Responded(_) => Self::Responded, + VagueInviterState::Complete(_) => Self::Complete, + } + } +} + +impl From<&VagueInviteeState> for ConState { + fn from(value: &VagueInviteeState) -> Self { + match value { + VagueInviteeState::Initial(_) => Self::Initial, + VagueInviteeState::Invited(_) => Self::Invited, + VagueInviteeState::Requested(_) => Self::Requested, + VagueInviteeState::Responded(_) => Self::Responded, + VagueInviteeState::Complete(_) => Self::Complete, + } + } +} + +impl VagueConnection { + pub fn state(&self) -> State { + (&self.state).into() + } +} diff --git a/aries_vcx/src/protocols/typestate_con/trait_bounds.rs b/aries_vcx/src/protocols/typestate_con/traits.rs similarity index 71% rename from aries_vcx/src/protocols/typestate_con/trait_bounds.rs rename to aries_vcx/src/protocols/typestate_con/traits.rs index 3dfb3119b7..9ebcfc5c00 100644 --- a/aries_vcx/src/protocols/typestate_con/trait_bounds.rs +++ b/aries_vcx/src/protocols/typestate_con/traits.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use messages::{diddoc::aries::diddoc::AriesDidDoc}; +use messages::diddoc::aries::diddoc::AriesDidDoc; use crate::errors::error::VcxResult; @@ -9,7 +9,8 @@ pub trait TheirDidDoc { fn their_did_doc(&self) -> &AriesDidDoc; } +/// Trait used for implementing a mechanism to send a message, used by [`super::Connection`]. #[async_trait] pub trait Transport { async fn send_message(&self, msg: Vec, service_endpoint: &str) -> VcxResult<()>; -} \ No newline at end of file +} diff --git a/libvcx/Cargo.toml b/libvcx/Cargo.toml index e70f1c77f8..8ce9d31729 100644 --- a/libvcx/Cargo.toml +++ b/libvcx/Cargo.toml @@ -38,6 +38,8 @@ tokio = { version = "1.20.3", features = ["rt-multi-thread"] } aries-vcx = { path = "../aries_vcx" } thiserror = "1.0.37" uuid = { version = "0.7.4", default-features = false, features = ["v4"] } +agency_client = { path = "../agency_client" } +async-trait = "0.1.61" [target.'cfg(target_os = "android")'.dependencies] android_logger = "0.5" diff --git a/libvcx/src/api_vcx/api_handle/mod.rs b/libvcx/src/api_vcx/api_handle/mod.rs index 4f173bb3ee..63f7dad124 100644 --- a/libvcx/src/api_vcx/api_handle/mod.rs +++ b/libvcx/src/api_vcx/api_handle/mod.rs @@ -9,3 +9,4 @@ pub mod out_of_band; pub mod proof; pub mod revocation_registry; pub mod schema; +pub mod typestate_con; \ No newline at end of file diff --git a/libvcx/src/api_vcx/api_handle/typestate_con.rs b/libvcx/src/api_vcx/api_handle/typestate_con.rs new file mode 100644 index 0000000000..f63bb34c37 --- /dev/null +++ b/libvcx/src/api_vcx/api_handle/typestate_con.rs @@ -0,0 +1,289 @@ +use std::{collections::HashMap, sync::RwLock}; + +use agency_client::httpclient::post_message; +use aries_vcx::{ + errors::error::VcxResult, + protocols::typestate_con::{ + invitee::InviteeConnection, inviter::InviterConnection, pairwise_info::PairwiseInfo, Connection, Transport, + VagueConnection, + }, +}; +use async_trait::async_trait; +use rand::Rng; + +use crate::{ + api_vcx::api_global::profile::get_main_profile, + errors::error::{LibvcxError, LibvcxErrorKind, LibvcxResult}, +}; + +type Map = HashMap; +type Cache = RwLock; + +lazy_static! { + static ref CONNECTION_MAP: Cache = RwLock::new(HashMap::new()); +} + +lazy_static! { + static ref HTTP_CLIENT: HttpClient = HttpClient; +} + +struct HttpClient; + +#[async_trait] +impl Transport for HttpClient { + async fn send_message(&self, msg: Vec, service_endpoint: &str) -> VcxResult<()> { + post_message(msg, service_endpoint).await?; + Ok(()) + } +} + +fn new_handle() -> LibvcxResult { + loop { + let handle = rand::thread_rng().gen::(); + if !CONNECTION_MAP.read()?.contains_key(&handle) { + break Ok(handle); + } + } +} + +fn remove_connection(handle: &u32) -> LibvcxResult> +where + Connection: TryFrom, +{ + CONNECTION_MAP + .write()? + .remove(handle) + .and_then(|c| c.try_into().ok()) + .ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("Unable to retrieve expected connection for handle: {}", handle), + ) + }) +} + +fn add_connection(connection: VagueConnection) -> LibvcxResult { + let handle = new_handle()?; + CONNECTION_MAP.write()?.insert(handle, connection); + Ok(handle) +} + +fn insert_connection(handle: u32, connection: Connection) -> LibvcxResult<()> +where + VagueConnection: From>, +{ + CONNECTION_MAP.write()?.insert(handle, connection.into()); + Ok(()) +} + +fn serialize(data: &T) -> LibvcxResult +where + T: serde::ser::Serialize, +{ + serde_json::to_string(data).map_err(|err| { + LibvcxError::from_msg( + LibvcxErrorKind::SerializationError, + format!("Serialization failed: {}", err), + ) + }) +} + +fn deserialize(data: &str) -> LibvcxResult +where + T: serde::de::DeserializeOwned, +{ + serde_json::from_str(data) + .map_err(|err| LibvcxError::from_msg(LibvcxErrorKind::InvalidJson, format!("Deserialization failed: {}", err))) +} + +// ----------------------------- CONSTRUCTORS ------------------------------------ +pub async fn create_inviter(pw_info: Option) -> LibvcxResult { + trace!("create_inviter >>>"); + let profile = get_main_profile()?; + + // This could probably be generated once and used/cloned around. + let pw_info = pw_info.unwrap_or(PairwiseInfo::create(&profile.inject_wallet()).await?); + let con = InviterConnection::new_invited("".to_owned(), pw_info); + + add_connection(con.into()) +} + +pub async fn create_invitee(invitation: &str) -> LibvcxResult { + trace!("create_invitee >>>"); + + let profile = get_main_profile()?; + let invitation = deserialize(invitation)?; + let pairwise_info = PairwiseInfo::create(&profile.inject_wallet()).await?; + + let con = InviteeConnection::new("".to_owned(), pairwise_info) + .accept_invitation(&profile, &invitation) + .await?; + + add_connection(con.into()) +} + +// Just trying to retro-fit this. +// It essentially creates an inviter connection in the initial state, also genereting an Invitation. +pub async fn create_invite(handle: u32, service_endpoint: String, routing_keys: Vec) -> LibvcxResult<()> { + trace!("create_invite >>>"); + + let profile = get_main_profile()?; + let pairwise_info = PairwiseInfo::create(&profile.inject_wallet()).await?; + let con = InviterConnection::new("".to_owned(), pairwise_info, routing_keys, service_endpoint); + + insert_connection(handle, con) +} + +// ----------------------------- GETTERS ------------------------------------ +// pub fn get_thread_id(handle: u32) -> LibvcxResult { +// trace!("get_thread_id >>> handle: {}", handle); +// CONNECTION_MAP.get(handle, |connection| Ok(connection.get_thread_id())) +// } + +// pub fn get_pairwise_info(handle: u32) -> LibvcxResult { +// trace!("get_pairwise_info >>> handle: {}", handle); +// CONNECTION_MAP.get(handle, |connection| serialize(connection.pairwise_info())) +// } + +// pub fn get_remote_did(handle: u32) -> LibvcxResult { +// trace!("get_remote_did >>> handle: {}", handle); +// CONNECTION_MAP.get(handle, |connection| connection.remote_did().map_err(|e| e.into())) +// } + +// pub fn get_remote_vk(handle: u32) -> LibvcxResult { +// trace!("get_remote_vk >>> handle: {}", handle); +// CONNECTION_MAP.get(handle, |connection| connection.remote_vk().map_err(|e| e.into())) +// } + +// pub fn get_state(handle: u32) -> LibvcxResult { +// trace!("get_state >>> handle: {}", handle); +// CONNECTION_MAP.get(handle, |connection| Ok(connection.get_state().into())) +// } + +// pub fn get_invitation(handle: u32) -> LibvcxResult { +// trace!("get_invitation >>> handle: {}", handle); + +// let invitation = get_connection(&handle)?.get_invitation(); +// serialize(invitation) +// } + +// ----------------------------- MSG PROCESSING ------------------------------------ +pub async fn process_invite(handle: u32, invitation: &str) -> LibvcxResult<()> { + trace!("process_invite >>>"); + + // ------------------ BREAKING CHANGE ------------------ + // The code below would do the proper thing, but the function must be async + // Also, this doesn't really make sense conceptually as the invitation is also passed + // when the invitee is created -> so the transition happens there automatically. + + let profile = get_main_profile()?; + let invitation = deserialize(invitation)?; + let con = remove_connection(&handle)? + .accept_invitation(&profile, &invitation) + .await?; + + insert_connection(handle, con) +} + +// ------------------ BREAKING CHANGE ------------------ +// Extra function arguments are deffered to send_response. +pub async fn process_request(handle: u32, request: &str) -> LibvcxResult<()> { + trace!("process_request >>>"); + + let con = remove_connection(&handle)?; + let request = deserialize(request)?; + let con = con.handle_request(request).await?; + + insert_connection(handle, con) +} + +pub async fn process_response(handle: u32, response: &str) -> LibvcxResult<()> { + trace!("process_response >>>"); + + let con = remove_connection(&handle)?; + let wallet = get_main_profile()?.inject_wallet(); + let response = deserialize(response)?; + let con = con.handle_response(&wallet, response).await?; + + insert_connection(handle, con) +} + +pub async fn process_ack(handle: u32, message: &str) -> LibvcxResult<()> { + trace!("process_ack >>>"); + + let con = remove_connection(&handle)?; + let msg = deserialize(message)?; + let con = con.acknowledge_connection(&msg)?; + + insert_connection(handle, con) +} + +// ------------------ BREAKING CHANGE ------------------ +// Got new arguments that were moved from process_request +pub async fn send_response(handle: u32, service_endpoint: String, routing_keys: Vec) -> LibvcxResult<()> { + trace!("send_response >>>"); + + let con = remove_connection(&handle)?; + let wallet = get_main_profile()?.inject_wallet(); + let con = con + .send_response(&wallet, service_endpoint, routing_keys, &*HTTP_CLIENT) + .await?; + + insert_connection(handle, con) +} + +pub async fn send_request(handle: u32, service_endpoint: String, routing_keys: Vec) -> LibvcxResult<()> { + trace!("send_request >>>"); + + let con = remove_connection(&handle)?; + let wallet = get_main_profile()?.inject_wallet(); + let con = con + .send_request(&wallet, service_endpoint, routing_keys, &*HTTP_CLIENT) + .await?; + + insert_connection(handle, con) +} + +pub async fn send_ack(handle: u32) -> LibvcxResult<()> { + trace!("send_ack >>>"); + + let con = remove_connection(&handle)?; + let wallet = get_main_profile()?.inject_wallet(); + let con = con.send_ack(&wallet, &*HTTP_CLIENT).await?; + + insert_connection(handle, con) +} + +// // ------------------------- (DE)SERIALIZATION ---------------------------------- +pub fn to_string(handle: u32) -> LibvcxResult { + trace!("to_string >>>"); + + CONNECTION_MAP + .read()? + .get(&handle) + .ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::InvalidHandle, + format!("[Connection Cache] get >> Object not found for handle: {}", handle), + ) + }) + .and_then(serialize) +} + +pub fn from_string(connection_data: &str) -> LibvcxResult { + trace!("from_string >>>"); + add_connection(deserialize(connection_data)?) +} + +// ------------------------------ CLEANUP --------------------------------------- +pub fn release(handle: u32) -> LibvcxResult<()> { + trace!("release >>>"); + + CONNECTION_MAP.write().map(|mut map| map.remove(&handle)).ok(); + Ok(()) +} + +pub fn release_all() { + trace!("release_all >>>"); + CONNECTION_MAP.write().map(|mut map| map.drain().for_each(drop)).ok(); +} From 05745403008f8a3af91a40e2fc7fd463d4497b22 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Sun, 29 Jan 2023 12:53:50 +0200 Subject: [PATCH 19/66] Completed typestate_con implementation in libvcx Signed-off-by: Bogdan Mircea --- .../connection/invitee/state_machine.rs | 2 +- .../typestate_con/common/states/complete.rs | 8 +- .../typestate_con/common/states/responded.rs | 12 +- .../protocols/typestate_con/invitee/mod.rs | 2 +- .../typestate_con/invitee/states/invited.rs | 12 +- .../typestate_con/invitee/states/requested.rs | 8 +- .../protocols/typestate_con/inviter/mod.rs | 6 + .../typestate_con/inviter/states/initial.rs | 8 + .../typestate_con/inviter/states/invited.rs | 6 +- .../typestate_con/inviter/states/requested.rs | 15 +- aries_vcx/src/protocols/typestate_con/mod.rs | 39 +++- .../src/protocols/typestate_con/serde/de.rs | 91 ++++++++- .../src/protocols/typestate_con/traits.rs | 6 + .../src/api_vcx/api_handle/typestate_con.rs | 183 +++++++++++++----- messages/src/protocols/connection/invite.rs | 8 +- 15 files changed, 333 insertions(+), 73 deletions(-) diff --git a/aries_vcx/src/protocols/connection/invitee/state_machine.rs b/aries_vcx/src/protocols/connection/invitee/state_machine.rs index 2fc959b035..18d304a3f0 100644 --- a/aries_vcx/src/protocols/connection/invitee/state_machine.rs +++ b/aries_vcx/src/protocols/connection/invitee/state_machine.rs @@ -240,7 +240,7 @@ impl SmConnectionInvitee { pub fn handle_invitation(self, invitation: Invitation) -> VcxResult { let Self { state, .. } = self; - let thread_id = invitation.get_id()?; + let thread_id = invitation.get_id().to_owned(); let state = match state { InviteeFullState::Initial(state) => InviteeFullState::Invited( ( diff --git a/aries_vcx/src/protocols/typestate_con/common/states/complete.rs b/aries_vcx/src/protocols/typestate_con/common/states/complete.rs index 1387ca75c6..e1f14d6794 100644 --- a/aries_vcx/src/protocols/typestate_con/common/states/complete.rs +++ b/aries_vcx/src/protocols/typestate_con/common/states/complete.rs @@ -3,7 +3,7 @@ use std::clone::Clone; use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::discovery::disclose::{Disclose, ProtocolDescriptor}; -use crate::protocols::typestate_con::traits::TheirDidDoc; +use crate::protocols::typestate_con::traits::{TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct CompleteState { @@ -34,4 +34,10 @@ impl TheirDidDoc for CompleteState { fn their_did_doc(&self) -> &AriesDidDoc { &self.did_doc } +} + +impl ThreadId for CompleteState { + fn thread_id(&self) -> &str { + &self.thread_id + } } \ No newline at end of file diff --git a/aries_vcx/src/protocols/typestate_con/common/states/responded.rs b/aries_vcx/src/protocols/typestate_con/common/states/responded.rs index d2c0ebaca3..953884e324 100644 --- a/aries_vcx/src/protocols/typestate_con/common/states/responded.rs +++ b/aries_vcx/src/protocols/typestate_con/common/states/responded.rs @@ -1,11 +1,11 @@ use messages::diddoc::aries::diddoc::AriesDidDoc; -use crate::protocols::typestate_con::traits::TheirDidDoc; +use crate::protocols::typestate_con::traits::{TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct RespondedState { pub(crate) did_doc: AriesDidDoc, - pub(crate) thread_id: String + pub(crate) thread_id: String, } impl RespondedState { @@ -18,4 +18,10 @@ impl TheirDidDoc for RespondedState { fn their_did_doc(&self) -> &AriesDidDoc { &self.did_doc } -} \ No newline at end of file +} + +impl ThreadId for RespondedState { + fn thread_id(&self) -> &str { + &self.thread_id + } +} diff --git a/aries_vcx/src/protocols/typestate_con/invitee/mod.rs b/aries_vcx/src/protocols/typestate_con/invitee/mod.rs index 9954f8cb2c..922c253244 100644 --- a/aries_vcx/src/protocols/typestate_con/invitee/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/invitee/mod.rs @@ -48,7 +48,7 @@ impl InviteeConnection { ) -> VcxResult> { trace!("Connection::into_invited >>> invitation: {:?}", &invitation); - let thread_id = invitation.get_id()?; + let thread_id = invitation.get_id().to_owned(); let did_doc = into_did_doc(profile, invitation).await?; let state = InvitedState { did_doc, thread_id }; diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs index 31ec2993d4..c8d573e2a2 100644 --- a/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs +++ b/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs @@ -1,11 +1,11 @@ use messages::diddoc::aries::diddoc::AriesDidDoc; -use crate::protocols::typestate_con::traits::TheirDidDoc; +use crate::protocols::typestate_con::traits::{TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct InvitedState { pub(crate) did_doc: AriesDidDoc, - pub(crate) thread_id: String + pub(crate) thread_id: String, } impl InvitedState { @@ -18,4 +18,10 @@ impl TheirDidDoc for InvitedState { fn their_did_doc(&self) -> &AriesDidDoc { &self.did_doc } -} \ No newline at end of file +} + +impl ThreadId for InvitedState { + fn thread_id(&self) -> &str { + &self.thread_id + } +} diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs index 86d82a253a..7cdfc603a6 100644 --- a/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs +++ b/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs @@ -1,6 +1,6 @@ use messages::diddoc::aries::diddoc::AriesDidDoc; -use crate::protocols::typestate_con::traits::TheirDidDoc; +use crate::protocols::typestate_con::traits::{TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct RequestedState { @@ -18,4 +18,10 @@ impl TheirDidDoc for RequestedState { fn their_did_doc(&self) -> &AriesDidDoc { &self.did_doc } +} + +impl ThreadId for RequestedState { + fn thread_id(&self) -> &str { + &self.thread_id + } } \ No newline at end of file diff --git a/aries_vcx/src/protocols/typestate_con/inviter/mod.rs b/aries_vcx/src/protocols/typestate_con/inviter/mod.rs index 12c6824fd8..e698d5952c 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/mod.rs @@ -72,6 +72,12 @@ impl InviterConnection { } } + /// As the inviter connection can be started directly in the invited state, + /// like with a public invitation, we might or might not have a thread ID. + pub fn thread_id(&self) -> Option<&str> { + self.state.thread_id() + } + pub async fn handle_request(self, request: Request) -> VcxResult> { trace!("Connection::process_request >>> request: {:?}", request,); diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/initial.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/initial.rs index a9e2809806..02721cf041 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/states/initial.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/states/initial.rs @@ -1,5 +1,7 @@ use messages::protocols::connection::invite::Invitation; +use crate::protocols::typestate_con::traits::ThreadId; + #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct InitialState { pub(crate) invitation: Invitation, @@ -10,3 +12,9 @@ impl InitialState { Self { invitation } } } + +impl ThreadId for InitialState { + fn thread_id(&self) -> &str { + self.invitation.get_id() + } +} diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs index 3f4e211f93..fbc5f70cde 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs @@ -7,4 +7,8 @@ impl InvitedState { pub fn new(thread_id: Option) -> Self { Self { thread_id } } -} + + pub fn thread_id(&self) -> Option<&str> { + self.thread_id.as_deref() + } +} \ No newline at end of file diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs index ba55a82c01..cfc570fdd1 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs @@ -1,6 +1,6 @@ -use messages::{protocols::connection::request::Request, diddoc::aries::diddoc::AriesDidDoc}; +use messages::{diddoc::aries::diddoc::AriesDidDoc, protocols::connection::request::Request}; -use crate::protocols::typestate_con::traits::TheirDidDoc; +use crate::protocols::typestate_con::traits::{TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct RequestedState { @@ -18,3 +18,14 @@ impl TheirDidDoc for RequestedState { &self.request.connection.did_doc } } + +impl ThreadId for RequestedState { + //TODO: This should land in the threadlike macro. + fn thread_id(&self) -> &str { + self.request + .thread + .as_ref() + .and_then(|t| t.thid.as_deref()) + .unwrap_or(&self.request.id.0) + } +} diff --git a/aries_vcx/src/protocols/typestate_con/mod.rs b/aries_vcx/src/protocols/typestate_con/mod.rs index f3e1d355bf..d06edc3232 100644 --- a/aries_vcx/src/protocols/typestate_con/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/mod.rs @@ -20,7 +20,10 @@ use crate::{ }; use self::{ - common::states::complete::CompleteState, pairwise_info::PairwiseInfo, serde::de::VagueState, traits::TheirDidDoc, + common::states::complete::CompleteState, + pairwise_info::PairwiseInfo, + serde::de::VagueState, + traits::{TheirDidDoc, ThreadId}, }; pub use self::serde::de::VagueConnection; @@ -57,6 +60,32 @@ impl Connection { pub fn protocols(&self) -> Vec { ProtocolRegistry::init().protocols() } + + pub(crate) async fn basic_send_message( + wallet: &Arc, + message: &A2AMessage, + sender_verkey: &str, + did_doc: &AriesDidDoc, + transport: &T, + ) -> VcxResult<()> + where + T: Transport, + { + let env = EncryptionEnvelope::create(wallet, message, Some(sender_verkey), did_doc).await?; + let msg = env.0; + let service_endpoint = did_doc.get_endpoint(); // This, like many other things, shouldn't clone... + + transport.send_message(msg, &service_endpoint).await + } +} + +impl Connection +where + S: ThreadId, +{ + pub fn thread_id(&self) -> &str { + self.state.thread_id() + } } impl Connection @@ -91,13 +120,9 @@ where where T: Transport, { - let sender_verkey = &self.pairwise_info.pw_vk; + let sender_verkey = &self.pairwise_info().pw_vk; let did_doc = self.their_did_doc(); - let env = EncryptionEnvelope::create(wallet, message, Some(sender_verkey), did_doc).await?; - let msg = env.0; - let service_endpoint = did_doc.get_endpoint(); // This, like many other things, shouldn't clone... - - transport.send_message(msg, &service_endpoint).await + Self::basic_send_message(wallet, message, sender_verkey, did_doc, transport).await } } diff --git a/aries_vcx/src/protocols/typestate_con/serde/de.rs b/aries_vcx/src/protocols/typestate_con/serde/de.rs index 20f60ae636..ac503ad103 100644 --- a/aries_vcx/src/protocols/typestate_con/serde/de.rs +++ b/aries_vcx/src/protocols/typestate_con/serde/de.rs @@ -1,5 +1,10 @@ +use std::sync::Arc; + +use messages::{a2a::A2AMessage, diddoc::aries::diddoc::AriesDidDoc, protocols::connection::invite::Invitation}; + use crate::{ - errors::error::{AriesVcxError, AriesVcxErrorKind}, + errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult}, + plugins::wallet::base_wallet::BaseWallet, protocols::typestate_con::{ common::states::{complete::CompleteState, responded::RespondedState}, initiation_type::{Invitee, Inviter}, @@ -12,7 +17,8 @@ use crate::{ requested::RequestedState as InviterRequested, }, pairwise_info::PairwiseInfo, - Connection, + traits::{TheirDidDoc, ThreadId}, + Connection, Transport, }, }; @@ -85,7 +91,7 @@ macro_rules! try_from_vague_to_concrete { }; } -/// Helper type mainly used for deserialization of a [`Connection`]. +/// Helper type mainly used for deserialization of a [`Connection`]. /// It does not expose methods to advance the connection protocol /// It does, however, expose some methods agnostic to the [`Connection`] type. #[derive(Debug, Serialize, Deserialize)] @@ -243,4 +249,83 @@ impl VagueConnection { pub fn state(&self) -> State { (&self.state).into() } + + pub fn thread_id(&self) -> Option<&str> { + match &self.state { + VagueState::Invitee(VagueInviteeState::Initial(_)) => None, + VagueState::Invitee(VagueInviteeState::Invited(s)) => Some(s.thread_id()), + VagueState::Invitee(VagueInviteeState::Requested(s)) => Some(s.thread_id()), + VagueState::Invitee(VagueInviteeState::Responded(s)) => Some(s.thread_id()), + VagueState::Invitee(VagueInviteeState::Complete(s)) => Some(s.thread_id()), + VagueState::Inviter(VagueInviterState::Initial(s)) => Some(s.thread_id()), + VagueState::Inviter(VagueInviterState::Invited(s)) => s.thread_id(), + VagueState::Inviter(VagueInviterState::Requested(s)) => Some(s.thread_id()), + VagueState::Inviter(VagueInviterState::Responded(s)) => Some(s.thread_id()), + VagueState::Inviter(VagueInviterState::Complete(s)) => Some(s.thread_id()), + } + } + + pub fn pairwise_info(&self) -> &PairwiseInfo { + &self.pairwise_info + } + + pub fn their_did_doc(&self) -> Option<&AriesDidDoc> { + match &self.state { + VagueState::Invitee(VagueInviteeState::Initial(_)) => None, + VagueState::Invitee(VagueInviteeState::Invited(s)) => Some(s.their_did_doc()), + VagueState::Invitee(VagueInviteeState::Requested(s)) => Some(s.their_did_doc()), + VagueState::Invitee(VagueInviteeState::Responded(s)) => Some(s.their_did_doc()), + VagueState::Invitee(VagueInviteeState::Complete(s)) => Some(s.their_did_doc()), + VagueState::Inviter(VagueInviterState::Initial(_)) => None, + VagueState::Inviter(VagueInviterState::Invited(_)) => None, + VagueState::Inviter(VagueInviterState::Requested(s)) => Some(s.their_did_doc()), + VagueState::Inviter(VagueInviterState::Responded(s)) => Some(s.their_did_doc()), + VagueState::Inviter(VagueInviterState::Complete(s)) => Some(s.their_did_doc()), + } + } + + pub fn remote_did(&self) -> Option<&str> { + self.their_did_doc().map(|d| d.id.as_str()) + } + + pub fn remote_vk(&self) -> VcxResult { + let did_doc = self.their_did_doc().ok_or(AriesVcxError::from_msg( + AriesVcxErrorKind::NotReady, + "No DidDoc present", + ))?; + + did_doc + .recipient_keys()? + .first() + .map(ToOwned::to_owned) + .ok_or(AriesVcxError::from_msg( + AriesVcxErrorKind::NotReady, + "Can't resolve recipient key from the counterparty diddoc.", + )) + } + + pub fn invitation(&self) -> Option<&Invitation> { + match &self.state { + VagueState::Inviter(VagueInviterState::Initial(s)) => Some(&s.invitation), + _ => None, + } + } + + pub async fn send_message( + &self, + wallet: &Arc, + message: &A2AMessage, + transport: &T, + ) -> VcxResult<()> + where + T: Transport, + { + let sender_verkey = &self.pairwise_info().pw_vk; + let did_doc = self.their_did_doc().ok_or(AriesVcxError::from_msg( + AriesVcxErrorKind::NotReady, + "No DidDoc present", + ))?; + + Connection::<(), ()>::basic_send_message(wallet, message, sender_verkey, did_doc, transport).await + } } diff --git a/aries_vcx/src/protocols/typestate_con/traits.rs b/aries_vcx/src/protocols/typestate_con/traits.rs index 9ebcfc5c00..32614b9ce6 100644 --- a/aries_vcx/src/protocols/typestate_con/traits.rs +++ b/aries_vcx/src/protocols/typestate_con/traits.rs @@ -14,3 +14,9 @@ pub trait TheirDidDoc { pub trait Transport { async fn send_message(&self, msg: Vec, service_endpoint: &str) -> VcxResult<()>; } + +/// Trait used for implementing common [`super::Connection`] behavior based +/// on states implementing it. +pub trait ThreadId { + fn thread_id(&self) -> &str; +} \ No newline at end of file diff --git a/libvcx/src/api_vcx/api_handle/typestate_con.rs b/libvcx/src/api_vcx/api_handle/typestate_con.rs index f63bb34c37..5b9d37da29 100644 --- a/libvcx/src/api_vcx/api_handle/typestate_con.rs +++ b/libvcx/src/api_vcx/api_handle/typestate_con.rs @@ -3,6 +3,7 @@ use std::{collections::HashMap, sync::RwLock}; use agency_client::httpclient::post_message; use aries_vcx::{ errors::error::VcxResult, + messages::protocols::basic_message::message::BasicMessage, protocols::typestate_con::{ invitee::InviteeConnection, inviter::InviterConnection, pairwise_info::PairwiseInfo, Connection, Transport, VagueConnection, @@ -46,6 +47,20 @@ fn new_handle() -> LibvcxResult { } } +fn add_connection(connection: VagueConnection) -> LibvcxResult { + let handle = new_handle()?; + CONNECTION_MAP.write()?.insert(handle, connection); + Ok(handle) +} + +fn insert_connection(handle: u32, connection: Connection) -> LibvcxResult<()> +where + VagueConnection: From>, +{ + CONNECTION_MAP.write()?.insert(handle, connection.into()); + Ok(()) +} + fn remove_connection(handle: &u32) -> LibvcxResult> where Connection: TryFrom, @@ -62,20 +77,6 @@ where }) } -fn add_connection(connection: VagueConnection) -> LibvcxResult { - let handle = new_handle()?; - CONNECTION_MAP.write()?.insert(handle, connection); - Ok(handle) -} - -fn insert_connection(handle: u32, connection: Connection) -> LibvcxResult<()> -where - VagueConnection: From>, -{ - CONNECTION_MAP.write()?.insert(handle, connection.into()); - Ok(()) -} - fn serialize(data: &T) -> LibvcxResult where T: serde::ser::Serialize, @@ -101,7 +102,6 @@ pub async fn create_inviter(pw_info: Option) -> LibvcxResult trace!("create_inviter >>>"); let profile = get_main_profile()?; - // This could probably be generated once and used/cloned around. let pw_info = pw_info.unwrap_or(PairwiseInfo::create(&profile.inject_wallet()).await?); let con = InviterConnection::new_invited("".to_owned(), pw_info); @@ -135,37 +135,106 @@ pub async fn create_invite(handle: u32, service_endpoint: String, routing_keys: } // ----------------------------- GETTERS ------------------------------------ -// pub fn get_thread_id(handle: u32) -> LibvcxResult { -// trace!("get_thread_id >>> handle: {}", handle); -// CONNECTION_MAP.get(handle, |connection| Ok(connection.get_thread_id())) -// } - -// pub fn get_pairwise_info(handle: u32) -> LibvcxResult { -// trace!("get_pairwise_info >>> handle: {}", handle); -// CONNECTION_MAP.get(handle, |connection| serialize(connection.pairwise_info())) -// } - -// pub fn get_remote_did(handle: u32) -> LibvcxResult { -// trace!("get_remote_did >>> handle: {}", handle); -// CONNECTION_MAP.get(handle, |connection| connection.remote_did().map_err(|e| e.into())) -// } - -// pub fn get_remote_vk(handle: u32) -> LibvcxResult { -// trace!("get_remote_vk >>> handle: {}", handle); -// CONNECTION_MAP.get(handle, |connection| connection.remote_vk().map_err(|e| e.into())) -// } - -// pub fn get_state(handle: u32) -> LibvcxResult { -// trace!("get_state >>> handle: {}", handle); -// CONNECTION_MAP.get(handle, |connection| Ok(connection.get_state().into())) -// } - -// pub fn get_invitation(handle: u32) -> LibvcxResult { -// trace!("get_invitation >>> handle: {}", handle); - -// let invitation = get_connection(&handle)?.get_invitation(); -// serialize(invitation) -// } +pub fn get_thread_id(handle: u32) -> LibvcxResult { + trace!("get_thread_id >>> handle: {}", handle); + + let lock = CONNECTION_MAP.read()?; + let con = lock.get(&handle).ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("Unable to retrieve expected connection for handle: {}", handle), + ) + })?; + + con.thread_id().map(ToOwned::to_owned).ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("No thread ID for connection with handle: {}", handle), + ) + }) +} + +pub fn get_pairwise_info(handle: u32) -> LibvcxResult { + trace!("get_pairwise_info >>> handle: {}", handle); + + let lock = CONNECTION_MAP.read()?; + let con = lock.get(&handle).ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("Unable to retrieve expected connection for handle: {}", handle), + ) + })?; + + serialize(con.pairwise_info()) +} + +pub fn get_remote_did(handle: u32) -> LibvcxResult { + trace!("get_remote_did >>> handle: {}", handle); + + let lock = CONNECTION_MAP.read()?; + let con = lock.get(&handle).ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("Unable to retrieve expected connection for handle: {}", handle), + ) + })?; + + con.remote_did().map(ToOwned::to_owned).ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("No remote DID for connection with handle: {}", handle), + ) + }) +} + +pub fn get_remote_vk(handle: u32) -> LibvcxResult { + trace!("get_remote_vk >>> handle: {}", handle); + + let lock = CONNECTION_MAP.read()?; + let con = lock.get(&handle).ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("Unable to retrieve expected connection for handle: {}", handle), + ) + })?; + + con.remote_vk().map_err(From::from) +} + +pub fn get_state(handle: u32) -> LibvcxResult { + trace!("get_state >>> handle: {}", handle); + + let lock = CONNECTION_MAP.read()?; + let con = lock.get(&handle).ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("Unable to retrieve expected connection for handle: {}", handle), + ) + })?; + + Ok(con.state().into()) +} + +pub fn get_invitation(handle: u32) -> LibvcxResult { + trace!("get_invitation >>> handle: {}", handle); + + let lock = CONNECTION_MAP.read()?; + let con = lock.get(&handle).ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("Unable to retrieve expected connection for handle: {}", handle), + ) + })?; + + let invitation = con.invitation().ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("No invitation for connection with handle: {}", handle), + ) + })?; + + serialize(invitation) +} // ----------------------------- MSG PROCESSING ------------------------------------ pub async fn process_invite(handle: u32, invitation: &str) -> LibvcxResult<()> { @@ -254,6 +323,28 @@ pub async fn send_ack(handle: u32) -> LibvcxResult<()> { insert_connection(handle, con) } +pub async fn send_generic_message(handle: u32, content: String) -> LibvcxResult<()> { + trace!("send_generic_message >>>"); + + let wallet = get_main_profile()?.inject_wallet(); + let message = BasicMessage::create() + .set_content(content) + .set_time() + .set_out_time() + .to_a2a_message(); + + let lock = CONNECTION_MAP.read()?; + let con = lock.get(&handle).ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("Unable to retrieve expected connection for handle: {}", handle), + ) + })?; + + con.send_message(&wallet, &message, &*HTTP_CLIENT).await?; + Ok(()) +} + // // ------------------------- (DE)SERIALIZATION ---------------------------------- pub fn to_string(handle: u32) -> LibvcxResult { trace!("to_string >>>"); diff --git a/messages/src/protocols/connection/invite.rs b/messages/src/protocols/connection/invite.rs index a113fc5dfd..da870e871b 100644 --- a/messages/src/protocols/connection/invite.rs +++ b/messages/src/protocols/connection/invite.rs @@ -41,11 +41,11 @@ pub struct PublicInvitation { } impl Invitation { - pub fn get_id(&self) -> MessagesResult { + pub fn get_id(&self) -> &str { match self { - Self::Pairwise(invite) => Ok(invite.id.0.clone()), - Self::Public(invite) => Ok(invite.id.0.clone()), - Self::OutOfBand(invite) => Ok(invite.id.0.clone()), + Self::Pairwise(invite) => &invite.id.0, + Self::Public(invite) => &invite.id.0, + Self::OutOfBand(invite) => &invite.id.0, } } } From 6f65e34e06519c8feeb4d849d939c986f3b7940d Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Mon, 30 Jan 2023 09:40:07 +0200 Subject: [PATCH 20/66] Renamed remove_connection in libvcx to get_cloned_connection and implemented cloning to persist previous state in the cache Signed-off-by: Bogdan Mircea --- .../src/protocols/typestate_con/serde/de.rs | 10 ++-- .../src/api_vcx/api_handle/typestate_con.rs | 46 +++++++++---------- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/aries_vcx/src/protocols/typestate_con/serde/de.rs b/aries_vcx/src/protocols/typestate_con/serde/de.rs index ac503ad103..9bd73531fd 100644 --- a/aries_vcx/src/protocols/typestate_con/serde/de.rs +++ b/aries_vcx/src/protocols/typestate_con/serde/de.rs @@ -94,20 +94,20 @@ macro_rules! try_from_vague_to_concrete { /// Helper type mainly used for deserialization of a [`Connection`]. /// It does not expose methods to advance the connection protocol /// It does, however, expose some methods agnostic to the [`Connection`] type. -#[derive(Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct VagueConnection { source_id: String, pairwise_info: PairwiseInfo, state: VagueState, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub enum VagueState { Inviter(VagueInviterState), Invitee(VagueInviteeState), } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub enum VagueInviterState { Initial(InviterInitial), Invited(InviterInvited), @@ -116,7 +116,7 @@ pub enum VagueInviterState { Complete(CompleteState), } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub enum VagueInviteeState { Initial(InviteeInitial), Invited(InviteeInvited), @@ -326,6 +326,8 @@ impl VagueConnection { "No DidDoc present", ))?; + // The generic types do not matter here as the method is available + // on all possible implementations. Connection::<(), ()>::basic_send_message(wallet, message, sender_verkey, did_doc, transport).await } } diff --git a/libvcx/src/api_vcx/api_handle/typestate_con.rs b/libvcx/src/api_vcx/api_handle/typestate_con.rs index 5b9d37da29..ae397a3d8a 100644 --- a/libvcx/src/api_vcx/api_handle/typestate_con.rs +++ b/libvcx/src/api_vcx/api_handle/typestate_con.rs @@ -47,6 +47,22 @@ fn new_handle() -> LibvcxResult { } } +fn get_cloned_connection(handle: &u32) -> LibvcxResult> +where + Connection: TryFrom, +{ + CONNECTION_MAP + .write()? + .get(handle) + .and_then(|c| c.clone().try_into().ok()) + .ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("Unable to retrieve expected connection for handle: {}", handle), + ) + }) +} + fn add_connection(connection: VagueConnection) -> LibvcxResult { let handle = new_handle()?; CONNECTION_MAP.write()?.insert(handle, connection); @@ -61,22 +77,6 @@ where Ok(()) } -fn remove_connection(handle: &u32) -> LibvcxResult> -where - Connection: TryFrom, -{ - CONNECTION_MAP - .write()? - .remove(handle) - .and_then(|c| c.try_into().ok()) - .ok_or_else(|| { - LibvcxError::from_msg( - LibvcxErrorKind::ObjectAccessError, - format!("Unable to retrieve expected connection for handle: {}", handle), - ) - }) -} - fn serialize(data: &T) -> LibvcxResult where T: serde::ser::Serialize, @@ -247,7 +247,7 @@ pub async fn process_invite(handle: u32, invitation: &str) -> LibvcxResult<()> { let profile = get_main_profile()?; let invitation = deserialize(invitation)?; - let con = remove_connection(&handle)? + let con = get_cloned_connection(&handle)? .accept_invitation(&profile, &invitation) .await?; @@ -259,7 +259,7 @@ pub async fn process_invite(handle: u32, invitation: &str) -> LibvcxResult<()> { pub async fn process_request(handle: u32, request: &str) -> LibvcxResult<()> { trace!("process_request >>>"); - let con = remove_connection(&handle)?; + let con = get_cloned_connection(&handle)?; let request = deserialize(request)?; let con = con.handle_request(request).await?; @@ -269,7 +269,7 @@ pub async fn process_request(handle: u32, request: &str) -> LibvcxResult<()> { pub async fn process_response(handle: u32, response: &str) -> LibvcxResult<()> { trace!("process_response >>>"); - let con = remove_connection(&handle)?; + let con = get_cloned_connection(&handle)?; let wallet = get_main_profile()?.inject_wallet(); let response = deserialize(response)?; let con = con.handle_response(&wallet, response).await?; @@ -280,7 +280,7 @@ pub async fn process_response(handle: u32, response: &str) -> LibvcxResult<()> { pub async fn process_ack(handle: u32, message: &str) -> LibvcxResult<()> { trace!("process_ack >>>"); - let con = remove_connection(&handle)?; + let con = get_cloned_connection(&handle)?; let msg = deserialize(message)?; let con = con.acknowledge_connection(&msg)?; @@ -292,7 +292,7 @@ pub async fn process_ack(handle: u32, message: &str) -> LibvcxResult<()> { pub async fn send_response(handle: u32, service_endpoint: String, routing_keys: Vec) -> LibvcxResult<()> { trace!("send_response >>>"); - let con = remove_connection(&handle)?; + let con = get_cloned_connection(&handle)?; let wallet = get_main_profile()?.inject_wallet(); let con = con .send_response(&wallet, service_endpoint, routing_keys, &*HTTP_CLIENT) @@ -304,7 +304,7 @@ pub async fn send_response(handle: u32, service_endpoint: String, routing_keys: pub async fn send_request(handle: u32, service_endpoint: String, routing_keys: Vec) -> LibvcxResult<()> { trace!("send_request >>>"); - let con = remove_connection(&handle)?; + let con = get_cloned_connection(&handle)?; let wallet = get_main_profile()?.inject_wallet(); let con = con .send_request(&wallet, service_endpoint, routing_keys, &*HTTP_CLIENT) @@ -316,7 +316,7 @@ pub async fn send_request(handle: u32, service_endpoint: String, routing_keys: V pub async fn send_ack(handle: u32) -> LibvcxResult<()> { trace!("send_ack >>>"); - let con = remove_connection(&handle)?; + let con = get_cloned_connection(&handle)?; let wallet = get_main_profile()?.inject_wallet(); let con = con.send_ack(&wallet, &*HTTP_CLIENT).await?; From ebba6486e90b4a3ad98b9fa8b6fcf267b2184cf3 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Mon, 30 Jan 2023 09:41:54 +0200 Subject: [PATCH 21/66] Removed the lazy_static HTTPCLIENT in favor of using the ZST directly Signed-off-by: Bogdan Mircea --- libvcx/src/api_vcx/api_handle/typestate_con.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/libvcx/src/api_vcx/api_handle/typestate_con.rs b/libvcx/src/api_vcx/api_handle/typestate_con.rs index ae397a3d8a..0aefce2414 100644 --- a/libvcx/src/api_vcx/api_handle/typestate_con.rs +++ b/libvcx/src/api_vcx/api_handle/typestate_con.rs @@ -24,10 +24,6 @@ lazy_static! { static ref CONNECTION_MAP: Cache = RwLock::new(HashMap::new()); } -lazy_static! { - static ref HTTP_CLIENT: HttpClient = HttpClient; -} - struct HttpClient; #[async_trait] @@ -295,7 +291,7 @@ pub async fn send_response(handle: u32, service_endpoint: String, routing_keys: let con = get_cloned_connection(&handle)?; let wallet = get_main_profile()?.inject_wallet(); let con = con - .send_response(&wallet, service_endpoint, routing_keys, &*HTTP_CLIENT) + .send_response(&wallet, service_endpoint, routing_keys, &HttpClient) .await?; insert_connection(handle, con) @@ -307,7 +303,7 @@ pub async fn send_request(handle: u32, service_endpoint: String, routing_keys: V let con = get_cloned_connection(&handle)?; let wallet = get_main_profile()?.inject_wallet(); let con = con - .send_request(&wallet, service_endpoint, routing_keys, &*HTTP_CLIENT) + .send_request(&wallet, service_endpoint, routing_keys, &HttpClient) .await?; insert_connection(handle, con) @@ -318,7 +314,7 @@ pub async fn send_ack(handle: u32) -> LibvcxResult<()> { let con = get_cloned_connection(&handle)?; let wallet = get_main_profile()?.inject_wallet(); - let con = con.send_ack(&wallet, &*HTTP_CLIENT).await?; + let con = con.send_ack(&wallet, &HttpClient).await?; insert_connection(handle, con) } @@ -341,7 +337,7 @@ pub async fn send_generic_message(handle: u32, content: String) -> LibvcxResult< ) })?; - con.send_message(&wallet, &message, &*HTTP_CLIENT).await?; + con.send_message(&wallet, &message, &HttpClient).await?; Ok(()) } From cf7b88b9e0e09b6a99b9d5da7092ba3b24d3e89f Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Mon, 30 Jan 2023 09:57:32 +0200 Subject: [PATCH 22/66] Retro-fitted the process_request and send_response methods for backwards compatibility Signed-off-by: Bogdan Mircea --- .../protocols/typestate_con/inviter/mod.rs | 87 +++++++++++-------- .../typestate_con/inviter/states/requested.rs | 22 +++-- .../src/api_vcx/api_handle/typestate_con.rs | 22 ++--- 3 files changed, 76 insertions(+), 55 deletions(-) diff --git a/aries_vcx/src/protocols/typestate_con/inviter/mod.rs b/aries_vcx/src/protocols/typestate_con/inviter/mod.rs index e698d5952c..accef0f9b8 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/mod.rs @@ -78,30 +78,8 @@ impl InviterConnection { self.state.thread_id() } - pub async fn handle_request(self, request: Request) -> VcxResult> { - trace!("Connection::process_request >>> request: {:?}", request,); - - // There must be some other way to validate the thread ID other than cloning the entire Request - self.state - .thread_id - .as_ref() - .map(|thread_id| verify_thread_id(thread_id, &A2AMessage::ConnectionRequest(request.clone()))) - .unwrap_or(Ok(()))?; - - request.connection.did_doc.validate()?; - - let state = RequestedState::new(request); - - Ok(Connection { - source_id: self.source_id, - pairwise_info: self.pairwise_info, - initiation_type: self.initiation_type, - state, - }) - } -} - -impl InviterConnection { + // This should ideally belong in the Connection + // but was placed here to retro-fit the previous API. async fn build_response( &self, wallet: &Arc, @@ -122,44 +100,81 @@ impl InviterConnection { sign_connection_response(wallet, &self.pairwise_info.pw_vk, response).await } - pub async fn send_response( + // Due to backwards compatibility, we generate the signed response and store that in the state. + // However, it would be more efficient to store the request and postpone the response generation and + // signing until the next state, thus taking advantage of the request attributes and avoiding cloning the DidDoc. + pub async fn handle_request( self, wallet: &Arc, + request: Request, new_service_endpoint: String, new_routing_keys: Vec, - transport: &T, - ) -> VcxResult> - where - T: Transport, - { + ) -> VcxResult> { trace!( - "Connection::send_response >>> service_endpoint: {}, routing_keys: {:?}", + "Connection::process_request >>> request: {:?}, service_endpoint: {}, routing_keys: {:?}", + request, new_service_endpoint, new_routing_keys, ); + // There must be some other way to validate the thread ID other than cloning the entire Request + self.state + .thread_id + .as_ref() + .map(|thread_id| verify_thread_id(thread_id, &A2AMessage::ConnectionRequest(request.clone()))) + .unwrap_or(Ok(()))?; + + request.connection.did_doc.validate()?; + let new_pairwise_info = PairwiseInfo::create(wallet).await?; - let thread_id = self.state.request.get_thread_id(); + let did_doc = request.connection.did_doc.clone(); let signed_response = self .build_response( wallet, - &self.state.request, + &request, &new_pairwise_info, new_service_endpoint, new_routing_keys, ) .await?; - self.send_message(wallet, &signed_response.to_a2a_message(), transport) + let state = RequestedState::new(signed_response, did_doc); + + Ok(Connection { + source_id: self.source_id, + pairwise_info: new_pairwise_info, + initiation_type: self.initiation_type, + state, + }) + } +} + +impl InviterConnection { + pub async fn send_response( + self, + wallet: &Arc, + transport: &T, + ) -> VcxResult> + where + T: Transport, + { + trace!( + "Connection::send_response >>> signed_response: {:?}", + &self.state.signed_response + ); + + let thread_id = self.state.signed_response.get_thread_id(); + + self.send_message(wallet, &self.state.signed_response.to_a2a_message(), transport) .await?; - let state = RespondedState::new(self.state.request.connection.did_doc, thread_id); + let state = RespondedState::new(self.state.did_doc, thread_id); Ok(Connection { state, source_id: self.source_id, - pairwise_info: new_pairwise_info, + pairwise_info: self.pairwise_info, initiation_type: self.initiation_type, }) } diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs index cfc570fdd1..6bf070d259 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs @@ -1,31 +1,35 @@ -use messages::{diddoc::aries::diddoc::AriesDidDoc, protocols::connection::request::Request}; +use messages::{diddoc::aries::diddoc::AriesDidDoc, protocols::connection::response::SignedResponse}; use crate::protocols::typestate_con::traits::{TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct RequestedState { - pub(crate) request: Request, + pub(crate) signed_response: SignedResponse, + pub(crate) did_doc: AriesDidDoc, } impl RequestedState { - pub fn new(request: Request) -> Self { - Self { request } + pub fn new(signed_response: SignedResponse, did_doc: AriesDidDoc) -> Self { + Self { + signed_response, + did_doc, + } } } impl TheirDidDoc for RequestedState { fn their_did_doc(&self) -> &AriesDidDoc { - &self.request.connection.did_doc + &self.did_doc } } impl ThreadId for RequestedState { //TODO: This should land in the threadlike macro. fn thread_id(&self) -> &str { - self.request + self.signed_response .thread - .as_ref() - .and_then(|t| t.thid.as_deref()) - .unwrap_or(&self.request.id.0) + .thid + .as_deref() + .unwrap_or(&self.signed_response.id.0) } } diff --git a/libvcx/src/api_vcx/api_handle/typestate_con.rs b/libvcx/src/api_vcx/api_handle/typestate_con.rs index 0aefce2414..a624355e0a 100644 --- a/libvcx/src/api_vcx/api_handle/typestate_con.rs +++ b/libvcx/src/api_vcx/api_handle/typestate_con.rs @@ -250,14 +250,20 @@ pub async fn process_invite(handle: u32, invitation: &str) -> LibvcxResult<()> { insert_connection(handle, con) } -// ------------------ BREAKING CHANGE ------------------ -// Extra function arguments are deffered to send_response. -pub async fn process_request(handle: u32, request: &str) -> LibvcxResult<()> { +pub async fn process_request( + handle: u32, + request: &str, + service_endpoint: String, + routing_keys: Vec, +) -> LibvcxResult<()> { trace!("process_request >>>"); let con = get_cloned_connection(&handle)?; + let wallet = get_main_profile()?.inject_wallet(); let request = deserialize(request)?; - let con = con.handle_request(request).await?; + let con = con + .handle_request(&wallet, request, service_endpoint, routing_keys) + .await?; insert_connection(handle, con) } @@ -283,16 +289,12 @@ pub async fn process_ack(handle: u32, message: &str) -> LibvcxResult<()> { insert_connection(handle, con) } -// ------------------ BREAKING CHANGE ------------------ -// Got new arguments that were moved from process_request -pub async fn send_response(handle: u32, service_endpoint: String, routing_keys: Vec) -> LibvcxResult<()> { +pub async fn send_response(handle: u32) -> LibvcxResult<()> { trace!("send_response >>>"); let con = get_cloned_connection(&handle)?; let wallet = get_main_profile()?.inject_wallet(); - let con = con - .send_response(&wallet, service_endpoint, routing_keys, &HttpClient) - .await?; + let con = con.send_response(&wallet, &HttpClient).await?; insert_connection(handle, con) } From ea14d5805b79b4dda82371cf9a0f2799e384fc8b Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Mon, 30 Jan 2023 14:55:13 +0200 Subject: [PATCH 23/66] Added ProblemReport generation and sending Signed-off-by: Bogdan Mircea --- .../protocols/typestate_con/invitee/mod.rs | 24 ++++++--- .../typestate_con/invitee/states/requested.rs | 8 +-- .../protocols/typestate_con/inviter/mod.rs | 31 ++++++++--- .../typestate_con/inviter/states/invited.rs | 10 +++- aries_vcx/src/protocols/typestate_con/mod.rs | 54 +++++++++++++++++-- .../src/protocols/typestate_con/serde/de.rs | 4 +- .../src/protocols/typestate_con/traits.rs | 8 ++- .../src/api_vcx/api_handle/typestate_con.rs | 9 +--- 8 files changed, 117 insertions(+), 31 deletions(-) diff --git a/aries_vcx/src/protocols/typestate_con/invitee/mod.rs b/aries_vcx/src/protocols/typestate_con/invitee/mod.rs index 922c253244..dcada8659f 100644 --- a/aries_vcx/src/protocols/typestate_con/invitee/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/invitee/mod.rs @@ -121,22 +121,34 @@ impl InviteeConnection { } impl InviteeConnection { - pub async fn handle_response( + pub async fn handle_response( self, wallet: &Arc, response: SignedResponse, - ) -> VcxResult> { + transport: &T, + ) -> VcxResult> + where + T: Transport, + { verify_thread_id(&self.state.thread_id, &A2AMessage::ConnectionResponse(response.clone()))?; let keys = &self.state.did_doc.recipient_keys()?; - let remote_vk = keys.first().ok_or(AriesVcxError::from_msg( + let their_vk = keys.first().ok_or(AriesVcxError::from_msg( AriesVcxErrorKind::InvalidState, "Cannot handle response: remote verkey not found", ))?; - let did_doc = decode_signed_connection_response(wallet, response, remote_vk) - .await - .map(|response| response.connection.did_doc)?; + let did_doc = match decode_signed_connection_response(wallet, response, their_vk).await { + Ok(response) => Ok(response.connection.did_doc), + Err(err) => { + error!("Request DidDoc validation failed! Sending ProblemReport..."); + + self.send_problem_report(wallet, &err, self.thread_id(), &self.state.did_doc, transport) + .await; + + Err(err) + } + }?; let state = RespondedState::new(did_doc, self.state.thread_id); diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs index 7cdfc603a6..00d62f53dc 100644 --- a/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs +++ b/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs @@ -1,11 +1,11 @@ use messages::diddoc::aries::diddoc::AriesDidDoc; -use crate::protocols::typestate_con::traits::{TheirDidDoc, ThreadId}; +use crate::protocols::typestate_con::traits::{HandleProblem, TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct RequestedState { pub(crate) did_doc: AriesDidDoc, - pub(crate) thread_id: String + pub(crate) thread_id: String, } impl RequestedState { @@ -24,4 +24,6 @@ impl ThreadId for RequestedState { fn thread_id(&self) -> &str { &self.thread_id } -} \ No newline at end of file +} + +impl HandleProblem for RequestedState {} diff --git a/aries_vcx/src/protocols/typestate_con/inviter/mod.rs b/aries_vcx/src/protocols/typestate_con/inviter/mod.rs index accef0f9b8..0db13dd147 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/mod.rs @@ -74,8 +74,8 @@ impl InviterConnection { /// As the inviter connection can be started directly in the invited state, /// like with a public invitation, we might or might not have a thread ID. - pub fn thread_id(&self) -> Option<&str> { - self.state.thread_id() + pub fn opt_thread_id(&self) -> Option<&str> { + self.state.opt_thread_id() } // This should ideally belong in the Connection @@ -101,15 +101,19 @@ impl InviterConnection { } // Due to backwards compatibility, we generate the signed response and store that in the state. - // However, it would be more efficient to store the request and postpone the response generation and + // However, it would be more efficient to store the request and postpone the response generation and // signing until the next state, thus taking advantage of the request attributes and avoiding cloning the DidDoc. - pub async fn handle_request( + pub async fn handle_request( self, wallet: &Arc, request: Request, new_service_endpoint: String, new_routing_keys: Vec, - ) -> VcxResult> { + transport: &T, + ) -> VcxResult> + where + T: Transport, + { trace!( "Connection::process_request >>> request: {:?}, service_endpoint: {}, routing_keys: {:?}", request, @@ -124,7 +128,22 @@ impl InviterConnection { .map(|thread_id| verify_thread_id(thread_id, &A2AMessage::ConnectionRequest(request.clone()))) .unwrap_or(Ok(()))?; - request.connection.did_doc.validate()?; + // If the request's DidDoc validation fails, we generate and send a ProblemReport. + // We then return early with the provided error. + if let Err(err) = request.connection.did_doc.validate() { + error!("Request DidDoc validation failed! Sending ProblemReport..."); + + self.send_problem_report( + wallet, + &err, + &request.get_thread_id(), + &request.connection.did_doc, + transport, + ) + .await; + + Err(err)?; + } let new_pairwise_info = PairwiseInfo::create(wallet).await?; let did_doc = request.connection.did_doc.clone(); diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs index fbc5f70cde..46e12a8387 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs @@ -1,3 +1,5 @@ +use crate::protocols::typestate_con::traits::HandleProblem; + #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct InvitedState { pub(crate) thread_id: Option, @@ -8,7 +10,11 @@ impl InvitedState { Self { thread_id } } - pub fn thread_id(&self) -> Option<&str> { + /// Unlike other states, the ones implementing the [`crate::protocols::typestate_con::traits::ThreadId`], + /// this state may or may not have a thread ID, so we're returning an option. + pub fn opt_thread_id(&self) -> Option<&str> { self.thread_id.as_deref() } -} \ No newline at end of file +} + +impl HandleProblem for InvitedState {} diff --git a/aries_vcx/src/protocols/typestate_con/mod.rs b/aries_vcx/src/protocols/typestate_con/mod.rs index d06edc3232..039ee28e83 100644 --- a/aries_vcx/src/protocols/typestate_con/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/mod.rs @@ -9,9 +9,12 @@ mod traits; use messages::{ a2a::{protocol_registry::ProtocolRegistry, A2AMessage}, diddoc::aries::diddoc::AriesDidDoc, - protocols::discovery::disclose::{Disclose, ProtocolDescriptor}, + protocols::{ + connection::problem_report::{ProblemCode, ProblemReport}, + discovery::disclose::{Disclose, ProtocolDescriptor}, + }, }; -use std::sync::Arc; +use std::{error::Error, sync::Arc}; use crate::{ errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult}, @@ -23,7 +26,7 @@ use self::{ common::states::complete::CompleteState, pairwise_info::PairwiseInfo, serde::de::VagueState, - traits::{TheirDidDoc, ThreadId}, + traits::{HandleProblem, TheirDidDoc, ThreadId}, }; pub use self::serde::de::VagueConnection; @@ -126,6 +129,51 @@ where } } +impl Connection +where + S: HandleProblem, +{ + fn create_problem_report(&self, err: &E, thread_id: &str) -> ProblemReport + where + E: Error, + { + ProblemReport::create() + .set_problem_code(ProblemCode::RequestProcessingError) + .set_explain(err.to_string()) + .set_thread_id(thread_id) + .set_out_time() + } + + async fn send_problem_report( + &self, + wallet: &Arc, + err: &E, + thread_id: &str, + did_doc: &AriesDidDoc, + transport: &T, + ) where + E: Error, + T: Transport, + { + let sender_verkey = &self.pairwise_info().pw_vk; + let problem_report = self.create_problem_report(err, thread_id); + let res = Self::basic_send_message( + wallet, + &problem_report.to_a2a_message(), + sender_verkey, + did_doc, + transport, + ) + .await; + + if let Err(e) = res { + trace!("Error encountered when sending ProblemReport: {}", e); + } else { + info!("Error report sent!"); + } + } +} + impl Connection { pub fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { self.state.remote_protocols() diff --git a/aries_vcx/src/protocols/typestate_con/serde/de.rs b/aries_vcx/src/protocols/typestate_con/serde/de.rs index 9bd73531fd..2b0364bacd 100644 --- a/aries_vcx/src/protocols/typestate_con/serde/de.rs +++ b/aries_vcx/src/protocols/typestate_con/serde/de.rs @@ -258,7 +258,7 @@ impl VagueConnection { VagueState::Invitee(VagueInviteeState::Responded(s)) => Some(s.thread_id()), VagueState::Invitee(VagueInviteeState::Complete(s)) => Some(s.thread_id()), VagueState::Inviter(VagueInviterState::Initial(s)) => Some(s.thread_id()), - VagueState::Inviter(VagueInviterState::Invited(s)) => s.thread_id(), + VagueState::Inviter(VagueInviterState::Invited(s)) => s.opt_thread_id(), VagueState::Inviter(VagueInviterState::Requested(s)) => Some(s.thread_id()), VagueState::Inviter(VagueInviterState::Responded(s)) => Some(s.thread_id()), VagueState::Inviter(VagueInviterState::Complete(s)) => Some(s.thread_id()), @@ -326,7 +326,7 @@ impl VagueConnection { "No DidDoc present", ))?; - // The generic types do not matter here as the method is available + // The generic types do not matter here as the method is available // on all possible implementations. Connection::<(), ()>::basic_send_message(wallet, message, sender_verkey, did_doc, transport).await } diff --git a/aries_vcx/src/protocols/typestate_con/traits.rs b/aries_vcx/src/protocols/typestate_con/traits.rs index 32614b9ce6..239503ea7c 100644 --- a/aries_vcx/src/protocols/typestate_con/traits.rs +++ b/aries_vcx/src/protocols/typestate_con/traits.rs @@ -15,8 +15,12 @@ pub trait Transport { async fn send_message(&self, msg: Vec, service_endpoint: &str) -> VcxResult<()>; } -/// Trait used for implementing common [`super::Connection`] behavior based +/// Trait used for implementing common [`super::Connection`] behavior based /// on states implementing it. pub trait ThreadId { fn thread_id(&self) -> &str; -} \ No newline at end of file +} + +/// Marker trait used for implementing [`messages::protocols::connection::problem_report::ProblemReport`] +/// handling on certain [`super::Connection`] types. +pub trait HandleProblem {} diff --git a/libvcx/src/api_vcx/api_handle/typestate_con.rs b/libvcx/src/api_vcx/api_handle/typestate_con.rs index a624355e0a..511628bc61 100644 --- a/libvcx/src/api_vcx/api_handle/typestate_con.rs +++ b/libvcx/src/api_vcx/api_handle/typestate_con.rs @@ -236,11 +236,6 @@ pub fn get_invitation(handle: u32) -> LibvcxResult { pub async fn process_invite(handle: u32, invitation: &str) -> LibvcxResult<()> { trace!("process_invite >>>"); - // ------------------ BREAKING CHANGE ------------------ - // The code below would do the proper thing, but the function must be async - // Also, this doesn't really make sense conceptually as the invitation is also passed - // when the invitee is created -> so the transition happens there automatically. - let profile = get_main_profile()?; let invitation = deserialize(invitation)?; let con = get_cloned_connection(&handle)? @@ -262,7 +257,7 @@ pub async fn process_request( let wallet = get_main_profile()?.inject_wallet(); let request = deserialize(request)?; let con = con - .handle_request(&wallet, request, service_endpoint, routing_keys) + .handle_request(&wallet, request, service_endpoint, routing_keys, &HttpClient) .await?; insert_connection(handle, con) @@ -274,7 +269,7 @@ pub async fn process_response(handle: u32, response: &str) -> LibvcxResult<()> { let con = get_cloned_connection(&handle)?; let wallet = get_main_profile()?.inject_wallet(); let response = deserialize(response)?; - let con = con.handle_response(&wallet, response).await?; + let con = con.handle_response(&wallet, response, &HttpClient).await?; insert_connection(handle, con) } From b81b2b6a8880ea57fefba19a069768909de2b146 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Mon, 30 Jan 2023 15:56:38 +0200 Subject: [PATCH 24/66] Added test From implementations between SerializableConnection and VagueConnection for compile-time check that types match Signed-off-by: Bogdan Mircea --- .../src/protocols/typestate_con/serde/de.rs | 64 ++++++++++++++++++- .../src/protocols/typestate_con/serde/mod.rs | 2 +- .../src/protocols/typestate_con/serde/ser.rs | 64 ++++++++++++++++++- 3 files changed, 123 insertions(+), 7 deletions(-) diff --git a/aries_vcx/src/protocols/typestate_con/serde/de.rs b/aries_vcx/src/protocols/typestate_con/serde/de.rs index 2b0364bacd..22c4cbc945 100644 --- a/aries_vcx/src/protocols/typestate_con/serde/de.rs +++ b/aries_vcx/src/protocols/typestate_con/serde/de.rs @@ -96,9 +96,9 @@ macro_rules! try_from_vague_to_concrete { /// It does, however, expose some methods agnostic to the [`Connection`] type. #[derive(Clone, Debug, Serialize, Deserialize)] pub struct VagueConnection { - source_id: String, - pairwise_info: PairwiseInfo, - state: VagueState, + pub(super) source_id: String, + pub(super) pairwise_info: PairwiseInfo, + pub(super) state: VagueState, } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -331,3 +331,61 @@ impl VagueConnection { Connection::<(), ()>::basic_send_message(wallet, message, sender_verkey, did_doc, transport).await } } + +/// Compile-time assurance that the deserialization type +/// of the [`Connection`], if modified, will be modified along the serialization type. +#[cfg(test)] +mod tests { + use crate::protocols::typestate_con::serde::ser::*; + + use super::*; + + impl<'a> From> for VagueInviteeState { + fn from(value: RefInviteeState<'a>) -> Self { + match value { + RefInviteeState::Initial(s) => Self::Initial(s.to_owned()), + RefInviteeState::Invited(s) => Self::Invited(s.to_owned()), + RefInviteeState::Requested(s) => Self::Requested(s.to_owned()), + RefInviteeState::Responded(s) => Self::Responded(s.to_owned()), + RefInviteeState::Complete(s) => Self::Complete(s.to_owned()), + } + } + } + + impl<'a> From> for VagueInviterState { + fn from(value: RefInviterState<'a>) -> Self { + match value { + RefInviterState::Initial(s) => Self::Initial(s.to_owned()), + RefInviterState::Invited(s) => Self::Invited(s.to_owned()), + RefInviterState::Requested(s) => Self::Requested(s.to_owned()), + RefInviterState::Responded(s) => Self::Responded(s.to_owned()), + RefInviterState::Complete(s) => Self::Complete(s.to_owned()), + } + } + } + + impl<'a> From> for VagueState { + fn from(value: RefState<'a>) -> Self { + match value { + RefState::Invitee(s) => Self::Invitee(s.into()), + RefState::Inviter(s) => Self::Inviter(s.into()), + } + } + } + + impl<'a> From> for VagueConnection { + fn from(value: SerializableConnection<'a>) -> Self { + let SerializableConnection { + source_id, + pairwise_info, + state, + } = value; + + Self { + source_id: source_id.to_owned(), + pairwise_info: pairwise_info.to_owned(), + state: state.into(), + } + } + } +} diff --git a/aries_vcx/src/protocols/typestate_con/serde/mod.rs b/aries_vcx/src/protocols/typestate_con/serde/mod.rs index 4397947172..2e6ab62c61 100644 --- a/aries_vcx/src/protocols/typestate_con/serde/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/serde/mod.rs @@ -1,2 +1,2 @@ pub mod de; -mod ser; +pub mod ser; diff --git a/aries_vcx/src/protocols/typestate_con/serde/ser.rs b/aries_vcx/src/protocols/typestate_con/serde/ser.rs index 063983280f..76e1d98a2c 100644 --- a/aries_vcx/src/protocols/typestate_con/serde/ser.rs +++ b/aries_vcx/src/protocols/typestate_con/serde/ser.rs @@ -32,9 +32,9 @@ where /// of a [`Connection`] (so we don't clone unnecessarily) to itself and then serialize it. #[derive(Debug, Serialize)] pub struct SerializableConnection<'a> { - source_id: &'a str, - pairwise_info: &'a PairwiseInfo, - pub state: RefState<'a>, + pub(super) source_id: &'a str, + pub(super) pairwise_info: &'a PairwiseInfo, + pub(super) state: RefState<'a>, } impl<'a> SerializableConnection<'a> { @@ -166,3 +166,61 @@ impl<'a> From<&'a CompleteState> for RefInviteeState<'a> { Self::Complete(value) } } + +/// Compile-time assurance that the serialization type +/// of the [`Connection`], if modified, will be modified along the deserialization type. +#[cfg(test)] +mod tests { + use crate::protocols::typestate_con::serde::de::*; + + use super::*; + + impl<'a> From<&'a VagueInviteeState> for RefInviteeState<'a> { + fn from(value: &'a VagueInviteeState) -> Self { + match value { + VagueInviteeState::Initial(s) => Self::Initial(s), + VagueInviteeState::Invited(s) => Self::Invited(s), + VagueInviteeState::Requested(s) => Self::Requested(s), + VagueInviteeState::Responded(s) => Self::Responded(s), + VagueInviteeState::Complete(s) => Self::Complete(s), + } + } + } + + impl<'a> From<&'a VagueInviterState> for RefInviterState<'a> { + fn from(value: &'a VagueInviterState) -> Self { + match value { + VagueInviterState::Initial(s) => Self::Initial(s), + VagueInviterState::Invited(s) => Self::Invited(s), + VagueInviterState::Requested(s) => Self::Requested(s), + VagueInviterState::Responded(s) => Self::Responded(s), + VagueInviterState::Complete(s) => Self::Complete(s), + } + } + } + + impl<'a> From<&'a VagueState> for RefState<'a> { + fn from(value: &'a VagueState) -> Self { + match value { + VagueState::Invitee(s) => Self::Invitee(s.into()), + VagueState::Inviter(s) => Self::Inviter(s.into()), + } + } + } + + impl<'a> From<&'a VagueConnection> for SerializableConnection<'a> { + fn from(value: &'a VagueConnection) -> Self { + let VagueConnection { + source_id, + pairwise_info, + state, + } = value; + + Self { + source_id, + pairwise_info, + state: state.into(), + } + } + } +} From 7595bbe150ce32966be014e6c2bcef97272712ab Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Mon, 30 Jan 2023 16:06:49 +0200 Subject: [PATCH 25/66] Added boilerplate macro for From impls for SerializationConnection Signed-off-by: Bogdan Mircea --- .../src/protocols/typestate_con/serde/de.rs | 2 +- .../src/protocols/typestate_con/serde/ser.rs | 171 +++++++----------- 2 files changed, 67 insertions(+), 106 deletions(-) diff --git a/aries_vcx/src/protocols/typestate_con/serde/de.rs b/aries_vcx/src/protocols/typestate_con/serde/de.rs index 22c4cbc945..c3428e5ff0 100644 --- a/aries_vcx/src/protocols/typestate_con/serde/de.rs +++ b/aries_vcx/src/protocols/typestate_con/serde/de.rs @@ -23,7 +23,7 @@ use crate::{ }; /// Macro used for boilerplace implementation of the -/// [`From`] trait from a concrete connection state to the vague state. +/// [`From`] trait from a concrete connection state to the equivalent vague state. macro_rules! from_concrete_to_vague { ($from:ident, $var:ident, $to:ident) => { impl From<$from> for $to { diff --git a/aries_vcx/src/protocols/typestate_con/serde/ser.rs b/aries_vcx/src/protocols/typestate_con/serde/ser.rs index 76e1d98a2c..0c0d4431b2 100644 --- a/aries_vcx/src/protocols/typestate_con/serde/ser.rs +++ b/aries_vcx/src/protocols/typestate_con/serde/ser.rs @@ -15,16 +15,31 @@ use crate::protocols::typestate_con::{ Connection, }; -impl Serialize for Connection -where - for<'a> SerializableConnection<'a>: From<&'a Connection>, -{ - fn serialize(&self, serializer: Serializer) -> Result - where - Serializer: ::serde::Serializer, - { - SerializableConnection::from(self).serialize(serializer) - } +/// Macro used for boilerplace implementation of the +/// [`From`] trait from a concrete connection state to the equivalent reference state +/// used for serialization. +macro_rules! from_concrete_to_serializable { + ($from:ident, $var:ident, $to:ident) => { + impl<'a> From<&'a $from> for $to<'a> { + fn from(value: &'a $from) -> Self { + Self::$var(value) + } + } + }; + + ($init_type:ident, $state:ident, $var:ident, $to:ident) => { + impl<'a, S> From<(&'a $init_type, &'a S)> for $to<'a> + where + $state<'a>: From<&'a S>, + S: 'a, + { + fn from(value: (&'a $init_type, &'a S)) -> Self { + let (_, state) = value; + let serde_state = From::from(state); + Self::$var(serde_state) + } + } + }; } /// Type used for serialization of a [`Connection`]. @@ -37,58 +52,12 @@ pub struct SerializableConnection<'a> { pub(super) state: RefState<'a>, } -impl<'a> SerializableConnection<'a> { - fn new(source_id: &'a str, pairwise_info: &'a PairwiseInfo, state: RefState<'a>) -> Self { - Self { - source_id, - pairwise_info, - state, - } - } -} - -impl<'a, I, S> From<&'a Connection> for SerializableConnection<'a> -where - RefState<'a>: From<(&'a I, &'a S)>, - I: 'a, - S: 'a, -{ - fn from(value: &'a Connection) -> Self { - let state = From::from((&value.initiation_type, &value.state)); - Self::new(&value.source_id, &value.pairwise_info, state) - } -} - #[derive(Debug, Serialize)] pub enum RefState<'a> { Inviter(RefInviterState<'a>), Invitee(RefInviteeState<'a>), } -impl<'a, S> From<(&'a Inviter, &'a S)> for RefState<'a> -where - RefInviterState<'a>: From<&'a S>, - S: 'a, -{ - fn from(value: (&'a Inviter, &'a S)) -> Self { - let (_, state) = value; - let serde_state = From::from(state); - Self::Inviter(serde_state) - } -} - -impl<'a, S> From<(&'a Invitee, &'a S)> for RefState<'a> -where - RefInviteeState<'a>: From<&'a S>, - S: 'a, -{ - fn from(value: (&'a Invitee, &'a S)) -> Self { - let (_, state) = value; - let serde_state = From::from(state); - Self::Invitee(serde_state) - } -} - #[derive(Debug, Serialize)] pub enum RefInviterState<'a> { Initial(&'a InviterInitial), @@ -98,36 +67,6 @@ pub enum RefInviterState<'a> { Complete(&'a CompleteState), } -impl<'a> From<&'a InviterInitial> for RefInviterState<'a> { - fn from(value: &'a InviterInitial) -> Self { - Self::Initial(value) - } -} - -impl<'a> From<&'a InviterInvited> for RefInviterState<'a> { - fn from(value: &'a InviterInvited) -> Self { - Self::Invited(value) - } -} - -impl<'a> From<&'a InviterRequested> for RefInviterState<'a> { - fn from(value: &'a InviterRequested) -> Self { - Self::Requested(value) - } -} - -impl<'a> From<&'a RespondedState> for RefInviterState<'a> { - fn from(value: &'a RespondedState) -> Self { - Self::Responded(value) - } -} - -impl<'a> From<&'a CompleteState> for RefInviterState<'a> { - fn from(value: &'a CompleteState) -> Self { - Self::Complete(value) - } -} - #[derive(Debug, Serialize)] pub enum RefInviteeState<'a> { Initial(&'a InviteeInitial), @@ -137,33 +76,55 @@ pub enum RefInviteeState<'a> { Complete(&'a CompleteState), } -impl<'a> From<&'a InviteeInitial> for RefInviteeState<'a> { - fn from(value: &'a InviteeInitial) -> Self { - Self::Initial(value) +impl<'a, I, S> From<&'a Connection> for SerializableConnection<'a> +where + RefState<'a>: From<(&'a I, &'a S)>, + I: 'a, + S: 'a, +{ + fn from(value: &'a Connection) -> Self { + let state = From::from((&value.initiation_type, &value.state)); + Self::new(&value.source_id, &value.pairwise_info, state) } } -impl<'a> From<&'a InviteeInvited> for RefInviteeState<'a> { - fn from(value: &'a InviteeInvited) -> Self { - Self::Invited(value) - } -} +from_concrete_to_serializable!(Inviter, RefInviterState, Inviter, RefState); +from_concrete_to_serializable!(Invitee, RefInviteeState, Invitee, RefState); -impl<'a> From<&'a InviteeRequested> for RefInviteeState<'a> { - fn from(value: &'a InviteeRequested) -> Self { - Self::Requested(value) - } -} +from_concrete_to_serializable!(InviterInitial, Initial, RefInviterState); +from_concrete_to_serializable!(InviterInvited, Invited, RefInviterState); +from_concrete_to_serializable!(InviterRequested, Requested, RefInviterState); +from_concrete_to_serializable!(RespondedState, Responded, RefInviterState); +from_concrete_to_serializable!(CompleteState, Complete, RefInviterState); -impl<'a> From<&'a RespondedState> for RefInviteeState<'a> { - fn from(value: &'a RespondedState) -> Self { - Self::Responded(value) +from_concrete_to_serializable!(InviteeInitial, Initial, RefInviteeState); +from_concrete_to_serializable!(InviteeInvited, Invited, RefInviteeState); +from_concrete_to_serializable!(InviteeRequested, Requested, RefInviteeState); +from_concrete_to_serializable!(RespondedState, Responded, RefInviteeState); +from_concrete_to_serializable!(CompleteState, Complete, RefInviteeState); + +impl<'a> SerializableConnection<'a> { + fn new(source_id: &'a str, pairwise_info: &'a PairwiseInfo, state: RefState<'a>) -> Self { + Self { + source_id, + pairwise_info, + state, + } } } -impl<'a> From<&'a CompleteState> for RefInviteeState<'a> { - fn from(value: &'a CompleteState) -> Self { - Self::Complete(value) +/// Manual implementation of [`Serialize`] for [`Connection`], +/// as we'll first convert into [`SerializableConnection`] for a [`Connection`] reference +/// and serialize that. +impl Serialize for Connection +where + for<'a> SerializableConnection<'a>: From<&'a Connection>, +{ + fn serialize(&self, serializer: Serializer) -> Result + where + Serializer: ::serde::Serializer, + { + SerializableConnection::from(self).serialize(serializer) } } From ef29fbede118603fa7c8507fc6abbd6952d911c1 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Tue, 31 Jan 2023 18:39:55 +0200 Subject: [PATCH 26/66] Modified aries-vcx-agent to use typestate connections Signed-off-by: Bogdan Mircea --- Cargo.lock | 5 +- agents/rust/aries-vcx-agent/Cargo.toml | 1 + .../rust/aries-vcx-agent/src/http_client.rs | 14 +++ agents/rust/aries-vcx-agent/src/lib.rs | 1 + .../src/services/connection.rs | 117 ++++++++++-------- .../aries-vcx-agent/src/services/holder.rs | 44 ++++--- .../aries-vcx-agent/src/services/issuer.rs | 28 +++-- .../aries-vcx-agent/src/services/prover.rs | 25 +++- .../aries-vcx-agent/src/services/verifier.rs | 26 ++-- .../protocols/typestate_con/invitee/mod.rs | 2 +- .../protocols/typestate_con/inviter/mod.rs | 10 +- aries_vcx/src/protocols/typestate_con/mod.rs | 2 +- .../src/api_vcx/api_handle/typestate_con.rs | 4 +- 13 files changed, 180 insertions(+), 99 deletions(-) create mode 100644 agents/rust/aries-vcx-agent/src/http_client.rs diff --git a/Cargo.lock b/Cargo.lock index 296946323d..46e1d44cc8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -217,6 +217,7 @@ name = "aries-vcx-agent" version = "0.51.1" dependencies = [ "aries-vcx", + "async-trait", "derive_builder 0.11.2", "log", "serde", @@ -335,9 +336,9 @@ checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" [[package]] name = "async-trait" -version = "0.1.63" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff18d764974428cf3a9328e23fc5c986f5fbed46e6cd4cdf42544df5d297ec1" +checksum = "1cd7fce9ba8c3c042128ce72d8b2ddbf3a05747efb67ea0313c635e10bda47a2" dependencies = [ "proc-macro2", "quote", diff --git a/agents/rust/aries-vcx-agent/Cargo.toml b/agents/rust/aries-vcx-agent/Cargo.toml index a44ac02010..366c51e51f 100644 --- a/agents/rust/aries-vcx-agent/Cargo.toml +++ b/agents/rust/aries-vcx-agent/Cargo.toml @@ -8,6 +8,7 @@ edition.workspace = true [dependencies] serde = "1.0.145" aries-vcx = { path = "../../../aries_vcx" } +async-trait = "0.1.64" derive_builder = "0.11.2" serde_json = "1.0.85" log = "0.4.17" diff --git a/agents/rust/aries-vcx-agent/src/http_client.rs b/agents/rust/aries-vcx-agent/src/http_client.rs new file mode 100644 index 0000000000..c8800100f5 --- /dev/null +++ b/agents/rust/aries-vcx-agent/src/http_client.rs @@ -0,0 +1,14 @@ +use aries_vcx::{ + agency_client::httpclient::post_message, errors::error::VcxResult, protocols::typestate_con::Transport, +}; +use async_trait::async_trait; + +pub struct HttpClient; + +#[async_trait] +impl Transport for HttpClient { + async fn send_message(&self, msg: Vec, service_endpoint: &str) -> VcxResult<()> { + post_message(msg, service_endpoint).await?; + Ok(()) + } +} diff --git a/agents/rust/aries-vcx-agent/src/lib.rs b/agents/rust/aries-vcx-agent/src/lib.rs index e99fd7f1a1..01114988e8 100644 --- a/agents/rust/aries-vcx-agent/src/lib.rs +++ b/agents/rust/aries-vcx-agent/src/lib.rs @@ -9,6 +9,7 @@ extern crate uuid; mod agent; mod error; +mod http_client; mod services; mod storage; diff --git a/agents/rust/aries-vcx-agent/src/services/connection.rs b/agents/rust/aries-vcx-agent/src/services/connection.rs index 89cc50fce7..079baf1943 100644 --- a/agents/rust/aries-vcx-agent/src/services/connection.rs +++ b/agents/rust/aries-vcx-agent/src/services/connection.rs @@ -1,24 +1,24 @@ use std::sync::{Arc, Mutex}; use crate::error::*; +use crate::http_client::HttpClient; use crate::storage::object_cache::ObjectCache; use crate::storage::Storage; -use aries_vcx::common::ledger::transactions::into_did_doc; use aries_vcx::core::profile::profile::Profile; -use aries_vcx::handlers::connection::connection::{Connection, ConnectionState}; use aries_vcx::messages::a2a::A2AMessage; use aries_vcx::messages::concepts::ack::Ack; use aries_vcx::messages::protocols::connection::invite::Invitation; use aries_vcx::messages::protocols::connection::request::Request; use aries_vcx::messages::protocols::connection::response::SignedResponse; -use aries_vcx::protocols::connection::pairwise_info::PairwiseInfo; +use aries_vcx::protocols::typestate_con::pairwise_info::PairwiseInfo; +use aries_vcx::protocols::typestate_con::{Connection, State, VagueConnection}; pub type ServiceEndpoint = String; pub struct ServiceConnections { profile: Arc, service_endpoint: ServiceEndpoint, - connections: Arc>, + connections: Arc>, } impl ServiceConnections { @@ -31,93 +31,110 @@ impl ServiceConnections { } pub async fn create_invitation(&self, pw_info: Option) -> AgentResult { - let inviter = Connection::create_inviter(&self.profile, pw_info) - .await? - .create_invite(self.service_endpoint.clone(), vec![]) - .await?; - let invite = inviter - .get_invite_details() - .ok_or_else(|| AgentError::from_kind(AgentErrorKind::InviteDetails))? - .clone(); - self.connections.insert(&inviter.get_thread_id(), inviter)?; + let pw_info = pw_info.unwrap_or(PairwiseInfo::create(&self.profile.inject_wallet()).await?); + let inviter = Connection::new_inviter("".to_owned(), pw_info, vec![], self.service_endpoint.clone()); + let invite = inviter.get_invitation().clone(); + let thread_id = inviter.thread_id().to_owned(); + + self.connections.insert(&thread_id, inviter.into())?; + Ok(invite) } pub async fn receive_invitation(&self, invite: Invitation) -> AgentResult { - let did_doc = into_did_doc(&self.profile, &invite).await?; - let invitee = Connection::create_invitee(&self.profile, did_doc) - .await? - .process_invite(invite)?; - self.connections.insert(&invitee.get_thread_id(), invitee) + let pairwise_info = PairwiseInfo::create(&self.profile.inject_wallet()).await?; + let invitee = Connection::new_invitee("".to_owned(), pairwise_info) + .accept_invitation(&self.profile, &invite) + .await?; + + let thread_id = invitee.thread_id().to_owned(); + + self.connections.insert(&thread_id, invitee.into()) } pub async fn send_request(&self, thread_id: &str) -> AgentResult<()> { - let invitee = self - .connections - .get(thread_id)? - .send_request(&self.profile, self.service_endpoint.clone(), vec![], None) + let invitee: Connection<_, _> = self.connections.get(thread_id)?.try_into()?; + let invitee = invitee + .send_request( + &self.profile.inject_wallet(), + self.service_endpoint.clone(), + vec![], + &HttpClient, + ) .await?; - self.connections.insert(thread_id, invitee)?; + + self.connections.insert(thread_id, invitee.into())?; Ok(()) } pub async fn accept_request(&self, thread_id: &str, request: Request) -> AgentResult<()> { - let inviter = self - .connections - .get(thread_id)? - .process_request(&self.profile, request, self.service_endpoint.clone(), vec![], None) + let inviter: Connection<_, _> = self.connections.get(thread_id)?.try_into()?; + let inviter = inviter + .handle_request( + &self.profile.inject_wallet(), + request, + self.service_endpoint.clone(), + vec![], + &HttpClient, + ) .await?; - self.connections.insert(thread_id, inviter)?; + + self.connections.insert(thread_id, inviter.into())?; + Ok(()) } pub async fn send_response(&self, thread_id: &str) -> AgentResult<()> { - let inviter = self - .connections - .get(thread_id)? - .send_response(&self.profile, None) + let inviter: Connection<_, _> = self.connections.get(thread_id)?.try_into()?; + let inviter = inviter + .send_response(&self.profile.inject_wallet(), &HttpClient) .await?; - self.connections.insert(thread_id, inviter)?; + + self.connections.insert(thread_id, inviter.into())?; + Ok(()) } pub async fn accept_response(&self, thread_id: &str, response: SignedResponse) -> AgentResult<()> { - let invitee = self - .connections - .get(thread_id)? - .process_response(&self.profile, response, None) + let invitee: Connection<_, _> = self.connections.get(thread_id)?.try_into()?; + let invitee = invitee + .handle_response(&self.profile.inject_wallet(), response, &HttpClient) .await?; - self.connections.insert(thread_id, invitee)?; + + self.connections.insert(thread_id, invitee.into())?; + Ok(()) } pub async fn send_ack(&self, thread_id: &str) -> AgentResult<()> { - let invitee = self.connections.get(thread_id)?.send_ack(&self.profile, None).await?; - self.connections.insert(thread_id, invitee)?; + let invitee: Connection<_, _> = self.connections.get(thread_id)?.try_into()?; + let invitee = invitee.send_ack(&self.profile.inject_wallet(), &HttpClient).await?; + + self.connections.insert(thread_id, invitee.into())?; + Ok(()) } pub async fn process_ack(&self, thread_id: &str, ack: Ack) -> AgentResult<()> { - let inviter = self - .connections - .get(thread_id)? - .process_ack(A2AMessage::Ack(ack)) - .await?; - self.connections.insert(thread_id, inviter)?; + let inviter: Connection<_, _> = self.connections.get(thread_id)?.try_into()?; + let inviter = inviter.acknowledge_connection(&A2AMessage::Ack(ack))?; + + self.connections.insert(thread_id, inviter.into())?; + Ok(()) } - pub fn get_state(&self, thread_id: &str) -> AgentResult { - Ok(self.connections.get(thread_id)?.get_state()) + pub fn get_state(&self, thread_id: &str) -> AgentResult { + Ok(self.connections.get(thread_id)?.state()) } - pub(in crate::services) fn get_by_id(&self, thread_id: &str) -> AgentResult { + pub(in crate::services) fn get_by_id(&self, thread_id: &str) -> AgentResult { self.connections.get(thread_id) } pub fn get_by_their_vk(&self, their_vk: &str) -> AgentResult> { let their_vk = their_vk.to_string(); - let f = |(id, m): (&String, &Mutex)| -> Option { + let f = |(id, m): (&String, &Mutex)| -> Option { let connection = m.lock().unwrap(); match connection.remote_vk() { Ok(remote_vk) if remote_vk == their_vk => Some(id.to_string()), diff --git a/agents/rust/aries-vcx-agent/src/services/holder.rs b/agents/rust/aries-vcx-agent/src/services/holder.rs index bba04ef78c..9db3e57b99 100644 --- a/agents/rust/aries-vcx-agent/src/services/holder.rs +++ b/agents/rust/aries-vcx-agent/src/services/holder.rs @@ -1,15 +1,18 @@ use std::sync::Arc; use crate::error::*; +use crate::http_client::HttpClient; use crate::services::connection::ServiceConnections; use crate::storage::object_cache::ObjectCache; use crate::storage::Storage; use aries_vcx::core::profile::profile::Profile; use aries_vcx::handlers::issuance::holder::Holder; +use aries_vcx::messages::a2a::A2AMessage; use aries_vcx::messages::protocols::issuance::credential::Credential; use aries_vcx::messages::protocols::issuance::credential_offer::CredentialOffer; use aries_vcx::messages::protocols::issuance::credential_proposal::CredentialProposalData; use aries_vcx::protocols::issuance::holder::state_machine::HolderState; +use aries_vcx::protocols::SendClosure; #[derive(Clone)] struct HolderWrapper { @@ -57,13 +60,15 @@ impl ServiceCredentialsHolder { proposal_data: CredentialProposalData, ) -> AgentResult { let connection = self.service_connections.get_by_id(connection_id)?; + let wallet = self.profile.inject_wallet(); + + let send_closure: SendClosure = Box::new(|msg: A2AMessage| { + Box::pin(async move { connection.send_message(&wallet, &msg, &HttpClient).await }) + }); + let mut holder = Holder::create("")?; - holder - .send_proposal( - proposal_data, - connection.send_message_closure(&self.profile, None).await?, - ) - .await?; + holder.send_proposal(proposal_data, send_closure).await?; + self.creds_holder .insert(&holder.get_thread_id()?, HolderWrapper::new(holder, connection_id)) } @@ -87,13 +92,14 @@ impl ServiceCredentialsHolder { (None, None) => return Err(AgentError::from_kind(AgentErrorKind::InvalidArguments)), }; let connection = self.service_connections.get_by_id(&connection_id)?; - holder - .send_request( - &self.profile, - connection.pairwise_info().pw_did.to_string(), - connection.send_message_closure(&self.profile, None).await?, - ) - .await?; + let wallet = self.profile.inject_wallet(); + let pw_did = connection.pairwise_info().pw_did.to_string(); + + let send_closure: SendClosure = Box::new(|msg: A2AMessage| { + Box::pin(async move { connection.send_message(&wallet, &msg, &HttpClient).await }) + }); + + holder.send_request(&self.profile, pw_did, send_closure).await?; self.creds_holder .insert(&holder.get_thread_id()?, HolderWrapper::new(holder, &connection_id)) } @@ -102,12 +108,14 @@ impl ServiceCredentialsHolder { let mut holder = self.get_holder(thread_id)?; let connection_id = self.get_connection_id(thread_id)?; let connection = self.service_connections.get_by_id(&connection_id)?; + let wallet = self.profile.inject_wallet(); + + let send_closure: SendClosure = Box::new(|msg: A2AMessage| { + Box::pin(async move { connection.send_message(&wallet, &msg, &HttpClient).await }) + }); + holder - .process_credential( - &self.profile, - credential, - connection.send_message_closure(&self.profile, None).await?, - ) + .process_credential(&self.profile, credential, send_closure) .await?; self.creds_holder .insert(&holder.get_thread_id()?, HolderWrapper::new(holder, &connection_id)) diff --git a/agents/rust/aries-vcx-agent/src/services/issuer.rs b/agents/rust/aries-vcx-agent/src/services/issuer.rs index 1ac75d7cf5..8ce69ed024 100644 --- a/agents/rust/aries-vcx-agent/src/services/issuer.rs +++ b/agents/rust/aries-vcx-agent/src/services/issuer.rs @@ -1,16 +1,19 @@ use std::sync::Arc; use crate::error::*; +use crate::http_client::HttpClient; use crate::services::connection::ServiceConnections; use crate::storage::object_cache::ObjectCache; use crate::storage::Storage; use aries_vcx::core::profile::profile::Profile; use aries_vcx::handlers::issuance::issuer::Issuer; +use aries_vcx::messages::a2a::A2AMessage; use aries_vcx::messages::protocols::issuance::credential_ack::CredentialAck; use aries_vcx::messages::protocols::issuance::credential_offer::OfferInfo; use aries_vcx::messages::protocols::issuance::credential_proposal::CredentialProposal; use aries_vcx::messages::protocols::issuance::credential_request::CredentialRequest; use aries_vcx::protocols::issuance::issuer::state_machine::IssuerState; +use aries_vcx::protocols::SendClosure; #[derive(Clone)] struct IssuerWrapper { @@ -74,9 +77,14 @@ impl ServiceCredentialsIssuer { issuer .build_credential_offer_msg(&self.profile, offer_info, None) .await?; - issuer - .send_credential_offer(connection.send_message_closure(&self.profile, None).await?) - .await?; + + let wallet = self.profile.inject_wallet(); + + let send_closure: SendClosure = Box::new(|msg: A2AMessage| { + Box::pin(async move { connection.send_message(&wallet, &msg, &HttpClient).await }) + }); + + issuer.send_credential_offer(send_closure).await?; self.creds_issuer .insert(&issuer.get_thread_id()?, IssuerWrapper::new(issuer, &connection_id)) } @@ -109,12 +117,14 @@ impl ServiceCredentialsIssuer { connection_id, } = self.creds_issuer.get(thread_id)?; let connection = self.service_connections.get_by_id(&connection_id)?; - issuer - .send_credential( - &self.profile, - connection.send_message_closure(&self.profile, None).await?, - ) - .await?; + + let wallet = self.profile.inject_wallet(); + + let send_closure: SendClosure = Box::new(|msg: A2AMessage| { + Box::pin(async move { connection.send_message(&wallet, &msg, &HttpClient).await }) + }); + + issuer.send_credential(&self.profile, send_closure).await?; self.creds_issuer .insert(&issuer.get_thread_id()?, IssuerWrapper::new(issuer, &connection_id))?; Ok(()) diff --git a/agents/rust/aries-vcx-agent/src/services/prover.rs b/agents/rust/aries-vcx-agent/src/services/prover.rs index 25f2e6ca7f..d5435ce411 100644 --- a/agents/rust/aries-vcx-agent/src/services/prover.rs +++ b/agents/rust/aries-vcx-agent/src/services/prover.rs @@ -2,14 +2,17 @@ use std::collections::HashMap; use std::sync::Arc; use crate::error::*; +use crate::http_client::HttpClient; use crate::storage::object_cache::ObjectCache; use crate::storage::Storage; use aries_vcx::core::profile::profile::Profile; use aries_vcx::handlers::proof_presentation::prover::Prover; +use aries_vcx::messages::a2a::A2AMessage; use aries_vcx::messages::protocols::proof_presentation::presentation_ack::PresentationAck; use aries_vcx::messages::protocols::proof_presentation::presentation_proposal::PresentationProposalData; use aries_vcx::messages::protocols::proof_presentation::presentation_request::PresentationRequest; use aries_vcx::protocols::proof_presentation::prover::state_machine::ProverState; +use aries_vcx::protocols::SendClosure; use serde_json::Value; use super::connection::ServiceConnections; @@ -87,9 +90,14 @@ impl ServiceProver { ) -> AgentResult { let connection = self.service_connections.get_by_id(connection_id)?; let mut prover = Prover::create("")?; - prover - .send_proposal(proposal, connection.send_message_closure(&self.profile, None).await?) - .await?; + + let wallet = self.profile.inject_wallet(); + + let send_closure: SendClosure = Box::new(|msg: A2AMessage| { + Box::pin(async move { connection.send_message(&wallet, &msg, &HttpClient).await }) + }); + + prover.send_proposal(proposal, send_closure).await?; self.provers .insert(&prover.get_thread_id()?, ProverWrapper::new(prover, connection_id)) } @@ -111,9 +119,14 @@ impl ServiceProver { prover .generate_presentation(&self.profile, credentials, "{}".to_string()) .await?; - prover - .send_presentation(connection.send_message_closure(&self.profile, None).await?) - .await?; + + let wallet = self.profile.inject_wallet(); + + let send_closure: SendClosure = Box::new(|msg: A2AMessage| { + Box::pin(async move { connection.send_message(&wallet, &msg, &HttpClient).await }) + }); + + prover.send_presentation(send_closure).await?; self.provers .insert(&prover.get_thread_id()?, ProverWrapper::new(prover, &connection_id))?; Ok(()) diff --git a/agents/rust/aries-vcx-agent/src/services/verifier.rs b/agents/rust/aries-vcx-agent/src/services/verifier.rs index 1a4cf93d99..f74559ef8c 100644 --- a/agents/rust/aries-vcx-agent/src/services/verifier.rs +++ b/agents/rust/aries-vcx-agent/src/services/verifier.rs @@ -1,15 +1,18 @@ use std::sync::Arc; use crate::error::*; +use crate::http_client::HttpClient; use crate::storage::object_cache::ObjectCache; use crate::storage::Storage; use aries_vcx::common::proofs::proof_request::PresentationRequestData; use aries_vcx::core::profile::profile::Profile; use aries_vcx::handlers::proof_presentation::verifier::Verifier; +use aries_vcx::messages::a2a::A2AMessage; use aries_vcx::messages::protocols::proof_presentation::presentation::Presentation; use aries_vcx::messages::protocols::proof_presentation::presentation_proposal::PresentationProposal; use aries_vcx::messages::status::Status; use aries_vcx::protocols::proof_presentation::verifier::state_machine::VerifierState; +use aries_vcx::protocols::SendClosure; use super::connection::ServiceConnections; @@ -55,9 +58,14 @@ impl ServiceVerifier { } else { Verifier::create_from_request("".to_string(), &request)? }; - verifier - .send_presentation_request(connection.send_message_closure(&self.profile, None).await?) - .await?; + + let wallet = self.profile.inject_wallet(); + + let send_closure: SendClosure = Box::new(|msg: A2AMessage| { + Box::pin(async move { connection.send_message(&wallet, &msg, &HttpClient).await }) + }); + + verifier.send_presentation_request(send_closure).await?; self.verifiers.insert( &verifier.get_thread_id()?, VerifierWrapper::new(verifier, connection_id), @@ -75,12 +83,14 @@ impl ServiceVerifier { connection_id, } = self.verifiers.get(thread_id)?; let connection = self.service_connections.get_by_id(&connection_id)?; + let wallet = self.profile.inject_wallet(); + + let send_closure: SendClosure = Box::new(|msg: A2AMessage| { + Box::pin(async move { connection.send_message(&wallet, &msg, &HttpClient).await }) + }); + verifier - .verify_presentation( - &self.profile, - presentation, - connection.send_message_closure(&self.profile, None).await?, - ) + .verify_presentation(&self.profile, presentation, send_closure) .await?; self.verifiers .insert(thread_id, VerifierWrapper::new(verifier, &connection_id))?; diff --git a/aries_vcx/src/protocols/typestate_con/invitee/mod.rs b/aries_vcx/src/protocols/typestate_con/invitee/mod.rs index dcada8659f..2cfbe1ed80 100644 --- a/aries_vcx/src/protocols/typestate_con/invitee/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/invitee/mod.rs @@ -32,7 +32,7 @@ use crate::{ pub type InviteeConnection = Connection; impl InviteeConnection { - pub fn new(source_id: String, pairwise_info: PairwiseInfo) -> Self { + pub fn new_invitee(source_id: String, pairwise_info: PairwiseInfo) -> Self { Self { source_id, state: InitialState, diff --git a/aries_vcx/src/protocols/typestate_con/inviter/mod.rs b/aries_vcx/src/protocols/typestate_con/inviter/mod.rs index 0db13dd147..2f2c8d090b 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/mod.rs @@ -26,7 +26,7 @@ use messages::protocols::connection::{ pub type InviterConnection = Connection; impl InviterConnection { - pub fn new( + pub fn new_inviter( source_id: String, pairwise_info: PairwiseInfo, routing_keys: Vec, @@ -63,7 +63,13 @@ impl InviterConnection { } impl InviterConnection { - pub fn new_invited(source_id: String, pairwise_info: PairwiseInfo) -> Self { + /// Creates an [`InviterConnection`], essentially bypassing the [`InitialState`] + /// where an [`Invitation`] is created. + /// + /// This is useful for cases where an [`Invitation`] is received by the invitee without + /// any interaction from the inviter, thus the next logical step is to wait for the invitee + /// to send a connection request. + pub fn new_awaiting_request(source_id: String, pairwise_info: PairwiseInfo) -> Self { Self { source_id, state: InvitedState::new(None), // what should the thread ID be in this case??? diff --git a/aries_vcx/src/protocols/typestate_con/mod.rs b/aries_vcx/src/protocols/typestate_con/mod.rs index 039ee28e83..588f54758d 100644 --- a/aries_vcx/src/protocols/typestate_con/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/mod.rs @@ -29,7 +29,7 @@ use self::{ traits::{HandleProblem, TheirDidDoc, ThreadId}, }; -pub use self::serde::de::VagueConnection; +pub use self::serde::de::{State, VagueConnection}; pub use self::traits::Transport; #[derive(Clone, Deserialize)] diff --git a/libvcx/src/api_vcx/api_handle/typestate_con.rs b/libvcx/src/api_vcx/api_handle/typestate_con.rs index 511628bc61..67d0c5d7d1 100644 --- a/libvcx/src/api_vcx/api_handle/typestate_con.rs +++ b/libvcx/src/api_vcx/api_handle/typestate_con.rs @@ -111,7 +111,7 @@ pub async fn create_invitee(invitation: &str) -> LibvcxResult { let invitation = deserialize(invitation)?; let pairwise_info = PairwiseInfo::create(&profile.inject_wallet()).await?; - let con = InviteeConnection::new("".to_owned(), pairwise_info) + let con = InviteeConnection::new_invitee("".to_owned(), pairwise_info) .accept_invitation(&profile, &invitation) .await?; @@ -125,7 +125,7 @@ pub async fn create_invite(handle: u32, service_endpoint: String, routing_keys: let profile = get_main_profile()?; let pairwise_info = PairwiseInfo::create(&profile.inject_wallet()).await?; - let con = InviterConnection::new("".to_owned(), pairwise_info, routing_keys, service_endpoint); + let con = InviterConnection::new_inviter("".to_owned(), pairwise_info, routing_keys, service_endpoint); insert_connection(handle, con) } From f4e677ed9381403b71b2d5ad57ba6530f94e5124 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Wed, 1 Feb 2023 11:11:11 +0200 Subject: [PATCH 27/66] Fixed method rename in libvcx Signed-off-by: Bogdan Mircea --- libvcx/src/api_vcx/api_handle/typestate_con.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libvcx/src/api_vcx/api_handle/typestate_con.rs b/libvcx/src/api_vcx/api_handle/typestate_con.rs index 67d0c5d7d1..66f90390cf 100644 --- a/libvcx/src/api_vcx/api_handle/typestate_con.rs +++ b/libvcx/src/api_vcx/api_handle/typestate_con.rs @@ -99,7 +99,7 @@ pub async fn create_inviter(pw_info: Option) -> LibvcxResult let profile = get_main_profile()?; let pw_info = pw_info.unwrap_or(PairwiseInfo::create(&profile.inject_wallet()).await?); - let con = InviterConnection::new_invited("".to_owned(), pw_info); + let con = InviterConnection::new_awaiting_request("".to_owned(), pw_info); add_connection(con.into()) } From 623437064d3d99c1cd61b7b795d261637979fbd6 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Wed, 1 Feb 2023 11:49:10 +0200 Subject: [PATCH 28/66] Removed send_invitation method Signed-off-by: Bogdan Mircea --- aries_vcx/src/protocols/typestate_con/inviter/mod.rs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/aries_vcx/src/protocols/typestate_con/inviter/mod.rs b/aries_vcx/src/protocols/typestate_con/inviter/mod.rs index 2f2c8d090b..31d7e08668 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/mod.rs @@ -2,7 +2,6 @@ pub mod states; use std::sync::Arc; -use crate::errors::error::{AriesVcxError, AriesVcxErrorKind}; use crate::handlers::util::verify_thread_id; use crate::utils::uuid; use crate::{ @@ -52,14 +51,6 @@ impl InviterConnection { pub fn get_invitation(&self) -> &Invitation { &self.state.invitation } - - pub fn send_invitation(self, _transport: &T) -> VcxResult> { - // Implement some way to actually send the invitation - Err(AriesVcxError::from_msg( - AriesVcxErrorKind::ActionNotSupported, - "sending invites isn't yet supported!", - )) - } } impl InviterConnection { From c0608470f54a196f12f10cc08a2ceec266087152 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Wed, 1 Feb 2023 13:57:34 +0200 Subject: [PATCH 29/66] Typestate connection cosmetic changes, comments, and modules re-organization Signed-off-by: Bogdan Mircea --- .../src/services/connection.rs | 8 +- .../typestate_con/generic/conversions.rs | 145 +++++++ .../protocols/typestate_con/generic/mod.rs | 285 +++++++++++++ .../typestate_con/generic/thin_state.rs | 53 +++ .../protocols/typestate_con/invitee/mod.rs | 18 +- .../typestate_con/invitee/states/initial.rs | 2 +- .../typestate_con/invitee/states/invited.rs | 8 +- .../typestate_con/invitee/states/requested.rs | 10 +- .../protocols/typestate_con/inviter/mod.rs | 20 +- .../typestate_con/inviter/states/initial.rs | 6 +- .../typestate_con/inviter/states/invited.rs | 6 +- .../typestate_con/inviter/states/requested.rs | 8 +- aries_vcx/src/protocols/typestate_con/mod.rs | 53 +-- .../src/protocols/typestate_con/serde/de.rs | 391 ------------------ .../src/protocols/typestate_con/serde/mod.rs | 2 - .../{serde/ser.rs => serializable.rs} | 66 +-- .../src/api_vcx/api_handle/typestate_con.rs | 19 +- 17 files changed, 569 insertions(+), 531 deletions(-) create mode 100644 aries_vcx/src/protocols/typestate_con/generic/conversions.rs create mode 100644 aries_vcx/src/protocols/typestate_con/generic/mod.rs create mode 100644 aries_vcx/src/protocols/typestate_con/generic/thin_state.rs delete mode 100644 aries_vcx/src/protocols/typestate_con/serde/de.rs delete mode 100644 aries_vcx/src/protocols/typestate_con/serde/mod.rs rename aries_vcx/src/protocols/typestate_con/{serde/ser.rs => serializable.rs} (64%) diff --git a/agents/rust/aries-vcx-agent/src/services/connection.rs b/agents/rust/aries-vcx-agent/src/services/connection.rs index 079baf1943..4715b84182 100644 --- a/agents/rust/aries-vcx-agent/src/services/connection.rs +++ b/agents/rust/aries-vcx-agent/src/services/connection.rs @@ -11,14 +11,14 @@ use aries_vcx::messages::protocols::connection::invite::Invitation; use aries_vcx::messages::protocols::connection::request::Request; use aries_vcx::messages::protocols::connection::response::SignedResponse; use aries_vcx::protocols::typestate_con::pairwise_info::PairwiseInfo; -use aries_vcx::protocols::typestate_con::{Connection, State, VagueConnection}; +use aries_vcx::protocols::typestate_con::{Connection, GenericConnection, State}; pub type ServiceEndpoint = String; pub struct ServiceConnections { profile: Arc, service_endpoint: ServiceEndpoint, - connections: Arc>, + connections: Arc>, } impl ServiceConnections { @@ -128,13 +128,13 @@ impl ServiceConnections { Ok(self.connections.get(thread_id)?.state()) } - pub(in crate::services) fn get_by_id(&self, thread_id: &str) -> AgentResult { + pub(in crate::services) fn get_by_id(&self, thread_id: &str) -> AgentResult { self.connections.get(thread_id) } pub fn get_by_their_vk(&self, their_vk: &str) -> AgentResult> { let their_vk = their_vk.to_string(); - let f = |(id, m): (&String, &Mutex)| -> Option { + let f = |(id, m): (&String, &Mutex)| -> Option { let connection = m.lock().unwrap(); match connection.remote_vk() { Ok(remote_vk) if remote_vk == their_vk => Some(id.to_string()), diff --git a/aries_vcx/src/protocols/typestate_con/generic/conversions.rs b/aries_vcx/src/protocols/typestate_con/generic/conversions.rs new file mode 100644 index 0000000000..b09434ef3d --- /dev/null +++ b/aries_vcx/src/protocols/typestate_con/generic/conversions.rs @@ -0,0 +1,145 @@ +use super::{GenericConnection, GenericState, InviteeState, InviterState}; +use crate::{ + errors::error::{AriesVcxError, AriesVcxErrorKind}, + protocols::typestate_con::{ + common::states::{complete::CompleteState, responded::RespondedState}, + initiation_type::{Invitee, Inviter}, + invitee::states::{ + initial::Initial as InviteeInitial, invited::Invited as InviteeInvited, + requested::Requested as InviteeRequested, + }, + inviter::states::{ + initial::Initial as InviterInitial, invited::Invited as InviterInvited, + requested::Requested as InviterRequested, + }, + Connection, + }, +}; + +/// Macro used for boilerplace implementation of the +/// [`From`] trait from a concrete connection state to the equivalent vague state. +macro_rules! from_concrete_to_vague { + ($from:ident, $var:ident, $to:ident) => { + impl From<$from> for $to { + fn from(value: $from) -> Self { + Self::$var(value) + } + } + }; + + ($init_type:ident, $state:ident, $var:ident, $to:ident) => { + impl From<($init_type, S)> for $to + where + $state: From, + { + fn from(value: ($init_type, S)) -> Self { + let (_, state) = value; + let serde_state = From::from(state); + Self::$var(serde_state) + } + } + }; +} + +/// Macro used for boilerplace implementation of the +/// [`TryFrom`] trait from a vague connection state to a concrete state. +macro_rules! try_from_vague_to_concrete { + ($from:ident, $var:ident, $to:ident) => { + impl TryFrom<$from> for $to { + type Error = AriesVcxError; + + fn try_from(value: $from) -> Result { + match value { + $from::$var(s) => Ok(s), + _ => Err(AriesVcxError::from_msg( + AriesVcxErrorKind::InvalidState, + format!("unexpected connection state: {:?}!", value), + )), + } + } + } + }; + + ($state:ident, $good_var:ident, $bad_var:ident, $init_type:ident) => { + impl TryFrom for ($init_type, S) + where + S: TryFrom<$state, Error = AriesVcxError>, + { + type Error = AriesVcxError; + + fn try_from(value: GenericState) -> Result { + match value { + GenericState::$good_var(s) => S::try_from(s).map(|s| ($init_type, s)), + GenericState::$bad_var(_) => Err(AriesVcxError::from_msg( + AriesVcxErrorKind::InvalidState, + concat!( + "Expected ", + stringify!(VagueState::$good_var), + "connection state, found ", + stringify!(VagueState::$bad_var), + ), + )), + } + } + } + }; +} + +// ---------------------------- From Concrete State to Vague State implementations ---------------------------- +impl From> for GenericConnection +where + GenericState: From<(I, S)>, +{ + fn from(value: Connection) -> Self { + let state = From::from((value.initiation_type, value.state)); + Self { + source_id: value.source_id, + pairwise_info: value.pairwise_info, + state, + } + } +} + +from_concrete_to_vague!(Inviter, InviterState, Inviter, GenericState); +from_concrete_to_vague!(Invitee, InviteeState, Invitee, GenericState); + +from_concrete_to_vague!(InviterInitial, Initial, InviterState); +from_concrete_to_vague!(InviterInvited, Invited, InviterState); +from_concrete_to_vague!(InviterRequested, Requested, InviterState); +from_concrete_to_vague!(RespondedState, Responded, InviterState); +from_concrete_to_vague!(CompleteState, Complete, InviterState); + +from_concrete_to_vague!(InviteeInitial, Initial, InviteeState); +from_concrete_to_vague!(InviteeInvited, Invited, InviteeState); +from_concrete_to_vague!(InviteeRequested, Requested, InviteeState); +from_concrete_to_vague!(RespondedState, Responded, InviteeState); +from_concrete_to_vague!(CompleteState, Complete, InviteeState); + +// ---------------------------- Try From Vague State to Concrete State implementations ---------------------------- +impl TryFrom for Connection +where + (I, S): TryFrom, +{ + type Error = AriesVcxError; + + fn try_from(value: GenericConnection) -> Result { + let (initiation_type, state) = TryFrom::try_from(value.state)?; + let con = Connection::from_parts(value.source_id, value.pairwise_info, initiation_type, state); + Ok(con) + } +} + +try_from_vague_to_concrete!(InviterState, Inviter, Invitee, Inviter); +try_from_vague_to_concrete!(InviteeState, Invitee, Inviter, Invitee); + +try_from_vague_to_concrete!(InviterState, Initial, InviterInitial); +try_from_vague_to_concrete!(InviterState, Invited, InviterInvited); +try_from_vague_to_concrete!(InviterState, Requested, InviterRequested); +try_from_vague_to_concrete!(InviterState, Responded, RespondedState); +try_from_vague_to_concrete!(InviterState, Complete, CompleteState); + +try_from_vague_to_concrete!(InviteeState, Initial, InviteeInitial); +try_from_vague_to_concrete!(InviteeState, Invited, InviteeInvited); +try_from_vague_to_concrete!(InviteeState, Requested, InviteeRequested); +try_from_vague_to_concrete!(InviteeState, Responded, RespondedState); +try_from_vague_to_concrete!(InviteeState, Complete, CompleteState); diff --git a/aries_vcx/src/protocols/typestate_con/generic/mod.rs b/aries_vcx/src/protocols/typestate_con/generic/mod.rs new file mode 100644 index 0000000000..9dd3794442 --- /dev/null +++ b/aries_vcx/src/protocols/typestate_con/generic/mod.rs @@ -0,0 +1,285 @@ +mod conversions; +mod thin_state; + +use std::sync::Arc; + +use messages::{a2a::A2AMessage, diddoc::aries::diddoc::AriesDidDoc, protocols::connection::invite::Invitation}; + +pub use self::thin_state::{State, ThinState}; + +use crate::{ + errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult}, + plugins::wallet::base_wallet::BaseWallet, + protocols::typestate_con::{ + common::states::{complete::CompleteState, responded::RespondedState}, + invitee::states::{ + initial::Initial as InviteeInitial, invited::Invited as InviteeInvited, + requested::Requested as InviteeRequested, + }, + inviter::states::{ + initial::Initial as InviterInitial, invited::Invited as InviterInvited, + requested::Requested as InviterRequested, + }, + pairwise_info::PairwiseInfo, + traits::{TheirDidDoc, ThreadId}, + Transport, + }, +}; + +use super::basic_send_message; + +/// A type that can encapsulate a [`Connection`] of any state. +/// While mainly used for deserialization, it exposes some methods for retrieving +/// connection information. +/// +/// However, using methods directly from [`Connection`], if possible, comes with certain +/// benefits such as being able to obtain an [`AriesDidDoc`] directly (if the state contains it) +/// and not an [`Option`] (which is what [`GenericConnection`] provides). +/// +/// [`GenericConnection`] implements [`From`] for all [`Connection`] states and +/// [`Connection`] implements [`TryFrom`] from [`GenericConnection`], with the conversion failing +/// if the [`GenericConnection`] is in a different state than the requested one. +/// This is also the mechanism used for direct deserialization of a [`Connection`]. +/// +/// Because a [`TryFrom`] conversion is fallible and consumes the [`GenericConnection`], a thin [`State`] +/// can be retrieved through [`GenericConnection::state`] method at runtime. In that case, a more dynamic conversion +/// could be done this way: +/// +/// ``` ignore +/// // Assume the `con` variable stores a `GenericConnection`: +/// +/// let initial_connections = Vec::new(); +/// let completed_connections = Vec::new(); +/// +/// // Unwrapping after the match is sound +/// // because we can guarantee the conversion will work +/// match con.state() { +/// State::Invitee(Stage::Initial) => initial_connections.push(con.try_into().unwrap()), +/// State::Invitee(Stage::Complete) => completed_connections.push(con.try_into().unwrap()) +/// } +/// ``` +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct GenericConnection { + pub(super) source_id: String, + pub(super) pairwise_info: PairwiseInfo, + pub(super) state: GenericState, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum GenericState { + Inviter(InviterState), + Invitee(InviteeState), +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum InviterState { + Initial(InviterInitial), + Invited(InviterInvited), + Requested(InviterRequested), + Responded(RespondedState), + Complete(CompleteState), +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum InviteeState { + Initial(InviteeInitial), + Invited(InviteeInvited), + Requested(InviteeRequested), + Responded(RespondedState), + Complete(CompleteState), +} + +impl GenericConnection { + /// Returns the underlying [`super::Connection`]'s state as a thin [`State`]. + /// Used for pattern matching when there's no hint as to what connection type + /// is expected from or stored into the [`GenericConnection`]. + pub fn state(&self) -> State { + (&self.state).into() + } + + pub fn thread_id(&self) -> Option<&str> { + match &self.state { + GenericState::Invitee(InviteeState::Initial(_)) => None, + GenericState::Invitee(InviteeState::Invited(s)) => Some(s.thread_id()), + GenericState::Invitee(InviteeState::Requested(s)) => Some(s.thread_id()), + GenericState::Invitee(InviteeState::Responded(s)) => Some(s.thread_id()), + GenericState::Invitee(InviteeState::Complete(s)) => Some(s.thread_id()), + GenericState::Inviter(InviterState::Initial(s)) => Some(s.thread_id()), + GenericState::Inviter(InviterState::Invited(s)) => s.opt_thread_id(), + GenericState::Inviter(InviterState::Requested(s)) => Some(s.thread_id()), + GenericState::Inviter(InviterState::Responded(s)) => Some(s.thread_id()), + GenericState::Inviter(InviterState::Complete(s)) => Some(s.thread_id()), + } + } + + pub fn pairwise_info(&self) -> &PairwiseInfo { + &self.pairwise_info + } + + pub fn their_did_doc(&self) -> Option<&AriesDidDoc> { + match &self.state { + GenericState::Invitee(InviteeState::Initial(_)) => None, + GenericState::Invitee(InviteeState::Invited(s)) => Some(s.their_did_doc()), + GenericState::Invitee(InviteeState::Requested(s)) => Some(s.their_did_doc()), + GenericState::Invitee(InviteeState::Responded(s)) => Some(s.their_did_doc()), + GenericState::Invitee(InviteeState::Complete(s)) => Some(s.their_did_doc()), + GenericState::Inviter(InviterState::Initial(_)) => None, + GenericState::Inviter(InviterState::Invited(_)) => None, + GenericState::Inviter(InviterState::Requested(s)) => Some(s.their_did_doc()), + GenericState::Inviter(InviterState::Responded(s)) => Some(s.their_did_doc()), + GenericState::Inviter(InviterState::Complete(s)) => Some(s.their_did_doc()), + } + } + + pub fn remote_did(&self) -> Option<&str> { + self.their_did_doc().map(|d| d.id.as_str()) + } + + pub fn remote_vk(&self) -> VcxResult { + let did_doc = self.their_did_doc().ok_or(AriesVcxError::from_msg( + AriesVcxErrorKind::NotReady, + "No DidDoc present", + ))?; + + did_doc + .recipient_keys()? + .first() + .map(ToOwned::to_owned) + .ok_or(AriesVcxError::from_msg( + AriesVcxErrorKind::NotReady, + "Can't resolve recipient key from the counterparty diddoc.", + )) + } + + pub fn invitation(&self) -> Option<&Invitation> { + match &self.state { + GenericState::Inviter(InviterState::Initial(s)) => Some(&s.invitation), + _ => None, + } + } + + pub async fn send_message( + &self, + wallet: &Arc, + message: &A2AMessage, + transport: &T, + ) -> VcxResult<()> + where + T: Transport, + { + let sender_verkey = &self.pairwise_info().pw_vk; + let did_doc = self.their_did_doc().ok_or(AriesVcxError::from_msg( + AriesVcxErrorKind::NotReady, + "No DidDoc present", + ))?; + + basic_send_message(wallet, message, sender_verkey, did_doc, transport).await + } +} + +/// Compile-time assurance that the deserialization type +/// of the [`Connection`], if modified, will be modified along the serialization type. +#[cfg(test)] +mod tests { + use crate::protocols::typestate_con::serializable::*; + + use super::*; + + impl<'a> From> for InviteeState { + fn from(value: RefInviteeState<'a>) -> Self { + match value { + RefInviteeState::Initial(s) => Self::Initial(s.to_owned()), + RefInviteeState::Invited(s) => Self::Invited(s.to_owned()), + RefInviteeState::Requested(s) => Self::Requested(s.to_owned()), + RefInviteeState::Responded(s) => Self::Responded(s.to_owned()), + RefInviteeState::Complete(s) => Self::Complete(s.to_owned()), + } + } + } + + impl<'a> From> for InviterState { + fn from(value: RefInviterState<'a>) -> Self { + match value { + RefInviterState::Initial(s) => Self::Initial(s.to_owned()), + RefInviterState::Invited(s) => Self::Invited(s.to_owned()), + RefInviterState::Requested(s) => Self::Requested(s.to_owned()), + RefInviterState::Responded(s) => Self::Responded(s.to_owned()), + RefInviterState::Complete(s) => Self::Complete(s.to_owned()), + } + } + } + + impl<'a> From> for GenericState { + fn from(value: RefState<'a>) -> Self { + match value { + RefState::Invitee(s) => Self::Invitee(s.into()), + RefState::Inviter(s) => Self::Inviter(s.into()), + } + } + } + + impl<'a> From> for GenericConnection { + fn from(value: SerializableConnection<'a>) -> Self { + let SerializableConnection { + source_id, + pairwise_info, + state, + } = value; + + Self { + source_id: source_id.to_owned(), + pairwise_info: pairwise_info.to_owned(), + state: state.into(), + } + } + } + + impl<'a> From<&'a InviteeState> for RefInviteeState<'a> { + fn from(value: &'a InviteeState) -> Self { + match value { + InviteeState::Initial(s) => Self::Initial(s), + InviteeState::Invited(s) => Self::Invited(s), + InviteeState::Requested(s) => Self::Requested(s), + InviteeState::Responded(s) => Self::Responded(s), + InviteeState::Complete(s) => Self::Complete(s), + } + } + } + + impl<'a> From<&'a InviterState> for RefInviterState<'a> { + fn from(value: &'a InviterState) -> Self { + match value { + InviterState::Initial(s) => Self::Initial(s), + InviterState::Invited(s) => Self::Invited(s), + InviterState::Requested(s) => Self::Requested(s), + InviterState::Responded(s) => Self::Responded(s), + InviterState::Complete(s) => Self::Complete(s), + } + } + } + + impl<'a> From<&'a GenericState> for RefState<'a> { + fn from(value: &'a GenericState) -> Self { + match value { + GenericState::Invitee(s) => Self::Invitee(s.into()), + GenericState::Inviter(s) => Self::Inviter(s.into()), + } + } + } + + impl<'a> From<&'a GenericConnection> for SerializableConnection<'a> { + fn from(value: &'a GenericConnection) -> Self { + let GenericConnection { + source_id, + pairwise_info, + state, + } = value; + + Self { + source_id, + pairwise_info, + state: state.into(), + } + } + } +} diff --git a/aries_vcx/src/protocols/typestate_con/generic/thin_state.rs b/aries_vcx/src/protocols/typestate_con/generic/thin_state.rs new file mode 100644 index 0000000000..7410c0b746 --- /dev/null +++ b/aries_vcx/src/protocols/typestate_con/generic/thin_state.rs @@ -0,0 +1,53 @@ +use super::{GenericState, InviteeState, InviterState}; + +/// Small sized enum used for determining +/// a connection's state in terms of initiation type. +#[derive(Clone, Copy, Debug)] +pub enum State { + Invitee(ThinState), + Inviter(ThinState), +} + +/// Small sized enum used for determining +/// a connection's state in terms of connection stage. +#[derive(Clone, Copy, Debug)] +pub enum ThinState { + Initial, + Invited, + Requested, + Responded, + Complete, +} + +impl From<&GenericState> for State { + fn from(value: &GenericState) -> Self { + match value { + GenericState::Invitee(v) => Self::Invitee(v.into()), + GenericState::Inviter(v) => Self::Inviter(v.into()), + } + } +} + +impl From<&InviterState> for ThinState { + fn from(value: &InviterState) -> Self { + match value { + InviterState::Initial(_) => Self::Initial, + InviterState::Invited(_) => Self::Invited, + InviterState::Requested(_) => Self::Requested, + InviterState::Responded(_) => Self::Responded, + InviterState::Complete(_) => Self::Complete, + } + } +} + +impl From<&InviteeState> for ThinState { + fn from(value: &InviteeState) -> Self { + match value { + InviteeState::Initial(_) => Self::Initial, + InviteeState::Invited(_) => Self::Invited, + InviteeState::Requested(_) => Self::Requested, + InviteeState::Responded(_) => Self::Responded, + InviteeState::Complete(_) => Self::Complete, + } + } +} diff --git a/aries_vcx/src/protocols/typestate_con/invitee/mod.rs b/aries_vcx/src/protocols/typestate_con/invitee/mod.rs index 2cfbe1ed80..07ee6f0f76 100644 --- a/aries_vcx/src/protocols/typestate_con/invitee/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/invitee/mod.rs @@ -6,7 +6,7 @@ use messages::protocols::connection::invite::Invitation; use crate::{common::ledger::transactions::into_did_doc, core::profile::profile::Profile, errors::error::VcxResult}; -use self::states::{initial::InitialState, invited::InvitedState, requested::RequestedState}; +use self::states::{initial::Initial, invited::Invited, requested::Requested}; use messages::{ a2a::A2AMessage, @@ -31,11 +31,11 @@ use crate::{ /// Convenience alias pub type InviteeConnection = Connection; -impl InviteeConnection { +impl InviteeConnection { pub fn new_invitee(source_id: String, pairwise_info: PairwiseInfo) -> Self { Self { source_id, - state: InitialState, + state: Initial, pairwise_info, initiation_type: Invitee, } @@ -45,12 +45,12 @@ impl InviteeConnection { self, profile: &Arc, invitation: &Invitation, - ) -> VcxResult> { + ) -> VcxResult> { trace!("Connection::into_invited >>> invitation: {:?}", &invitation); let thread_id = invitation.get_id().to_owned(); let did_doc = into_did_doc(profile, invitation).await?; - let state = InvitedState { did_doc, thread_id }; + let state = Invited { did_doc, thread_id }; // Convert to `InvitedState` Ok(Connection { @@ -62,14 +62,14 @@ impl InviteeConnection { } } -impl InviteeConnection { +impl InviteeConnection { pub async fn send_request( self, wallet: &Arc, service_endpoint: String, routing_keys: Vec, transport: &T, - ) -> VcxResult> + ) -> VcxResult> where T: Transport, { @@ -112,7 +112,7 @@ impl InviteeConnection { self.send_message(wallet, &request.to_a2a_message(), transport).await?; Ok(Connection { - state: RequestedState::new(self.state.did_doc, self.state.thread_id), + state: Requested::new(self.state.did_doc, self.state.thread_id), source_id: self.source_id, pairwise_info: self.pairwise_info, initiation_type: Invitee, @@ -120,7 +120,7 @@ impl InviteeConnection { } } -impl InviteeConnection { +impl InviteeConnection { pub async fn handle_response( self, wallet: &Arc, diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/initial.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/initial.rs index 88fb901100..3bebf35de9 100644 --- a/aries_vcx/src/protocols/typestate_con/invitee/states/initial.rs +++ b/aries_vcx/src/protocols/typestate_con/invitee/states/initial.rs @@ -1,2 +1,2 @@ #[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq)] -pub struct InitialState; +pub struct Initial; diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs index c8d573e2a2..abb7e62533 100644 --- a/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs +++ b/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs @@ -3,24 +3,24 @@ use messages::diddoc::aries::diddoc::AriesDidDoc; use crate::protocols::typestate_con::traits::{TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct InvitedState { +pub struct Invited { pub(crate) did_doc: AriesDidDoc, pub(crate) thread_id: String, } -impl InvitedState { +impl Invited { pub fn new(did_doc: AriesDidDoc, thread_id: String) -> Self { Self { did_doc, thread_id } } } -impl TheirDidDoc for InvitedState { +impl TheirDidDoc for Invited { fn their_did_doc(&self) -> &AriesDidDoc { &self.did_doc } } -impl ThreadId for InvitedState { +impl ThreadId for Invited { fn thread_id(&self) -> &str { &self.thread_id } diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs index 00d62f53dc..61311ec216 100644 --- a/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs +++ b/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs @@ -3,27 +3,27 @@ use messages::diddoc::aries::diddoc::AriesDidDoc; use crate::protocols::typestate_con::traits::{HandleProblem, TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct RequestedState { +pub struct Requested { pub(crate) did_doc: AriesDidDoc, pub(crate) thread_id: String, } -impl RequestedState { +impl Requested { pub fn new(did_doc: AriesDidDoc, thread_id: String) -> Self { Self { did_doc, thread_id } } } -impl TheirDidDoc for RequestedState { +impl TheirDidDoc for Requested { fn their_did_doc(&self) -> &AriesDidDoc { &self.did_doc } } -impl ThreadId for RequestedState { +impl ThreadId for Requested { fn thread_id(&self) -> &str { &self.thread_id } } -impl HandleProblem for RequestedState {} +impl HandleProblem for Requested {} diff --git a/aries_vcx/src/protocols/typestate_con/inviter/mod.rs b/aries_vcx/src/protocols/typestate_con/inviter/mod.rs index 31d7e08668..cc055475b0 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/mod.rs @@ -8,8 +8,8 @@ use crate::{ common::signing::sign_connection_response, errors::error::VcxResult, plugins::wallet::base_wallet::BaseWallet, }; -use self::states::initial::InitialState; -use self::states::{invited::InvitedState, requested::RequestedState}; +use self::states::initial::Initial; +use self::states::{invited::Invited, requested::Requested}; use super::common::states::complete::CompleteState; use super::common::states::responded::RespondedState; use super::traits::Transport; @@ -24,7 +24,7 @@ use messages::protocols::connection::{ pub type InviterConnection = Connection; -impl InviterConnection { +impl InviterConnection { pub fn new_inviter( source_id: String, pairwise_info: PairwiseInfo, @@ -42,7 +42,7 @@ impl InviterConnection { Self { source_id, - state: InitialState::new(invitation), + state: Initial::new(invitation), pairwise_info, initiation_type: Inviter, } @@ -53,17 +53,17 @@ impl InviterConnection { } } -impl InviterConnection { +impl InviterConnection { /// Creates an [`InviterConnection`], essentially bypassing the [`InitialState`] /// where an [`Invitation`] is created. - /// + /// /// This is useful for cases where an [`Invitation`] is received by the invitee without /// any interaction from the inviter, thus the next logical step is to wait for the invitee /// to send a connection request. pub fn new_awaiting_request(source_id: String, pairwise_info: PairwiseInfo) -> Self { Self { source_id, - state: InvitedState::new(None), // what should the thread ID be in this case??? + state: Invited::new(None), // what should the thread ID be in this case??? pairwise_info, initiation_type: Inviter, } @@ -107,7 +107,7 @@ impl InviterConnection { new_service_endpoint: String, new_routing_keys: Vec, transport: &T, - ) -> VcxResult> + ) -> VcxResult> where T: Transport, { @@ -155,7 +155,7 @@ impl InviterConnection { ) .await?; - let state = RequestedState::new(signed_response, did_doc); + let state = Requested::new(signed_response, did_doc); Ok(Connection { source_id: self.source_id, @@ -166,7 +166,7 @@ impl InviterConnection { } } -impl InviterConnection { +impl InviterConnection { pub async fn send_response( self, wallet: &Arc, diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/initial.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/initial.rs index 02721cf041..2445e01398 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/states/initial.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/states/initial.rs @@ -3,17 +3,17 @@ use messages::protocols::connection::invite::Invitation; use crate::protocols::typestate_con::traits::ThreadId; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct InitialState { +pub struct Initial { pub(crate) invitation: Invitation, } -impl InitialState { +impl Initial { pub fn new(invitation: Invitation) -> Self { Self { invitation } } } -impl ThreadId for InitialState { +impl ThreadId for Initial { fn thread_id(&self) -> &str { self.invitation.get_id() } diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs index 46e12a8387..8dc14f64d5 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs @@ -1,11 +1,11 @@ use crate::protocols::typestate_con::traits::HandleProblem; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct InvitedState { +pub struct Invited { pub(crate) thread_id: Option, } -impl InvitedState { +impl Invited { pub fn new(thread_id: Option) -> Self { Self { thread_id } } @@ -17,4 +17,4 @@ impl InvitedState { } } -impl HandleProblem for InvitedState {} +impl HandleProblem for Invited {} diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs index 6bf070d259..36e55af461 100644 --- a/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs +++ b/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs @@ -3,12 +3,12 @@ use messages::{diddoc::aries::diddoc::AriesDidDoc, protocols::connection::respon use crate::protocols::typestate_con::traits::{TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct RequestedState { +pub struct Requested { pub(crate) signed_response: SignedResponse, pub(crate) did_doc: AriesDidDoc, } -impl RequestedState { +impl Requested { pub fn new(signed_response: SignedResponse, did_doc: AriesDidDoc) -> Self { Self { signed_response, @@ -17,13 +17,13 @@ impl RequestedState { } } -impl TheirDidDoc for RequestedState { +impl TheirDidDoc for Requested { fn their_did_doc(&self) -> &AriesDidDoc { &self.did_doc } } -impl ThreadId for RequestedState { +impl ThreadId for Requested { //TODO: This should land in the threadlike macro. fn thread_id(&self) -> &str { self.signed_response diff --git a/aries_vcx/src/protocols/typestate_con/mod.rs b/aries_vcx/src/protocols/typestate_con/mod.rs index 588f54758d..517c644547 100644 --- a/aries_vcx/src/protocols/typestate_con/mod.rs +++ b/aries_vcx/src/protocols/typestate_con/mod.rs @@ -1,9 +1,10 @@ -mod common; -mod initiation_type; +pub mod common; +mod generic; +pub mod initiation_type; pub mod invitee; pub mod inviter; pub mod pairwise_info; -mod serde; +mod serializable; mod traits; use messages::{ @@ -24,17 +25,17 @@ use crate::{ use self::{ common::states::complete::CompleteState, + generic::GenericState, pairwise_info::PairwiseInfo, - serde::de::VagueState, traits::{HandleProblem, TheirDidDoc, ThreadId}, }; -pub use self::serde::de::{State, VagueConnection}; +pub use self::generic::{GenericConnection, State, ThinState}; pub use self::traits::Transport; #[derive(Clone, Deserialize)] -#[serde(try_from = "VagueConnection")] -#[serde(bound = "(I, S): TryFrom")] +#[serde(try_from = "GenericConnection")] +#[serde(bound = "(I, S): TryFrom")] pub struct Connection { source_id: String, pairwise_info: PairwiseInfo, @@ -63,23 +64,6 @@ impl Connection { pub fn protocols(&self) -> Vec { ProtocolRegistry::init().protocols() } - - pub(crate) async fn basic_send_message( - wallet: &Arc, - message: &A2AMessage, - sender_verkey: &str, - did_doc: &AriesDidDoc, - transport: &T, - ) -> VcxResult<()> - where - T: Transport, - { - let env = EncryptionEnvelope::create(wallet, message, Some(sender_verkey), did_doc).await?; - let msg = env.0; - let service_endpoint = did_doc.get_endpoint(); // This, like many other things, shouldn't clone... - - transport.send_message(msg, &service_endpoint).await - } } impl Connection @@ -125,7 +109,7 @@ where { let sender_verkey = &self.pairwise_info().pw_vk; let did_doc = self.their_did_doc(); - Self::basic_send_message(wallet, message, sender_verkey, did_doc, transport).await + basic_send_message(wallet, message, sender_verkey, did_doc, transport).await } } @@ -157,7 +141,7 @@ where { let sender_verkey = &self.pairwise_info().pw_vk; let problem_report = self.create_problem_report(err, thread_id); - let res = Self::basic_send_message( + let res = basic_send_message( wallet, &problem_report.to_a2a_message(), sender_verkey, @@ -183,3 +167,20 @@ impl Connection { self.state.handle_disclose(disclose) } } + +pub(crate) async fn basic_send_message( + wallet: &Arc, + message: &A2AMessage, + sender_verkey: &str, + did_doc: &AriesDidDoc, + transport: &T, +) -> VcxResult<()> +where + T: Transport, +{ + let env = EncryptionEnvelope::create(wallet, message, Some(sender_verkey), did_doc).await?; + let msg = env.0; + let service_endpoint = did_doc.get_endpoint(); // This, like many other things, shouldn't clone... + + transport.send_message(msg, &service_endpoint).await +} diff --git a/aries_vcx/src/protocols/typestate_con/serde/de.rs b/aries_vcx/src/protocols/typestate_con/serde/de.rs deleted file mode 100644 index c3428e5ff0..0000000000 --- a/aries_vcx/src/protocols/typestate_con/serde/de.rs +++ /dev/null @@ -1,391 +0,0 @@ -use std::sync::Arc; - -use messages::{a2a::A2AMessage, diddoc::aries::diddoc::AriesDidDoc, protocols::connection::invite::Invitation}; - -use crate::{ - errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult}, - plugins::wallet::base_wallet::BaseWallet, - protocols::typestate_con::{ - common::states::{complete::CompleteState, responded::RespondedState}, - initiation_type::{Invitee, Inviter}, - invitee::states::{ - initial::InitialState as InviteeInitial, invited::InvitedState as InviteeInvited, - requested::RequestedState as InviteeRequested, - }, - inviter::states::{ - initial::InitialState as InviterInitial, invited::InvitedState as InviterInvited, - requested::RequestedState as InviterRequested, - }, - pairwise_info::PairwiseInfo, - traits::{TheirDidDoc, ThreadId}, - Connection, Transport, - }, -}; - -/// Macro used for boilerplace implementation of the -/// [`From`] trait from a concrete connection state to the equivalent vague state. -macro_rules! from_concrete_to_vague { - ($from:ident, $var:ident, $to:ident) => { - impl From<$from> for $to { - fn from(value: $from) -> Self { - Self::$var(value) - } - } - }; - - ($init_type:ident, $state:ident, $var:ident, $to:ident) => { - impl From<($init_type, S)> for $to - where - $state: From, - { - fn from(value: ($init_type, S)) -> Self { - let (_, state) = value; - let serde_state = From::from(state); - Self::$var(serde_state) - } - } - }; -} - -/// Macro used for boilerplace implementation of the -/// [`TryFrom`] trait from a vague connection state to a concrete state. -macro_rules! try_from_vague_to_concrete { - ($from:ident, $var:ident, $to:ident) => { - impl TryFrom<$from> for $to { - type Error = AriesVcxError; - - fn try_from(value: $from) -> Result { - match value { - $from::$var(s) => Ok(s), - _ => Err(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidState, - format!("unexpected connection state: {:?}!", value), - )), - } - } - } - }; - - ($state:ident, $good_var:ident, $bad_var:ident, $init_type:ident) => { - impl TryFrom for ($init_type, S) - where - S: TryFrom<$state, Error = AriesVcxError>, - { - type Error = AriesVcxError; - - fn try_from(value: VagueState) -> Result { - match value { - VagueState::$good_var(s) => S::try_from(s).map(|s| ($init_type, s)), - VagueState::$bad_var(_) => Err(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidState, - concat!( - "Expected ", - stringify!(VagueState::$good_var), - "connection state, found ", - stringify!(VagueState::$bad_var), - ), - )), - } - } - } - }; -} - -/// Helper type mainly used for deserialization of a [`Connection`]. -/// It does not expose methods to advance the connection protocol -/// It does, however, expose some methods agnostic to the [`Connection`] type. -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct VagueConnection { - pub(super) source_id: String, - pub(super) pairwise_info: PairwiseInfo, - pub(super) state: VagueState, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub enum VagueState { - Inviter(VagueInviterState), - Invitee(VagueInviteeState), -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub enum VagueInviterState { - Initial(InviterInitial), - Invited(InviterInvited), - Requested(InviterRequested), - Responded(RespondedState), - Complete(CompleteState), -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub enum VagueInviteeState { - Initial(InviteeInitial), - Invited(InviteeInvited), - Requested(InviteeRequested), - Responded(RespondedState), - Complete(CompleteState), -} - -// ---------------------------- From Concrete State to Vague State implementations ---------------------------- -impl From> for VagueConnection -where - VagueState: From<(I, S)>, -{ - fn from(value: Connection) -> Self { - let state = From::from((value.initiation_type, value.state)); - Self { - source_id: value.source_id, - pairwise_info: value.pairwise_info, - state, - } - } -} - -from_concrete_to_vague!(Inviter, VagueInviterState, Inviter, VagueState); -from_concrete_to_vague!(Invitee, VagueInviteeState, Invitee, VagueState); - -from_concrete_to_vague!(InviterInitial, Initial, VagueInviterState); -from_concrete_to_vague!(InviterInvited, Invited, VagueInviterState); -from_concrete_to_vague!(InviterRequested, Requested, VagueInviterState); -from_concrete_to_vague!(RespondedState, Responded, VagueInviterState); -from_concrete_to_vague!(CompleteState, Complete, VagueInviterState); - -from_concrete_to_vague!(InviteeInitial, Initial, VagueInviteeState); -from_concrete_to_vague!(InviteeInvited, Invited, VagueInviteeState); -from_concrete_to_vague!(InviteeRequested, Requested, VagueInviteeState); -from_concrete_to_vague!(RespondedState, Responded, VagueInviteeState); -from_concrete_to_vague!(CompleteState, Complete, VagueInviteeState); - -// ---------------------------- Try From Vague State to Concrete State implementations ---------------------------- -impl TryFrom for Connection -where - (I, S): TryFrom, -{ - type Error = AriesVcxError; - - fn try_from(value: VagueConnection) -> Result { - let (initiation_type, state) = TryFrom::try_from(value.state)?; - let con = Connection::from_parts(value.source_id, value.pairwise_info, initiation_type, state); - Ok(con) - } -} - -try_from_vague_to_concrete!(VagueInviterState, Inviter, Invitee, Inviter); -try_from_vague_to_concrete!(VagueInviteeState, Invitee, Inviter, Invitee); - -try_from_vague_to_concrete!(VagueInviterState, Initial, InviterInitial); -try_from_vague_to_concrete!(VagueInviterState, Invited, InviterInvited); -try_from_vague_to_concrete!(VagueInviterState, Requested, InviterRequested); -try_from_vague_to_concrete!(VagueInviterState, Responded, RespondedState); -try_from_vague_to_concrete!(VagueInviterState, Complete, CompleteState); - -try_from_vague_to_concrete!(VagueInviteeState, Initial, InviteeInitial); -try_from_vague_to_concrete!(VagueInviteeState, Invited, InviteeInvited); -try_from_vague_to_concrete!(VagueInviteeState, Requested, InviteeRequested); -try_from_vague_to_concrete!(VagueInviteeState, Responded, RespondedState); -try_from_vague_to_concrete!(VagueInviteeState, Complete, CompleteState); - -/// Small sized enum used for determining -/// a connection's state in terms of initiation type. -#[derive(Clone, Copy, Debug)] -pub enum State { - Invitee(ConState), - Inviter(ConState), -} - -/// Small sized enum used for determining -/// a connection's state in terms of connection stage. -#[derive(Clone, Copy, Debug)] -pub enum ConState { - Initial, - Invited, - Requested, - Responded, - Complete, -} - -impl From for u32 { - fn from(value: State) -> Self { - match value { - State::Invitee(v) => v as u32, - State::Inviter(v) => v as u32, - } - } -} - -impl From<&VagueState> for State { - fn from(value: &VagueState) -> Self { - match value { - VagueState::Invitee(v) => Self::Invitee(v.into()), - VagueState::Inviter(v) => Self::Inviter(v.into()), - } - } -} - -impl From<&VagueInviterState> for ConState { - fn from(value: &VagueInviterState) -> Self { - match value { - VagueInviterState::Initial(_) => Self::Initial, - VagueInviterState::Invited(_) => Self::Invited, - VagueInviterState::Requested(_) => Self::Requested, - VagueInviterState::Responded(_) => Self::Responded, - VagueInviterState::Complete(_) => Self::Complete, - } - } -} - -impl From<&VagueInviteeState> for ConState { - fn from(value: &VagueInviteeState) -> Self { - match value { - VagueInviteeState::Initial(_) => Self::Initial, - VagueInviteeState::Invited(_) => Self::Invited, - VagueInviteeState::Requested(_) => Self::Requested, - VagueInviteeState::Responded(_) => Self::Responded, - VagueInviteeState::Complete(_) => Self::Complete, - } - } -} - -impl VagueConnection { - pub fn state(&self) -> State { - (&self.state).into() - } - - pub fn thread_id(&self) -> Option<&str> { - match &self.state { - VagueState::Invitee(VagueInviteeState::Initial(_)) => None, - VagueState::Invitee(VagueInviteeState::Invited(s)) => Some(s.thread_id()), - VagueState::Invitee(VagueInviteeState::Requested(s)) => Some(s.thread_id()), - VagueState::Invitee(VagueInviteeState::Responded(s)) => Some(s.thread_id()), - VagueState::Invitee(VagueInviteeState::Complete(s)) => Some(s.thread_id()), - VagueState::Inviter(VagueInviterState::Initial(s)) => Some(s.thread_id()), - VagueState::Inviter(VagueInviterState::Invited(s)) => s.opt_thread_id(), - VagueState::Inviter(VagueInviterState::Requested(s)) => Some(s.thread_id()), - VagueState::Inviter(VagueInviterState::Responded(s)) => Some(s.thread_id()), - VagueState::Inviter(VagueInviterState::Complete(s)) => Some(s.thread_id()), - } - } - - pub fn pairwise_info(&self) -> &PairwiseInfo { - &self.pairwise_info - } - - pub fn their_did_doc(&self) -> Option<&AriesDidDoc> { - match &self.state { - VagueState::Invitee(VagueInviteeState::Initial(_)) => None, - VagueState::Invitee(VagueInviteeState::Invited(s)) => Some(s.their_did_doc()), - VagueState::Invitee(VagueInviteeState::Requested(s)) => Some(s.their_did_doc()), - VagueState::Invitee(VagueInviteeState::Responded(s)) => Some(s.their_did_doc()), - VagueState::Invitee(VagueInviteeState::Complete(s)) => Some(s.their_did_doc()), - VagueState::Inviter(VagueInviterState::Initial(_)) => None, - VagueState::Inviter(VagueInviterState::Invited(_)) => None, - VagueState::Inviter(VagueInviterState::Requested(s)) => Some(s.their_did_doc()), - VagueState::Inviter(VagueInviterState::Responded(s)) => Some(s.their_did_doc()), - VagueState::Inviter(VagueInviterState::Complete(s)) => Some(s.their_did_doc()), - } - } - - pub fn remote_did(&self) -> Option<&str> { - self.their_did_doc().map(|d| d.id.as_str()) - } - - pub fn remote_vk(&self) -> VcxResult { - let did_doc = self.their_did_doc().ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::NotReady, - "No DidDoc present", - ))?; - - did_doc - .recipient_keys()? - .first() - .map(ToOwned::to_owned) - .ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::NotReady, - "Can't resolve recipient key from the counterparty diddoc.", - )) - } - - pub fn invitation(&self) -> Option<&Invitation> { - match &self.state { - VagueState::Inviter(VagueInviterState::Initial(s)) => Some(&s.invitation), - _ => None, - } - } - - pub async fn send_message( - &self, - wallet: &Arc, - message: &A2AMessage, - transport: &T, - ) -> VcxResult<()> - where - T: Transport, - { - let sender_verkey = &self.pairwise_info().pw_vk; - let did_doc = self.their_did_doc().ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::NotReady, - "No DidDoc present", - ))?; - - // The generic types do not matter here as the method is available - // on all possible implementations. - Connection::<(), ()>::basic_send_message(wallet, message, sender_verkey, did_doc, transport).await - } -} - -/// Compile-time assurance that the deserialization type -/// of the [`Connection`], if modified, will be modified along the serialization type. -#[cfg(test)] -mod tests { - use crate::protocols::typestate_con::serde::ser::*; - - use super::*; - - impl<'a> From> for VagueInviteeState { - fn from(value: RefInviteeState<'a>) -> Self { - match value { - RefInviteeState::Initial(s) => Self::Initial(s.to_owned()), - RefInviteeState::Invited(s) => Self::Invited(s.to_owned()), - RefInviteeState::Requested(s) => Self::Requested(s.to_owned()), - RefInviteeState::Responded(s) => Self::Responded(s.to_owned()), - RefInviteeState::Complete(s) => Self::Complete(s.to_owned()), - } - } - } - - impl<'a> From> for VagueInviterState { - fn from(value: RefInviterState<'a>) -> Self { - match value { - RefInviterState::Initial(s) => Self::Initial(s.to_owned()), - RefInviterState::Invited(s) => Self::Invited(s.to_owned()), - RefInviterState::Requested(s) => Self::Requested(s.to_owned()), - RefInviterState::Responded(s) => Self::Responded(s.to_owned()), - RefInviterState::Complete(s) => Self::Complete(s.to_owned()), - } - } - } - - impl<'a> From> for VagueState { - fn from(value: RefState<'a>) -> Self { - match value { - RefState::Invitee(s) => Self::Invitee(s.into()), - RefState::Inviter(s) => Self::Inviter(s.into()), - } - } - } - - impl<'a> From> for VagueConnection { - fn from(value: SerializableConnection<'a>) -> Self { - let SerializableConnection { - source_id, - pairwise_info, - state, - } = value; - - Self { - source_id: source_id.to_owned(), - pairwise_info: pairwise_info.to_owned(), - state: state.into(), - } - } - } -} diff --git a/aries_vcx/src/protocols/typestate_con/serde/mod.rs b/aries_vcx/src/protocols/typestate_con/serde/mod.rs deleted file mode 100644 index 2e6ab62c61..0000000000 --- a/aries_vcx/src/protocols/typestate_con/serde/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod de; -pub mod ser; diff --git a/aries_vcx/src/protocols/typestate_con/serde/ser.rs b/aries_vcx/src/protocols/typestate_con/serializable.rs similarity index 64% rename from aries_vcx/src/protocols/typestate_con/serde/ser.rs rename to aries_vcx/src/protocols/typestate_con/serializable.rs index 0c0d4431b2..ca6f899b8f 100644 --- a/aries_vcx/src/protocols/typestate_con/serde/ser.rs +++ b/aries_vcx/src/protocols/typestate_con/serializable.rs @@ -4,12 +4,12 @@ use crate::protocols::typestate_con::{ common::states::{complete::CompleteState, responded::RespondedState}, initiation_type::{Invitee, Inviter}, invitee::states::{ - initial::InitialState as InviteeInitial, invited::InvitedState as InviteeInvited, - requested::RequestedState as InviteeRequested, + initial::Initial as InviteeInitial, invited::Invited as InviteeInvited, + requested::Requested as InviteeRequested, }, inviter::states::{ - initial::InitialState as InviterInitial, invited::InvitedState as InviterInvited, - requested::RequestedState as InviterRequested, + initial::Initial as InviterInitial, invited::Invited as InviterInvited, + requested::Requested as InviterRequested, }, pairwise_info::PairwiseInfo, Connection, @@ -127,61 +127,3 @@ where SerializableConnection::from(self).serialize(serializer) } } - -/// Compile-time assurance that the serialization type -/// of the [`Connection`], if modified, will be modified along the deserialization type. -#[cfg(test)] -mod tests { - use crate::protocols::typestate_con::serde::de::*; - - use super::*; - - impl<'a> From<&'a VagueInviteeState> for RefInviteeState<'a> { - fn from(value: &'a VagueInviteeState) -> Self { - match value { - VagueInviteeState::Initial(s) => Self::Initial(s), - VagueInviteeState::Invited(s) => Self::Invited(s), - VagueInviteeState::Requested(s) => Self::Requested(s), - VagueInviteeState::Responded(s) => Self::Responded(s), - VagueInviteeState::Complete(s) => Self::Complete(s), - } - } - } - - impl<'a> From<&'a VagueInviterState> for RefInviterState<'a> { - fn from(value: &'a VagueInviterState) -> Self { - match value { - VagueInviterState::Initial(s) => Self::Initial(s), - VagueInviterState::Invited(s) => Self::Invited(s), - VagueInviterState::Requested(s) => Self::Requested(s), - VagueInviterState::Responded(s) => Self::Responded(s), - VagueInviterState::Complete(s) => Self::Complete(s), - } - } - } - - impl<'a> From<&'a VagueState> for RefState<'a> { - fn from(value: &'a VagueState) -> Self { - match value { - VagueState::Invitee(s) => Self::Invitee(s.into()), - VagueState::Inviter(s) => Self::Inviter(s.into()), - } - } - } - - impl<'a> From<&'a VagueConnection> for SerializableConnection<'a> { - fn from(value: &'a VagueConnection) -> Self { - let VagueConnection { - source_id, - pairwise_info, - state, - } = value; - - Self { - source_id, - pairwise_info, - state: state.into(), - } - } - } -} diff --git a/libvcx/src/api_vcx/api_handle/typestate_con.rs b/libvcx/src/api_vcx/api_handle/typestate_con.rs index 66f90390cf..168cf8aeab 100644 --- a/libvcx/src/api_vcx/api_handle/typestate_con.rs +++ b/libvcx/src/api_vcx/api_handle/typestate_con.rs @@ -5,8 +5,8 @@ use aries_vcx::{ errors::error::VcxResult, messages::protocols::basic_message::message::BasicMessage, protocols::typestate_con::{ - invitee::InviteeConnection, inviter::InviterConnection, pairwise_info::PairwiseInfo, Connection, Transport, - VagueConnection, + invitee::InviteeConnection, inviter::InviterConnection, pairwise_info::PairwiseInfo, Connection, + GenericConnection, State, Transport, }, }; use async_trait::async_trait; @@ -17,7 +17,7 @@ use crate::{ errors::error::{LibvcxError, LibvcxErrorKind, LibvcxResult}, }; -type Map = HashMap; +type Map = HashMap; type Cache = RwLock; lazy_static! { @@ -45,7 +45,7 @@ fn new_handle() -> LibvcxResult { fn get_cloned_connection(handle: &u32) -> LibvcxResult> where - Connection: TryFrom, + Connection: TryFrom, { CONNECTION_MAP .write()? @@ -59,7 +59,7 @@ where }) } -fn add_connection(connection: VagueConnection) -> LibvcxResult { +fn add_connection(connection: GenericConnection) -> LibvcxResult { let handle = new_handle()?; CONNECTION_MAP.write()?.insert(handle, connection); Ok(handle) @@ -67,7 +67,7 @@ fn add_connection(connection: VagueConnection) -> LibvcxResult { fn insert_connection(handle: u32, connection: Connection) -> LibvcxResult<()> where - VagueConnection: From>, + GenericConnection: From>, { CONNECTION_MAP.write()?.insert(handle, connection.into()); Ok(()) @@ -208,7 +208,12 @@ pub fn get_state(handle: u32) -> LibvcxResult { ) })?; - Ok(con.state().into()) + let state_id = match con.state() { + State::Invitee(s) => s as u32, + State::Inviter(s) => s as u32, + }; + + Ok(state_id) } pub fn get_invitation(handle: u32) -> LibvcxResult { From 1abda21dff459dadfad34d28e3a1442179033e0e Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Wed, 1 Feb 2023 14:20:43 +0200 Subject: [PATCH 30/66] Removed previous non-mediated Connection in favor of newer typestate Connection Signed-off-by: Bogdan Mircea --- .../rust/aries-vcx-agent/src/http_client.rs | 2 +- .../src/services/connection.rs | 4 +- .../src/handlers/connection/cloud_agent.rs | 2 +- .../src/handlers/connection/connection.rs | 651 ------------------ .../connection/mediated_connection.rs | 6 +- aries_vcx/src/handlers/connection/mod.rs | 1 - aries_vcx/src/handlers/mod.rs | 27 +- .../common/mod.rs | 0 .../common/states/complete.rs | 2 +- .../common/states/mod.rs | 0 .../common/states/responded.rs | 2 +- .../generic/conversions.rs | 2 +- .../generic/mod.rs | 4 +- .../generic/thin_state.rs | 0 .../initiation_type.rs | 0 .../src/protocols/connection/invitee/mod.rs | 191 ++++- .../connection/invitee/states/initial.rs | 28 +- .../connection/invitee/states/invited.rs | 30 +- .../connection/invitee/states/mod.rs | 8 +- .../connection/invitee/states/requested.rs | 42 +- .../src/protocols/connection/inviter/mod.rs | 213 +++++- .../connection/inviter/states/initial.rs | 21 +- .../connection/inviter/states/invited.rs | 37 +- .../connection/inviter/states/mod.rs | 8 +- .../connection/inviter/states/requested.rs | 49 +- aries_vcx/src/protocols/connection/mod.rs | 183 +++++ .../serializable.rs | 2 +- .../{typestate_con => connection}/traits.rs | 0 .../mediated_connection/invitee/mod.rs | 2 + .../invitee/state_machine.rs | 12 +- .../invitee/states/complete.rs | 4 +- .../invitee/states/initial.rs | 26 + .../invitee/states/invited.rs | 17 + .../mediated_connection/invitee/states/mod.rs | 5 + .../invitee/states/requested.rs | 33 + .../invitee/states/responded.rs | 2 +- .../mediated_connection/inviter/mod.rs | 2 + .../inviter/state_machine.rs | 12 +- .../inviter/states/complete.rs | 0 .../inviter/states/initial.rs | 21 + .../inviter/states/invited.rs | 33 + .../mediated_connection/inviter/states/mod.rs | 5 + .../inviter/states/requested.rs | 32 + .../inviter/states/responded.rs | 4 +- .../src/protocols/mediated_connection/mod.rs | 3 + .../pairwise_info.rs | 0 aries_vcx/src/protocols/mod.rs | 4 +- .../protocols/typestate_con/invitee/mod.rs | 189 ----- .../typestate_con/invitee/states/initial.rs | 2 - .../typestate_con/invitee/states/invited.rs | 27 - .../typestate_con/invitee/states/mod.rs | 3 - .../typestate_con/invitee/states/requested.rs | 29 - .../protocols/typestate_con/inviter/mod.rs | 211 ------ .../typestate_con/inviter/states/initial.rs | 20 - .../typestate_con/inviter/states/invited.rs | 20 - .../typestate_con/inviter/states/mod.rs | 3 - .../typestate_con/inviter/states/requested.rs | 35 - aries_vcx/src/protocols/typestate_con/mod.rs | 186 ----- aries_vcx/tests/test_connection.rs | 2 +- aries_vcx/tests/utils/devsetup_agent.rs | 6 +- aries_vcx/tests/utils/scenarios.rs | 4 +- .../api_c/protocols/mediated_connection.rs | 2 +- libvcx/src/api_vcx/api_global/wallet.rs | 2 +- libvcx/src/api_vcx/api_handle/connection.rs | 356 +++++++--- .../api_vcx/api_handle/mediated_connection.rs | 2 +- libvcx/src/api_vcx/api_handle/mod.rs | 3 +- .../src/api_vcx/api_handle/typestate_con.rs | 378 ---------- wrappers/vcx-napi-rs/src/api/connection.rs | 6 +- .../src/api/mediated_connection.rs | 2 +- 69 files changed, 1164 insertions(+), 2056 deletions(-) delete mode 100644 aries_vcx/src/handlers/connection/connection.rs rename aries_vcx/src/protocols/{typestate_con => connection}/common/mod.rs (100%) rename aries_vcx/src/protocols/{typestate_con => connection}/common/states/complete.rs (93%) rename aries_vcx/src/protocols/{typestate_con => connection}/common/states/mod.rs (100%) rename aries_vcx/src/protocols/{typestate_con => connection}/common/states/responded.rs (88%) rename aries_vcx/src/protocols/{typestate_con => connection}/generic/conversions.rs (99%) rename aries_vcx/src/protocols/{typestate_con => connection}/generic/mod.rs (99%) rename aries_vcx/src/protocols/{typestate_con => connection}/generic/thin_state.rs (100%) rename aries_vcx/src/protocols/{typestate_con => connection}/initiation_type.rs (100%) rename aries_vcx/src/protocols/{typestate_con => connection}/serializable.rs (99%) rename aries_vcx/src/protocols/{typestate_con => connection}/traits.rs (100%) create mode 100644 aries_vcx/src/protocols/mediated_connection/invitee/mod.rs rename aries_vcx/src/protocols/{connection => mediated_connection}/invitee/state_machine.rs (98%) rename aries_vcx/src/protocols/{connection => mediated_connection}/invitee/states/complete.rs (90%) create mode 100644 aries_vcx/src/protocols/mediated_connection/invitee/states/initial.rs create mode 100644 aries_vcx/src/protocols/mediated_connection/invitee/states/invited.rs create mode 100644 aries_vcx/src/protocols/mediated_connection/invitee/states/mod.rs create mode 100644 aries_vcx/src/protocols/mediated_connection/invitee/states/requested.rs rename aries_vcx/src/protocols/{connection => mediated_connection}/invitee/states/responded.rs (90%) create mode 100644 aries_vcx/src/protocols/mediated_connection/inviter/mod.rs rename aries_vcx/src/protocols/{connection => mediated_connection}/inviter/state_machine.rs (98%) rename aries_vcx/src/protocols/{connection => mediated_connection}/inviter/states/complete.rs (100%) create mode 100644 aries_vcx/src/protocols/mediated_connection/inviter/states/initial.rs create mode 100644 aries_vcx/src/protocols/mediated_connection/inviter/states/invited.rs create mode 100644 aries_vcx/src/protocols/mediated_connection/inviter/states/mod.rs create mode 100644 aries_vcx/src/protocols/mediated_connection/inviter/states/requested.rs rename aries_vcx/src/protocols/{connection => mediated_connection}/inviter/states/responded.rs (86%) create mode 100644 aries_vcx/src/protocols/mediated_connection/mod.rs rename aries_vcx/src/protocols/{typestate_con => mediated_connection}/pairwise_info.rs (100%) delete mode 100644 aries_vcx/src/protocols/typestate_con/invitee/mod.rs delete mode 100644 aries_vcx/src/protocols/typestate_con/invitee/states/initial.rs delete mode 100644 aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs delete mode 100644 aries_vcx/src/protocols/typestate_con/invitee/states/mod.rs delete mode 100644 aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs delete mode 100644 aries_vcx/src/protocols/typestate_con/inviter/mod.rs delete mode 100644 aries_vcx/src/protocols/typestate_con/inviter/states/initial.rs delete mode 100644 aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs delete mode 100644 aries_vcx/src/protocols/typestate_con/inviter/states/mod.rs delete mode 100644 aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs delete mode 100644 aries_vcx/src/protocols/typestate_con/mod.rs delete mode 100644 libvcx/src/api_vcx/api_handle/typestate_con.rs diff --git a/agents/rust/aries-vcx-agent/src/http_client.rs b/agents/rust/aries-vcx-agent/src/http_client.rs index c8800100f5..8412480567 100644 --- a/agents/rust/aries-vcx-agent/src/http_client.rs +++ b/agents/rust/aries-vcx-agent/src/http_client.rs @@ -1,5 +1,5 @@ use aries_vcx::{ - agency_client::httpclient::post_message, errors::error::VcxResult, protocols::typestate_con::Transport, + agency_client::httpclient::post_message, errors::error::VcxResult, protocols::connection::Transport, }; use async_trait::async_trait; diff --git a/agents/rust/aries-vcx-agent/src/services/connection.rs b/agents/rust/aries-vcx-agent/src/services/connection.rs index 4715b84182..e936a7045c 100644 --- a/agents/rust/aries-vcx-agent/src/services/connection.rs +++ b/agents/rust/aries-vcx-agent/src/services/connection.rs @@ -10,8 +10,8 @@ use aries_vcx::messages::concepts::ack::Ack; use aries_vcx::messages::protocols::connection::invite::Invitation; use aries_vcx::messages::protocols::connection::request::Request; use aries_vcx::messages::protocols::connection::response::SignedResponse; -use aries_vcx::protocols::typestate_con::pairwise_info::PairwiseInfo; -use aries_vcx::protocols::typestate_con::{Connection, GenericConnection, State}; +use aries_vcx::protocols::connection::pairwise_info::PairwiseInfo; +use aries_vcx::protocols::connection::{Connection, GenericConnection, State}; pub type ServiceEndpoint = String; diff --git a/aries_vcx/src/handlers/connection/cloud_agent.rs b/aries_vcx/src/handlers/connection/cloud_agent.rs index b9cf70aeef..ed71690f16 100644 --- a/aries_vcx/src/handlers/connection/cloud_agent.rs +++ b/aries_vcx/src/handlers/connection/cloud_agent.rs @@ -9,7 +9,7 @@ use agency_client::wallet::base_agency_client_wallet::BaseAgencyClientWallet; use crate::agency_client::MessageStatusCode; use crate::errors::error::prelude::*; use crate::plugins::wallet::agency_client_wallet::ToBaseWallet; -use crate::protocols::connection::pairwise_info::PairwiseInfo; +use crate::protocols::mediated_connection::pairwise_info::PairwiseInfo; use crate::utils::encryption_envelope::EncryptionEnvelope; use messages::a2a::A2AMessage; diff --git a/aries_vcx/src/handlers/connection/connection.rs b/aries_vcx/src/handlers/connection/connection.rs deleted file mode 100644 index be6e580b62..0000000000 --- a/aries_vcx/src/handlers/connection/connection.rs +++ /dev/null @@ -1,651 +0,0 @@ -use std::clone::Clone; -use std::sync::Arc; - -use messages::a2a::A2AMessage; -use messages::protocols::basic_message::message::BasicMessage; -use messages::protocols::connection::response::SignedResponse; -use serde::{Deserialize, Serialize}; - -use crate::core::profile::profile::Profile; -use crate::errors::error::prelude::*; -use crate::protocols::connection::invitee::state_machine::{InviteeFullState, InviteeState, SmConnectionInvitee}; -use crate::protocols::connection::inviter::state_machine::{InviterFullState, InviterState, SmConnectionInviter}; -use crate::protocols::connection::pairwise_info::PairwiseInfo; -use crate::protocols::{SendClosure, SendClosureConnection}; -use crate::utils::send_message; -use messages::diddoc::aries::diddoc::AriesDidDoc; -use messages::protocols::connection::invite::Invitation; -use messages::protocols::connection::request::Request; - -#[derive(Clone, PartialEq, Serialize, Deserialize)] -pub struct Connection { - connection_sm: SmConnection, -} - -#[derive(Clone, PartialEq, Serialize, Deserialize)] -pub enum SmConnection { - Inviter(SmConnectionInviter), - Invitee(SmConnectionInvitee), -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub enum SmConnectionState { - Inviter(InviterFullState), - Invitee(InviteeFullState), -} - -#[derive(Debug, PartialEq, Eq)] -pub enum ConnectionState { - Inviter(InviterState), - Invitee(InviteeState), -} - -impl Connection { - // ----------------------------- CONSTRUCTORS ------------------------------------ - pub async fn create_inviter(profile: &Arc, pw_info: Option) -> VcxResult { - let pw_info = pw_info.unwrap_or(PairwiseInfo::create(&profile.inject_wallet()).await?); - trace!("Connection::create_inviter >>>"); - Ok(Self { - connection_sm: SmConnection::Inviter(SmConnectionInviter::new("", pw_info)), - }) - } - - pub async fn create_invitee(profile: &Arc, did_doc: AriesDidDoc) -> VcxResult { - trace!("Connection::create_with_invite >>>"); - Ok(Self { - connection_sm: SmConnection::Invitee(SmConnectionInvitee::new( - "", - PairwiseInfo::create(&profile.inject_wallet()).await?, - did_doc, - )), - }) - } - - // ----------------------------- GETTERS ------------------------------------ - pub fn get_thread_id(&self) -> String { - match &self.connection_sm { - SmConnection::Inviter(sm_inviter) => sm_inviter.get_thread_id(), - SmConnection::Invitee(sm_invitee) => sm_invitee.get_thread_id(), - } - } - - pub fn get_state(&self) -> ConnectionState { - match &self.connection_sm { - SmConnection::Inviter(sm_inviter) => ConnectionState::Inviter(sm_inviter.get_state()), - SmConnection::Invitee(sm_invitee) => ConnectionState::Invitee(sm_invitee.get_state()), - } - } - - pub fn pairwise_info(&self) -> &PairwiseInfo { - match &self.connection_sm { - SmConnection::Inviter(sm_inviter) => sm_inviter.pairwise_info(), - SmConnection::Invitee(sm_invitee) => sm_invitee.pairwise_info(), - } - } - - pub fn remote_did(&self) -> VcxResult { - match &self.connection_sm { - SmConnection::Inviter(sm_inviter) => sm_inviter.remote_did(), - SmConnection::Invitee(sm_invitee) => sm_invitee.remote_did(), - } - } - - pub fn remote_vk(&self) -> VcxResult { - match &self.connection_sm { - SmConnection::Inviter(sm_inviter) => sm_inviter.remote_vk(), - SmConnection::Invitee(sm_invitee) => sm_invitee.remote_vk(), - } - } - - pub fn state_object(&self) -> SmConnectionState { - match &self.connection_sm { - SmConnection::Inviter(sm_inviter) => SmConnectionState::Inviter(sm_inviter.state_object().clone()), - SmConnection::Invitee(sm_invitee) => SmConnectionState::Invitee(sm_invitee.state_object().clone()), - } - } - - pub fn their_did_doc(&self) -> Option { - match &self.connection_sm { - SmConnection::Inviter(sm_inviter) => sm_inviter.their_did_doc(), - SmConnection::Invitee(sm_invitee) => sm_invitee.their_did_doc(), - } - } - - pub fn get_invite_details(&self) -> Option<&Invitation> { - trace!("Connection::get_invite_details >>>"); - match &self.connection_sm { - SmConnection::Inviter(sm_inviter) => sm_inviter.get_invitation(), - SmConnection::Invitee(_sm_invitee) => None, - } - } - - // ----------------------------- MSG PROCESSING ------------------------------------ - pub fn process_invite(self, invitation: Invitation) -> VcxResult { - trace!("Connection::process_invite >>> invitation: {:?}", invitation); - let connection_sm = match &self.connection_sm { - SmConnection::Inviter(_sm_inviter) => { - return Err(AriesVcxError::from_msg(AriesVcxErrorKind::NotReady, "Invalid action")); - } - SmConnection::Invitee(sm_invitee) => { - SmConnection::Invitee(sm_invitee.clone().handle_invitation(invitation)?) - } - }; - Ok(Self { connection_sm }) - } - - pub async fn process_request( - self, - profile: &Arc, - request: Request, - service_endpoint: String, - routing_keys: Vec, - send_message: Option, - ) -> VcxResult { - trace!( - "Connection::process_request >>> request: {:?}, service_endpoint: {}, routing_keys: {:?}", - request, - service_endpoint, - routing_keys, - ); - let connection_sm = match &self.connection_sm { - SmConnection::Inviter(sm_inviter) => { - let send_message = send_message.unwrap_or(self.send_message_closure_connection(profile)); - let new_pairwise_info = PairwiseInfo::create(&profile.inject_wallet()).await?; - SmConnection::Inviter( - sm_inviter - .clone() - .handle_connection_request( - profile.inject_wallet(), - request, - &new_pairwise_info, - routing_keys, - service_endpoint, - send_message, - ) - .await?, - ) - } - SmConnection::Invitee(_) => { - return Err(AriesVcxError::from_msg(AriesVcxErrorKind::NotReady, "Invalid action")); - } - }; - Ok(Self { connection_sm }) - } - - pub async fn process_response( - self, - profile: &Arc, - response: SignedResponse, - send_message: Option, - ) -> VcxResult { - let connection_sm = match &self.connection_sm { - SmConnection::Inviter(_) => { - return Err(AriesVcxError::from_msg(AriesVcxErrorKind::NotReady, "Invalid action")); - } - SmConnection::Invitee(sm_invitee) => { - let send_message = send_message.unwrap_or(self.send_message_closure_connection(profile)); - SmConnection::Invitee( - sm_invitee - .clone() - .handle_connection_response(&profile.inject_wallet(), response, send_message) - .await?, - ) - } - }; - Ok(Self { connection_sm }) - } - - pub async fn process_ack(self, message: A2AMessage) -> VcxResult { - trace!("Connection::process_ack >>> message: {:?}", message); - let connection_sm = match &self.connection_sm { - SmConnection::Inviter(sm_inviter) => { - SmConnection::Inviter(sm_inviter.clone().handle_confirmation_message(&message).await?) - } - SmConnection::Invitee(_) => { - return Err(AriesVcxError::from_msg(AriesVcxErrorKind::NotReady, "Invalid action")); - } - }; - Ok(Self { connection_sm }) - } - - // ----------------------------- MSG SENDING ------------------------------------ - pub async fn send_response( - self, - profile: &Arc, - send_message: Option, - ) -> VcxResult { - trace!("Connection::send_response >>>"); - let connection_sm = match self.connection_sm.clone() { - SmConnection::Inviter(sm_inviter) => { - if let InviterFullState::Requested(_) = sm_inviter.state_object() { - let send_message = send_message.unwrap_or(self.send_message_closure_connection(profile)); - SmConnection::Inviter(sm_inviter.handle_send_response(send_message).await?) - } else { - return Err(AriesVcxError::from_msg(AriesVcxErrorKind::NotReady, "Invalid action")); - } - } - SmConnection::Invitee(_) => { - return Err(AriesVcxError::from_msg(AriesVcxErrorKind::NotReady, "Invalid action")); - } - }; - Ok(Self { connection_sm }) - } - - pub async fn send_request( - self, - profile: &Arc, - service_endpoint: String, - routing_keys: Vec, - send_message: Option, - ) -> VcxResult { - trace!("Connection::send_request"); - let connection_sm = match &self.connection_sm { - SmConnection::Inviter(_) => { - return Err(AriesVcxError::from_msg( - AriesVcxErrorKind::NotReady, - "Inviter cannot send connection request", - )); - } - SmConnection::Invitee(sm_invitee) => SmConnection::Invitee( - sm_invitee - .clone() - .send_connection_request( - routing_keys, - service_endpoint, - send_message.unwrap_or(self.send_message_closure_connection(profile)), - ) - .await?, - ), - }; - Ok(Self { connection_sm }) - } - - pub async fn send_ack( - self, - profile: &Arc, - send_message: Option, - ) -> VcxResult { - trace!("Connection::send_ack"); - let connection_sm = match &self.connection_sm { - SmConnection::Inviter(_) => { - return Err(AriesVcxError::from_msg( - AriesVcxErrorKind::NotReady, - "Inviter cannot send ack", - )); - } - SmConnection::Invitee(sm_invitee) => SmConnection::Invitee( - sm_invitee - .clone() - .handle_send_ack(send_message.unwrap_or(self.send_message_closure_connection(profile))) - .await?, - ), - }; - Ok(Self { connection_sm }) - } - - pub async fn create_invite(self, service_endpoint: String, routing_keys: Vec) -> VcxResult { - trace!("Connection::create_invite >>>"); - let connection_sm = match &self.connection_sm { - SmConnection::Inviter(sm_inviter) => { - SmConnection::Inviter(sm_inviter.clone().create_invitation(routing_keys, service_endpoint)?) - } - SmConnection::Invitee(_) => { - return Err(AriesVcxError::from_msg( - AriesVcxErrorKind::NotReady, - "Invitee cannot create invite", - )); - } - }; - Ok(Self { connection_sm }) - } - - pub async fn send_generic_message( - &self, - profile: &Arc, - send_message: Option, - content: String, - ) -> VcxResult<()> { - trace!("Connection::send_generic_message >>>"); - let message = BasicMessage::create() - .set_content(content) - .set_time() - .set_out_time() - .to_a2a_message(); - let send_message = self.send_message_closure(profile, send_message).await?; - send_message(message).await - } - - pub async fn send_message_closure( - &self, - profile: &Arc, - send_message: Option, - ) -> VcxResult { - trace!("send_message_closure >>>"); - let did_doc = self.their_did_doc().ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::NotReady, - "Cannot send message: Remote Connection information is not set", - ))?; - let sender_vk = self.pairwise_info().pw_vk.clone(); - let send_message = send_message.unwrap_or(self.send_message_closure_connection(profile)); - Ok(Box::new(move |message: A2AMessage| { - Box::pin(send_message(message, sender_vk.clone(), did_doc.clone())) - })) - } - - fn send_message_closure_connection(&self, profile: &Arc) -> SendClosureConnection { - trace!("send_message_closure_connection >>>"); - let wallet = profile.inject_wallet(); - Box::new(move |message: A2AMessage, sender_vk: String, did_doc: AriesDidDoc| { - Box::pin(send_message(wallet, sender_vk, did_doc, message)) - }) - } - - // ------------------------- (DE)SERIALIZATION ---------------------------------- - pub fn to_string(&self) -> VcxResult { - serde_json::to_string(&self).map_err(|err| { - AriesVcxError::from_msg( - AriesVcxErrorKind::SerializationError, - format!("Cannot serialize Connection: {:?}", err), - ) - }) - } - - pub fn from_string(serialized: &str) -> VcxResult { - serde_json::from_str(serialized).map_err(|err| { - AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidJson, - format!("Cannot deserialize Connection: {:?}", err), - ) - }) - } -} - -#[cfg(feature = "test_utils")] -#[cfg(test)] -pub mod test_utils { - use async_channel::Sender; - - use super::*; - - pub(super) fn _routing_keys() -> Vec { - vec![] - } - - pub(super) fn _service_endpoint() -> String { - String::from("https://service-endpoint.org") - } - - pub(super) fn _send_message(sender: Sender) -> Option { - Some(Box::new( - move |message: A2AMessage, _sender_vk: String, _did_doc: AriesDidDoc| { - Box::pin(async move { - sender.send(message).await.map_err(|err| { - AriesVcxError::from_msg( - AriesVcxErrorKind::IOError, - format!("Failed to send message: {:?}", err), - ) - }) - }) - }, - )) - } -} - -#[cfg(test)] -#[cfg(feature = "general_test")] -mod unit_tests { - use crate::common::ledger::transactions::into_did_doc; - use crate::common::test_utils::{indy_handles_to_profile, mock_profile}; - use crate::utils::devsetup::{SetupInstitutionWallet, SetupMocks}; - use crate::utils::mockdata::mockdata_connection::{ - CONNECTION_SM_INVITEE_COMPLETED, CONNECTION_SM_INVITEE_INVITED, CONNECTION_SM_INVITEE_REQUESTED, - CONNECTION_SM_INVITEE_RESPONDED, CONNECTION_SM_INVITER_COMPLETED, CONNECTION_SM_INVITER_REQUESTED, - CONNECTION_SM_INVITER_RESPONDED, - }; - - use async_channel::bounded; - use messages::protocols::basic_message::message::BasicMessage; - use messages::protocols::connection::invite::test_utils::{ - _pairwise_invitation, _pairwise_invitation_random_id, _public_invitation, _public_invitation_random_id, - }; - use messages::protocols::connection::request::unit_tests::_request; - - use super::test_utils::*; - use super::*; - - #[tokio::test] - #[ignore] - async fn test_create_with_pairwise_invite() { - let _setup = SetupMocks::init(); - let invite = Invitation::Pairwise(_pairwise_invitation()); - let connection = Connection::create_invitee(&mock_profile(), AriesDidDoc::default()) - .await - .unwrap() - .process_invite(invite) - .unwrap(); - assert_eq!(connection.get_state(), ConnectionState::Invitee(InviteeState::Invited)); - } - - #[tokio::test] - async fn test_create_with_public_invite() { - let _setup = SetupMocks::init(); - let invite = Invitation::Public(_public_invitation()); - let connection = Connection::create_invitee(&mock_profile(), AriesDidDoc::default()) - .await - .unwrap() - .process_invite(invite) - .unwrap(); - assert_eq!(connection.get_state(), ConnectionState::Invitee(InviteeState::Invited)); - } - - #[tokio::test] - async fn test_connect_sets_correct_thread_id_based_on_invitation_type() { - let _setup = SetupMocks::init(); - - let invite = _public_invitation_random_id(); - let connection = Connection::create_invitee(&mock_profile(), AriesDidDoc::default()) - .await - .unwrap() - .process_invite(Invitation::Public(invite.clone())) - .unwrap() - .send_request(&mock_profile(), _service_endpoint(), vec![], None) - .await - .unwrap(); - assert_eq!( - connection.get_state(), - ConnectionState::Invitee(InviteeState::Requested) - ); - assert_ne!(connection.get_thread_id(), invite.id.0); - - let invite = _pairwise_invitation_random_id(); - let connection = Connection::create_invitee(&mock_profile(), AriesDidDoc::default()) - .await - .unwrap() - .process_invite(Invitation::Pairwise(invite.clone())) - .unwrap() - .send_request(&mock_profile(), _service_endpoint(), vec![], None) - .await - .unwrap(); - assert_eq!( - connection.get_state(), - ConnectionState::Invitee(InviteeState::Requested) - ); - assert_eq!(connection.get_thread_id(), invite.id.0); - } - - #[tokio::test] - async fn test_create_with_request() { - let _setup = SetupMocks::init(); - - let connection = Connection::create_inviter(&mock_profile(), None) - .await - .unwrap() - .process_request(&mock_profile(), _request(), _service_endpoint(), _routing_keys(), None) - .await - .unwrap(); - - assert_eq!( - connection.get_state(), - ConnectionState::Inviter(InviterState::Requested) - ); - } - - #[tokio::test] - async fn test_inviter_deserialize_serialized() { - let _setup = SetupMocks::init(); - let connection = Connection::create_inviter(&mock_profile(), None) - .await - .unwrap() - .process_request(&mock_profile(), _request(), _service_endpoint(), _routing_keys(), None) - .await - .unwrap(); - let ser_conn = connection.to_string().unwrap(); - assert_eq!( - ser_conn, - Connection::from_string(&ser_conn).unwrap().to_string().unwrap() - ); - } - - #[tokio::test] - async fn test_invitee_deserialize_serialized() { - let _setup = SetupMocks::init(); - let invite = _pairwise_invitation_random_id(); - let connection = Connection::create_invitee(&mock_profile(), AriesDidDoc::default()) - .await - .unwrap() - .process_invite(Invitation::Pairwise(invite.clone())) - .unwrap() - .send_request(&mock_profile(), _service_endpoint(), vec![], None) - .await - .unwrap(); - let ser_conn = connection.to_string().unwrap(); - assert_eq!( - ser_conn, - Connection::from_string(&ser_conn).unwrap().to_string().unwrap() - ); - } - - #[test] - fn test_deserialize_and_serialize_should_produce_the_same_object() { - fn test_deserialize_and_serialize(sm_serialized: &str) { - let original_object: serde_json::Value = serde_json::from_str(sm_serialized).unwrap(); - let connection = Connection::from_string(sm_serialized).unwrap(); - let reserialized = connection.to_string().unwrap(); - let reserialized_object: serde_json::Value = serde_json::from_str(&reserialized).unwrap(); - assert_eq!(original_object, reserialized_object); - } - - // let _setup = SetupMocks::init(); - test_deserialize_and_serialize(CONNECTION_SM_INVITEE_INVITED); - test_deserialize_and_serialize(CONNECTION_SM_INVITEE_REQUESTED); - test_deserialize_and_serialize(CONNECTION_SM_INVITEE_RESPONDED); - test_deserialize_and_serialize(CONNECTION_SM_INVITEE_COMPLETED); - test_deserialize_and_serialize(CONNECTION_SM_INVITER_REQUESTED); - test_deserialize_and_serialize(CONNECTION_SM_INVITER_RESPONDED); - test_deserialize_and_serialize(CONNECTION_SM_INVITER_COMPLETED); - } - - #[tokio::test] - async fn test_connection_e2e() { - let setup = SetupInstitutionWallet::init().await; - let profile = indy_handles_to_profile(setup.wallet_handle, 0); - - let (sender, receiver) = bounded(1); - - // Inviter creates connection and sends invite - let inviter = Connection::create_inviter(&profile, None) - .await - .unwrap() - .create_invite(_service_endpoint(), _routing_keys()) - .await - .unwrap(); - let invite = if let Invitation::Pairwise(invite) = inviter.get_invite_details().unwrap().clone() { - invite - } else { - panic!("Invalid invitation type"); - }; - - // Invitee receives an invite and sends request - let did_doc = into_did_doc(&mock_profile(), &Invitation::Pairwise(invite.clone())) - .await - .unwrap(); - let invitee = Connection::create_invitee(&profile, did_doc) - .await - .unwrap() - .process_invite(Invitation::Pairwise(invite)) - .unwrap(); - assert_eq!(invitee.get_state(), ConnectionState::Invitee(InviteeState::Invited)); - let invitee = invitee - .send_request( - &profile, - _service_endpoint(), - _routing_keys(), - _send_message(sender.clone()), - ) - .await - .unwrap(); - assert_eq!(invitee.get_state(), ConnectionState::Invitee(InviteeState::Requested)); - - // Inviter receives requests and sends response - let request = if let A2AMessage::ConnectionRequest(request) = receiver.recv().await.unwrap() { - request - } else { - panic!("Received invalid message type") - }; - - let inviter = inviter - .process_request( - &profile, - request, - _service_endpoint(), - _routing_keys(), - _send_message(sender.clone()), - ) - .await - .unwrap(); - assert_eq!(inviter.get_state(), ConnectionState::Inviter(InviterState::Requested)); - let inviter = inviter - .send_response(&profile, _send_message(sender.clone())) - .await - .unwrap(); - assert_eq!(inviter.get_state(), ConnectionState::Inviter(InviterState::Responded)); - - // Invitee receives response and sends ack - let response = if let A2AMessage::ConnectionResponse(response) = receiver.recv().await.unwrap() { - response - } else { - panic!("Received invalid message type") - }; - - let invitee = invitee - .process_response(&profile, response, _send_message(sender.clone())) - .await - .unwrap(); - assert_eq!(invitee.get_state(), ConnectionState::Invitee(InviteeState::Responded)); - let invitee = invitee.send_ack(&profile, _send_message(sender.clone())).await.unwrap(); - assert_eq!(invitee.get_state(), ConnectionState::Invitee(InviteeState::Completed)); - - // Inviter receives an ack - let ack = receiver.recv().await.unwrap(); - let inviter = inviter.process_ack(ack).await.unwrap(); - assert_eq!(inviter.get_state(), ConnectionState::Inviter(InviterState::Completed)); - - // Invitee sends basic message - let content = "Hello"; - let basic_message = BasicMessage::create().set_content(content.to_string()).to_a2a_message(); - invitee - .send_message_closure(&profile, _send_message(sender.clone())) - .await - .unwrap()(basic_message) - .await - .unwrap(); - - // Inviter receives basic message - let message = if let A2AMessage::BasicMessage(message) = receiver.recv().await.unwrap() { - message - } else { - panic!("Received invalid message type") - }; - assert_eq!(message.content, content.to_string()); - } -} diff --git a/aries_vcx/src/handlers/connection/mediated_connection.rs b/aries_vcx/src/handlers/connection/mediated_connection.rs index c5a6247891..2655c691d6 100644 --- a/aries_vcx/src/handlers/connection/mediated_connection.rs +++ b/aries_vcx/src/handlers/connection/mediated_connection.rs @@ -19,9 +19,9 @@ use crate::handlers::connection::cloud_agent::CloudAgentInfo; use crate::handlers::connection::legacy_agent_info::LegacyAgentInfo; use crate::handlers::discovery::{respond_discovery_query, send_discovery_query}; use crate::handlers::trust_ping::TrustPingSender; -use crate::protocols::connection::invitee::state_machine::{InviteeFullState, InviteeState, SmConnectionInvitee}; -use crate::protocols::connection::inviter::state_machine::{InviterFullState, InviterState, SmConnectionInviter}; -use crate::protocols::connection::pairwise_info::PairwiseInfo; +use crate::protocols::mediated_connection::invitee::state_machine::{InviteeFullState, InviteeState, SmConnectionInvitee}; +use crate::protocols::mediated_connection::inviter::state_machine::{InviterFullState, InviterState, SmConnectionInviter}; +use crate::protocols::mediated_connection::pairwise_info::PairwiseInfo; use crate::protocols::oob::{build_handshake_reuse_accepted_msg, build_handshake_reuse_msg}; use crate::protocols::trustping::build_ping_response; use crate::protocols::{SendClosure, SendClosureConnection}; diff --git a/aries_vcx/src/handlers/connection/mod.rs b/aries_vcx/src/handlers/connection/mod.rs index 83c2c2cab3..0bfbb9d588 100644 --- a/aries_vcx/src/handlers/connection/mod.rs +++ b/aries_vcx/src/handlers/connection/mod.rs @@ -1,4 +1,3 @@ pub mod cloud_agent; -pub mod connection; pub mod legacy_agent_info; pub mod mediated_connection; diff --git a/aries_vcx/src/handlers/mod.rs b/aries_vcx/src/handlers/mod.rs index 853074bca3..e766b15d7a 100644 --- a/aries_vcx/src/handlers/mod.rs +++ b/aries_vcx/src/handlers/mod.rs @@ -1,13 +1,11 @@ use crate::handlers::connection::mediated_connection::ConnectionState as MediatedConnectionState; -use crate::protocols::connection::invitee::state_machine::InviteeState; -use crate::protocols::connection::inviter::state_machine::InviterState; +use crate::protocols::mediated_connection::invitee::state_machine::InviteeState; +use crate::protocols::mediated_connection::inviter::state_machine::InviterState; use crate::protocols::issuance::holder::state_machine::HolderState; use crate::protocols::issuance::issuer::state_machine::IssuerState; use crate::protocols::proof_presentation::prover::state_machine::ProverState; use crate::protocols::proof_presentation::verifier::state_machine::VerifierState; -use self::connection::connection::ConnectionState; - pub mod connection; pub mod discovery; pub mod issuance; @@ -38,27 +36,6 @@ impl From for u32 { } } -impl From for u32 { - fn from(state: ConnectionState) -> u32 { - match state { - ConnectionState::Inviter(inviter_state) => match inviter_state { - InviterState::Initial => 0, - InviterState::Invited => 1, - InviterState::Requested => 2, - InviterState::Responded => 3, - InviterState::Completed => 4, - }, - ConnectionState::Invitee(invitee_state) => match invitee_state { - InviteeState::Initial => 0, - InviteeState::Invited => 1, - InviteeState::Requested => 2, - InviteeState::Responded => 3, - InviteeState::Completed => 4, - }, - } - } -} - impl From for u32 { fn from(state: HolderState) -> u32 { match state { diff --git a/aries_vcx/src/protocols/typestate_con/common/mod.rs b/aries_vcx/src/protocols/connection/common/mod.rs similarity index 100% rename from aries_vcx/src/protocols/typestate_con/common/mod.rs rename to aries_vcx/src/protocols/connection/common/mod.rs diff --git a/aries_vcx/src/protocols/typestate_con/common/states/complete.rs b/aries_vcx/src/protocols/connection/common/states/complete.rs similarity index 93% rename from aries_vcx/src/protocols/typestate_con/common/states/complete.rs rename to aries_vcx/src/protocols/connection/common/states/complete.rs index e1f14d6794..fcec31030d 100644 --- a/aries_vcx/src/protocols/typestate_con/common/states/complete.rs +++ b/aries_vcx/src/protocols/connection/common/states/complete.rs @@ -3,7 +3,7 @@ use std::clone::Clone; use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::discovery::disclose::{Disclose, ProtocolDescriptor}; -use crate::protocols::typestate_con::traits::{TheirDidDoc, ThreadId}; +use crate::protocols::connection::traits::{TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct CompleteState { diff --git a/aries_vcx/src/protocols/typestate_con/common/states/mod.rs b/aries_vcx/src/protocols/connection/common/states/mod.rs similarity index 100% rename from aries_vcx/src/protocols/typestate_con/common/states/mod.rs rename to aries_vcx/src/protocols/connection/common/states/mod.rs diff --git a/aries_vcx/src/protocols/typestate_con/common/states/responded.rs b/aries_vcx/src/protocols/connection/common/states/responded.rs similarity index 88% rename from aries_vcx/src/protocols/typestate_con/common/states/responded.rs rename to aries_vcx/src/protocols/connection/common/states/responded.rs index 953884e324..4060ebf253 100644 --- a/aries_vcx/src/protocols/typestate_con/common/states/responded.rs +++ b/aries_vcx/src/protocols/connection/common/states/responded.rs @@ -1,6 +1,6 @@ use messages::diddoc::aries::diddoc::AriesDidDoc; -use crate::protocols::typestate_con::traits::{TheirDidDoc, ThreadId}; +use crate::protocols::connection::traits::{TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct RespondedState { diff --git a/aries_vcx/src/protocols/typestate_con/generic/conversions.rs b/aries_vcx/src/protocols/connection/generic/conversions.rs similarity index 99% rename from aries_vcx/src/protocols/typestate_con/generic/conversions.rs rename to aries_vcx/src/protocols/connection/generic/conversions.rs index b09434ef3d..43ead03cfc 100644 --- a/aries_vcx/src/protocols/typestate_con/generic/conversions.rs +++ b/aries_vcx/src/protocols/connection/generic/conversions.rs @@ -1,7 +1,7 @@ use super::{GenericConnection, GenericState, InviteeState, InviterState}; use crate::{ errors::error::{AriesVcxError, AriesVcxErrorKind}, - protocols::typestate_con::{ + protocols::connection::{ common::states::{complete::CompleteState, responded::RespondedState}, initiation_type::{Invitee, Inviter}, invitee::states::{ diff --git a/aries_vcx/src/protocols/typestate_con/generic/mod.rs b/aries_vcx/src/protocols/connection/generic/mod.rs similarity index 99% rename from aries_vcx/src/protocols/typestate_con/generic/mod.rs rename to aries_vcx/src/protocols/connection/generic/mod.rs index 9dd3794442..381af9dadb 100644 --- a/aries_vcx/src/protocols/typestate_con/generic/mod.rs +++ b/aries_vcx/src/protocols/connection/generic/mod.rs @@ -10,7 +10,7 @@ pub use self::thin_state::{State, ThinState}; use crate::{ errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult}, plugins::wallet::base_wallet::BaseWallet, - protocols::typestate_con::{ + protocols::connection::{ common::states::{complete::CompleteState, responded::RespondedState}, invitee::states::{ initial::Initial as InviteeInitial, invited::Invited as InviteeInvited, @@ -181,7 +181,7 @@ impl GenericConnection { /// of the [`Connection`], if modified, will be modified along the serialization type. #[cfg(test)] mod tests { - use crate::protocols::typestate_con::serializable::*; + use crate::protocols::connection::serializable::*; use super::*; diff --git a/aries_vcx/src/protocols/typestate_con/generic/thin_state.rs b/aries_vcx/src/protocols/connection/generic/thin_state.rs similarity index 100% rename from aries_vcx/src/protocols/typestate_con/generic/thin_state.rs rename to aries_vcx/src/protocols/connection/generic/thin_state.rs diff --git a/aries_vcx/src/protocols/typestate_con/initiation_type.rs b/aries_vcx/src/protocols/connection/initiation_type.rs similarity index 100% rename from aries_vcx/src/protocols/typestate_con/initiation_type.rs rename to aries_vcx/src/protocols/connection/initiation_type.rs diff --git a/aries_vcx/src/protocols/connection/invitee/mod.rs b/aries_vcx/src/protocols/connection/invitee/mod.rs index 6b37a228b6..07ee6f0f76 100644 --- a/aries_vcx/src/protocols/connection/invitee/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/mod.rs @@ -1,2 +1,189 @@ -pub mod state_machine; -mod states; +pub mod states; + +use std::sync::Arc; + +use messages::protocols::connection::invite::Invitation; + +use crate::{common::ledger::transactions::into_did_doc, core::profile::profile::Profile, errors::error::VcxResult}; + +use self::states::{initial::Initial, invited::Invited, requested::Requested}; + +use messages::{ + a2a::A2AMessage, + concepts::ack::Ack, + protocols::connection::{request::Request, response::SignedResponse}, +}; + +use super::{ + common::states::{complete::CompleteState, responded::RespondedState}, + initiation_type::Invitee, + pairwise_info::PairwiseInfo, + traits::Transport, + Connection, +}; +use crate::{ + common::signing::decode_signed_connection_response, + errors::error::{AriesVcxError, AriesVcxErrorKind}, + handlers::util::verify_thread_id, + plugins::wallet::base_wallet::BaseWallet, +}; + +/// Convenience alias +pub type InviteeConnection = Connection; + +impl InviteeConnection { + pub fn new_invitee(source_id: String, pairwise_info: PairwiseInfo) -> Self { + Self { + source_id, + state: Initial, + pairwise_info, + initiation_type: Invitee, + } + } + + pub async fn accept_invitation( + self, + profile: &Arc, + invitation: &Invitation, + ) -> VcxResult> { + trace!("Connection::into_invited >>> invitation: {:?}", &invitation); + + let thread_id = invitation.get_id().to_owned(); + let did_doc = into_did_doc(profile, invitation).await?; + let state = Invited { did_doc, thread_id }; + + // Convert to `InvitedState` + Ok(Connection { + state, + source_id: self.source_id, + pairwise_info: self.pairwise_info, + initiation_type: Invitee, + }) + } +} + +impl InviteeConnection { + pub async fn send_request( + self, + wallet: &Arc, + service_endpoint: String, + routing_keys: Vec, + transport: &T, + ) -> VcxResult> + where + T: Transport, + { + trace!("Connection::send_request"); + + let recipient_keys = vec![self.pairwise_info.pw_vk.clone()]; + + let request = Request::create() + .set_label(self.source_id.to_string()) + .set_did(self.pairwise_info.pw_did.to_string()) + .set_service_endpoint(service_endpoint) + .set_keys(recipient_keys, routing_keys) + .set_out_time(); + + // Should be properly retrieved from Invitation. + // Also there's if this Request will just be serialized, it might as well take references. + let request = request.set_parent_thread_id(&self.state.thread_id); + + // The Invitation gets lost along the way when converting from Invited to Requested + // in previous implementations. Apart from these thread ID's, it's not used at all. + // + // Might as well implement it properly when accepting an Invitation in the `into_invited` method. + // + // let request_id = request.id.0.clone(); + // + // let (request, thread_id) = match &self.state.invitation { + // Invitation::Public(_) => ( + // request + // .set_parent_thread_id(&self.thread_id) + // .set_thread_id_matching_id(), + // request_id, + // ), + // Invitation::Pairwise(_) => (request.set_thread_id(&self.thread_id), self.thread_id().to_owned()), + // Invitation::OutOfBand(invite) => ( + // request.set_parent_thread_id(&invite.id.0).set_thread_id_matching_id(), + // request_id, + // ), + // }; + + self.send_message(wallet, &request.to_a2a_message(), transport).await?; + + Ok(Connection { + state: Requested::new(self.state.did_doc, self.state.thread_id), + source_id: self.source_id, + pairwise_info: self.pairwise_info, + initiation_type: Invitee, + }) + } +} + +impl InviteeConnection { + pub async fn handle_response( + self, + wallet: &Arc, + response: SignedResponse, + transport: &T, + ) -> VcxResult> + where + T: Transport, + { + verify_thread_id(&self.state.thread_id, &A2AMessage::ConnectionResponse(response.clone()))?; + + let keys = &self.state.did_doc.recipient_keys()?; + let their_vk = keys.first().ok_or(AriesVcxError::from_msg( + AriesVcxErrorKind::InvalidState, + "Cannot handle response: remote verkey not found", + ))?; + + let did_doc = match decode_signed_connection_response(wallet, response, their_vk).await { + Ok(response) => Ok(response.connection.did_doc), + Err(err) => { + error!("Request DidDoc validation failed! Sending ProblemReport..."); + + self.send_problem_report(wallet, &err, self.thread_id(), &self.state.did_doc, transport) + .await; + + Err(err) + } + }?; + + let state = RespondedState::new(did_doc, self.state.thread_id); + + Ok(Connection { + state, + source_id: self.source_id, + pairwise_info: self.pairwise_info, + initiation_type: Invitee, + }) + } +} + +impl InviteeConnection { + pub async fn send_ack( + self, + wallet: &Arc, + transport: &T, + ) -> VcxResult> + where + T: Transport, + { + let msg = Ack::create() + .set_out_time() + .set_thread_id(&self.state.thread_id) + .to_a2a_message(); + + self.send_message(wallet, &msg, transport).await?; + + let state = CompleteState::new(self.state.did_doc, self.state.thread_id, None); + + Ok(Connection { + state, + source_id: self.source_id, + pairwise_info: self.pairwise_info, + initiation_type: Invitee, + }) + } +} diff --git a/aries_vcx/src/protocols/connection/invitee/states/initial.rs b/aries_vcx/src/protocols/connection/invitee/states/initial.rs index 7522e6afc6..3bebf35de9 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/initial.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/initial.rs @@ -1,26 +1,2 @@ -use crate::protocols::connection::invitee::states::invited::InvitedState; -use messages::diddoc::aries::diddoc::AriesDidDoc; -use messages::protocols::connection::invite::Invitation; -use messages::protocols::connection::problem_report::ProblemReport; - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct InitialState { - problem_report: Option, - pub did_doc: Option, -} - -impl From<(InitialState, Invitation, AriesDidDoc)> for InvitedState { - fn from((_state, invitation, did_doc): (InitialState, Invitation, AriesDidDoc)) -> InvitedState { - trace!("ConnectionInvitee: transit state from InitialState to InvitedState"); - InvitedState { invitation, did_doc } - } -} - -impl InitialState { - pub fn new(problem_report: Option, did_doc: Option) -> Self { - InitialState { - problem_report, - did_doc, - } - } -} +#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq)] +pub struct Initial; diff --git a/aries_vcx/src/protocols/connection/invitee/states/invited.rs b/aries_vcx/src/protocols/connection/invitee/states/invited.rs index 622894b93e..6ab793ffde 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/invited.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/invited.rs @@ -1,17 +1,27 @@ -use crate::protocols::connection::invitee::states::requested::RequestedState; use messages::diddoc::aries::diddoc::AriesDidDoc; -use messages::protocols::connection::invite::Invitation; -use messages::protocols::connection::request::Request; + +use crate::protocols::connection::traits::{TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct InvitedState { - pub invitation: Invitation, - pub did_doc: AriesDidDoc, +pub struct Invited { + pub(crate) did_doc: AriesDidDoc, + pub(crate) thread_id: String, +} + +impl Invited { + pub fn new(did_doc: AriesDidDoc, thread_id: String) -> Self { + Self { did_doc, thread_id } + } +} + +impl TheirDidDoc for Invited { + fn their_did_doc(&self) -> &AriesDidDoc { + &self.did_doc + } } -impl From<(InvitedState, Request, AriesDidDoc)> for RequestedState { - fn from((_state, request, did_doc): (InvitedState, Request, AriesDidDoc)) -> RequestedState { - trace!("ConnectionInvitee: transit state from InvitedState to RequestedState"); - RequestedState { request, did_doc } +impl ThreadId for Invited { + fn thread_id(&self) -> &str { + &self.thread_id } } diff --git a/aries_vcx/src/protocols/connection/invitee/states/mod.rs b/aries_vcx/src/protocols/connection/invitee/states/mod.rs index 2c1b5a715f..d4151d969c 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/mod.rs @@ -1,5 +1,3 @@ -pub(super) mod complete; -pub(super) mod initial; -pub(super) mod invited; -pub(super) mod requested; -pub(super) mod responded; +pub mod invited; +pub mod requested; +pub mod initial; \ No newline at end of file diff --git a/aries_vcx/src/protocols/connection/invitee/states/requested.rs b/aries_vcx/src/protocols/connection/invitee/states/requested.rs index d56f47b9f2..bc6db8907b 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/requested.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/requested.rs @@ -1,33 +1,29 @@ -use crate::protocols::connection::invitee::states::initial::InitialState; -use crate::protocols::connection::invitee::states::responded::RespondedState; use messages::diddoc::aries::diddoc::AriesDidDoc; -use messages::protocols::connection::problem_report::ProblemReport; -use messages::protocols::connection::request::Request; -use messages::protocols::connection::response::Response; + +use crate::protocols::connection::traits::{HandleProblem, TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct RequestedState { - pub request: Request, - pub did_doc: AriesDidDoc, +pub struct Requested { + pub(crate) did_doc: AriesDidDoc, + pub(crate) thread_id: String, } -impl From<(RequestedState, ProblemReport)> for InitialState { - fn from((_state, problem_report): (RequestedState, ProblemReport)) -> InitialState { - trace!( - "ConnectionInvitee: transit state from RequestedState to InitialState, problem_report: {:?}", - problem_report - ); - InitialState::new(Some(problem_report), None) +impl Requested { + pub fn new(did_doc: AriesDidDoc, thread_id: String) -> Self { + Self { did_doc, thread_id } } } -impl From<(RequestedState, Response)> for RespondedState { - fn from((state, response): (RequestedState, Response)) -> RespondedState { - trace!("ConnectionInvitee: transit state from RequestedState to RespondedState"); - RespondedState { - response, - did_doc: state.did_doc, - request: state.request, - } +impl TheirDidDoc for Requested { + fn their_did_doc(&self) -> &AriesDidDoc { + &self.did_doc } } + +impl ThreadId for Requested { + fn thread_id(&self) -> &str { + &self.thread_id + } +} + +impl HandleProblem for Requested {} diff --git a/aries_vcx/src/protocols/connection/inviter/mod.rs b/aries_vcx/src/protocols/connection/inviter/mod.rs index 6b37a228b6..cc055475b0 100644 --- a/aries_vcx/src/protocols/connection/inviter/mod.rs +++ b/aries_vcx/src/protocols/connection/inviter/mod.rs @@ -1,2 +1,211 @@ -pub mod state_machine; -mod states; +pub mod states; + +use std::sync::Arc; + +use crate::handlers::util::verify_thread_id; +use crate::utils::uuid; +use crate::{ + common::signing::sign_connection_response, errors::error::VcxResult, plugins::wallet::base_wallet::BaseWallet, +}; + +use self::states::initial::Initial; +use self::states::{invited::Invited, requested::Requested}; +use super::common::states::complete::CompleteState; +use super::common::states::responded::RespondedState; +use super::traits::Transport; +use super::{initiation_type::Inviter, pairwise_info::PairwiseInfo, Connection}; +use messages::a2a::A2AMessage; +use messages::protocols::connection::invite::PairwiseInvitation; +use messages::protocols::connection::{ + invite::Invitation, + request::Request, + response::{Response, SignedResponse}, +}; + +pub type InviterConnection = Connection; + +impl InviterConnection { + pub fn new_inviter( + source_id: String, + pairwise_info: PairwiseInfo, + routing_keys: Vec, + service_endpoint: String, + ) -> Self { + let invite: PairwiseInvitation = PairwiseInvitation::create() + .set_id(&uuid::uuid()) + .set_label(&source_id) + .set_recipient_keys(vec![pairwise_info.pw_vk.clone()]) + .set_routing_keys(routing_keys) + .set_service_endpoint(service_endpoint); + + let invitation = Invitation::Pairwise(invite); + + Self { + source_id, + state: Initial::new(invitation), + pairwise_info, + initiation_type: Inviter, + } + } + + pub fn get_invitation(&self) -> &Invitation { + &self.state.invitation + } +} + +impl InviterConnection { + /// Creates an [`InviterConnection`], essentially bypassing the [`InitialState`] + /// where an [`Invitation`] is created. + /// + /// This is useful for cases where an [`Invitation`] is received by the invitee without + /// any interaction from the inviter, thus the next logical step is to wait for the invitee + /// to send a connection request. + pub fn new_awaiting_request(source_id: String, pairwise_info: PairwiseInfo) -> Self { + Self { + source_id, + state: Invited::new(None), // what should the thread ID be in this case??? + pairwise_info, + initiation_type: Inviter, + } + } + + /// As the inviter connection can be started directly in the invited state, + /// like with a public invitation, we might or might not have a thread ID. + pub fn opt_thread_id(&self) -> Option<&str> { + self.state.opt_thread_id() + } + + // This should ideally belong in the Connection + // but was placed here to retro-fit the previous API. + async fn build_response( + &self, + wallet: &Arc, + request: &Request, + new_pairwise_info: &PairwiseInfo, + new_service_endpoint: String, + new_routing_keys: Vec, + ) -> VcxResult { + let new_recipient_keys = vec![new_pairwise_info.pw_vk.clone()]; + let response = Response::create() + .set_did(new_pairwise_info.pw_did.to_string()) + .set_service_endpoint(new_service_endpoint) + .set_keys(new_recipient_keys, new_routing_keys) + .ask_for_ack() + .set_thread_id(&request.get_thread_id()) + .set_out_time(); + + sign_connection_response(wallet, &self.pairwise_info.pw_vk, response).await + } + + // Due to backwards compatibility, we generate the signed response and store that in the state. + // However, it would be more efficient to store the request and postpone the response generation and + // signing until the next state, thus taking advantage of the request attributes and avoiding cloning the DidDoc. + pub async fn handle_request( + self, + wallet: &Arc, + request: Request, + new_service_endpoint: String, + new_routing_keys: Vec, + transport: &T, + ) -> VcxResult> + where + T: Transport, + { + trace!( + "Connection::process_request >>> request: {:?}, service_endpoint: {}, routing_keys: {:?}", + request, + new_service_endpoint, + new_routing_keys, + ); + + // There must be some other way to validate the thread ID other than cloning the entire Request + self.state + .thread_id + .as_ref() + .map(|thread_id| verify_thread_id(thread_id, &A2AMessage::ConnectionRequest(request.clone()))) + .unwrap_or(Ok(()))?; + + // If the request's DidDoc validation fails, we generate and send a ProblemReport. + // We then return early with the provided error. + if let Err(err) = request.connection.did_doc.validate() { + error!("Request DidDoc validation failed! Sending ProblemReport..."); + + self.send_problem_report( + wallet, + &err, + &request.get_thread_id(), + &request.connection.did_doc, + transport, + ) + .await; + + Err(err)?; + } + + let new_pairwise_info = PairwiseInfo::create(wallet).await?; + let did_doc = request.connection.did_doc.clone(); + + let signed_response = self + .build_response( + wallet, + &request, + &new_pairwise_info, + new_service_endpoint, + new_routing_keys, + ) + .await?; + + let state = Requested::new(signed_response, did_doc); + + Ok(Connection { + source_id: self.source_id, + pairwise_info: new_pairwise_info, + initiation_type: self.initiation_type, + state, + }) + } +} + +impl InviterConnection { + pub async fn send_response( + self, + wallet: &Arc, + transport: &T, + ) -> VcxResult> + where + T: Transport, + { + trace!( + "Connection::send_response >>> signed_response: {:?}", + &self.state.signed_response + ); + + let thread_id = self.state.signed_response.get_thread_id(); + + self.send_message(wallet, &self.state.signed_response.to_a2a_message(), transport) + .await?; + + let state = RespondedState::new(self.state.did_doc, thread_id); + + Ok(Connection { + state, + source_id: self.source_id, + pairwise_info: self.pairwise_info, + initiation_type: self.initiation_type, + }) + } +} + +impl InviterConnection { + pub fn acknowledge_connection(self, msg: &A2AMessage) -> VcxResult> { + verify_thread_id(&self.state.thread_id, msg)?; + let state = CompleteState::new(self.state.did_doc, self.state.thread_id, None); + + Ok(Connection { + source_id: self.source_id, + pairwise_info: self.pairwise_info, + initiation_type: self.initiation_type, + state, + }) + } +} diff --git a/aries_vcx/src/protocols/connection/inviter/states/initial.rs b/aries_vcx/src/protocols/connection/inviter/states/initial.rs index ffb41f66ab..e290e1993b 100644 --- a/aries_vcx/src/protocols/connection/inviter/states/initial.rs +++ b/aries_vcx/src/protocols/connection/inviter/states/initial.rs @@ -1,21 +1,20 @@ -use crate::protocols::connection::inviter::states::invited::InvitedState; use messages::protocols::connection::invite::Invitation; -use messages::protocols::connection::problem_report::ProblemReport; + +use crate::protocols::connection::traits::ThreadId; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct InitialState { - problem_report: Option, +pub struct Initial { + pub(crate) invitation: Invitation, } -impl From<(InitialState, Invitation)> for InvitedState { - fn from((_state, invitation): (InitialState, Invitation)) -> InvitedState { - trace!("ConnectionInviter: transit state from InitialState to InvitedState"); - InvitedState { invitation } +impl Initial { + pub fn new(invitation: Invitation) -> Self { + Self { invitation } } } -impl InitialState { - pub fn new(problem_report: Option) -> Self { - InitialState { problem_report } +impl ThreadId for Initial { + fn thread_id(&self) -> &str { + self.invitation.get_id() } } diff --git a/aries_vcx/src/protocols/connection/inviter/states/invited.rs b/aries_vcx/src/protocols/connection/inviter/states/invited.rs index 409f0d4269..592b2aa714 100644 --- a/aries_vcx/src/protocols/connection/inviter/states/invited.rs +++ b/aries_vcx/src/protocols/connection/inviter/states/invited.rs @@ -1,33 +1,20 @@ -use crate::protocols::connection::inviter::states::initial::InitialState; -use crate::protocols::connection::inviter::states::requested::RequestedState; -use messages::protocols::connection::invite::Invitation; -use messages::protocols::connection::problem_report::ProblemReport; -use messages::protocols::connection::request::Request; -use messages::protocols::connection::response::SignedResponse; +use crate::protocols::connection::traits::HandleProblem; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct InvitedState { - pub invitation: Invitation, +pub struct Invited { + pub(crate) thread_id: Option, } -// TODO: These have no justification for being here anymore -impl From for InitialState { - fn from(problem_report: ProblemReport) -> InitialState { - trace!( - "ConnectionInviter: transit state to InitialState, problem_report: {:?}", - problem_report - ); - InitialState::new(Some(problem_report)) +impl Invited { + pub fn new(thread_id: Option) -> Self { + Self { thread_id } } -} -impl From<(Request, SignedResponse)> for RequestedState { - fn from((request, signed_response): (Request, SignedResponse)) -> RequestedState { - trace!("ConnectionInviter: transit state to RespondedState"); - RequestedState { - signed_response, - did_doc: request.connection.did_doc, - thread_id: request.id.0, - } + /// Unlike other states, the ones implementing the [`crate::protocols::typestate_con::traits::ThreadId`], + /// this state may or may not have a thread ID, so we're returning an option. + pub fn opt_thread_id(&self) -> Option<&str> { + self.thread_id.as_deref() } } + +impl HandleProblem for Invited {} diff --git a/aries_vcx/src/protocols/connection/inviter/states/mod.rs b/aries_vcx/src/protocols/connection/inviter/states/mod.rs index 2c1b5a715f..d4151d969c 100644 --- a/aries_vcx/src/protocols/connection/inviter/states/mod.rs +++ b/aries_vcx/src/protocols/connection/inviter/states/mod.rs @@ -1,5 +1,3 @@ -pub(super) mod complete; -pub(super) mod initial; -pub(super) mod invited; -pub(super) mod requested; -pub(super) mod responded; +pub mod invited; +pub mod requested; +pub mod initial; \ No newline at end of file diff --git a/aries_vcx/src/protocols/connection/inviter/states/requested.rs b/aries_vcx/src/protocols/connection/inviter/states/requested.rs index 11772b957e..7134cbc34c 100644 --- a/aries_vcx/src/protocols/connection/inviter/states/requested.rs +++ b/aries_vcx/src/protocols/connection/inviter/states/requested.rs @@ -1,32 +1,35 @@ -use crate::protocols::connection::inviter::states::initial::InitialState; -use crate::protocols::connection::inviter::states::responded::RespondedState; -use messages::diddoc::aries::diddoc::AriesDidDoc; -use messages::protocols::connection::problem_report::ProblemReport; -use messages::protocols::connection::response::SignedResponse; +use messages::{diddoc::aries::diddoc::AriesDidDoc, protocols::connection::response::SignedResponse}; + +use crate::protocols::connection::traits::{TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct RequestedState { - pub signed_response: SignedResponse, - pub did_doc: AriesDidDoc, - pub thread_id: String, +pub struct Requested { + pub(crate) signed_response: SignedResponse, + pub(crate) did_doc: AriesDidDoc, } -impl From<(RequestedState, ProblemReport)> for InitialState { - fn from((_state, problem_report): (RequestedState, ProblemReport)) -> InitialState { - trace!( - "ConnectionInviter: transit state from RequestedState to InitialState, problem_report: {:?}", - problem_report - ); - InitialState::new(Some(problem_report)) +impl Requested { + pub fn new(signed_response: SignedResponse, did_doc: AriesDidDoc) -> Self { + Self { + signed_response, + did_doc, + } } } -impl From for RespondedState { - fn from(state: RequestedState) -> RespondedState { - trace!("ConnectionInviter: transit state from RequestedState to RespondedState"); - RespondedState { - signed_response: state.signed_response, - did_doc: state.did_doc, - } +impl TheirDidDoc for Requested { + fn their_did_doc(&self) -> &AriesDidDoc { + &self.did_doc + } +} + +impl ThreadId for Requested { + //TODO: This should land in the threadlike macro. + fn thread_id(&self) -> &str { + self.signed_response + .thread + .thid + .as_deref() + .unwrap_or(&self.signed_response.id.0) } } diff --git a/aries_vcx/src/protocols/connection/mod.rs b/aries_vcx/src/protocols/connection/mod.rs index 83222afec8..517c644547 100644 --- a/aries_vcx/src/protocols/connection/mod.rs +++ b/aries_vcx/src/protocols/connection/mod.rs @@ -1,3 +1,186 @@ +pub mod common; +mod generic; +pub mod initiation_type; pub mod invitee; pub mod inviter; pub mod pairwise_info; +mod serializable; +mod traits; + +use messages::{ + a2a::{protocol_registry::ProtocolRegistry, A2AMessage}, + diddoc::aries::diddoc::AriesDidDoc, + protocols::{ + connection::problem_report::{ProblemCode, ProblemReport}, + discovery::disclose::{Disclose, ProtocolDescriptor}, + }, +}; +use std::{error::Error, sync::Arc}; + +use crate::{ + errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult}, + plugins::wallet::base_wallet::BaseWallet, + utils::encryption_envelope::EncryptionEnvelope, +}; + +use self::{ + common::states::complete::CompleteState, + generic::GenericState, + pairwise_info::PairwiseInfo, + traits::{HandleProblem, TheirDidDoc, ThreadId}, +}; + +pub use self::generic::{GenericConnection, State, ThinState}; +pub use self::traits::Transport; + +#[derive(Clone, Deserialize)] +#[serde(try_from = "GenericConnection")] +#[serde(bound = "(I, S): TryFrom")] +pub struct Connection { + source_id: String, + pairwise_info: PairwiseInfo, + initiation_type: I, + state: S, +} + +impl Connection { + pub(crate) fn from_parts(source_id: String, pairwise_info: PairwiseInfo, initiation_type: I, state: S) -> Self { + Self { + source_id, + pairwise_info, + initiation_type, + state, + } + } + + pub fn pairwise_info(&self) -> &PairwiseInfo { + &self.pairwise_info + } + + pub fn source_id(&self) -> &str { + &self.source_id + } + + pub fn protocols(&self) -> Vec { + ProtocolRegistry::init().protocols() + } +} + +impl Connection +where + S: ThreadId, +{ + pub fn thread_id(&self) -> &str { + self.state.thread_id() + } +} + +impl Connection +where + S: TheirDidDoc, +{ + pub fn their_did_doc(&self) -> &AriesDidDoc { + self.state.their_did_doc() + } + + pub fn remote_did(&self) -> &str { + &self.their_did_doc().id + } + + pub fn remote_vk(&self) -> VcxResult { + self.their_did_doc() + .recipient_keys()? + .first() + .map(ToOwned::to_owned) + .ok_or(AriesVcxError::from_msg( + AriesVcxErrorKind::NotReady, + "Can't resolve recipient key from the counterparty diddoc.", + )) + } + + pub async fn send_message( + &self, + wallet: &Arc, + message: &A2AMessage, + transport: &T, + ) -> VcxResult<()> + where + T: Transport, + { + let sender_verkey = &self.pairwise_info().pw_vk; + let did_doc = self.their_did_doc(); + basic_send_message(wallet, message, sender_verkey, did_doc, transport).await + } +} + +impl Connection +where + S: HandleProblem, +{ + fn create_problem_report(&self, err: &E, thread_id: &str) -> ProblemReport + where + E: Error, + { + ProblemReport::create() + .set_problem_code(ProblemCode::RequestProcessingError) + .set_explain(err.to_string()) + .set_thread_id(thread_id) + .set_out_time() + } + + async fn send_problem_report( + &self, + wallet: &Arc, + err: &E, + thread_id: &str, + did_doc: &AriesDidDoc, + transport: &T, + ) where + E: Error, + T: Transport, + { + let sender_verkey = &self.pairwise_info().pw_vk; + let problem_report = self.create_problem_report(err, thread_id); + let res = basic_send_message( + wallet, + &problem_report.to_a2a_message(), + sender_verkey, + did_doc, + transport, + ) + .await; + + if let Err(e) = res { + trace!("Error encountered when sending ProblemReport: {}", e); + } else { + info!("Error report sent!"); + } + } +} + +impl Connection { + pub fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { + self.state.remote_protocols() + } + + pub fn handle_disclose(&mut self, disclose: Disclose) { + self.state.handle_disclose(disclose) + } +} + +pub(crate) async fn basic_send_message( + wallet: &Arc, + message: &A2AMessage, + sender_verkey: &str, + did_doc: &AriesDidDoc, + transport: &T, +) -> VcxResult<()> +where + T: Transport, +{ + let env = EncryptionEnvelope::create(wallet, message, Some(sender_verkey), did_doc).await?; + let msg = env.0; + let service_endpoint = did_doc.get_endpoint(); // This, like many other things, shouldn't clone... + + transport.send_message(msg, &service_endpoint).await +} diff --git a/aries_vcx/src/protocols/typestate_con/serializable.rs b/aries_vcx/src/protocols/connection/serializable.rs similarity index 99% rename from aries_vcx/src/protocols/typestate_con/serializable.rs rename to aries_vcx/src/protocols/connection/serializable.rs index ca6f899b8f..0baf17610e 100644 --- a/aries_vcx/src/protocols/typestate_con/serializable.rs +++ b/aries_vcx/src/protocols/connection/serializable.rs @@ -1,6 +1,6 @@ use serde::Serialize; -use crate::protocols::typestate_con::{ +use crate::protocols::connection::{ common::states::{complete::CompleteState, responded::RespondedState}, initiation_type::{Invitee, Inviter}, invitee::states::{ diff --git a/aries_vcx/src/protocols/typestate_con/traits.rs b/aries_vcx/src/protocols/connection/traits.rs similarity index 100% rename from aries_vcx/src/protocols/typestate_con/traits.rs rename to aries_vcx/src/protocols/connection/traits.rs diff --git a/aries_vcx/src/protocols/mediated_connection/invitee/mod.rs b/aries_vcx/src/protocols/mediated_connection/invitee/mod.rs new file mode 100644 index 0000000000..6b37a228b6 --- /dev/null +++ b/aries_vcx/src/protocols/mediated_connection/invitee/mod.rs @@ -0,0 +1,2 @@ +pub mod state_machine; +mod states; diff --git a/aries_vcx/src/protocols/connection/invitee/state_machine.rs b/aries_vcx/src/protocols/mediated_connection/invitee/state_machine.rs similarity index 98% rename from aries_vcx/src/protocols/connection/invitee/state_machine.rs rename to aries_vcx/src/protocols/mediated_connection/invitee/state_machine.rs index 18d304a3f0..fd65509e3b 100644 --- a/aries_vcx/src/protocols/connection/invitee/state_machine.rs +++ b/aries_vcx/src/protocols/mediated_connection/invitee/state_machine.rs @@ -6,12 +6,12 @@ use crate::common::signing::decode_signed_connection_response; use crate::errors::error::prelude::*; use crate::handlers::util::verify_thread_id; use crate::plugins::wallet::base_wallet::BaseWallet; -use crate::protocols::connection::invitee::states::complete::CompleteState; -use crate::protocols::connection::invitee::states::initial::InitialState; -use crate::protocols::connection::invitee::states::invited::InvitedState; -use crate::protocols::connection::invitee::states::requested::RequestedState; -use crate::protocols::connection::invitee::states::responded::RespondedState; -use crate::protocols::connection::pairwise_info::PairwiseInfo; +use crate::protocols::mediated_connection::invitee::states::complete::CompleteState; +use crate::protocols::mediated_connection::invitee::states::initial::InitialState; +use crate::protocols::mediated_connection::invitee::states::invited::InvitedState; +use crate::protocols::mediated_connection::invitee::states::requested::RequestedState; +use crate::protocols::mediated_connection::invitee::states::responded::RespondedState; +use crate::protocols::mediated_connection::pairwise_info::PairwiseInfo; use crate::protocols::SendClosureConnection; use messages::a2a::protocol_registry::ProtocolRegistry; use messages::a2a::A2AMessage; diff --git a/aries_vcx/src/protocols/connection/invitee/states/complete.rs b/aries_vcx/src/protocols/mediated_connection/invitee/states/complete.rs similarity index 90% rename from aries_vcx/src/protocols/connection/invitee/states/complete.rs rename to aries_vcx/src/protocols/mediated_connection/invitee/states/complete.rs index fed457c333..e162121deb 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/complete.rs +++ b/aries_vcx/src/protocols/mediated_connection/invitee/states/complete.rs @@ -1,7 +1,7 @@ use std::clone::Clone; -use crate::protocols::connection::invitee::states::requested::RequestedState; -use crate::protocols::connection::invitee::states::responded::RespondedState; +use crate::protocols::mediated_connection::invitee::states::requested::RequestedState; +use crate::protocols::mediated_connection::invitee::states::responded::RespondedState; use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::connection::response::Response; use messages::protocols::discovery::disclose::ProtocolDescriptor; diff --git a/aries_vcx/src/protocols/mediated_connection/invitee/states/initial.rs b/aries_vcx/src/protocols/mediated_connection/invitee/states/initial.rs new file mode 100644 index 0000000000..14438d8145 --- /dev/null +++ b/aries_vcx/src/protocols/mediated_connection/invitee/states/initial.rs @@ -0,0 +1,26 @@ +use crate::protocols::mediated_connection::invitee::states::invited::InvitedState; +use messages::diddoc::aries::diddoc::AriesDidDoc; +use messages::protocols::connection::invite::Invitation; +use messages::protocols::connection::problem_report::ProblemReport; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct InitialState { + problem_report: Option, + pub did_doc: Option, +} + +impl From<(InitialState, Invitation, AriesDidDoc)> for InvitedState { + fn from((_state, invitation, did_doc): (InitialState, Invitation, AriesDidDoc)) -> InvitedState { + trace!("ConnectionInvitee: transit state from InitialState to InvitedState"); + InvitedState { invitation, did_doc } + } +} + +impl InitialState { + pub fn new(problem_report: Option, did_doc: Option) -> Self { + InitialState { + problem_report, + did_doc, + } + } +} diff --git a/aries_vcx/src/protocols/mediated_connection/invitee/states/invited.rs b/aries_vcx/src/protocols/mediated_connection/invitee/states/invited.rs new file mode 100644 index 0000000000..e1b0a95db1 --- /dev/null +++ b/aries_vcx/src/protocols/mediated_connection/invitee/states/invited.rs @@ -0,0 +1,17 @@ +use crate::protocols::mediated_connection::invitee::states::requested::RequestedState; +use messages::diddoc::aries::diddoc::AriesDidDoc; +use messages::protocols::connection::invite::Invitation; +use messages::protocols::connection::request::Request; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct InvitedState { + pub invitation: Invitation, + pub did_doc: AriesDidDoc, +} + +impl From<(InvitedState, Request, AriesDidDoc)> for RequestedState { + fn from((_state, request, did_doc): (InvitedState, Request, AriesDidDoc)) -> RequestedState { + trace!("ConnectionInvitee: transit state from InvitedState to RequestedState"); + RequestedState { request, did_doc } + } +} diff --git a/aries_vcx/src/protocols/mediated_connection/invitee/states/mod.rs b/aries_vcx/src/protocols/mediated_connection/invitee/states/mod.rs new file mode 100644 index 0000000000..2c1b5a715f --- /dev/null +++ b/aries_vcx/src/protocols/mediated_connection/invitee/states/mod.rs @@ -0,0 +1,5 @@ +pub(super) mod complete; +pub(super) mod initial; +pub(super) mod invited; +pub(super) mod requested; +pub(super) mod responded; diff --git a/aries_vcx/src/protocols/mediated_connection/invitee/states/requested.rs b/aries_vcx/src/protocols/mediated_connection/invitee/states/requested.rs new file mode 100644 index 0000000000..328540982e --- /dev/null +++ b/aries_vcx/src/protocols/mediated_connection/invitee/states/requested.rs @@ -0,0 +1,33 @@ +use crate::protocols::mediated_connection::invitee::states::initial::InitialState; +use crate::protocols::mediated_connection::invitee::states::responded::RespondedState; +use messages::diddoc::aries::diddoc::AriesDidDoc; +use messages::protocols::connection::problem_report::ProblemReport; +use messages::protocols::connection::request::Request; +use messages::protocols::connection::response::Response; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct RequestedState { + pub request: Request, + pub did_doc: AriesDidDoc, +} + +impl From<(RequestedState, ProblemReport)> for InitialState { + fn from((_state, problem_report): (RequestedState, ProblemReport)) -> InitialState { + trace!( + "ConnectionInvitee: transit state from RequestedState to InitialState, problem_report: {:?}", + problem_report + ); + InitialState::new(Some(problem_report), None) + } +} + +impl From<(RequestedState, Response)> for RespondedState { + fn from((state, response): (RequestedState, Response)) -> RespondedState { + trace!("ConnectionInvitee: transit state from RequestedState to RespondedState"); + RespondedState { + response, + did_doc: state.did_doc, + request: state.request, + } + } +} diff --git a/aries_vcx/src/protocols/connection/invitee/states/responded.rs b/aries_vcx/src/protocols/mediated_connection/invitee/states/responded.rs similarity index 90% rename from aries_vcx/src/protocols/connection/invitee/states/responded.rs rename to aries_vcx/src/protocols/mediated_connection/invitee/states/responded.rs index 9d3e2bc28a..6c22664028 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/responded.rs +++ b/aries_vcx/src/protocols/mediated_connection/invitee/states/responded.rs @@ -1,4 +1,4 @@ -use crate::protocols::connection::invitee::states::initial::InitialState; +use crate::protocols::mediated_connection::invitee::states::initial::InitialState; use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::connection::problem_report::ProblemReport; use messages::protocols::connection::request::Request; diff --git a/aries_vcx/src/protocols/mediated_connection/inviter/mod.rs b/aries_vcx/src/protocols/mediated_connection/inviter/mod.rs new file mode 100644 index 0000000000..6b37a228b6 --- /dev/null +++ b/aries_vcx/src/protocols/mediated_connection/inviter/mod.rs @@ -0,0 +1,2 @@ +pub mod state_machine; +mod states; diff --git a/aries_vcx/src/protocols/connection/inviter/state_machine.rs b/aries_vcx/src/protocols/mediated_connection/inviter/state_machine.rs similarity index 98% rename from aries_vcx/src/protocols/connection/inviter/state_machine.rs rename to aries_vcx/src/protocols/mediated_connection/inviter/state_machine.rs index 89fe3e6d64..0c0c9a2c0f 100644 --- a/aries_vcx/src/protocols/connection/inviter/state_machine.rs +++ b/aries_vcx/src/protocols/mediated_connection/inviter/state_machine.rs @@ -15,12 +15,12 @@ use crate::common::signing::sign_connection_response; use crate::errors::error::prelude::*; use crate::handlers::util::verify_thread_id; use crate::plugins::wallet::base_wallet::BaseWallet; -use crate::protocols::connection::inviter::states::complete::CompleteState; -use crate::protocols::connection::inviter::states::initial::InitialState; -use crate::protocols::connection::inviter::states::invited::InvitedState; -use crate::protocols::connection::inviter::states::requested::RequestedState; -use crate::protocols::connection::inviter::states::responded::RespondedState; -use crate::protocols::connection::pairwise_info::PairwiseInfo; +use crate::protocols::mediated_connection::inviter::states::complete::CompleteState; +use crate::protocols::mediated_connection::inviter::states::initial::InitialState; +use crate::protocols::mediated_connection::inviter::states::invited::InvitedState; +use crate::protocols::mediated_connection::inviter::states::requested::RequestedState; +use crate::protocols::mediated_connection::inviter::states::responded::RespondedState; +use crate::protocols::mediated_connection::pairwise_info::PairwiseInfo; use crate::protocols::SendClosureConnection; #[derive(Clone, Serialize, Deserialize)] diff --git a/aries_vcx/src/protocols/connection/inviter/states/complete.rs b/aries_vcx/src/protocols/mediated_connection/inviter/states/complete.rs similarity index 100% rename from aries_vcx/src/protocols/connection/inviter/states/complete.rs rename to aries_vcx/src/protocols/mediated_connection/inviter/states/complete.rs diff --git a/aries_vcx/src/protocols/mediated_connection/inviter/states/initial.rs b/aries_vcx/src/protocols/mediated_connection/inviter/states/initial.rs new file mode 100644 index 0000000000..3db73379be --- /dev/null +++ b/aries_vcx/src/protocols/mediated_connection/inviter/states/initial.rs @@ -0,0 +1,21 @@ +use crate::protocols::mediated_connection::inviter::states::invited::InvitedState; +use messages::protocols::connection::invite::Invitation; +use messages::protocols::connection::problem_report::ProblemReport; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct InitialState { + problem_report: Option, +} + +impl From<(InitialState, Invitation)> for InvitedState { + fn from((_state, invitation): (InitialState, Invitation)) -> InvitedState { + trace!("ConnectionInviter: transit state from InitialState to InvitedState"); + InvitedState { invitation } + } +} + +impl InitialState { + pub fn new(problem_report: Option) -> Self { + InitialState { problem_report } + } +} diff --git a/aries_vcx/src/protocols/mediated_connection/inviter/states/invited.rs b/aries_vcx/src/protocols/mediated_connection/inviter/states/invited.rs new file mode 100644 index 0000000000..ad52645362 --- /dev/null +++ b/aries_vcx/src/protocols/mediated_connection/inviter/states/invited.rs @@ -0,0 +1,33 @@ +use crate::protocols::mediated_connection::inviter::states::initial::InitialState; +use crate::protocols::mediated_connection::inviter::states::requested::RequestedState; +use messages::protocols::connection::invite::Invitation; +use messages::protocols::connection::problem_report::ProblemReport; +use messages::protocols::connection::request::Request; +use messages::protocols::connection::response::SignedResponse; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct InvitedState { + pub invitation: Invitation, +} + +// TODO: These have no justification for being here anymore +impl From for InitialState { + fn from(problem_report: ProblemReport) -> InitialState { + trace!( + "ConnectionInviter: transit state to InitialState, problem_report: {:?}", + problem_report + ); + InitialState::new(Some(problem_report)) + } +} + +impl From<(Request, SignedResponse)> for RequestedState { + fn from((request, signed_response): (Request, SignedResponse)) -> RequestedState { + trace!("ConnectionInviter: transit state to RespondedState"); + RequestedState { + signed_response, + did_doc: request.connection.did_doc, + thread_id: request.id.0, + } + } +} diff --git a/aries_vcx/src/protocols/mediated_connection/inviter/states/mod.rs b/aries_vcx/src/protocols/mediated_connection/inviter/states/mod.rs new file mode 100644 index 0000000000..2c1b5a715f --- /dev/null +++ b/aries_vcx/src/protocols/mediated_connection/inviter/states/mod.rs @@ -0,0 +1,5 @@ +pub(super) mod complete; +pub(super) mod initial; +pub(super) mod invited; +pub(super) mod requested; +pub(super) mod responded; diff --git a/aries_vcx/src/protocols/mediated_connection/inviter/states/requested.rs b/aries_vcx/src/protocols/mediated_connection/inviter/states/requested.rs new file mode 100644 index 0000000000..74985b0c1f --- /dev/null +++ b/aries_vcx/src/protocols/mediated_connection/inviter/states/requested.rs @@ -0,0 +1,32 @@ +use crate::protocols::mediated_connection::inviter::states::initial::InitialState; +use crate::protocols::mediated_connection::inviter::states::responded::RespondedState; +use messages::diddoc::aries::diddoc::AriesDidDoc; +use messages::protocols::connection::problem_report::ProblemReport; +use messages::protocols::connection::response::SignedResponse; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct RequestedState { + pub signed_response: SignedResponse, + pub did_doc: AriesDidDoc, + pub thread_id: String, +} + +impl From<(RequestedState, ProblemReport)> for InitialState { + fn from((_state, problem_report): (RequestedState, ProblemReport)) -> InitialState { + trace!( + "ConnectionInviter: transit state from RequestedState to InitialState, problem_report: {:?}", + problem_report + ); + InitialState::new(Some(problem_report)) + } +} + +impl From for RespondedState { + fn from(state: RequestedState) -> RespondedState { + trace!("ConnectionInviter: transit state from RequestedState to RespondedState"); + RespondedState { + signed_response: state.signed_response, + did_doc: state.did_doc, + } + } +} diff --git a/aries_vcx/src/protocols/connection/inviter/states/responded.rs b/aries_vcx/src/protocols/mediated_connection/inviter/states/responded.rs similarity index 86% rename from aries_vcx/src/protocols/connection/inviter/states/responded.rs rename to aries_vcx/src/protocols/mediated_connection/inviter/states/responded.rs index 397eb3110d..f166d08e99 100644 --- a/aries_vcx/src/protocols/connection/inviter/states/responded.rs +++ b/aries_vcx/src/protocols/mediated_connection/inviter/states/responded.rs @@ -5,8 +5,8 @@ use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::connection::problem_report::ProblemReport; use messages::protocols::connection::response::SignedResponse; -use crate::protocols::connection::inviter::states::complete::CompleteState; -use crate::protocols::connection::inviter::states::initial::InitialState; +use crate::protocols::mediated_connection::inviter::states::complete::CompleteState; +use crate::protocols::mediated_connection::inviter::states::initial::InitialState; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct RespondedState { diff --git a/aries_vcx/src/protocols/mediated_connection/mod.rs b/aries_vcx/src/protocols/mediated_connection/mod.rs new file mode 100644 index 0000000000..83222afec8 --- /dev/null +++ b/aries_vcx/src/protocols/mediated_connection/mod.rs @@ -0,0 +1,3 @@ +pub mod invitee; +pub mod inviter; +pub mod pairwise_info; diff --git a/aries_vcx/src/protocols/typestate_con/pairwise_info.rs b/aries_vcx/src/protocols/mediated_connection/pairwise_info.rs similarity index 100% rename from aries_vcx/src/protocols/typestate_con/pairwise_info.rs rename to aries_vcx/src/protocols/mediated_connection/pairwise_info.rs diff --git a/aries_vcx/src/protocols/mod.rs b/aries_vcx/src/protocols/mod.rs index 49693fb554..85fe22ae26 100644 --- a/aries_vcx/src/protocols/mod.rs +++ b/aries_vcx/src/protocols/mod.rs @@ -5,13 +5,13 @@ use messages::diddoc::aries::diddoc::AriesDidDoc; use crate::errors::error::VcxResult; pub mod common; -pub mod connection; +pub mod mediated_connection; pub mod issuance; pub mod oob; pub mod proof_presentation; pub mod revocation_notification; pub mod trustping; -pub mod typestate_con; +pub mod connection; pub type SendClosure = Box BoxFuture<'static, VcxResult<()>> + Send + Sync>; pub type SendClosureConnection = diff --git a/aries_vcx/src/protocols/typestate_con/invitee/mod.rs b/aries_vcx/src/protocols/typestate_con/invitee/mod.rs deleted file mode 100644 index 07ee6f0f76..0000000000 --- a/aries_vcx/src/protocols/typestate_con/invitee/mod.rs +++ /dev/null @@ -1,189 +0,0 @@ -pub mod states; - -use std::sync::Arc; - -use messages::protocols::connection::invite::Invitation; - -use crate::{common::ledger::transactions::into_did_doc, core::profile::profile::Profile, errors::error::VcxResult}; - -use self::states::{initial::Initial, invited::Invited, requested::Requested}; - -use messages::{ - a2a::A2AMessage, - concepts::ack::Ack, - protocols::connection::{request::Request, response::SignedResponse}, -}; - -use super::{ - common::states::{complete::CompleteState, responded::RespondedState}, - initiation_type::Invitee, - pairwise_info::PairwiseInfo, - traits::Transport, - Connection, -}; -use crate::{ - common::signing::decode_signed_connection_response, - errors::error::{AriesVcxError, AriesVcxErrorKind}, - handlers::util::verify_thread_id, - plugins::wallet::base_wallet::BaseWallet, -}; - -/// Convenience alias -pub type InviteeConnection = Connection; - -impl InviteeConnection { - pub fn new_invitee(source_id: String, pairwise_info: PairwiseInfo) -> Self { - Self { - source_id, - state: Initial, - pairwise_info, - initiation_type: Invitee, - } - } - - pub async fn accept_invitation( - self, - profile: &Arc, - invitation: &Invitation, - ) -> VcxResult> { - trace!("Connection::into_invited >>> invitation: {:?}", &invitation); - - let thread_id = invitation.get_id().to_owned(); - let did_doc = into_did_doc(profile, invitation).await?; - let state = Invited { did_doc, thread_id }; - - // Convert to `InvitedState` - Ok(Connection { - state, - source_id: self.source_id, - pairwise_info: self.pairwise_info, - initiation_type: Invitee, - }) - } -} - -impl InviteeConnection { - pub async fn send_request( - self, - wallet: &Arc, - service_endpoint: String, - routing_keys: Vec, - transport: &T, - ) -> VcxResult> - where - T: Transport, - { - trace!("Connection::send_request"); - - let recipient_keys = vec![self.pairwise_info.pw_vk.clone()]; - - let request = Request::create() - .set_label(self.source_id.to_string()) - .set_did(self.pairwise_info.pw_did.to_string()) - .set_service_endpoint(service_endpoint) - .set_keys(recipient_keys, routing_keys) - .set_out_time(); - - // Should be properly retrieved from Invitation. - // Also there's if this Request will just be serialized, it might as well take references. - let request = request.set_parent_thread_id(&self.state.thread_id); - - // The Invitation gets lost along the way when converting from Invited to Requested - // in previous implementations. Apart from these thread ID's, it's not used at all. - // - // Might as well implement it properly when accepting an Invitation in the `into_invited` method. - // - // let request_id = request.id.0.clone(); - // - // let (request, thread_id) = match &self.state.invitation { - // Invitation::Public(_) => ( - // request - // .set_parent_thread_id(&self.thread_id) - // .set_thread_id_matching_id(), - // request_id, - // ), - // Invitation::Pairwise(_) => (request.set_thread_id(&self.thread_id), self.thread_id().to_owned()), - // Invitation::OutOfBand(invite) => ( - // request.set_parent_thread_id(&invite.id.0).set_thread_id_matching_id(), - // request_id, - // ), - // }; - - self.send_message(wallet, &request.to_a2a_message(), transport).await?; - - Ok(Connection { - state: Requested::new(self.state.did_doc, self.state.thread_id), - source_id: self.source_id, - pairwise_info: self.pairwise_info, - initiation_type: Invitee, - }) - } -} - -impl InviteeConnection { - pub async fn handle_response( - self, - wallet: &Arc, - response: SignedResponse, - transport: &T, - ) -> VcxResult> - where - T: Transport, - { - verify_thread_id(&self.state.thread_id, &A2AMessage::ConnectionResponse(response.clone()))?; - - let keys = &self.state.did_doc.recipient_keys()?; - let their_vk = keys.first().ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidState, - "Cannot handle response: remote verkey not found", - ))?; - - let did_doc = match decode_signed_connection_response(wallet, response, their_vk).await { - Ok(response) => Ok(response.connection.did_doc), - Err(err) => { - error!("Request DidDoc validation failed! Sending ProblemReport..."); - - self.send_problem_report(wallet, &err, self.thread_id(), &self.state.did_doc, transport) - .await; - - Err(err) - } - }?; - - let state = RespondedState::new(did_doc, self.state.thread_id); - - Ok(Connection { - state, - source_id: self.source_id, - pairwise_info: self.pairwise_info, - initiation_type: Invitee, - }) - } -} - -impl InviteeConnection { - pub async fn send_ack( - self, - wallet: &Arc, - transport: &T, - ) -> VcxResult> - where - T: Transport, - { - let msg = Ack::create() - .set_out_time() - .set_thread_id(&self.state.thread_id) - .to_a2a_message(); - - self.send_message(wallet, &msg, transport).await?; - - let state = CompleteState::new(self.state.did_doc, self.state.thread_id, None); - - Ok(Connection { - state, - source_id: self.source_id, - pairwise_info: self.pairwise_info, - initiation_type: Invitee, - }) - } -} diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/initial.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/initial.rs deleted file mode 100644 index 3bebf35de9..0000000000 --- a/aries_vcx/src/protocols/typestate_con/invitee/states/initial.rs +++ /dev/null @@ -1,2 +0,0 @@ -#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq)] -pub struct Initial; diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs deleted file mode 100644 index abb7e62533..0000000000 --- a/aries_vcx/src/protocols/typestate_con/invitee/states/invited.rs +++ /dev/null @@ -1,27 +0,0 @@ -use messages::diddoc::aries::diddoc::AriesDidDoc; - -use crate::protocols::typestate_con::traits::{TheirDidDoc, ThreadId}; - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct Invited { - pub(crate) did_doc: AriesDidDoc, - pub(crate) thread_id: String, -} - -impl Invited { - pub fn new(did_doc: AriesDidDoc, thread_id: String) -> Self { - Self { did_doc, thread_id } - } -} - -impl TheirDidDoc for Invited { - fn their_did_doc(&self) -> &AriesDidDoc { - &self.did_doc - } -} - -impl ThreadId for Invited { - fn thread_id(&self) -> &str { - &self.thread_id - } -} diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/mod.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/mod.rs deleted file mode 100644 index d4151d969c..0000000000 --- a/aries_vcx/src/protocols/typestate_con/invitee/states/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod invited; -pub mod requested; -pub mod initial; \ No newline at end of file diff --git a/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs b/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs deleted file mode 100644 index 61311ec216..0000000000 --- a/aries_vcx/src/protocols/typestate_con/invitee/states/requested.rs +++ /dev/null @@ -1,29 +0,0 @@ -use messages::diddoc::aries::diddoc::AriesDidDoc; - -use crate::protocols::typestate_con::traits::{HandleProblem, TheirDidDoc, ThreadId}; - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct Requested { - pub(crate) did_doc: AriesDidDoc, - pub(crate) thread_id: String, -} - -impl Requested { - pub fn new(did_doc: AriesDidDoc, thread_id: String) -> Self { - Self { did_doc, thread_id } - } -} - -impl TheirDidDoc for Requested { - fn their_did_doc(&self) -> &AriesDidDoc { - &self.did_doc - } -} - -impl ThreadId for Requested { - fn thread_id(&self) -> &str { - &self.thread_id - } -} - -impl HandleProblem for Requested {} diff --git a/aries_vcx/src/protocols/typestate_con/inviter/mod.rs b/aries_vcx/src/protocols/typestate_con/inviter/mod.rs deleted file mode 100644 index cc055475b0..0000000000 --- a/aries_vcx/src/protocols/typestate_con/inviter/mod.rs +++ /dev/null @@ -1,211 +0,0 @@ -pub mod states; - -use std::sync::Arc; - -use crate::handlers::util::verify_thread_id; -use crate::utils::uuid; -use crate::{ - common::signing::sign_connection_response, errors::error::VcxResult, plugins::wallet::base_wallet::BaseWallet, -}; - -use self::states::initial::Initial; -use self::states::{invited::Invited, requested::Requested}; -use super::common::states::complete::CompleteState; -use super::common::states::responded::RespondedState; -use super::traits::Transport; -use super::{initiation_type::Inviter, pairwise_info::PairwiseInfo, Connection}; -use messages::a2a::A2AMessage; -use messages::protocols::connection::invite::PairwiseInvitation; -use messages::protocols::connection::{ - invite::Invitation, - request::Request, - response::{Response, SignedResponse}, -}; - -pub type InviterConnection = Connection; - -impl InviterConnection { - pub fn new_inviter( - source_id: String, - pairwise_info: PairwiseInfo, - routing_keys: Vec, - service_endpoint: String, - ) -> Self { - let invite: PairwiseInvitation = PairwiseInvitation::create() - .set_id(&uuid::uuid()) - .set_label(&source_id) - .set_recipient_keys(vec![pairwise_info.pw_vk.clone()]) - .set_routing_keys(routing_keys) - .set_service_endpoint(service_endpoint); - - let invitation = Invitation::Pairwise(invite); - - Self { - source_id, - state: Initial::new(invitation), - pairwise_info, - initiation_type: Inviter, - } - } - - pub fn get_invitation(&self) -> &Invitation { - &self.state.invitation - } -} - -impl InviterConnection { - /// Creates an [`InviterConnection`], essentially bypassing the [`InitialState`] - /// where an [`Invitation`] is created. - /// - /// This is useful for cases where an [`Invitation`] is received by the invitee without - /// any interaction from the inviter, thus the next logical step is to wait for the invitee - /// to send a connection request. - pub fn new_awaiting_request(source_id: String, pairwise_info: PairwiseInfo) -> Self { - Self { - source_id, - state: Invited::new(None), // what should the thread ID be in this case??? - pairwise_info, - initiation_type: Inviter, - } - } - - /// As the inviter connection can be started directly in the invited state, - /// like with a public invitation, we might or might not have a thread ID. - pub fn opt_thread_id(&self) -> Option<&str> { - self.state.opt_thread_id() - } - - // This should ideally belong in the Connection - // but was placed here to retro-fit the previous API. - async fn build_response( - &self, - wallet: &Arc, - request: &Request, - new_pairwise_info: &PairwiseInfo, - new_service_endpoint: String, - new_routing_keys: Vec, - ) -> VcxResult { - let new_recipient_keys = vec![new_pairwise_info.pw_vk.clone()]; - let response = Response::create() - .set_did(new_pairwise_info.pw_did.to_string()) - .set_service_endpoint(new_service_endpoint) - .set_keys(new_recipient_keys, new_routing_keys) - .ask_for_ack() - .set_thread_id(&request.get_thread_id()) - .set_out_time(); - - sign_connection_response(wallet, &self.pairwise_info.pw_vk, response).await - } - - // Due to backwards compatibility, we generate the signed response and store that in the state. - // However, it would be more efficient to store the request and postpone the response generation and - // signing until the next state, thus taking advantage of the request attributes and avoiding cloning the DidDoc. - pub async fn handle_request( - self, - wallet: &Arc, - request: Request, - new_service_endpoint: String, - new_routing_keys: Vec, - transport: &T, - ) -> VcxResult> - where - T: Transport, - { - trace!( - "Connection::process_request >>> request: {:?}, service_endpoint: {}, routing_keys: {:?}", - request, - new_service_endpoint, - new_routing_keys, - ); - - // There must be some other way to validate the thread ID other than cloning the entire Request - self.state - .thread_id - .as_ref() - .map(|thread_id| verify_thread_id(thread_id, &A2AMessage::ConnectionRequest(request.clone()))) - .unwrap_or(Ok(()))?; - - // If the request's DidDoc validation fails, we generate and send a ProblemReport. - // We then return early with the provided error. - if let Err(err) = request.connection.did_doc.validate() { - error!("Request DidDoc validation failed! Sending ProblemReport..."); - - self.send_problem_report( - wallet, - &err, - &request.get_thread_id(), - &request.connection.did_doc, - transport, - ) - .await; - - Err(err)?; - } - - let new_pairwise_info = PairwiseInfo::create(wallet).await?; - let did_doc = request.connection.did_doc.clone(); - - let signed_response = self - .build_response( - wallet, - &request, - &new_pairwise_info, - new_service_endpoint, - new_routing_keys, - ) - .await?; - - let state = Requested::new(signed_response, did_doc); - - Ok(Connection { - source_id: self.source_id, - pairwise_info: new_pairwise_info, - initiation_type: self.initiation_type, - state, - }) - } -} - -impl InviterConnection { - pub async fn send_response( - self, - wallet: &Arc, - transport: &T, - ) -> VcxResult> - where - T: Transport, - { - trace!( - "Connection::send_response >>> signed_response: {:?}", - &self.state.signed_response - ); - - let thread_id = self.state.signed_response.get_thread_id(); - - self.send_message(wallet, &self.state.signed_response.to_a2a_message(), transport) - .await?; - - let state = RespondedState::new(self.state.did_doc, thread_id); - - Ok(Connection { - state, - source_id: self.source_id, - pairwise_info: self.pairwise_info, - initiation_type: self.initiation_type, - }) - } -} - -impl InviterConnection { - pub fn acknowledge_connection(self, msg: &A2AMessage) -> VcxResult> { - verify_thread_id(&self.state.thread_id, msg)?; - let state = CompleteState::new(self.state.did_doc, self.state.thread_id, None); - - Ok(Connection { - source_id: self.source_id, - pairwise_info: self.pairwise_info, - initiation_type: self.initiation_type, - state, - }) - } -} diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/initial.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/initial.rs deleted file mode 100644 index 2445e01398..0000000000 --- a/aries_vcx/src/protocols/typestate_con/inviter/states/initial.rs +++ /dev/null @@ -1,20 +0,0 @@ -use messages::protocols::connection::invite::Invitation; - -use crate::protocols::typestate_con::traits::ThreadId; - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct Initial { - pub(crate) invitation: Invitation, -} - -impl Initial { - pub fn new(invitation: Invitation) -> Self { - Self { invitation } - } -} - -impl ThreadId for Initial { - fn thread_id(&self) -> &str { - self.invitation.get_id() - } -} diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs deleted file mode 100644 index 8dc14f64d5..0000000000 --- a/aries_vcx/src/protocols/typestate_con/inviter/states/invited.rs +++ /dev/null @@ -1,20 +0,0 @@ -use crate::protocols::typestate_con::traits::HandleProblem; - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct Invited { - pub(crate) thread_id: Option, -} - -impl Invited { - pub fn new(thread_id: Option) -> Self { - Self { thread_id } - } - - /// Unlike other states, the ones implementing the [`crate::protocols::typestate_con::traits::ThreadId`], - /// this state may or may not have a thread ID, so we're returning an option. - pub fn opt_thread_id(&self) -> Option<&str> { - self.thread_id.as_deref() - } -} - -impl HandleProblem for Invited {} diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/mod.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/mod.rs deleted file mode 100644 index d4151d969c..0000000000 --- a/aries_vcx/src/protocols/typestate_con/inviter/states/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod invited; -pub mod requested; -pub mod initial; \ No newline at end of file diff --git a/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs b/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs deleted file mode 100644 index 36e55af461..0000000000 --- a/aries_vcx/src/protocols/typestate_con/inviter/states/requested.rs +++ /dev/null @@ -1,35 +0,0 @@ -use messages::{diddoc::aries::diddoc::AriesDidDoc, protocols::connection::response::SignedResponse}; - -use crate::protocols::typestate_con::traits::{TheirDidDoc, ThreadId}; - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct Requested { - pub(crate) signed_response: SignedResponse, - pub(crate) did_doc: AriesDidDoc, -} - -impl Requested { - pub fn new(signed_response: SignedResponse, did_doc: AriesDidDoc) -> Self { - Self { - signed_response, - did_doc, - } - } -} - -impl TheirDidDoc for Requested { - fn their_did_doc(&self) -> &AriesDidDoc { - &self.did_doc - } -} - -impl ThreadId for Requested { - //TODO: This should land in the threadlike macro. - fn thread_id(&self) -> &str { - self.signed_response - .thread - .thid - .as_deref() - .unwrap_or(&self.signed_response.id.0) - } -} diff --git a/aries_vcx/src/protocols/typestate_con/mod.rs b/aries_vcx/src/protocols/typestate_con/mod.rs deleted file mode 100644 index 517c644547..0000000000 --- a/aries_vcx/src/protocols/typestate_con/mod.rs +++ /dev/null @@ -1,186 +0,0 @@ -pub mod common; -mod generic; -pub mod initiation_type; -pub mod invitee; -pub mod inviter; -pub mod pairwise_info; -mod serializable; -mod traits; - -use messages::{ - a2a::{protocol_registry::ProtocolRegistry, A2AMessage}, - diddoc::aries::diddoc::AriesDidDoc, - protocols::{ - connection::problem_report::{ProblemCode, ProblemReport}, - discovery::disclose::{Disclose, ProtocolDescriptor}, - }, -}; -use std::{error::Error, sync::Arc}; - -use crate::{ - errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult}, - plugins::wallet::base_wallet::BaseWallet, - utils::encryption_envelope::EncryptionEnvelope, -}; - -use self::{ - common::states::complete::CompleteState, - generic::GenericState, - pairwise_info::PairwiseInfo, - traits::{HandleProblem, TheirDidDoc, ThreadId}, -}; - -pub use self::generic::{GenericConnection, State, ThinState}; -pub use self::traits::Transport; - -#[derive(Clone, Deserialize)] -#[serde(try_from = "GenericConnection")] -#[serde(bound = "(I, S): TryFrom")] -pub struct Connection { - source_id: String, - pairwise_info: PairwiseInfo, - initiation_type: I, - state: S, -} - -impl Connection { - pub(crate) fn from_parts(source_id: String, pairwise_info: PairwiseInfo, initiation_type: I, state: S) -> Self { - Self { - source_id, - pairwise_info, - initiation_type, - state, - } - } - - pub fn pairwise_info(&self) -> &PairwiseInfo { - &self.pairwise_info - } - - pub fn source_id(&self) -> &str { - &self.source_id - } - - pub fn protocols(&self) -> Vec { - ProtocolRegistry::init().protocols() - } -} - -impl Connection -where - S: ThreadId, -{ - pub fn thread_id(&self) -> &str { - self.state.thread_id() - } -} - -impl Connection -where - S: TheirDidDoc, -{ - pub fn their_did_doc(&self) -> &AriesDidDoc { - self.state.their_did_doc() - } - - pub fn remote_did(&self) -> &str { - &self.their_did_doc().id - } - - pub fn remote_vk(&self) -> VcxResult { - self.their_did_doc() - .recipient_keys()? - .first() - .map(ToOwned::to_owned) - .ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::NotReady, - "Can't resolve recipient key from the counterparty diddoc.", - )) - } - - pub async fn send_message( - &self, - wallet: &Arc, - message: &A2AMessage, - transport: &T, - ) -> VcxResult<()> - where - T: Transport, - { - let sender_verkey = &self.pairwise_info().pw_vk; - let did_doc = self.their_did_doc(); - basic_send_message(wallet, message, sender_verkey, did_doc, transport).await - } -} - -impl Connection -where - S: HandleProblem, -{ - fn create_problem_report(&self, err: &E, thread_id: &str) -> ProblemReport - where - E: Error, - { - ProblemReport::create() - .set_problem_code(ProblemCode::RequestProcessingError) - .set_explain(err.to_string()) - .set_thread_id(thread_id) - .set_out_time() - } - - async fn send_problem_report( - &self, - wallet: &Arc, - err: &E, - thread_id: &str, - did_doc: &AriesDidDoc, - transport: &T, - ) where - E: Error, - T: Transport, - { - let sender_verkey = &self.pairwise_info().pw_vk; - let problem_report = self.create_problem_report(err, thread_id); - let res = basic_send_message( - wallet, - &problem_report.to_a2a_message(), - sender_verkey, - did_doc, - transport, - ) - .await; - - if let Err(e) = res { - trace!("Error encountered when sending ProblemReport: {}", e); - } else { - info!("Error report sent!"); - } - } -} - -impl Connection { - pub fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { - self.state.remote_protocols() - } - - pub fn handle_disclose(&mut self, disclose: Disclose) { - self.state.handle_disclose(disclose) - } -} - -pub(crate) async fn basic_send_message( - wallet: &Arc, - message: &A2AMessage, - sender_verkey: &str, - did_doc: &AriesDidDoc, - transport: &T, -) -> VcxResult<()> -where - T: Transport, -{ - let env = EncryptionEnvelope::create(wallet, message, Some(sender_verkey), did_doc).await?; - let msg = env.0; - let service_endpoint = did_doc.get_endpoint(); // This, like many other things, shouldn't clone... - - transport.send_message(msg, &service_endpoint).await -} diff --git a/aries_vcx/tests/test_connection.rs b/aries_vcx/tests/test_connection.rs index 0f1b52b20d..d010d16082 100644 --- a/aries_vcx/tests/test_connection.rs +++ b/aries_vcx/tests/test_connection.rs @@ -16,7 +16,7 @@ mod integration_tests { use aries_vcx::handlers::out_of_band::sender::OutOfBandSender; use aries_vcx::messages::a2a::A2AMessage; use aries_vcx::messages::protocols::out_of_band::{GoalCode, HandshakeProtocol}; - use aries_vcx::protocols::connection::invitee::state_machine::InviteeState; + use aries_vcx::protocols::mediated_connection::invitee::state_machine::InviteeState; use aries_vcx::utils::devsetup::*; use aries_vcx::utils::mockdata::mockdata_proof::REQUESTED_ATTRIBUTES; use async_channel::bounded; diff --git a/aries_vcx/tests/utils/devsetup_agent.rs b/aries_vcx/tests/utils/devsetup_agent.rs index a71f8bad06..62e4420785 100644 --- a/aries_vcx/tests/utils/devsetup_agent.rs +++ b/aries_vcx/tests/utils/devsetup_agent.rs @@ -10,7 +10,7 @@ pub mod test_utils { use aries_vcx::handlers::revocation_notification::sender::RevocationNotificationSender; use aries_vcx::plugins::wallet::base_wallet::BaseWallet; use aries_vcx::plugins::wallet::indy_wallet::IndySdkWallet; - use aries_vcx::protocols::connection::pairwise_info::PairwiseInfo; + use aries_vcx::protocols::mediated_connection::pairwise_info::PairwiseInfo; use aries_vcx::protocols::revocation_notification::sender::state_machine::SenderConfigBuilder; use futures::future::BoxFuture; use messages::concepts::ack::please_ack::AckOn; @@ -48,8 +48,8 @@ pub mod test_utils { use aries_vcx::messages::protocols::issuance::credential_offer::CredentialOffer; use aries_vcx::messages::protocols::issuance::credential_offer::OfferInfo; use aries_vcx::messages::protocols::proof_presentation::presentation_request::PresentationRequest; - use aries_vcx::protocols::connection::invitee::state_machine::InviteeState; - use aries_vcx::protocols::connection::inviter::state_machine::InviterState; + use aries_vcx::protocols::mediated_connection::invitee::state_machine::InviteeState; + use aries_vcx::protocols::mediated_connection::inviter::state_machine::InviterState; use aries_vcx::protocols::issuance::holder::state_machine::HolderState; use aries_vcx::protocols::issuance::issuer::state_machine::IssuerState; use aries_vcx::protocols::proof_presentation::prover::state_machine::ProverState; diff --git a/aries_vcx/tests/utils/scenarios.rs b/aries_vcx/tests/utils/scenarios.rs index e500c16d96..c3104e674a 100644 --- a/aries_vcx/tests/utils/scenarios.rs +++ b/aries_vcx/tests/utils/scenarios.rs @@ -35,8 +35,8 @@ pub mod test_utils { Attribute, PresentationProposalData, }; use aries_vcx::messages::protocols::proof_presentation::presentation_request::PresentationRequest; - use aries_vcx::protocols::connection::invitee::state_machine::InviteeState; - use aries_vcx::protocols::connection::inviter::state_machine::InviterState; + use aries_vcx::protocols::mediated_connection::invitee::state_machine::InviteeState; + use aries_vcx::protocols::mediated_connection::inviter::state_machine::InviterState; use aries_vcx::protocols::issuance::holder::state_machine::HolderState; use aries_vcx::protocols::issuance::issuer::state_machine::IssuerState; use aries_vcx::protocols::proof_presentation::prover::state_machine::ProverState; diff --git a/libvcx/src/api_c/protocols/mediated_connection.rs b/libvcx/src/api_c/protocols/mediated_connection.rs index bbd9677c8c..ef9dfdf04d 100644 --- a/libvcx/src/api_c/protocols/mediated_connection.rs +++ b/libvcx/src/api_c/protocols/mediated_connection.rs @@ -4,7 +4,7 @@ use futures::future::BoxFuture; use libc::c_char; use crate::api_c::cutils; -use aries_vcx::protocols::connection::pairwise_info::PairwiseInfo; +use aries_vcx::protocols::mediated_connection::pairwise_info::PairwiseInfo; use crate::api_c::types::CommandHandle; use crate::api_vcx::api_handle::mediated_connection; diff --git a/libvcx/src/api_vcx/api_global/wallet.rs b/libvcx/src/api_vcx/api_global/wallet.rs index 7678c00994..07eed0388c 100644 --- a/libvcx/src/api_vcx/api_global/wallet.rs +++ b/libvcx/src/api_vcx/api_global/wallet.rs @@ -5,7 +5,7 @@ use aries_vcx::indy::wallet::{ close_search_wallet, fetch_next_records_wallet, import, open_search_wallet, IssuerConfig, RestoreWalletConfigs, WalletConfig, }; -use aries_vcx::protocols::connection::pairwise_info::PairwiseInfo; +use aries_vcx::protocols::mediated_connection::pairwise_info::PairwiseInfo; use aries_vcx::vdrtools::{SearchHandle, WalletHandle, INVALID_WALLET_HANDLE}; use crate::api_vcx::api_global::profile::{get_main_profile, get_main_wallet, indy_handles_to_profile}; diff --git a/libvcx/src/api_vcx/api_handle/connection.rs b/libvcx/src/api_vcx/api_handle/connection.rs index b7ec33a8d5..3d28f3e738 100644 --- a/libvcx/src/api_vcx/api_handle/connection.rs +++ b/libvcx/src/api_vcx/api_handle/connection.rs @@ -1,22 +1,85 @@ +use std::{collections::HashMap, sync::RwLock}; + +use agency_client::httpclient::post_message; use aries_vcx::{ - common::ledger::transactions::into_did_doc, handlers::connection::connection::Connection, - protocols::connection::pairwise_info::PairwiseInfo, + errors::error::VcxResult, + messages::protocols::basic_message::message::BasicMessage, + protocols::connection::{ + invitee::InviteeConnection, inviter::InviterConnection, pairwise_info::PairwiseInfo, Connection, + GenericConnection, State, Transport, + }, }; +use async_trait::async_trait; +use rand::Rng; use crate::{ - api_vcx::{api_global::profile::get_main_profile, api_handle::object_cache::ObjectCache}, + api_vcx::api_global::profile::get_main_profile, errors::error::{LibvcxError, LibvcxErrorKind, LibvcxResult}, }; +type Map = HashMap; +type Cache = RwLock; + lazy_static! { - static ref CONNECTION_MAP: ObjectCache = - ObjectCache::::new("nonmediated-connections-cache"); + static ref CONNECTION_MAP: Cache = RwLock::new(HashMap::new()); +} + +struct HttpClient; + +#[async_trait] +impl Transport for HttpClient { + async fn send_message(&self, msg: Vec, service_endpoint: &str) -> VcxResult<()> { + post_message(msg, service_endpoint).await?; + Ok(()) + } +} + +fn new_handle() -> LibvcxResult { + loop { + let handle = rand::thread_rng().gen::(); + if !CONNECTION_MAP.read()?.contains_key(&handle) { + break Ok(handle); + } + } +} + +fn get_cloned_generic_connection(handle: &u32) -> LibvcxResult { + CONNECTION_MAP.write()?.get(handle).cloned().ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("Unable to retrieve expected connection for handle: {}", handle), + ) + }) } -fn store_connection(connection: Connection) -> LibvcxResult { +fn get_cloned_connection(handle: &u32) -> LibvcxResult> +where + Connection: TryFrom, +{ CONNECTION_MAP - .add(connection) - .map_err(|e| LibvcxError::from_msg(LibvcxErrorKind::IOError, e.to_string())) + .write()? + .get(handle) + .and_then(|c| c.clone().try_into().ok()) + .ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("Unable to retrieve expected connection for handle: {}", handle), + ) + }) +} + +fn add_connection(connection: GenericConnection) -> LibvcxResult { + let handle = new_handle()?; + CONNECTION_MAP.write()?.insert(handle, connection); + Ok(handle) +} + +fn insert_connection(handle: u32, connection: Connection) -> LibvcxResult<()> +where + GenericConnection: From>, +{ + CONNECTION_MAP.write()?.insert(handle, connection.into()); + Ok(()) } fn serialize(data: &T) -> LibvcxResult @@ -42,62 +105,158 @@ where // ----------------------------- CONSTRUCTORS ------------------------------------ pub async fn create_inviter(pw_info: Option) -> LibvcxResult { trace!("create_inviter >>>"); - store_connection(Connection::create_inviter(&get_main_profile()?, pw_info).await?) + let profile = get_main_profile()?; + + let pw_info = pw_info.unwrap_or(PairwiseInfo::create(&profile.inject_wallet()).await?); + let con = InviterConnection::new_awaiting_request("".to_owned(), pw_info); + + add_connection(con.into()) } pub async fn create_invitee(invitation: &str) -> LibvcxResult { trace!("create_invitee >>>"); + + let profile = get_main_profile()?; + let invitation = deserialize(invitation)?; + let pairwise_info = PairwiseInfo::create(&profile.inject_wallet()).await?; + + let con = InviteeConnection::new_invitee("".to_owned(), pairwise_info) + .accept_invitation(&profile, &invitation) + .await?; + + add_connection(con.into()) +} + +// Just trying to retro-fit this. +// It essentially creates an inviter connection in the initial state, also genereting an Invitation. +pub async fn create_invite(handle: u32, service_endpoint: String, routing_keys: Vec) -> LibvcxResult<()> { + trace!("create_invite >>>"); + let profile = get_main_profile()?; - store_connection( - Connection::create_invitee(&profile, into_did_doc(&profile, &deserialize(invitation)?).await?).await?, - ) + let pairwise_info = PairwiseInfo::create(&profile.inject_wallet()).await?; + let con = InviterConnection::new_inviter("".to_owned(), pairwise_info, routing_keys, service_endpoint); + + insert_connection(handle, con) } // ----------------------------- GETTERS ------------------------------------ pub fn get_thread_id(handle: u32) -> LibvcxResult { trace!("get_thread_id >>> handle: {}", handle); - CONNECTION_MAP.get(handle, |connection| Ok(connection.get_thread_id())) + + let lock = CONNECTION_MAP.read()?; + let con = lock.get(&handle).ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("Unable to retrieve expected connection for handle: {}", handle), + ) + })?; + + con.thread_id().map(ToOwned::to_owned).ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("No thread ID for connection with handle: {}", handle), + ) + }) } pub fn get_pairwise_info(handle: u32) -> LibvcxResult { trace!("get_pairwise_info >>> handle: {}", handle); - CONNECTION_MAP.get(handle, |connection| serialize(connection.pairwise_info())) + + let lock = CONNECTION_MAP.read()?; + let con = lock.get(&handle).ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("Unable to retrieve expected connection for handle: {}", handle), + ) + })?; + + serialize(con.pairwise_info()) } pub fn get_remote_did(handle: u32) -> LibvcxResult { trace!("get_remote_did >>> handle: {}", handle); - CONNECTION_MAP.get(handle, |connection| connection.remote_did().map_err(|e| e.into())) + + let lock = CONNECTION_MAP.read()?; + let con = lock.get(&handle).ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("Unable to retrieve expected connection for handle: {}", handle), + ) + })?; + + con.remote_did().map(ToOwned::to_owned).ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("No remote DID for connection with handle: {}", handle), + ) + }) } pub fn get_remote_vk(handle: u32) -> LibvcxResult { trace!("get_remote_vk >>> handle: {}", handle); - CONNECTION_MAP.get(handle, |connection| connection.remote_vk().map_err(|e| e.into())) + + let lock = CONNECTION_MAP.read()?; + let con = lock.get(&handle).ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("Unable to retrieve expected connection for handle: {}", handle), + ) + })?; + + con.remote_vk().map_err(From::from) } pub fn get_state(handle: u32) -> LibvcxResult { trace!("get_state >>> handle: {}", handle); - CONNECTION_MAP.get(handle, |connection| Ok(connection.get_state().into())) + + let lock = CONNECTION_MAP.read()?; + let con = lock.get(&handle).ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("Unable to retrieve expected connection for handle: {}", handle), + ) + })?; + + let state_id = match con.state() { + State::Invitee(s) => s as u32, + State::Inviter(s) => s as u32, + }; + + Ok(state_id) } pub fn get_invitation(handle: u32) -> LibvcxResult { trace!("get_invitation >>> handle: {}", handle); - CONNECTION_MAP.get(handle, |connection| { - serialize(connection.get_invite_details().ok_or(LibvcxError::from_msg( - LibvcxErrorKind::ActionNotSupported, - "Invitation is not available for the connection.", - ))?) - }) + + let lock = CONNECTION_MAP.read()?; + let con = lock.get(&handle).ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("Unable to retrieve expected connection for handle: {}", handle), + ) + })?; + + let invitation = con.invitation().ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("No invitation for connection with handle: {}", handle), + ) + })?; + + serialize(invitation) } // ----------------------------- MSG PROCESSING ------------------------------------ -pub fn process_invite(handle: u32, invitation: &str) -> LibvcxResult<()> { +pub async fn process_invite(handle: u32, invitation: &str) -> LibvcxResult<()> { trace!("process_invite >>>"); - CONNECTION_MAP.insert( - handle, - CONNECTION_MAP - .get_cloned(handle)? - .process_invite(deserialize(invitation)?)?, - ) + + let profile = get_main_profile()?; + let invitation = deserialize(invitation)?; + let con = get_cloned_connection(&handle)? + .accept_invitation(&profile, &invitation) + .await?; + + insert_connection(handle, con) } pub async fn process_request( @@ -107,114 +266,115 @@ pub async fn process_request( routing_keys: Vec, ) -> LibvcxResult<()> { trace!("process_request >>>"); - CONNECTION_MAP.insert( - handle, - CONNECTION_MAP - .get_cloned(handle)? - .process_request( - &get_main_profile()?, - deserialize(request)?, - service_endpoint, - routing_keys, - None, - ) - .await?, - ) + + let con = get_cloned_connection(&handle)?; + let wallet = get_main_profile()?.inject_wallet(); + let request = deserialize(request)?; + let con = con + .handle_request(&wallet, request, service_endpoint, routing_keys, &HttpClient) + .await?; + + insert_connection(handle, con) } pub async fn process_response(handle: u32, response: &str) -> LibvcxResult<()> { trace!("process_response >>>"); - CONNECTION_MAP.insert( - handle, - CONNECTION_MAP - .get_cloned(handle)? - .process_response(&get_main_profile()?, deserialize(response)?, None) - .await?, - ) + + let con = get_cloned_connection(&handle)?; + let wallet = get_main_profile()?.inject_wallet(); + let response = deserialize(response)?; + let con = con.handle_response(&wallet, response, &HttpClient).await?; + + insert_connection(handle, con) } pub async fn process_ack(handle: u32, message: &str) -> LibvcxResult<()> { trace!("process_ack >>>"); - CONNECTION_MAP.insert( - handle, - CONNECTION_MAP - .get_cloned(handle)? - .process_ack(deserialize(message)?) - .await?, - ) + + let con = get_cloned_connection(&handle)?; + let msg = deserialize(message)?; + let con = con.acknowledge_connection(&msg)?; + + insert_connection(handle, con) } pub async fn send_response(handle: u32) -> LibvcxResult<()> { trace!("send_response >>>"); - CONNECTION_MAP.insert( - handle, - CONNECTION_MAP - .get_cloned(handle)? - .send_response(&get_main_profile()?, None) - .await?, - ) + + let con = get_cloned_connection(&handle)?; + let wallet = get_main_profile()?.inject_wallet(); + let con = con.send_response(&wallet, &HttpClient).await?; + + insert_connection(handle, con) } pub async fn send_request(handle: u32, service_endpoint: String, routing_keys: Vec) -> LibvcxResult<()> { trace!("send_request >>>"); - CONNECTION_MAP.insert( - handle, - CONNECTION_MAP - .get_cloned(handle)? - .send_request(&get_main_profile()?, service_endpoint, routing_keys, None) - .await?, - ) + + let con = get_cloned_connection(&handle)?; + let wallet = get_main_profile()?.inject_wallet(); + let con = con + .send_request(&wallet, service_endpoint, routing_keys, &HttpClient) + .await?; + + insert_connection(handle, con) } pub async fn send_ack(handle: u32) -> LibvcxResult<()> { trace!("send_ack >>>"); - CONNECTION_MAP.insert( - handle, - CONNECTION_MAP - .get_cloned(handle)? - .send_ack(&get_main_profile()?, None) - .await?, - ) + + let con = get_cloned_connection(&handle)?; + let wallet = get_main_profile()?.inject_wallet(); + let con = con.send_ack(&wallet, &HttpClient).await?; + + insert_connection(handle, con) } pub async fn send_generic_message(handle: u32, content: String) -> LibvcxResult<()> { trace!("send_generic_message >>>"); - CONNECTION_MAP - .get_cloned(handle)? - .send_generic_message(&get_main_profile()?, None, content) - .await - .map_err(|e| e.into()) -} -pub async fn create_invite(handle: u32, service_endpoint: String, routing_keys: Vec) -> LibvcxResult<()> { - trace!("create_invite >>>"); - CONNECTION_MAP.insert( - handle, - CONNECTION_MAP - .get_cloned(handle)? - .create_invite(service_endpoint, routing_keys) - .await?, - ) + let wallet = get_main_profile()?.inject_wallet(); + let message = BasicMessage::create() + .set_content(content) + .set_time() + .set_out_time() + .to_a2a_message(); + + let con = get_cloned_generic_connection(&handle)?; + con.send_message(&wallet, &message, &HttpClient).await?; + Ok(()) } -// ------------------------- (DE)SERIALIZATION ---------------------------------- +// // ------------------------- (DE)SERIALIZATION ---------------------------------- pub fn to_string(handle: u32) -> LibvcxResult { trace!("to_string >>>"); - CONNECTION_MAP.get(handle, |connection| connection.to_string().map_err(|err| err.into())) + + CONNECTION_MAP + .read()? + .get(&handle) + .ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::InvalidHandle, + format!("[Connection Cache] get >> Object not found for handle: {}", handle), + ) + }) + .and_then(serialize) } pub fn from_string(connection_data: &str) -> LibvcxResult { trace!("from_string >>>"); - store_connection(Connection::from_string(connection_data)?) + add_connection(deserialize(connection_data)?) } // ------------------------------ CLEANUP --------------------------------------- pub fn release(handle: u32) -> LibvcxResult<()> { trace!("release >>>"); - CONNECTION_MAP.release(handle) + + CONNECTION_MAP.write().map(|mut map| map.remove(&handle)).ok(); + Ok(()) } pub fn release_all() { trace!("release_all >>>"); - CONNECTION_MAP.drain().ok(); + CONNECTION_MAP.write().map(|mut map| map.drain().for_each(drop)).ok(); } diff --git a/libvcx/src/api_vcx/api_handle/mediated_connection.rs b/libvcx/src/api_vcx/api_handle/mediated_connection.rs index 6a358b0f68..01acc7b4d6 100644 --- a/libvcx/src/api_vcx/api_handle/mediated_connection.rs +++ b/libvcx/src/api_vcx/api_handle/mediated_connection.rs @@ -10,7 +10,7 @@ use aries_vcx::messages::a2a::A2AMessage; use aries_vcx::messages::protocols::connection::invite::Invitation as InvitationV3; use aries_vcx::messages::protocols::connection::invite::PublicInvitation; use aries_vcx::messages::protocols::connection::request::Request; -use aries_vcx::protocols::connection::pairwise_info::PairwiseInfo; +use aries_vcx::protocols::mediated_connection::pairwise_info::PairwiseInfo; use aries_vcx::protocols::SendClosure; use crate::api_vcx::api_global::agency_client::get_main_agency_client; diff --git a/libvcx/src/api_vcx/api_handle/mod.rs b/libvcx/src/api_vcx/api_handle/mod.rs index 63f7dad124..53e8210e30 100644 --- a/libvcx/src/api_vcx/api_handle/mod.rs +++ b/libvcx/src/api_vcx/api_handle/mod.rs @@ -1,4 +1,3 @@ -pub mod connection; pub mod credential; pub mod credential_def; pub mod disclosed_proof; @@ -9,4 +8,4 @@ pub mod out_of_band; pub mod proof; pub mod revocation_registry; pub mod schema; -pub mod typestate_con; \ No newline at end of file +pub mod connection; \ No newline at end of file diff --git a/libvcx/src/api_vcx/api_handle/typestate_con.rs b/libvcx/src/api_vcx/api_handle/typestate_con.rs deleted file mode 100644 index 168cf8aeab..0000000000 --- a/libvcx/src/api_vcx/api_handle/typestate_con.rs +++ /dev/null @@ -1,378 +0,0 @@ -use std::{collections::HashMap, sync::RwLock}; - -use agency_client::httpclient::post_message; -use aries_vcx::{ - errors::error::VcxResult, - messages::protocols::basic_message::message::BasicMessage, - protocols::typestate_con::{ - invitee::InviteeConnection, inviter::InviterConnection, pairwise_info::PairwiseInfo, Connection, - GenericConnection, State, Transport, - }, -}; -use async_trait::async_trait; -use rand::Rng; - -use crate::{ - api_vcx::api_global::profile::get_main_profile, - errors::error::{LibvcxError, LibvcxErrorKind, LibvcxResult}, -}; - -type Map = HashMap; -type Cache = RwLock; - -lazy_static! { - static ref CONNECTION_MAP: Cache = RwLock::new(HashMap::new()); -} - -struct HttpClient; - -#[async_trait] -impl Transport for HttpClient { - async fn send_message(&self, msg: Vec, service_endpoint: &str) -> VcxResult<()> { - post_message(msg, service_endpoint).await?; - Ok(()) - } -} - -fn new_handle() -> LibvcxResult { - loop { - let handle = rand::thread_rng().gen::(); - if !CONNECTION_MAP.read()?.contains_key(&handle) { - break Ok(handle); - } - } -} - -fn get_cloned_connection(handle: &u32) -> LibvcxResult> -where - Connection: TryFrom, -{ - CONNECTION_MAP - .write()? - .get(handle) - .and_then(|c| c.clone().try_into().ok()) - .ok_or_else(|| { - LibvcxError::from_msg( - LibvcxErrorKind::ObjectAccessError, - format!("Unable to retrieve expected connection for handle: {}", handle), - ) - }) -} - -fn add_connection(connection: GenericConnection) -> LibvcxResult { - let handle = new_handle()?; - CONNECTION_MAP.write()?.insert(handle, connection); - Ok(handle) -} - -fn insert_connection(handle: u32, connection: Connection) -> LibvcxResult<()> -where - GenericConnection: From>, -{ - CONNECTION_MAP.write()?.insert(handle, connection.into()); - Ok(()) -} - -fn serialize(data: &T) -> LibvcxResult -where - T: serde::ser::Serialize, -{ - serde_json::to_string(data).map_err(|err| { - LibvcxError::from_msg( - LibvcxErrorKind::SerializationError, - format!("Serialization failed: {}", err), - ) - }) -} - -fn deserialize(data: &str) -> LibvcxResult -where - T: serde::de::DeserializeOwned, -{ - serde_json::from_str(data) - .map_err(|err| LibvcxError::from_msg(LibvcxErrorKind::InvalidJson, format!("Deserialization failed: {}", err))) -} - -// ----------------------------- CONSTRUCTORS ------------------------------------ -pub async fn create_inviter(pw_info: Option) -> LibvcxResult { - trace!("create_inviter >>>"); - let profile = get_main_profile()?; - - let pw_info = pw_info.unwrap_or(PairwiseInfo::create(&profile.inject_wallet()).await?); - let con = InviterConnection::new_awaiting_request("".to_owned(), pw_info); - - add_connection(con.into()) -} - -pub async fn create_invitee(invitation: &str) -> LibvcxResult { - trace!("create_invitee >>>"); - - let profile = get_main_profile()?; - let invitation = deserialize(invitation)?; - let pairwise_info = PairwiseInfo::create(&profile.inject_wallet()).await?; - - let con = InviteeConnection::new_invitee("".to_owned(), pairwise_info) - .accept_invitation(&profile, &invitation) - .await?; - - add_connection(con.into()) -} - -// Just trying to retro-fit this. -// It essentially creates an inviter connection in the initial state, also genereting an Invitation. -pub async fn create_invite(handle: u32, service_endpoint: String, routing_keys: Vec) -> LibvcxResult<()> { - trace!("create_invite >>>"); - - let profile = get_main_profile()?; - let pairwise_info = PairwiseInfo::create(&profile.inject_wallet()).await?; - let con = InviterConnection::new_inviter("".to_owned(), pairwise_info, routing_keys, service_endpoint); - - insert_connection(handle, con) -} - -// ----------------------------- GETTERS ------------------------------------ -pub fn get_thread_id(handle: u32) -> LibvcxResult { - trace!("get_thread_id >>> handle: {}", handle); - - let lock = CONNECTION_MAP.read()?; - let con = lock.get(&handle).ok_or_else(|| { - LibvcxError::from_msg( - LibvcxErrorKind::ObjectAccessError, - format!("Unable to retrieve expected connection for handle: {}", handle), - ) - })?; - - con.thread_id().map(ToOwned::to_owned).ok_or_else(|| { - LibvcxError::from_msg( - LibvcxErrorKind::ObjectAccessError, - format!("No thread ID for connection with handle: {}", handle), - ) - }) -} - -pub fn get_pairwise_info(handle: u32) -> LibvcxResult { - trace!("get_pairwise_info >>> handle: {}", handle); - - let lock = CONNECTION_MAP.read()?; - let con = lock.get(&handle).ok_or_else(|| { - LibvcxError::from_msg( - LibvcxErrorKind::ObjectAccessError, - format!("Unable to retrieve expected connection for handle: {}", handle), - ) - })?; - - serialize(con.pairwise_info()) -} - -pub fn get_remote_did(handle: u32) -> LibvcxResult { - trace!("get_remote_did >>> handle: {}", handle); - - let lock = CONNECTION_MAP.read()?; - let con = lock.get(&handle).ok_or_else(|| { - LibvcxError::from_msg( - LibvcxErrorKind::ObjectAccessError, - format!("Unable to retrieve expected connection for handle: {}", handle), - ) - })?; - - con.remote_did().map(ToOwned::to_owned).ok_or_else(|| { - LibvcxError::from_msg( - LibvcxErrorKind::ObjectAccessError, - format!("No remote DID for connection with handle: {}", handle), - ) - }) -} - -pub fn get_remote_vk(handle: u32) -> LibvcxResult { - trace!("get_remote_vk >>> handle: {}", handle); - - let lock = CONNECTION_MAP.read()?; - let con = lock.get(&handle).ok_or_else(|| { - LibvcxError::from_msg( - LibvcxErrorKind::ObjectAccessError, - format!("Unable to retrieve expected connection for handle: {}", handle), - ) - })?; - - con.remote_vk().map_err(From::from) -} - -pub fn get_state(handle: u32) -> LibvcxResult { - trace!("get_state >>> handle: {}", handle); - - let lock = CONNECTION_MAP.read()?; - let con = lock.get(&handle).ok_or_else(|| { - LibvcxError::from_msg( - LibvcxErrorKind::ObjectAccessError, - format!("Unable to retrieve expected connection for handle: {}", handle), - ) - })?; - - let state_id = match con.state() { - State::Invitee(s) => s as u32, - State::Inviter(s) => s as u32, - }; - - Ok(state_id) -} - -pub fn get_invitation(handle: u32) -> LibvcxResult { - trace!("get_invitation >>> handle: {}", handle); - - let lock = CONNECTION_MAP.read()?; - let con = lock.get(&handle).ok_or_else(|| { - LibvcxError::from_msg( - LibvcxErrorKind::ObjectAccessError, - format!("Unable to retrieve expected connection for handle: {}", handle), - ) - })?; - - let invitation = con.invitation().ok_or_else(|| { - LibvcxError::from_msg( - LibvcxErrorKind::ObjectAccessError, - format!("No invitation for connection with handle: {}", handle), - ) - })?; - - serialize(invitation) -} - -// ----------------------------- MSG PROCESSING ------------------------------------ -pub async fn process_invite(handle: u32, invitation: &str) -> LibvcxResult<()> { - trace!("process_invite >>>"); - - let profile = get_main_profile()?; - let invitation = deserialize(invitation)?; - let con = get_cloned_connection(&handle)? - .accept_invitation(&profile, &invitation) - .await?; - - insert_connection(handle, con) -} - -pub async fn process_request( - handle: u32, - request: &str, - service_endpoint: String, - routing_keys: Vec, -) -> LibvcxResult<()> { - trace!("process_request >>>"); - - let con = get_cloned_connection(&handle)?; - let wallet = get_main_profile()?.inject_wallet(); - let request = deserialize(request)?; - let con = con - .handle_request(&wallet, request, service_endpoint, routing_keys, &HttpClient) - .await?; - - insert_connection(handle, con) -} - -pub async fn process_response(handle: u32, response: &str) -> LibvcxResult<()> { - trace!("process_response >>>"); - - let con = get_cloned_connection(&handle)?; - let wallet = get_main_profile()?.inject_wallet(); - let response = deserialize(response)?; - let con = con.handle_response(&wallet, response, &HttpClient).await?; - - insert_connection(handle, con) -} - -pub async fn process_ack(handle: u32, message: &str) -> LibvcxResult<()> { - trace!("process_ack >>>"); - - let con = get_cloned_connection(&handle)?; - let msg = deserialize(message)?; - let con = con.acknowledge_connection(&msg)?; - - insert_connection(handle, con) -} - -pub async fn send_response(handle: u32) -> LibvcxResult<()> { - trace!("send_response >>>"); - - let con = get_cloned_connection(&handle)?; - let wallet = get_main_profile()?.inject_wallet(); - let con = con.send_response(&wallet, &HttpClient).await?; - - insert_connection(handle, con) -} - -pub async fn send_request(handle: u32, service_endpoint: String, routing_keys: Vec) -> LibvcxResult<()> { - trace!("send_request >>>"); - - let con = get_cloned_connection(&handle)?; - let wallet = get_main_profile()?.inject_wallet(); - let con = con - .send_request(&wallet, service_endpoint, routing_keys, &HttpClient) - .await?; - - insert_connection(handle, con) -} - -pub async fn send_ack(handle: u32) -> LibvcxResult<()> { - trace!("send_ack >>>"); - - let con = get_cloned_connection(&handle)?; - let wallet = get_main_profile()?.inject_wallet(); - let con = con.send_ack(&wallet, &HttpClient).await?; - - insert_connection(handle, con) -} - -pub async fn send_generic_message(handle: u32, content: String) -> LibvcxResult<()> { - trace!("send_generic_message >>>"); - - let wallet = get_main_profile()?.inject_wallet(); - let message = BasicMessage::create() - .set_content(content) - .set_time() - .set_out_time() - .to_a2a_message(); - - let lock = CONNECTION_MAP.read()?; - let con = lock.get(&handle).ok_or_else(|| { - LibvcxError::from_msg( - LibvcxErrorKind::ObjectAccessError, - format!("Unable to retrieve expected connection for handle: {}", handle), - ) - })?; - - con.send_message(&wallet, &message, &HttpClient).await?; - Ok(()) -} - -// // ------------------------- (DE)SERIALIZATION ---------------------------------- -pub fn to_string(handle: u32) -> LibvcxResult { - trace!("to_string >>>"); - - CONNECTION_MAP - .read()? - .get(&handle) - .ok_or_else(|| { - LibvcxError::from_msg( - LibvcxErrorKind::InvalidHandle, - format!("[Connection Cache] get >> Object not found for handle: {}", handle), - ) - }) - .and_then(serialize) -} - -pub fn from_string(connection_data: &str) -> LibvcxResult { - trace!("from_string >>>"); - add_connection(deserialize(connection_data)?) -} - -// ------------------------------ CLEANUP --------------------------------------- -pub fn release(handle: u32) -> LibvcxResult<()> { - trace!("release >>>"); - - CONNECTION_MAP.write().map(|mut map| map.remove(&handle)).ok(); - Ok(()) -} - -pub fn release_all() { - trace!("release_all >>>"); - CONNECTION_MAP.write().map(|mut map| map.drain().for_each(drop)).ok(); -} diff --git a/wrappers/vcx-napi-rs/src/api/connection.rs b/wrappers/vcx-napi-rs/src/api/connection.rs index a6b098b777..e5f31afee6 100644 --- a/wrappers/vcx-napi-rs/src/api/connection.rs +++ b/wrappers/vcx-napi-rs/src/api/connection.rs @@ -64,9 +64,11 @@ pub fn connection_get_invitation(handle: u32) -> napi::Result { } #[napi] -pub fn connection_process_invite(handle: u32, invitation: String) -> napi::Result<()> { +pub async fn connection_process_invite(handle: u32, invitation: String) -> napi::Result<()> { trace!("connection_process_invite >>> handle: {:?}", handle); - connection::process_invite(handle, &invitation).map_err(to_napi_err) + connection::process_invite(handle, &invitation) + .await + .map_err(to_napi_err) } #[napi] diff --git a/wrappers/vcx-napi-rs/src/api/mediated_connection.rs b/wrappers/vcx-napi-rs/src/api/mediated_connection.rs index e6e646ebae..3f78c27719 100644 --- a/wrappers/vcx-napi-rs/src/api/mediated_connection.rs +++ b/wrappers/vcx-napi-rs/src/api/mediated_connection.rs @@ -3,7 +3,7 @@ use napi_derive::napi; use vcx::api_vcx::api_handle::mediated_connection; use vcx::api_vcx::api_handle::mediated_connection::parse_status_codes; -use vcx::aries_vcx::protocols::connection::pairwise_info::PairwiseInfo; +use vcx::aries_vcx::protocols::mediated_connection::pairwise_info::PairwiseInfo; use vcx::errors::error::{LibvcxError, LibvcxErrorKind}; use vcx::serde_json; From 7c932e5fe9a57901a307b335e34e516e63a62277 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Wed, 1 Feb 2023 16:28:19 +0200 Subject: [PATCH 31/66] Fixed state differences in Node.js wrapper Signed-off-by: Bogdan Mircea --- agents/node/vcxagent-core/package.json | 3 ++- wrappers/node/test/suite1/ariesvcx-connection.test.ts | 6 +++--- wrappers/vcx-napi-rs/package.json | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/agents/node/vcxagent-core/package.json b/agents/node/vcxagent-core/package.json index bd76834fe3..756a00a647 100644 --- a/agents/node/vcxagent-core/package.json +++ b/agents/node/vcxagent-core/package.json @@ -46,7 +46,7 @@ "test:integration:out-of-band": "jest --forceExit --env=node --runInBand test/out-of-band.spec.js", "test:integration:nonmediated-endpoint": "jest --forceExit --env=node --runInBand test/nonmediated-endpoint.spec.js", "test:integration:nonmediated-connection": "jest --forceExit --env=node --runInBand test/nonmediated-connection.spec.js" - }, + }, "dependencies": { "axios": "^0.27.2", "ffi-napi": "^4.0.3", @@ -54,6 +54,7 @@ "lodash": "^4.17.21", "mkdirp": "^1.0.4", "node-persist": "^3.1.0", + "ref-napi": "file:../../../../../ref-napi-3.0.3.tgz", "sleep-promise": "^9.0.1", "uuid": "^8.3.2" }, diff --git a/wrappers/node/test/suite1/ariesvcx-connection.test.ts b/wrappers/node/test/suite1/ariesvcx-connection.test.ts index bfb4e289ed..50b13a5f27 100644 --- a/wrappers/node/test/suite1/ariesvcx-connection.test.ts +++ b/wrappers/node/test/suite1/ariesvcx-connection.test.ts @@ -13,10 +13,10 @@ describe('Nonmediated connection:', () => { const serviceEndpoint = 'http://localhost:8080'; const routingKeys = [ 'routingKey' ]; const connection = await NonmediatedConnection.createInviter(); - assert.equal(connection.getState(), ConnectionStateType.Initial); + assert.equal(connection.getState(), ConnectionStateType.Invited); await connection.createInvite({ serviceEndpoint, routingKeys }); - assert.equal(connection.getState(), ConnectionStateType.Invited); + assert.equal(connection.getState(), ConnectionStateType.Initial); const invite = JSON.parse(connection.getInvitation()); expect(invite.routingKeys).deep.equal(routingKeys); @@ -27,7 +27,7 @@ describe('Nonmediated connection:', () => { describe('serialize / deserialize:', () => { it('success', async () => { const connection = await NonmediatedConnection.createInviter(); - assert.equal(connection.getState(), ConnectionStateType.Initial); + assert.equal(connection.getState(), ConnectionStateType.Invited); const serialized = connection.serialize() const deserialized = NonmediatedConnection.deserialize(serialized); diff --git a/wrappers/vcx-napi-rs/package.json b/wrappers/vcx-napi-rs/package.json index a496df0414..968ef83542 100644 --- a/wrappers/vcx-napi-rs/package.json +++ b/wrappers/vcx-napi-rs/package.json @@ -51,4 +51,4 @@ "@hyperledger/vcx-napi-rs-linux-x64-gnu": "undefined", "@hyperledger/vcx-napi-rs-linux-x64-musl": "undefined" } -} +} \ No newline at end of file From 695305a86b8cce886ea9ca983fb0580ec459be18 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Wed, 1 Feb 2023 16:57:42 +0200 Subject: [PATCH 32/66] Reuse request did_doc Signed-off-by: Bogdan Mircea --- aries_vcx/src/protocols/connection/inviter/mod.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/aries_vcx/src/protocols/connection/inviter/mod.rs b/aries_vcx/src/protocols/connection/inviter/mod.rs index cc055475b0..423b0cb7c4 100644 --- a/aries_vcx/src/protocols/connection/inviter/mod.rs +++ b/aries_vcx/src/protocols/connection/inviter/mod.rs @@ -97,9 +97,6 @@ impl InviterConnection { sign_connection_response(wallet, &self.pairwise_info.pw_vk, response).await } - // Due to backwards compatibility, we generate the signed response and store that in the state. - // However, it would be more efficient to store the request and postpone the response generation and - // signing until the next state, thus taking advantage of the request attributes and avoiding cloning the DidDoc. pub async fn handle_request( self, wallet: &Arc, @@ -143,8 +140,6 @@ impl InviterConnection { } let new_pairwise_info = PairwiseInfo::create(wallet).await?; - let did_doc = request.connection.did_doc.clone(); - let signed_response = self .build_response( wallet, @@ -155,6 +150,7 @@ impl InviterConnection { ) .await?; + let did_doc = request.connection.did_doc; let state = Requested::new(signed_response, did_doc); Ok(Connection { From e88ce9e7a321597bd2c787371d92726d60422d96 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Wed, 1 Feb 2023 17:34:30 +0200 Subject: [PATCH 33/66] Moved Transport trait and auto-implemented for references of types implementing it Signed-off-by: Bogdan Mircea --- .../rust/aries-vcx-agent/src/http_client.rs | 5 ++--- aries_vcx/src/lib.rs | 1 + .../connection/common/states/complete.rs | 2 +- .../connection/common/states/responded.rs | 2 +- .../src/protocols/connection/generic/mod.rs | 4 ++-- .../src/protocols/connection/invitee/mod.rs | 3 +-- .../connection/invitee/states/invited.rs | 2 +- .../connection/invitee/states/requested.rs | 2 +- .../src/protocols/connection/inviter/mod.rs | 2 +- .../connection/inviter/states/initial.rs | 2 +- .../connection/inviter/states/invited.rs | 2 +- .../connection/inviter/states/requested.rs | 2 +- aries_vcx/src/protocols/connection/mod.rs | 6 +++--- .../connection/{traits.rs => trait_bounds.rs} | 11 +---------- aries_vcx/src/transport.rs | 19 +++++++++++++++++++ libvcx/src/api_vcx/api_handle/connection.rs | 3 ++- 16 files changed, 39 insertions(+), 29 deletions(-) rename aries_vcx/src/protocols/connection/{traits.rs => trait_bounds.rs} (61%) create mode 100644 aries_vcx/src/transport.rs diff --git a/agents/rust/aries-vcx-agent/src/http_client.rs b/agents/rust/aries-vcx-agent/src/http_client.rs index 8412480567..75e84acfe5 100644 --- a/agents/rust/aries-vcx-agent/src/http_client.rs +++ b/agents/rust/aries-vcx-agent/src/http_client.rs @@ -1,6 +1,5 @@ -use aries_vcx::{ - agency_client::httpclient::post_message, errors::error::VcxResult, protocols::connection::Transport, -}; +use aries_vcx::{agency_client::httpclient::post_message, errors::error::VcxResult, transport::Transport}; + use async_trait::async_trait; pub struct HttpClient; diff --git a/aries_vcx/src/lib.rs b/aries_vcx/src/lib.rs index a7be688bf4..ab438c3029 100644 --- a/aries_vcx/src/lib.rs +++ b/aries_vcx/src/lib.rs @@ -49,6 +49,7 @@ pub mod common; pub mod core; pub mod errors; pub mod plugins; +pub mod transport; #[cfg(test)] pub mod test { diff --git a/aries_vcx/src/protocols/connection/common/states/complete.rs b/aries_vcx/src/protocols/connection/common/states/complete.rs index fcec31030d..955c0ec003 100644 --- a/aries_vcx/src/protocols/connection/common/states/complete.rs +++ b/aries_vcx/src/protocols/connection/common/states/complete.rs @@ -3,7 +3,7 @@ use std::clone::Clone; use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::discovery::disclose::{Disclose, ProtocolDescriptor}; -use crate::protocols::connection::traits::{TheirDidDoc, ThreadId}; +use crate::protocols::connection::trait_bounds::{TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct CompleteState { diff --git a/aries_vcx/src/protocols/connection/common/states/responded.rs b/aries_vcx/src/protocols/connection/common/states/responded.rs index 4060ebf253..ba7548b592 100644 --- a/aries_vcx/src/protocols/connection/common/states/responded.rs +++ b/aries_vcx/src/protocols/connection/common/states/responded.rs @@ -1,6 +1,6 @@ use messages::diddoc::aries::diddoc::AriesDidDoc; -use crate::protocols::connection::traits::{TheirDidDoc, ThreadId}; +use crate::protocols::connection::trait_bounds::{TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct RespondedState { diff --git a/aries_vcx/src/protocols/connection/generic/mod.rs b/aries_vcx/src/protocols/connection/generic/mod.rs index 381af9dadb..92642db4e6 100644 --- a/aries_vcx/src/protocols/connection/generic/mod.rs +++ b/aries_vcx/src/protocols/connection/generic/mod.rs @@ -21,9 +21,9 @@ use crate::{ requested::Requested as InviterRequested, }, pairwise_info::PairwiseInfo, - traits::{TheirDidDoc, ThreadId}, - Transport, + trait_bounds::{TheirDidDoc, ThreadId}, }, + transport::Transport, }; use super::basic_send_message; diff --git a/aries_vcx/src/protocols/connection/invitee/mod.rs b/aries_vcx/src/protocols/connection/invitee/mod.rs index 07ee6f0f76..cd1dbf5a20 100644 --- a/aries_vcx/src/protocols/connection/invitee/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/mod.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use messages::protocols::connection::invite::Invitation; -use crate::{common::ledger::transactions::into_did_doc, core::profile::profile::Profile, errors::error::VcxResult}; +use crate::{common::ledger::transactions::into_did_doc, core::profile::profile::Profile, errors::error::VcxResult, transport::Transport}; use self::states::{initial::Initial, invited::Invited, requested::Requested}; @@ -18,7 +18,6 @@ use super::{ common::states::{complete::CompleteState, responded::RespondedState}, initiation_type::Invitee, pairwise_info::PairwiseInfo, - traits::Transport, Connection, }; use crate::{ diff --git a/aries_vcx/src/protocols/connection/invitee/states/invited.rs b/aries_vcx/src/protocols/connection/invitee/states/invited.rs index 6ab793ffde..2e071590d6 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/invited.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/invited.rs @@ -1,6 +1,6 @@ use messages::diddoc::aries::diddoc::AriesDidDoc; -use crate::protocols::connection::traits::{TheirDidDoc, ThreadId}; +use crate::protocols::connection::trait_bounds::{TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Invited { diff --git a/aries_vcx/src/protocols/connection/invitee/states/requested.rs b/aries_vcx/src/protocols/connection/invitee/states/requested.rs index bc6db8907b..4716462716 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/requested.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/requested.rs @@ -1,6 +1,6 @@ use messages::diddoc::aries::diddoc::AriesDidDoc; -use crate::protocols::connection::traits::{HandleProblem, TheirDidDoc, ThreadId}; +use crate::protocols::connection::trait_bounds::{HandleProblem, TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Requested { diff --git a/aries_vcx/src/protocols/connection/inviter/mod.rs b/aries_vcx/src/protocols/connection/inviter/mod.rs index 423b0cb7c4..812a9be024 100644 --- a/aries_vcx/src/protocols/connection/inviter/mod.rs +++ b/aries_vcx/src/protocols/connection/inviter/mod.rs @@ -3,6 +3,7 @@ pub mod states; use std::sync::Arc; use crate::handlers::util::verify_thread_id; +use crate::transport::Transport; use crate::utils::uuid; use crate::{ common::signing::sign_connection_response, errors::error::VcxResult, plugins::wallet::base_wallet::BaseWallet, @@ -12,7 +13,6 @@ use self::states::initial::Initial; use self::states::{invited::Invited, requested::Requested}; use super::common::states::complete::CompleteState; use super::common::states::responded::RespondedState; -use super::traits::Transport; use super::{initiation_type::Inviter, pairwise_info::PairwiseInfo, Connection}; use messages::a2a::A2AMessage; use messages::protocols::connection::invite::PairwiseInvitation; diff --git a/aries_vcx/src/protocols/connection/inviter/states/initial.rs b/aries_vcx/src/protocols/connection/inviter/states/initial.rs index e290e1993b..88238d2d54 100644 --- a/aries_vcx/src/protocols/connection/inviter/states/initial.rs +++ b/aries_vcx/src/protocols/connection/inviter/states/initial.rs @@ -1,6 +1,6 @@ use messages::protocols::connection::invite::Invitation; -use crate::protocols::connection::traits::ThreadId; +use crate::protocols::connection::trait_bounds::ThreadId; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Initial { diff --git a/aries_vcx/src/protocols/connection/inviter/states/invited.rs b/aries_vcx/src/protocols/connection/inviter/states/invited.rs index 592b2aa714..d61e490b79 100644 --- a/aries_vcx/src/protocols/connection/inviter/states/invited.rs +++ b/aries_vcx/src/protocols/connection/inviter/states/invited.rs @@ -1,4 +1,4 @@ -use crate::protocols::connection::traits::HandleProblem; +use crate::protocols::connection::trait_bounds::HandleProblem; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Invited { diff --git a/aries_vcx/src/protocols/connection/inviter/states/requested.rs b/aries_vcx/src/protocols/connection/inviter/states/requested.rs index 7134cbc34c..b004c66c8c 100644 --- a/aries_vcx/src/protocols/connection/inviter/states/requested.rs +++ b/aries_vcx/src/protocols/connection/inviter/states/requested.rs @@ -1,6 +1,6 @@ use messages::{diddoc::aries::diddoc::AriesDidDoc, protocols::connection::response::SignedResponse}; -use crate::protocols::connection::traits::{TheirDidDoc, ThreadId}; +use crate::protocols::connection::trait_bounds::{TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Requested { diff --git a/aries_vcx/src/protocols/connection/mod.rs b/aries_vcx/src/protocols/connection/mod.rs index 517c644547..a6a885e70d 100644 --- a/aries_vcx/src/protocols/connection/mod.rs +++ b/aries_vcx/src/protocols/connection/mod.rs @@ -5,7 +5,7 @@ pub mod invitee; pub mod inviter; pub mod pairwise_info; mod serializable; -mod traits; +mod trait_bounds; use messages::{ a2a::{protocol_registry::ProtocolRegistry, A2AMessage}, @@ -20,6 +20,7 @@ use std::{error::Error, sync::Arc}; use crate::{ errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult}, plugins::wallet::base_wallet::BaseWallet, + transport::Transport, utils::encryption_envelope::EncryptionEnvelope, }; @@ -27,11 +28,10 @@ use self::{ common::states::complete::CompleteState, generic::GenericState, pairwise_info::PairwiseInfo, - traits::{HandleProblem, TheirDidDoc, ThreadId}, + trait_bounds::{HandleProblem, TheirDidDoc, ThreadId}, }; pub use self::generic::{GenericConnection, State, ThinState}; -pub use self::traits::Transport; #[derive(Clone, Deserialize)] #[serde(try_from = "GenericConnection")] diff --git a/aries_vcx/src/protocols/connection/traits.rs b/aries_vcx/src/protocols/connection/trait_bounds.rs similarity index 61% rename from aries_vcx/src/protocols/connection/traits.rs rename to aries_vcx/src/protocols/connection/trait_bounds.rs index 239503ea7c..ad8a6fa46e 100644 --- a/aries_vcx/src/protocols/connection/traits.rs +++ b/aries_vcx/src/protocols/connection/trait_bounds.rs @@ -1,26 +1,17 @@ -use async_trait::async_trait; use messages::diddoc::aries::diddoc::AriesDidDoc; -use crate::errors::error::VcxResult; - /// Trait used for implementing common [`super::Connection`] behavior based /// on states implementing it. pub trait TheirDidDoc { fn their_did_doc(&self) -> &AriesDidDoc; } -/// Trait used for implementing a mechanism to send a message, used by [`super::Connection`]. -#[async_trait] -pub trait Transport { - async fn send_message(&self, msg: Vec, service_endpoint: &str) -> VcxResult<()>; -} - /// Trait used for implementing common [`super::Connection`] behavior based /// on states implementing it. pub trait ThreadId { fn thread_id(&self) -> &str; } -/// Marker trait used for implementing [`messages::protocols::connection::problem_report::ProblemReport`] +/// Marker trait used for implementing [`messages::protocols::connection::problem_report::ProblemReport`] /// handling on certain [`super::Connection`] types. pub trait HandleProblem {} diff --git a/aries_vcx/src/transport.rs b/aries_vcx/src/transport.rs new file mode 100644 index 0000000000..68488efbf4 --- /dev/null +++ b/aries_vcx/src/transport.rs @@ -0,0 +1,19 @@ +use async_trait::async_trait; + +use crate::errors::error::VcxResult; + +/// Trait used for implementing a mechanism to send a message, used by [`super::Connection`]. +#[async_trait] +pub trait Transport: Send + Sync { + async fn send_message(&self, msg: Vec, service_endpoint: &str) -> VcxResult<()>; +} + +#[async_trait] +impl Transport for &T +where + T: Transport + ?Sized, +{ + async fn send_message(&self, msg: Vec, service_endpoint: &str) -> VcxResult<()> { + self.send_message(msg, service_endpoint).await + } +} diff --git a/libvcx/src/api_vcx/api_handle/connection.rs b/libvcx/src/api_vcx/api_handle/connection.rs index 3d28f3e738..8743965c34 100644 --- a/libvcx/src/api_vcx/api_handle/connection.rs +++ b/libvcx/src/api_vcx/api_handle/connection.rs @@ -6,8 +6,9 @@ use aries_vcx::{ messages::protocols::basic_message::message::BasicMessage, protocols::connection::{ invitee::InviteeConnection, inviter::InviterConnection, pairwise_info::PairwiseInfo, Connection, - GenericConnection, State, Transport, + GenericConnection, State, }, + transport::Transport, }; use async_trait::async_trait; use rand::Rng; From e30200dd3830448a4cd97544a5b2244153a84049 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Wed, 1 Feb 2023 18:13:25 +0200 Subject: [PATCH 34/66] Fix FFI wrapper to return a Promise for the async request handling Signed-off-by: Bogdan Mircea --- wrappers/vcx-napi-rs/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/vcx-napi-rs/index.d.ts b/wrappers/vcx-napi-rs/index.d.ts index 3ffcdff69e..b633692a0c 100644 --- a/wrappers/vcx-napi-rs/index.d.ts +++ b/wrappers/vcx-napi-rs/index.d.ts @@ -15,7 +15,7 @@ export function connectionGetPairwiseInfo(handle: number): string export function connectionGetRemoteDid(handle: number): string export function connectionGetState(handle: number): number export function connectionGetInvitation(handle: number): string -export function connectionProcessInvite(handle: number, invitation: string): void +export function connectionProcessInvite(handle: number, invitation: string): Promise export function connectionProcessRequest(handle: number, request: string, serviceEndpoint: string, routingKeys: Array): Promise export function connectionProcessResponse(handle: number, response: string): Promise export function connectionProcessAck(handle: number, message: string): Promise From b839c862eea44789105a6b88bdee05aebe5af6e1 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Thu, 2 Feb 2023 11:49:06 +0200 Subject: [PATCH 35/66] Reverting dependencies in vcxagent-core Signed-off-by: Bogdan Mircea --- agents/node/vcxagent-core/package.json | 1 - wrappers/vcx-napi-rs/package.json | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/agents/node/vcxagent-core/package.json b/agents/node/vcxagent-core/package.json index 756a00a647..c44d882bc1 100644 --- a/agents/node/vcxagent-core/package.json +++ b/agents/node/vcxagent-core/package.json @@ -54,7 +54,6 @@ "lodash": "^4.17.21", "mkdirp": "^1.0.4", "node-persist": "^3.1.0", - "ref-napi": "file:../../../../../ref-napi-3.0.3.tgz", "sleep-promise": "^9.0.1", "uuid": "^8.3.2" }, diff --git a/wrappers/vcx-napi-rs/package.json b/wrappers/vcx-napi-rs/package.json index 968ef83542..a496df0414 100644 --- a/wrappers/vcx-napi-rs/package.json +++ b/wrappers/vcx-napi-rs/package.json @@ -51,4 +51,4 @@ "@hyperledger/vcx-napi-rs-linux-x64-gnu": "undefined", "@hyperledger/vcx-napi-rs-linux-x64-musl": "undefined" } -} \ No newline at end of file +} From b2ce58e9e2fcd2ad310e6cf11f8bee8944eb8144 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Thu, 2 Feb 2023 12:39:25 +0200 Subject: [PATCH 36/66] Ignore dist dirs Signed-off-by: Bogdan Mircea --- .gitignore | 1 + wrappers/vcx-napi-rs/package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 63bbf362f3..427e3cfe5e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ **/.DS_Store **/node_modules **/*.node +**/dist wrappers/ios/vcx/vcx.framework/** wrappers/ios/vcx/vcx.framework.dSYM/** wrappers/ios_legacy/vcx/vcx.framework/** diff --git a/wrappers/vcx-napi-rs/package.json b/wrappers/vcx-napi-rs/package.json index a496df0414..968ef83542 100644 --- a/wrappers/vcx-napi-rs/package.json +++ b/wrappers/vcx-napi-rs/package.json @@ -51,4 +51,4 @@ "@hyperledger/vcx-napi-rs-linux-x64-gnu": "undefined", "@hyperledger/vcx-napi-rs-linux-x64-musl": "undefined" } -} +} \ No newline at end of file From 876a09940cc7c049d9b8ea04c005412a093ab701 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Thu, 2 Feb 2023 16:28:58 +0200 Subject: [PATCH 37/66] Reverted NAPI changes and mimicked old connection states more accurately for backwards compatibility Signed-off-by: Bogdan Mircea --- .../src/services/connection.rs | 3 +- .../connection/common/states/complete.rs | 10 +- .../{invitee => common}/states/initial.rs | 0 .../protocols/connection/common/states/mod.rs | 3 +- .../connection/common/states/responded.rs | 8 +- .../connection/generic/conversions.rs | 36 +- .../src/protocols/connection/generic/mod.rs | 32 +- .../src/protocols/connection/invitee/mod.rs | 19 +- .../connection/invitee/states/mod.rs | 3 +- .../src/protocols/connection/inviter/mod.rs | 82 +- .../connection/inviter/states/initial.rs | 20 - .../connection/inviter/states/invited.rs | 18 +- .../connection/inviter/states/mod.rs | 3 +- aries_vcx/src/protocols/connection/mod.rs | 4 +- .../src/protocols/connection/serializable.rs | 38 +- libvcx/src/api_vcx/api_handle/connection.rs | 30 +- wrappers/node/package-lock.json | 1397 +++++++++++++---- .../test/suite1/ariesvcx-connection.test.ts | 6 +- wrappers/vcx-napi-rs/package-lock.json | 24 +- 19 files changed, 1207 insertions(+), 529 deletions(-) rename aries_vcx/src/protocols/connection/{invitee => common}/states/initial.rs (100%) delete mode 100644 aries_vcx/src/protocols/connection/inviter/states/initial.rs diff --git a/agents/rust/aries-vcx-agent/src/services/connection.rs b/agents/rust/aries-vcx-agent/src/services/connection.rs index e936a7045c..04a473973b 100644 --- a/agents/rust/aries-vcx-agent/src/services/connection.rs +++ b/agents/rust/aries-vcx-agent/src/services/connection.rs @@ -32,7 +32,8 @@ impl ServiceConnections { pub async fn create_invitation(&self, pw_info: Option) -> AgentResult { let pw_info = pw_info.unwrap_or(PairwiseInfo::create(&self.profile.inject_wallet()).await?); - let inviter = Connection::new_inviter("".to_owned(), pw_info, vec![], self.service_endpoint.clone()); + let inviter = + Connection::new_inviter("".to_owned(), pw_info).create_invitation(vec![], self.service_endpoint.clone()); let invite = inviter.get_invitation().clone(); let thread_id = inviter.thread_id().to_owned(); diff --git a/aries_vcx/src/protocols/connection/common/states/complete.rs b/aries_vcx/src/protocols/connection/common/states/complete.rs index 955c0ec003..d624d14ac1 100644 --- a/aries_vcx/src/protocols/connection/common/states/complete.rs +++ b/aries_vcx/src/protocols/connection/common/states/complete.rs @@ -6,13 +6,13 @@ use messages::protocols::discovery::disclose::{Disclose, ProtocolDescriptor}; use crate::protocols::connection::trait_bounds::{TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct CompleteState { +pub struct Complete { pub(crate) did_doc: AriesDidDoc, pub(crate) thread_id: String, pub(crate) protocols: Option>, } -impl CompleteState { +impl Complete { pub fn new(did_doc: AriesDidDoc, thread_id: String, protocols: Option>) -> Self { Self { did_doc, @@ -30,14 +30,14 @@ impl CompleteState { } } -impl TheirDidDoc for CompleteState { +impl TheirDidDoc for Complete { fn their_did_doc(&self) -> &AriesDidDoc { &self.did_doc } } -impl ThreadId for CompleteState { +impl ThreadId for Complete { fn thread_id(&self) -> &str { &self.thread_id } -} \ No newline at end of file +} diff --git a/aries_vcx/src/protocols/connection/invitee/states/initial.rs b/aries_vcx/src/protocols/connection/common/states/initial.rs similarity index 100% rename from aries_vcx/src/protocols/connection/invitee/states/initial.rs rename to aries_vcx/src/protocols/connection/common/states/initial.rs diff --git a/aries_vcx/src/protocols/connection/common/states/mod.rs b/aries_vcx/src/protocols/connection/common/states/mod.rs index 77cc20b701..2f2acaa2f5 100644 --- a/aries_vcx/src/protocols/connection/common/states/mod.rs +++ b/aries_vcx/src/protocols/connection/common/states/mod.rs @@ -1,2 +1,3 @@ pub mod complete; -pub mod responded; \ No newline at end of file +pub mod responded; +pub mod initial; \ No newline at end of file diff --git a/aries_vcx/src/protocols/connection/common/states/responded.rs b/aries_vcx/src/protocols/connection/common/states/responded.rs index ba7548b592..36d2f0a79a 100644 --- a/aries_vcx/src/protocols/connection/common/states/responded.rs +++ b/aries_vcx/src/protocols/connection/common/states/responded.rs @@ -3,24 +3,24 @@ use messages::diddoc::aries::diddoc::AriesDidDoc; use crate::protocols::connection::trait_bounds::{TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct RespondedState { +pub struct Responded { pub(crate) did_doc: AriesDidDoc, pub(crate) thread_id: String, } -impl RespondedState { +impl Responded { pub fn new(did_doc: AriesDidDoc, thread_id: String) -> Self { Self { did_doc, thread_id } } } -impl TheirDidDoc for RespondedState { +impl TheirDidDoc for Responded { fn their_did_doc(&self) -> &AriesDidDoc { &self.did_doc } } -impl ThreadId for RespondedState { +impl ThreadId for Responded { fn thread_id(&self) -> &str { &self.thread_id } diff --git a/aries_vcx/src/protocols/connection/generic/conversions.rs b/aries_vcx/src/protocols/connection/generic/conversions.rs index 43ead03cfc..168d5922fb 100644 --- a/aries_vcx/src/protocols/connection/generic/conversions.rs +++ b/aries_vcx/src/protocols/connection/generic/conversions.rs @@ -2,16 +2,10 @@ use super::{GenericConnection, GenericState, InviteeState, InviterState}; use crate::{ errors::error::{AriesVcxError, AriesVcxErrorKind}, protocols::connection::{ - common::states::{complete::CompleteState, responded::RespondedState}, + common::states::{complete::Complete, initial::Initial, responded::Responded}, initiation_type::{Invitee, Inviter}, - invitee::states::{ - initial::Initial as InviteeInitial, invited::Invited as InviteeInvited, - requested::Requested as InviteeRequested, - }, - inviter::states::{ - initial::Initial as InviterInitial, invited::Invited as InviterInvited, - requested::Requested as InviterRequested, - }, + invitee::states::{invited::Invited as InviteeInvited, requested::Requested as InviteeRequested}, + inviter::states::{invited::Invited as InviterInvited, requested::Requested as InviterRequested}, Connection, }, }; @@ -103,17 +97,17 @@ where from_concrete_to_vague!(Inviter, InviterState, Inviter, GenericState); from_concrete_to_vague!(Invitee, InviteeState, Invitee, GenericState); -from_concrete_to_vague!(InviterInitial, Initial, InviterState); +from_concrete_to_vague!(Initial, Initial, InviterState); from_concrete_to_vague!(InviterInvited, Invited, InviterState); from_concrete_to_vague!(InviterRequested, Requested, InviterState); -from_concrete_to_vague!(RespondedState, Responded, InviterState); -from_concrete_to_vague!(CompleteState, Complete, InviterState); +from_concrete_to_vague!(Responded, Responded, InviterState); +from_concrete_to_vague!(Complete, Complete, InviterState); -from_concrete_to_vague!(InviteeInitial, Initial, InviteeState); +from_concrete_to_vague!(Initial, Initial, InviteeState); from_concrete_to_vague!(InviteeInvited, Invited, InviteeState); from_concrete_to_vague!(InviteeRequested, Requested, InviteeState); -from_concrete_to_vague!(RespondedState, Responded, InviteeState); -from_concrete_to_vague!(CompleteState, Complete, InviteeState); +from_concrete_to_vague!(Responded, Responded, InviteeState); +from_concrete_to_vague!(Complete, Complete, InviteeState); // ---------------------------- Try From Vague State to Concrete State implementations ---------------------------- impl TryFrom for Connection @@ -132,14 +126,14 @@ where try_from_vague_to_concrete!(InviterState, Inviter, Invitee, Inviter); try_from_vague_to_concrete!(InviteeState, Invitee, Inviter, Invitee); -try_from_vague_to_concrete!(InviterState, Initial, InviterInitial); +try_from_vague_to_concrete!(InviterState, Initial, Initial); try_from_vague_to_concrete!(InviterState, Invited, InviterInvited); try_from_vague_to_concrete!(InviterState, Requested, InviterRequested); -try_from_vague_to_concrete!(InviterState, Responded, RespondedState); -try_from_vague_to_concrete!(InviterState, Complete, CompleteState); +try_from_vague_to_concrete!(InviterState, Responded, Responded); +try_from_vague_to_concrete!(InviterState, Complete, Complete); -try_from_vague_to_concrete!(InviteeState, Initial, InviteeInitial); +try_from_vague_to_concrete!(InviteeState, Initial, Initial); try_from_vague_to_concrete!(InviteeState, Invited, InviteeInvited); try_from_vague_to_concrete!(InviteeState, Requested, InviteeRequested); -try_from_vague_to_concrete!(InviteeState, Responded, RespondedState); -try_from_vague_to_concrete!(InviteeState, Complete, CompleteState); +try_from_vague_to_concrete!(InviteeState, Responded, Responded); +try_from_vague_to_concrete!(InviteeState, Complete, Complete); diff --git a/aries_vcx/src/protocols/connection/generic/mod.rs b/aries_vcx/src/protocols/connection/generic/mod.rs index 92642db4e6..d7cbdb824c 100644 --- a/aries_vcx/src/protocols/connection/generic/mod.rs +++ b/aries_vcx/src/protocols/connection/generic/mod.rs @@ -11,22 +11,16 @@ use crate::{ errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult}, plugins::wallet::base_wallet::BaseWallet, protocols::connection::{ - common::states::{complete::CompleteState, responded::RespondedState}, - invitee::states::{ - initial::Initial as InviteeInitial, invited::Invited as InviteeInvited, - requested::Requested as InviteeRequested, - }, - inviter::states::{ - initial::Initial as InviterInitial, invited::Invited as InviterInvited, - requested::Requested as InviterRequested, - }, + common::states::{complete::Complete, responded::Responded}, + invitee::states::{invited::Invited as InviteeInvited, requested::Requested as InviteeRequested}, + inviter::states::{invited::Invited as InviterInvited, requested::Requested as InviterRequested}, pairwise_info::PairwiseInfo, trait_bounds::{TheirDidDoc, ThreadId}, }, transport::Transport, }; -use super::basic_send_message; +use super::{basic_send_message, common::states::initial::Initial}; /// A type that can encapsulate a [`Connection`] of any state. /// While mainly used for deserialization, it exposes some methods for retrieving @@ -73,20 +67,20 @@ pub enum GenericState { #[derive(Clone, Debug, Serialize, Deserialize)] pub enum InviterState { - Initial(InviterInitial), + Initial(Initial), Invited(InviterInvited), Requested(InviterRequested), - Responded(RespondedState), - Complete(CompleteState), + Responded(Responded), + Complete(Complete), } #[derive(Clone, Debug, Serialize, Deserialize)] pub enum InviteeState { - Initial(InviteeInitial), + Initial(Initial), Invited(InviteeInvited), Requested(InviteeRequested), - Responded(RespondedState), - Complete(CompleteState), + Responded(Responded), + Complete(Complete), } impl GenericConnection { @@ -104,8 +98,8 @@ impl GenericConnection { GenericState::Invitee(InviteeState::Requested(s)) => Some(s.thread_id()), GenericState::Invitee(InviteeState::Responded(s)) => Some(s.thread_id()), GenericState::Invitee(InviteeState::Complete(s)) => Some(s.thread_id()), - GenericState::Inviter(InviterState::Initial(s)) => Some(s.thread_id()), - GenericState::Inviter(InviterState::Invited(s)) => s.opt_thread_id(), + GenericState::Inviter(InviterState::Initial(_)) => None, + GenericState::Inviter(InviterState::Invited(s)) => Some(s.thread_id()), GenericState::Inviter(InviterState::Requested(s)) => Some(s.thread_id()), GenericState::Inviter(InviterState::Responded(s)) => Some(s.thread_id()), GenericState::Inviter(InviterState::Complete(s)) => Some(s.thread_id()), @@ -153,7 +147,7 @@ impl GenericConnection { pub fn invitation(&self) -> Option<&Invitation> { match &self.state { - GenericState::Inviter(InviterState::Initial(s)) => Some(&s.invitation), + GenericState::Inviter(InviterState::Invited(s)) => Some(&s.invitation), _ => None, } } diff --git a/aries_vcx/src/protocols/connection/invitee/mod.rs b/aries_vcx/src/protocols/connection/invitee/mod.rs index cd1dbf5a20..f5b1cd0159 100644 --- a/aries_vcx/src/protocols/connection/invitee/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/mod.rs @@ -4,9 +4,12 @@ use std::sync::Arc; use messages::protocols::connection::invite::Invitation; -use crate::{common::ledger::transactions::into_did_doc, core::profile::profile::Profile, errors::error::VcxResult, transport::Transport}; +use crate::{ + common::ledger::transactions::into_did_doc, core::profile::profile::Profile, errors::error::VcxResult, + transport::Transport, +}; -use self::states::{initial::Initial, invited::Invited, requested::Requested}; +use self::states::{invited::Invited, requested::Requested}; use messages::{ a2a::A2AMessage, @@ -15,7 +18,7 @@ use messages::{ }; use super::{ - common::states::{complete::CompleteState, responded::RespondedState}, + common::states::{complete::Complete, initial::Initial, responded::Responded}, initiation_type::Invitee, pairwise_info::PairwiseInfo, Connection, @@ -125,7 +128,7 @@ impl InviteeConnection { wallet: &Arc, response: SignedResponse, transport: &T, - ) -> VcxResult> + ) -> VcxResult> where T: Transport, { @@ -149,7 +152,7 @@ impl InviteeConnection { } }?; - let state = RespondedState::new(did_doc, self.state.thread_id); + let state = Responded::new(did_doc, self.state.thread_id); Ok(Connection { state, @@ -160,12 +163,12 @@ impl InviteeConnection { } } -impl InviteeConnection { +impl InviteeConnection { pub async fn send_ack( self, wallet: &Arc, transport: &T, - ) -> VcxResult> + ) -> VcxResult> where T: Transport, { @@ -176,7 +179,7 @@ impl InviteeConnection { self.send_message(wallet, &msg, transport).await?; - let state = CompleteState::new(self.state.did_doc, self.state.thread_id, None); + let state = Complete::new(self.state.did_doc, self.state.thread_id, None); Ok(Connection { state, diff --git a/aries_vcx/src/protocols/connection/invitee/states/mod.rs b/aries_vcx/src/protocols/connection/invitee/states/mod.rs index d4151d969c..0cbaf26c40 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/mod.rs @@ -1,3 +1,2 @@ pub mod invited; -pub mod requested; -pub mod initial; \ No newline at end of file +pub mod requested; \ No newline at end of file diff --git a/aries_vcx/src/protocols/connection/inviter/mod.rs b/aries_vcx/src/protocols/connection/inviter/mod.rs index 812a9be024..4b588dc564 100644 --- a/aries_vcx/src/protocols/connection/inviter/mod.rs +++ b/aries_vcx/src/protocols/connection/inviter/mod.rs @@ -3,16 +3,17 @@ pub mod states; use std::sync::Arc; use crate::handlers::util::verify_thread_id; +use crate::protocols::connection::trait_bounds::ThreadId; use crate::transport::Transport; use crate::utils::uuid; use crate::{ common::signing::sign_connection_response, errors::error::VcxResult, plugins::wallet::base_wallet::BaseWallet, }; -use self::states::initial::Initial; use self::states::{invited::Invited, requested::Requested}; -use super::common::states::complete::CompleteState; -use super::common::states::responded::RespondedState; +use super::common::states::complete::Complete; +use super::common::states::initial::Initial; +use super::common::states::responded::Responded; use super::{initiation_type::Inviter, pairwise_info::PairwiseInfo, Connection}; use messages::a2a::A2AMessage; use messages::protocols::connection::invite::PairwiseInvitation; @@ -25,56 +26,35 @@ use messages::protocols::connection::{ pub type InviterConnection = Connection; impl InviterConnection { - pub fn new_inviter( - source_id: String, - pairwise_info: PairwiseInfo, - routing_keys: Vec, - service_endpoint: String, - ) -> Self { + pub fn new_inviter(source_id: String, pairwise_info: PairwiseInfo) -> Self { + Self { + source_id, + state: Initial, + pairwise_info, + initiation_type: Inviter, + } + } + + pub fn create_invitation(self, routing_keys: Vec, service_endpoint: String) -> InviterConnection { let invite: PairwiseInvitation = PairwiseInvitation::create() .set_id(&uuid::uuid()) - .set_label(&source_id) - .set_recipient_keys(vec![pairwise_info.pw_vk.clone()]) + .set_label(&self.source_id) + .set_recipient_keys(vec![self.pairwise_info.pw_vk.clone()]) .set_routing_keys(routing_keys) .set_service_endpoint(service_endpoint); let invitation = Invitation::Pairwise(invite); - Self { - source_id, - state: Initial::new(invitation), - pairwise_info, - initiation_type: Inviter, + Connection { + source_id: self.source_id, + pairwise_info: self.pairwise_info, + initiation_type: self.initiation_type, + state: Invited::new(invitation), } } - - pub fn get_invitation(&self) -> &Invitation { - &self.state.invitation - } } impl InviterConnection { - /// Creates an [`InviterConnection`], essentially bypassing the [`InitialState`] - /// where an [`Invitation`] is created. - /// - /// This is useful for cases where an [`Invitation`] is received by the invitee without - /// any interaction from the inviter, thus the next logical step is to wait for the invitee - /// to send a connection request. - pub fn new_awaiting_request(source_id: String, pairwise_info: PairwiseInfo) -> Self { - Self { - source_id, - state: Invited::new(None), // what should the thread ID be in this case??? - pairwise_info, - initiation_type: Inviter, - } - } - - /// As the inviter connection can be started directly in the invited state, - /// like with a public invitation, we might or might not have a thread ID. - pub fn opt_thread_id(&self) -> Option<&str> { - self.state.opt_thread_id() - } - // This should ideally belong in the Connection // but was placed here to retro-fit the previous API. async fn build_response( @@ -116,11 +96,7 @@ impl InviterConnection { ); // There must be some other way to validate the thread ID other than cloning the entire Request - self.state - .thread_id - .as_ref() - .map(|thread_id| verify_thread_id(thread_id, &A2AMessage::ConnectionRequest(request.clone()))) - .unwrap_or(Ok(()))?; + verify_thread_id(self.state.thread_id(), &A2AMessage::ConnectionRequest(request.clone()))?; // If the request's DidDoc validation fails, we generate and send a ProblemReport. // We then return early with the provided error. @@ -160,6 +136,10 @@ impl InviterConnection { state, }) } + + pub fn get_invitation(&self) -> &Invitation { + &self.state.invitation + } } impl InviterConnection { @@ -167,7 +147,7 @@ impl InviterConnection { self, wallet: &Arc, transport: &T, - ) -> VcxResult> + ) -> VcxResult> where T: Transport, { @@ -181,7 +161,7 @@ impl InviterConnection { self.send_message(wallet, &self.state.signed_response.to_a2a_message(), transport) .await?; - let state = RespondedState::new(self.state.did_doc, thread_id); + let state = Responded::new(self.state.did_doc, thread_id); Ok(Connection { state, @@ -192,10 +172,10 @@ impl InviterConnection { } } -impl InviterConnection { - pub fn acknowledge_connection(self, msg: &A2AMessage) -> VcxResult> { +impl InviterConnection { + pub fn acknowledge_connection(self, msg: &A2AMessage) -> VcxResult> { verify_thread_id(&self.state.thread_id, msg)?; - let state = CompleteState::new(self.state.did_doc, self.state.thread_id, None); + let state = Complete::new(self.state.did_doc, self.state.thread_id, None); Ok(Connection { source_id: self.source_id, diff --git a/aries_vcx/src/protocols/connection/inviter/states/initial.rs b/aries_vcx/src/protocols/connection/inviter/states/initial.rs deleted file mode 100644 index 88238d2d54..0000000000 --- a/aries_vcx/src/protocols/connection/inviter/states/initial.rs +++ /dev/null @@ -1,20 +0,0 @@ -use messages::protocols::connection::invite::Invitation; - -use crate::protocols::connection::trait_bounds::ThreadId; - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct Initial { - pub(crate) invitation: Invitation, -} - -impl Initial { - pub fn new(invitation: Invitation) -> Self { - Self { invitation } - } -} - -impl ThreadId for Initial { - fn thread_id(&self) -> &str { - self.invitation.get_id() - } -} diff --git a/aries_vcx/src/protocols/connection/inviter/states/invited.rs b/aries_vcx/src/protocols/connection/inviter/states/invited.rs index d61e490b79..a18bd55d94 100644 --- a/aries_vcx/src/protocols/connection/inviter/states/invited.rs +++ b/aries_vcx/src/protocols/connection/inviter/states/invited.rs @@ -1,19 +1,21 @@ -use crate::protocols::connection::trait_bounds::HandleProblem; +use messages::protocols::connection::invite::Invitation; + +use crate::protocols::connection::trait_bounds::{HandleProblem, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Invited { - pub(crate) thread_id: Option, + pub(crate) invitation: Invitation, } impl Invited { - pub fn new(thread_id: Option) -> Self { - Self { thread_id } + pub fn new(invitation: Invitation) -> Self { + Self { invitation } } +} - /// Unlike other states, the ones implementing the [`crate::protocols::typestate_con::traits::ThreadId`], - /// this state may or may not have a thread ID, so we're returning an option. - pub fn opt_thread_id(&self) -> Option<&str> { - self.thread_id.as_deref() +impl ThreadId for Invited { + fn thread_id(&self) -> &str { + self.invitation.get_id() } } diff --git a/aries_vcx/src/protocols/connection/inviter/states/mod.rs b/aries_vcx/src/protocols/connection/inviter/states/mod.rs index d4151d969c..0cbaf26c40 100644 --- a/aries_vcx/src/protocols/connection/inviter/states/mod.rs +++ b/aries_vcx/src/protocols/connection/inviter/states/mod.rs @@ -1,3 +1,2 @@ pub mod invited; -pub mod requested; -pub mod initial; \ No newline at end of file +pub mod requested; \ No newline at end of file diff --git a/aries_vcx/src/protocols/connection/mod.rs b/aries_vcx/src/protocols/connection/mod.rs index a6a885e70d..8ca6c24a88 100644 --- a/aries_vcx/src/protocols/connection/mod.rs +++ b/aries_vcx/src/protocols/connection/mod.rs @@ -25,7 +25,7 @@ use crate::{ }; use self::{ - common::states::complete::CompleteState, + common::states::complete::Complete, generic::GenericState, pairwise_info::PairwiseInfo, trait_bounds::{HandleProblem, TheirDidDoc, ThreadId}, @@ -158,7 +158,7 @@ where } } -impl Connection { +impl Connection { pub fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { self.state.remote_protocols() } diff --git a/aries_vcx/src/protocols/connection/serializable.rs b/aries_vcx/src/protocols/connection/serializable.rs index 0baf17610e..c49dff03b2 100644 --- a/aries_vcx/src/protocols/connection/serializable.rs +++ b/aries_vcx/src/protocols/connection/serializable.rs @@ -1,20 +1,16 @@ use serde::Serialize; use crate::protocols::connection::{ - common::states::{complete::CompleteState, responded::RespondedState}, + common::states::{complete::Complete, responded::Responded}, initiation_type::{Invitee, Inviter}, - invitee::states::{ - initial::Initial as InviteeInitial, invited::Invited as InviteeInvited, - requested::Requested as InviteeRequested, - }, - inviter::states::{ - initial::Initial as InviterInitial, invited::Invited as InviterInvited, - requested::Requested as InviterRequested, - }, + invitee::states::{invited::Invited as InviteeInvited, requested::Requested as InviteeRequested}, + inviter::states::{invited::Invited as InviterInvited, requested::Requested as InviterRequested}, pairwise_info::PairwiseInfo, Connection, }; +use super::common::states::initial::Initial; + /// Macro used for boilerplace implementation of the /// [`From`] trait from a concrete connection state to the equivalent reference state /// used for serialization. @@ -60,20 +56,20 @@ pub enum RefState<'a> { #[derive(Debug, Serialize)] pub enum RefInviterState<'a> { - Initial(&'a InviterInitial), + Initial(&'a Initial), Invited(&'a InviterInvited), Requested(&'a InviterRequested), - Responded(&'a RespondedState), - Complete(&'a CompleteState), + Responded(&'a Responded), + Complete(&'a Complete), } #[derive(Debug, Serialize)] pub enum RefInviteeState<'a> { - Initial(&'a InviteeInitial), + Initial(&'a Initial), Invited(&'a InviteeInvited), Requested(&'a InviteeRequested), - Responded(&'a RespondedState), - Complete(&'a CompleteState), + Responded(&'a Responded), + Complete(&'a Complete), } impl<'a, I, S> From<&'a Connection> for SerializableConnection<'a> @@ -91,17 +87,17 @@ where from_concrete_to_serializable!(Inviter, RefInviterState, Inviter, RefState); from_concrete_to_serializable!(Invitee, RefInviteeState, Invitee, RefState); -from_concrete_to_serializable!(InviterInitial, Initial, RefInviterState); +from_concrete_to_serializable!(Initial, Initial, RefInviterState); from_concrete_to_serializable!(InviterInvited, Invited, RefInviterState); from_concrete_to_serializable!(InviterRequested, Requested, RefInviterState); -from_concrete_to_serializable!(RespondedState, Responded, RefInviterState); -from_concrete_to_serializable!(CompleteState, Complete, RefInviterState); +from_concrete_to_serializable!(Responded, Responded, RefInviterState); +from_concrete_to_serializable!(Complete, Complete, RefInviterState); -from_concrete_to_serializable!(InviteeInitial, Initial, RefInviteeState); +from_concrete_to_serializable!(Initial, Initial, RefInviteeState); from_concrete_to_serializable!(InviteeInvited, Invited, RefInviteeState); from_concrete_to_serializable!(InviteeRequested, Requested, RefInviteeState); -from_concrete_to_serializable!(RespondedState, Responded, RefInviteeState); -from_concrete_to_serializable!(CompleteState, Complete, RefInviteeState); +from_concrete_to_serializable!(Responded, Responded, RefInviteeState); +from_concrete_to_serializable!(Complete, Complete, RefInviteeState); impl<'a> SerializableConnection<'a> { fn new(source_id: &'a str, pairwise_info: &'a PairwiseInfo, state: RefState<'a>) -> Self { diff --git a/libvcx/src/api_vcx/api_handle/connection.rs b/libvcx/src/api_vcx/api_handle/connection.rs index 8743965c34..984e803b24 100644 --- a/libvcx/src/api_vcx/api_handle/connection.rs +++ b/libvcx/src/api_vcx/api_handle/connection.rs @@ -109,37 +109,22 @@ pub async fn create_inviter(pw_info: Option) -> LibvcxResult let profile = get_main_profile()?; let pw_info = pw_info.unwrap_or(PairwiseInfo::create(&profile.inject_wallet()).await?); - let con = InviterConnection::new_awaiting_request("".to_owned(), pw_info); + let con = InviterConnection::new_inviter("".to_owned(), pw_info); add_connection(con.into()) } -pub async fn create_invitee(invitation: &str) -> LibvcxResult { +pub async fn create_invitee(_invitation: &str) -> LibvcxResult { trace!("create_invitee >>>"); let profile = get_main_profile()?; - let invitation = deserialize(invitation)?; let pairwise_info = PairwiseInfo::create(&profile.inject_wallet()).await?; - let con = InviteeConnection::new_invitee("".to_owned(), pairwise_info) - .accept_invitation(&profile, &invitation) - .await?; + let con = InviteeConnection::new_invitee("".to_owned(), pairwise_info); add_connection(con.into()) } -// Just trying to retro-fit this. -// It essentially creates an inviter connection in the initial state, also genereting an Invitation. -pub async fn create_invite(handle: u32, service_endpoint: String, routing_keys: Vec) -> LibvcxResult<()> { - trace!("create_invite >>>"); - - let profile = get_main_profile()?; - let pairwise_info = PairwiseInfo::create(&profile.inject_wallet()).await?; - let con = InviterConnection::new_inviter("".to_owned(), pairwise_info, routing_keys, service_endpoint); - - insert_connection(handle, con) -} - // ----------------------------- GETTERS ------------------------------------ pub fn get_thread_id(handle: u32) -> LibvcxResult { trace!("get_thread_id >>> handle: {}", handle); @@ -346,6 +331,15 @@ pub async fn send_generic_message(handle: u32, content: String) -> LibvcxResult< Ok(()) } +pub async fn create_invite(handle: u32, service_endpoint: String, routing_keys: Vec) -> LibvcxResult<()> { + trace!("create_invite >>>"); + + let con = get_cloned_connection(&handle)?; + let con = con.create_invitation(routing_keys, service_endpoint); + + insert_connection(handle, con) +} + // // ------------------------- (DE)SERIALIZATION ---------------------------------- pub fn to_string(handle: u32) -> LibvcxResult { trace!("to_string >>>"); diff --git a/wrappers/node/package-lock.json b/wrappers/node/package-lock.json index 3016882f3f..20bd644c6c 100644 --- a/wrappers/node/package-lock.json +++ b/wrappers/node/package-lock.json @@ -40,7 +40,6 @@ } }, "../vcx-napi-rs": { - "name": "@hyperledger/vcx-napi-rs", "dev": true, "license": "Apache-2.0", "devDependencies": { @@ -57,24 +56,27 @@ }, "node_modules/@babel/code-frame": { "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/highlight": "^7.10.4" } }, "node_modules/@babel/helper-validator-identifier": { "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", @@ -86,8 +88,9 @@ }, "node_modules/@babel/highlight/node_modules/ansi-styles": { "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -97,8 +100,9 @@ }, "node_modules/@babel/highlight/node_modules/chalk": { "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -110,37 +114,42 @@ }, "node_modules/@babel/highlight/node_modules/color-convert": { "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "1.1.3" } }, "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/@babel/highlight/node_modules/has-flag": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/highlight/node_modules/supports-color": { "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -150,8 +159,9 @@ }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -161,8 +171,9 @@ }, "node_modules/@eslint/eslintrc": { "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "dev": true, - "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.1.1", @@ -180,16 +191,18 @@ }, "node_modules/@eslint/eslintrc/node_modules/ignore": { "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/@humanwhocodes/config-array": { "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@humanwhocodes/object-schema": "^1.2.0", "debug": "^4.1.1", @@ -201,8 +214,9 @@ }, "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", - "dev": true, - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true }, "node_modules/@hyperledger/vcx-napi-rs": { "resolved": "../vcx-napi-rs", @@ -210,21 +224,24 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.14", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -232,8 +249,9 @@ }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, - "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -244,16 +262,18 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, - "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, - "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -264,71 +284,84 @@ }, "node_modules/@tsconfig/node10": { "version": "1.0.9", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true }, "node_modules/@tsconfig/node12": { "version": "1.0.11", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true }, "node_modules/@tsconfig/node14": { "version": "1.0.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true }, "node_modules/@tsconfig/node16": { "version": "1.0.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true }, "node_modules/@types/app-module-path": { "version": "2.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/app-module-path/-/app-module-path-2.2.0.tgz", + "integrity": "sha512-r47Kt3ApJDzUU2xCNzaBI25Au5Xfdvf0Gyomveqvg46nQ3J4PaDLicObhyX6cMhvMVWJMB/BnkXdv1E4zxP+6w==", + "dev": true }, "node_modules/@types/chai": { "version": "4.3.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz", + "integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==", + "dev": true }, "node_modules/@types/json-schema": { "version": "7.0.11", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true }, "node_modules/@types/lodash": { - "version": "4.14.188", - "dev": true, - "license": "MIT" + "version": "4.14.191", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", + "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==", + "dev": true }, "node_modules/@types/mocha": { "version": "8.2.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", + "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", + "dev": true }, "node_modules/@types/node": { "version": "12.20.55", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true }, "node_modules/@types/uuid": { "version": "8.3.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", + "dev": true }, "node_modules/@types/weak-napi": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/weak-napi/-/weak-napi-1.0.1.tgz", + "integrity": "sha512-EqTeT7n+f6uxfLFRDcJEOu12dH0AT2fZlb8MTQKDG8E70T7uP//qG4CMdNKV3Ra/cxG7/Z1i04GT7Ll0QriWvQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", + "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", "dev": true, - "license": "MIT", "dependencies": { "@typescript-eslint/experimental-utils": "4.33.0", "@typescript-eslint/scope-manager": "4.33.0", @@ -358,8 +391,9 @@ }, "node_modules/@typescript-eslint/experimental-utils": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", + "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", "dev": true, - "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.7", "@typescript-eslint/scope-manager": "4.33.0", @@ -381,8 +415,9 @@ }, "node_modules/@typescript-eslint/parser": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", + "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/scope-manager": "4.33.0", "@typescript-eslint/types": "4.33.0", @@ -407,8 +442,9 @@ }, "node_modules/@typescript-eslint/scope-manager": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", + "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", "dev": true, - "license": "MIT", "dependencies": { "@typescript-eslint/types": "4.33.0", "@typescript-eslint/visitor-keys": "4.33.0" @@ -423,8 +459,9 @@ }, "node_modules/@typescript-eslint/types": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", + "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", "dev": true, - "license": "MIT", "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" }, @@ -435,8 +472,9 @@ }, "node_modules/@typescript-eslint/typescript-estree": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", + "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/types": "4.33.0", "@typescript-eslint/visitor-keys": "4.33.0", @@ -461,8 +499,9 @@ }, "node_modules/@typescript-eslint/visitor-keys": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", + "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", "dev": true, - "license": "MIT", "dependencies": { "@typescript-eslint/types": "4.33.0", "eslint-visitor-keys": "^2.0.0" @@ -477,13 +516,15 @@ }, "node_modules/@ungap/promise-all-settled": { "version": "1.1.2", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true }, "node_modules/acorn": { "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true, - "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -493,24 +534,27 @@ }, "node_modules/acorn-jsx": { "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/acorn-walk": { "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/ajv": { "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -524,24 +568,27 @@ }, "node_modules/ansi-colors": { "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/ansi-regex": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -553,9 +600,10 @@ } }, "node_modules/anymatch": { - "version": "3.1.2", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, - "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -566,63 +614,72 @@ }, "node_modules/app-module-path": { "version": "2.2.0", - "dev": true, - "license": "BSD-2-Clause" + "resolved": "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz", + "integrity": "sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ==", + "dev": true }, "node_modules/arg": { "version": "4.1.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true }, "node_modules/argparse": { "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, - "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } }, "node_modules/array-union": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/assertion-error": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true, - "license": "MIT", "engines": { "node": "*" } }, "node_modules/astral-regex": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/balanced-match": { "version": "1.0.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "node_modules/binary-extensions": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/brace-expansion": { "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -630,8 +687,9 @@ }, "node_modules/braces": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, - "license": "MIT", "dependencies": { "fill-range": "^7.0.1" }, @@ -641,21 +699,24 @@ }, "node_modules/browser-stdout": { "version": "1.3.1", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true }, "node_modules/callsites": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/camelcase": { "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -665,8 +726,9 @@ }, "node_modules/chai": { "version": "4.3.7", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", + "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", "dev": true, - "license": "MIT", "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.2", @@ -682,8 +744,9 @@ }, "node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -697,14 +760,17 @@ }, "node_modules/check-error": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", "dev": true, - "license": "MIT", "engines": { "node": "*" } }, "node_modules/chokidar": { "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "funding": [ { @@ -712,7 +778,6 @@ "url": "https://paulmillr.com/funding/" } ], - "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -731,8 +796,9 @@ }, "node_modules/cliui": { "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, - "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -741,8 +807,9 @@ }, "node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -752,23 +819,27 @@ }, "node_modules/color-name": { "version": "1.1.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/concat-map": { "version": "0.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true }, "node_modules/create-require": { "version": "1.1.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true }, "node_modules/cross-spawn": { "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, - "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -780,8 +851,9 @@ }, "node_modules/debug": { "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, - "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -796,8 +868,9 @@ }, "node_modules/decamelize": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -806,9 +879,10 @@ } }, "node_modules/deep-eql": { - "version": "4.1.2", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", "dev": true, - "license": "MIT", "dependencies": { "type-detect": "^4.0.0" }, @@ -818,21 +892,24 @@ }, "node_modules/deep-is": { "version": "0.1.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true }, "node_modules/diff": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/dir-glob": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, - "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -842,8 +919,9 @@ }, "node_modules/doctrine": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, - "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -853,13 +931,15 @@ }, "node_modules/emoji-regex": { "version": "8.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/enquirer": { "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", "dev": true, - "license": "MIT", "dependencies": { "ansi-colors": "^4.1.1" }, @@ -869,16 +949,18 @@ }, "node_modules/escalade": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/escape-string-regexp": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -888,8 +970,9 @@ }, "node_modules/eslint": { "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.4.3", @@ -944,8 +1027,9 @@ }, "node_modules/eslint-config-prettier": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-7.2.0.tgz", + "integrity": "sha512-rV4Qu0C3nfJKPOAhFujFxB7RMP+URFyQqqOZW9DMRD7ZDTFyjaIlETU3xzHELt++4ugC0+Jm084HQYkkJe+Ivg==", "dev": true, - "license": "MIT", "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -955,8 +1039,9 @@ }, "node_modules/eslint-plugin-prettier": { "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", + "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", "dev": true, - "license": "MIT", "dependencies": { "prettier-linter-helpers": "^1.0.0" }, @@ -975,8 +1060,9 @@ }, "node_modules/eslint-scope": { "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -987,8 +1073,9 @@ }, "node_modules/eslint-utils": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, - "license": "MIT", "dependencies": { "eslint-visitor-keys": "^2.0.0" }, @@ -1004,16 +1091,18 @@ }, "node_modules/eslint-visitor-keys": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=10" } }, "node_modules/eslint/node_modules/eslint-utils": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, - "license": "MIT", "dependencies": { "eslint-visitor-keys": "^1.1.0" }, @@ -1026,24 +1115,27 @@ }, "node_modules/eslint/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=4" } }, "node_modules/eslint/node_modules/ignore": { "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/espree": { "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "acorn": "^7.4.0", "acorn-jsx": "^5.3.1", @@ -1055,16 +1147,18 @@ }, "node_modules/espree/node_modules/eslint-visitor-keys": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=4" } }, "node_modules/esprima": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, - "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -1075,8 +1169,9 @@ }, "node_modules/esquery": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -1086,16 +1181,18 @@ }, "node_modules/esquery/node_modules/estraverse": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/esrecurse": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -1105,42 +1202,48 @@ }, "node_modules/esrecurse/node_modules/estraverse": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/estraverse": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/esutils": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true }, "node_modules/fast-diff": { "version": "1.2.0", - "dev": true, - "license": "Apache-2.0" + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true }, "node_modules/fast-glob": { "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, - "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -1154,26 +1257,30 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true }, "node_modules/fastq": { - "version": "1.13.0", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, - "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, "node_modules/file-entry-cache": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, - "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" }, @@ -1183,8 +1290,9 @@ }, "node_modules/fill-range": { "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, - "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -1194,8 +1302,9 @@ }, "node_modules/find-up": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, - "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -1209,16 +1318,18 @@ }, "node_modules/flat": { "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, - "license": "BSD-3-Clause", "bin": { "flat": "cli.js" } }, "node_modules/flat-cache": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, - "license": "MIT", "dependencies": { "flatted": "^3.1.0", "rimraf": "^3.0.2" @@ -1229,12 +1340,14 @@ }, "node_modules/flatted": { "version": "3.2.7", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true }, "node_modules/fs-extra": { "version": "4.0.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -1243,13 +1356,16 @@ }, "node_modules/fs.realpath": { "version": "1.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true }, "node_modules/fsevents": { "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, - "license": "MIT", + "hasInstallScript": true, "optional": true, "os": [ "darwin" @@ -1260,40 +1376,46 @@ }, "node_modules/functional-red-black-tree": { "version": "1.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true }, "node_modules/get-caller-file": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, - "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-func-name": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", "dev": true, - "license": "MIT", "engines": { "node": "*" } }, "node_modules/get-symbol-from-current-process-h": { "version": "1.0.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/get-symbol-from-current-process-h/-/get-symbol-from-current-process-h-1.0.2.tgz", + "integrity": "sha512-syloC6fsCt62ELLrr1VKBM1ggOpMdetX9hTrdW77UQdcApPHLmf7CI7OKcN1c9kYuNxKcDe4iJ4FY9sX3aw2xw==" }, "node_modules/get-uv-event-loop-napi-h": { "version": "1.0.6", - "license": "MIT", + "resolved": "https://registry.npmjs.org/get-uv-event-loop-napi-h/-/get-uv-event-loop-napi-h-1.0.6.tgz", + "integrity": "sha512-t5c9VNR84nRoF+eLiz6wFrEp1SE2Acg0wS+Ysa2zF0eROes+LzOfuTaVHxGy8AbS8rq7FHEJzjnCZo1BupwdJg==", "dependencies": { "get-symbol-from-current-process-h": "^1.0.1" } }, "node_modules/glob": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, - "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -1311,8 +1433,9 @@ }, "node_modules/glob-parent": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -1321,9 +1444,10 @@ } }, "node_modules/globals": { - "version": "13.17.0", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, - "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -1336,8 +1460,9 @@ }, "node_modules/globby": { "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, - "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -1355,44 +1480,50 @@ }, "node_modules/graceful-fs": { "version": "4.2.10", - "license": "ISC" + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "node_modules/growl": { "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true, - "license": "MIT", "engines": { "node": ">=4.x" } }, "node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/he": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, - "license": "MIT", "bin": { "he": "bin/he" } }, "node_modules/ignore": { - "version": "5.2.0", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true, - "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/import-fresh": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, - "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -1406,16 +1537,18 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.8.19" } }, "node_modules/inflight": { "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, - "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -1423,13 +1556,15 @@ }, "node_modules/inherits": { "version": "2.0.4", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "node_modules/is-binary-path": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, - "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -1439,24 +1574,27 @@ }, "node_modules/is-extglob": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-glob": { "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, - "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -1466,24 +1604,27 @@ }, "node_modules/is-number": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.12.0" } }, "node_modules/is-plain-obj": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-unicode-supported": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -1493,18 +1634,21 @@ }, "node_modules/isexe": { "version": "2.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, "node_modules/js-tokens": { "version": "4.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, "node_modules/js-yaml": { "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, - "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -1515,25 +1659,29 @@ }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true }, "node_modules/jsonfile": { "version": "4.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "node_modules/levn": { "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, - "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -1544,8 +1692,9 @@ }, "node_modules/locate-path": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, - "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -1558,22 +1707,26 @@ }, "node_modules/lodash": { "version": "4.17.21", - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "node_modules/lodash.merge": { "version": "4.6.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true }, "node_modules/lodash.truncate": { "version": "4.4.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true }, "node_modules/log-symbols": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, - "license": "MIT", "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -1587,16 +1740,18 @@ }, "node_modules/loupe": { "version": "2.3.6", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", + "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", "dev": true, - "license": "MIT", "dependencies": { "get-func-name": "^2.0.0" } }, "node_modules/lru-cache": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, - "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -1606,21 +1761,24 @@ }, "node_modules/make-error": { "version": "1.3.6", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true }, "node_modules/merge2": { "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/micromatch": { "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, - "license": "MIT", "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -1631,8 +1789,9 @@ }, "node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1642,8 +1801,9 @@ }, "node_modules/mocha": { "version": "9.2.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", + "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", "dev": true, - "license": "MIT", "dependencies": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", @@ -1684,21 +1844,24 @@ }, "node_modules/mocha/node_modules/ansi-colors": { "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/mocha/node_modules/argparse": { "version": "2.0.1", - "dev": true, - "license": "Python-2.0" + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "node_modules/mocha/node_modules/debug": { "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, - "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -1713,13 +1876,15 @@ }, "node_modules/mocha/node_modules/debug/node_modules/ms": { "version": "2.1.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "node_modules/mocha/node_modules/js-yaml": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -1729,8 +1894,9 @@ }, "node_modules/mocha/node_modules/minimatch": { "version": "4.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", + "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1740,13 +1906,15 @@ }, "node_modules/mocha/node_modules/ms": { "version": "2.1.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true }, "node_modules/mocha/node_modules/supports-color": { "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -1759,13 +1927,15 @@ }, "node_modules/ms": { "version": "2.1.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "node_modules/nanoid": { "version": "3.3.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", + "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", "dev": true, - "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -1775,16 +1945,19 @@ }, "node_modules/natural-compare": { "version": "1.4.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true }, "node_modules/node-addon-api": { "version": "3.2.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" }, "node_modules/node-gyp-build": { - "version": "4.5.0", - "license": "MIT", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", + "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", @@ -1793,24 +1966,27 @@ }, "node_modules/normalize-path": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/once": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, - "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/optionator": { "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, - "license": "MIT", "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -1825,8 +2001,9 @@ }, "node_modules/p-limit": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, - "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -1839,8 +2016,9 @@ }, "node_modules/p-locate": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, - "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -1853,8 +2031,9 @@ }, "node_modules/parent-module": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, - "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -1864,48 +2043,54 @@ }, "node_modules/path-exists": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/path-key": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-type": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/pathval": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true, - "license": "MIT", "engines": { "node": "*" } }, "node_modules/picomatch": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8.6" }, @@ -1915,16 +2100,18 @@ }, "node_modules/prelude-ls": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.8.0" } }, "node_modules/prettier": { - "version": "2.7.1", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz", + "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==", "dev": true, - "license": "MIT", "bin": { "prettier": "bin-prettier.js" }, @@ -1937,8 +2124,9 @@ }, "node_modules/prettier-linter-helpers": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, - "license": "MIT", "dependencies": { "fast-diff": "^1.1.2" }, @@ -1948,22 +2136,26 @@ }, "node_modules/progress": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/punycode": { - "version": "2.1.1", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/queue-microtask": { "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, "funding": [ { @@ -1978,21 +2170,22 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/randombytes": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, - "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } }, "node_modules/readdirp": { "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, - "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -2002,8 +2195,9 @@ }, "node_modules/regexpp": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" }, @@ -2013,32 +2207,36 @@ }, "node_modules/require-directory": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/require-from-string": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/resolve-from": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/reusify": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, - "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -2046,8 +2244,9 @@ }, "node_modules/rimraf": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, - "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -2060,6 +2259,8 @@ }, "node_modules/run-parallel": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { @@ -2075,13 +2276,14 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } }, "node_modules/safe-buffer": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { @@ -2096,13 +2298,13 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/semver": { "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, - "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -2115,15 +2317,17 @@ }, "node_modules/serialize-javascript": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } }, "node_modules/setimmediate-napi": { "version": "1.0.6", - "license": "MIT", + "resolved": "https://registry.npmjs.org/setimmediate-napi/-/setimmediate-napi-1.0.6.tgz", + "integrity": "sha512-sdNXN15Av1jPXuSal4Mk4tEAKn0+8lfF9Z50/negaQMrAIO9c1qM0eiCh8fT6gctp0RiCObk+6/Xfn5RMGdZoA==", "dependencies": { "get-symbol-from-current-process-h": "^1.0.1", "get-uv-event-loop-napi-h": "^1.0.5" @@ -2131,8 +2335,9 @@ }, "node_modules/shebang-command": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -2142,24 +2347,27 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/slash": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/slice-ansi": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -2174,13 +2382,15 @@ }, "node_modules/sprintf-js": { "version": "1.0.3", - "dev": true, - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true }, "node_modules/string-width": { "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -2192,8 +2402,9 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -2203,8 +2414,9 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" }, @@ -2214,8 +2426,9 @@ }, "node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -2225,8 +2438,9 @@ }, "node_modules/table": { "version": "6.8.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "ajv": "^8.0.1", "lodash.truncate": "^4.4.2", @@ -2239,9 +2453,10 @@ } }, "node_modules/table/node_modules/ajv": { - "version": "8.11.0", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -2255,18 +2470,21 @@ }, "node_modules/table/node_modules/json-schema-traverse": { "version": "1.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true }, "node_modules/text-table": { "version": "0.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true }, "node_modules/to-regex-range": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -2276,8 +2494,9 @@ }, "node_modules/ts-node": { "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, - "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -2317,9 +2536,10 @@ } }, "node_modules/ts-node/node_modules/acorn": { - "version": "8.8.1", + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "dev": true, - "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -2329,21 +2549,24 @@ }, "node_modules/ts-node/node_modules/diff": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/tslib": { "version": "1.14.1", - "dev": true, - "license": "0BSD" + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true }, "node_modules/tsutils": { "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, - "license": "MIT", "dependencies": { "tslib": "^1.8.1" }, @@ -2356,8 +2579,9 @@ }, "node_modules/type-check": { "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, - "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -2367,16 +2591,18 @@ }, "node_modules/type-detect": { "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/type-fest": { "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, - "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -2385,9 +2611,10 @@ } }, "node_modules/typescript": { - "version": "4.8.4", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, - "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -2398,40 +2625,46 @@ }, "node_modules/universalify": { "version": "0.1.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "engines": { "node": ">= 4.0.0" } }, "node_modules/uri-js": { "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } }, "node_modules/uuid": { "version": "8.3.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/v8-compile-cache": { "version": "2.3.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true }, "node_modules/weak-napi": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/weak-napi/-/weak-napi-2.0.2.tgz", + "integrity": "sha512-LcOSVFrghtVXf4QH+DLIy8iPiCktV7lVbqRDYP+bDPpLzC41RCHQPMyQOnPpWO41Ie4CmnDxS+mbL72r5xFMMQ==", "hasInstallScript": true, - "license": "MIT", "dependencies": { "node-addon-api": "^3.0.0", "node-gyp-build": "^4.2.1", @@ -2440,8 +2673,9 @@ }, "node_modules/which": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -2454,21 +2688,24 @@ }, "node_modules/word-wrap": { "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/workerpool": { "version": "6.2.0", - "dev": true, - "license": "Apache-2.0" + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "dev": true }, "node_modules/wrap-ansi": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -2483,26 +2720,30 @@ }, "node_modules/wrappy": { "version": "1.0.2", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true }, "node_modules/y18n": { "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, - "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yallist": { "version": "4.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "node_modules/yargs": { "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, - "license": "MIT", "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -2518,16 +2759,18 @@ }, "node_modules/yargs-parser": { "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", "dev": true, - "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yargs-unparser": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, - "license": "MIT", "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", @@ -2540,16 +2783,18 @@ }, "node_modules/yn": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/yocto-queue": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -2561,6 +2806,8 @@ "dependencies": { "@babel/code-frame": { "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { "@babel/highlight": "^7.10.4" @@ -2568,10 +2815,14 @@ }, "@babel/helper-validator-identifier": { "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "dev": true }, "@babel/highlight": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.18.6", @@ -2581,6 +2832,8 @@ "dependencies": { "ansi-styles": { "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { "color-convert": "^1.9.0" @@ -2588,6 +2841,8 @@ }, "chalk": { "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -2597,6 +2852,8 @@ }, "color-convert": { "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "requires": { "color-name": "1.1.3" @@ -2604,18 +2861,26 @@ }, "color-name": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "escape-string-regexp": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true }, "has-flag": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, "supports-color": { "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -2625,6 +2890,8 @@ }, "@cspotcode/source-map-support": { "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, "requires": { "@jridgewell/trace-mapping": "0.3.9" @@ -2632,6 +2899,8 @@ }, "@eslint/eslintrc": { "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -2647,12 +2916,16 @@ "dependencies": { "ignore": { "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true } } }, "@humanwhocodes/config-array": { "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.0", @@ -2662,6 +2935,8 @@ }, "@humanwhocodes/object-schema": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, "@hyperledger/vcx-napi-rs": { @@ -2678,14 +2953,20 @@ }, "@jridgewell/resolve-uri": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "dev": true }, "@jridgewell/sourcemap-codec": { "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", "dev": true }, "@jridgewell/trace-mapping": { "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, "requires": { "@jridgewell/resolve-uri": "^3.0.3", @@ -2694,6 +2975,8 @@ }, "@nodelib/fs.scandir": { "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "requires": { "@nodelib/fs.stat": "2.0.5", @@ -2702,10 +2985,14 @@ }, "@nodelib/fs.stat": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true }, "@nodelib/fs.walk": { "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "requires": { "@nodelib/fs.scandir": "2.1.5", @@ -2714,50 +3001,74 @@ }, "@tsconfig/node10": { "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", "dev": true }, "@tsconfig/node12": { "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", "dev": true }, "@tsconfig/node14": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", "dev": true }, "@tsconfig/node16": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "dev": true }, "@types/app-module-path": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@types/app-module-path/-/app-module-path-2.2.0.tgz", + "integrity": "sha512-r47Kt3ApJDzUU2xCNzaBI25Au5Xfdvf0Gyomveqvg46nQ3J4PaDLicObhyX6cMhvMVWJMB/BnkXdv1E4zxP+6w==", "dev": true }, "@types/chai": { "version": "4.3.4", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz", + "integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==", "dev": true }, "@types/json-schema": { "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, "@types/lodash": { - "version": "4.14.188", + "version": "4.14.191", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", + "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==", "dev": true }, "@types/mocha": { "version": "8.2.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", + "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", "dev": true }, "@types/node": { "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", "dev": true }, "@types/uuid": { "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", "dev": true }, "@types/weak-napi": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/weak-napi/-/weak-napi-1.0.1.tgz", + "integrity": "sha512-EqTeT7n+f6uxfLFRDcJEOu12dH0AT2fZlb8MTQKDG8E70T7uP//qG4CMdNKV3Ra/cxG7/Z1i04GT7Ll0QriWvQ==", "dev": true, "requires": { "@types/node": "*" @@ -2765,6 +3076,8 @@ }, "@typescript-eslint/eslint-plugin": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", + "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", "dev": true, "requires": { "@typescript-eslint/experimental-utils": "4.33.0", @@ -2779,6 +3092,8 @@ }, "@typescript-eslint/experimental-utils": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", + "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", "dev": true, "requires": { "@types/json-schema": "^7.0.7", @@ -2791,6 +3106,8 @@ }, "@typescript-eslint/parser": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", + "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", "dev": true, "requires": { "@typescript-eslint/scope-manager": "4.33.0", @@ -2801,6 +3118,8 @@ }, "@typescript-eslint/scope-manager": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", + "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", "dev": true, "requires": { "@typescript-eslint/types": "4.33.0", @@ -2809,10 +3128,14 @@ }, "@typescript-eslint/types": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", + "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", "dev": true }, "@typescript-eslint/typescript-estree": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", + "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", "dev": true, "requires": { "@typescript-eslint/types": "4.33.0", @@ -2826,6 +3149,8 @@ }, "@typescript-eslint/visitor-keys": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", + "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", "dev": true, "requires": { "@typescript-eslint/types": "4.33.0", @@ -2834,23 +3159,33 @@ }, "@ungap/promise-all-settled": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", "dev": true }, "acorn": { "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true }, "acorn-jsx": { "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "requires": {} }, "acorn-walk": { "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true }, "ajv": { "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -2861,21 +3196,29 @@ }, "ansi-colors": { "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true }, "ansi-regex": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { "color-convert": "^2.0.1" } }, "anymatch": { - "version": "3.1.2", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -2884,14 +3227,20 @@ }, "app-module-path": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz", + "integrity": "sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ==", "dev": true }, "arg": { "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true }, "argparse": { "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { "sprintf-js": "~1.0.2" @@ -2899,26 +3248,38 @@ }, "array-union": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, "assertion-error": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true }, "astral-regex": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, "balanced-match": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "binary-extensions": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, "brace-expansion": { "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { "balanced-match": "^1.0.0", @@ -2927,6 +3288,8 @@ }, "braces": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { "fill-range": "^7.0.1" @@ -2934,18 +3297,26 @@ }, "browser-stdout": { "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, "callsites": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, "camelcase": { "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true }, "chai": { "version": "4.3.7", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", + "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", "dev": true, "requires": { "assertion-error": "^1.1.0", @@ -2959,6 +3330,8 @@ }, "chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -2967,10 +3340,14 @@ }, "check-error": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", "dev": true }, "chokidar": { "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "requires": { "anymatch": "~3.1.2", @@ -2985,6 +3362,8 @@ }, "cliui": { "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { "string-width": "^4.2.0", @@ -2994,6 +3373,8 @@ }, "color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" @@ -3001,18 +3382,26 @@ }, "color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "concat-map": { "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, "create-require": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, "cross-spawn": { "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { "path-key": "^3.1.0", @@ -3022,6 +3411,8 @@ }, "debug": { "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -3029,10 +3420,14 @@ }, "decamelize": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true }, "deep-eql": { - "version": "4.1.2", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", "dev": true, "requires": { "type-detect": "^4.0.0" @@ -3040,14 +3435,20 @@ }, "deep-is": { "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, "diff": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, "dir-glob": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, "requires": { "path-type": "^4.0.0" @@ -3055,6 +3456,8 @@ }, "doctrine": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "requires": { "esutils": "^2.0.2" @@ -3062,10 +3465,14 @@ }, "emoji-regex": { "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "enquirer": { "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", "dev": true, "requires": { "ansi-colors": "^4.1.1" @@ -3073,14 +3480,20 @@ }, "escalade": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true }, "escape-string-regexp": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, "eslint": { "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "dev": true, "requires": { "@babel/code-frame": "7.12.11", @@ -3127,6 +3540,8 @@ "dependencies": { "eslint-utils": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" @@ -3134,23 +3549,31 @@ "dependencies": { "eslint-visitor-keys": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true } } }, "ignore": { "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true } } }, "eslint-config-prettier": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-7.2.0.tgz", + "integrity": "sha512-rV4Qu0C3nfJKPOAhFujFxB7RMP+URFyQqqOZW9DMRD7ZDTFyjaIlETU3xzHELt++4ugC0+Jm084HQYkkJe+Ivg==", "dev": true, "requires": {} }, "eslint-plugin-prettier": { "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", + "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", "dev": true, "requires": { "prettier-linter-helpers": "^1.0.0" @@ -3158,6 +3581,8 @@ }, "eslint-scope": { "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "requires": { "esrecurse": "^4.3.0", @@ -3166,6 +3591,8 @@ }, "eslint-utils": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, "requires": { "eslint-visitor-keys": "^2.0.0" @@ -3173,10 +3600,14 @@ }, "eslint-visitor-keys": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true }, "espree": { "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, "requires": { "acorn": "^7.4.0", @@ -3186,16 +3617,22 @@ "dependencies": { "eslint-visitor-keys": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true } } }, "esprima": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, "esquery": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -3203,12 +3640,16 @@ "dependencies": { "estraverse": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } }, "esrecurse": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "requires": { "estraverse": "^5.2.0" @@ -3216,28 +3657,40 @@ "dependencies": { "estraverse": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } }, "estraverse": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, "esutils": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, "fast-deep-equal": { "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "fast-diff": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", "dev": true }, "fast-glob": { "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -3249,14 +3702,20 @@ }, "fast-json-stable-stringify": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, "fast-levenshtein": { "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "fastq": { - "version": "1.13.0", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -3264,6 +3723,8 @@ }, "file-entry-cache": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "requires": { "flat-cache": "^3.0.4" @@ -3271,6 +3732,8 @@ }, "fill-range": { "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "requires": { "to-regex-range": "^5.0.1" @@ -3278,6 +3741,8 @@ }, "find-up": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "requires": { "locate-path": "^6.0.0", @@ -3286,10 +3751,14 @@ }, "flat": { "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true }, "flat-cache": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "requires": { "flatted": "^3.1.0", @@ -3298,10 +3767,14 @@ }, "flatted": { "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, "fs-extra": { "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", "requires": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -3310,36 +3783,52 @@ }, "fs.realpath": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, "fsevents": { "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "optional": true }, "functional-red-black-tree": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", "dev": true }, "get-caller-file": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "get-func-name": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", "dev": true }, "get-symbol-from-current-process-h": { - "version": "1.0.2" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-from-current-process-h/-/get-symbol-from-current-process-h-1.0.2.tgz", + "integrity": "sha512-syloC6fsCt62ELLrr1VKBM1ggOpMdetX9hTrdW77UQdcApPHLmf7CI7OKcN1c9kYuNxKcDe4iJ4FY9sX3aw2xw==" }, "get-uv-event-loop-napi-h": { "version": "1.0.6", + "resolved": "https://registry.npmjs.org/get-uv-event-loop-napi-h/-/get-uv-event-loop-napi-h-1.0.6.tgz", + "integrity": "sha512-t5c9VNR84nRoF+eLiz6wFrEp1SE2Acg0wS+Ysa2zF0eROes+LzOfuTaVHxGy8AbS8rq7FHEJzjnCZo1BupwdJg==", "requires": { "get-symbol-from-current-process-h": "^1.0.1" } }, "glob": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -3352,13 +3841,17 @@ }, "glob-parent": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { "is-glob": "^4.0.1" } }, "globals": { - "version": "13.17.0", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -3366,6 +3859,8 @@ }, "globby": { "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "requires": { "array-union": "^2.1.0", @@ -3377,26 +3872,38 @@ } }, "graceful-fs": { - "version": "4.2.10" + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "growl": { "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, "has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "he": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, "ignore": { - "version": "5.2.0", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true }, "import-fresh": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "requires": { "parent-module": "^1.0.0", @@ -3405,10 +3912,14 @@ }, "imurmurhash": { "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true }, "inflight": { "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "requires": { "once": "^1.3.0", @@ -3417,10 +3928,14 @@ }, "inherits": { "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "is-binary-path": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "requires": { "binary-extensions": "^2.0.0" @@ -3428,14 +3943,20 @@ }, "is-extglob": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "is-glob": { "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "requires": { "is-extglob": "^2.1.1" @@ -3443,26 +3964,38 @@ }, "is-number": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, "is-plain-obj": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, "is-unicode-supported": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true }, "isexe": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, "js-tokens": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, "js-yaml": { "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -3471,20 +4004,28 @@ }, "json-schema-traverse": { "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "jsonfile": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "requires": { "graceful-fs": "^4.1.6" } }, "levn": { "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "requires": { "prelude-ls": "^1.2.1", @@ -3493,24 +4034,34 @@ }, "locate-path": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "requires": { "p-locate": "^5.0.0" } }, "lodash": { - "version": "4.17.21" + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash.merge": { "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, "lodash.truncate": { "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", "dev": true }, "log-symbols": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "requires": { "chalk": "^4.1.0", @@ -3519,6 +4070,8 @@ }, "loupe": { "version": "2.3.6", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", + "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", "dev": true, "requires": { "get-func-name": "^2.0.0" @@ -3526,6 +4079,8 @@ }, "lru-cache": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "requires": { "yallist": "^4.0.0" @@ -3533,14 +4088,20 @@ }, "make-error": { "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, "merge2": { "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true }, "micromatch": { "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "requires": { "braces": "^3.0.2", @@ -3549,6 +4110,8 @@ }, "minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -3556,6 +4119,8 @@ }, "mocha": { "version": "9.2.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", + "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", "dev": true, "requires": { "@ungap/promise-all-settled": "1.1.2", @@ -3586,14 +4151,20 @@ "dependencies": { "ansi-colors": { "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true }, "argparse": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, "debug": { "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "requires": { "ms": "2.1.2" @@ -3601,12 +4172,16 @@ "dependencies": { "ms": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } }, "js-yaml": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "requires": { "argparse": "^2.0.1" @@ -3614,6 +4189,8 @@ }, "minimatch": { "version": "4.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", + "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -3621,10 +4198,14 @@ }, "ms": { "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "supports-color": { "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -3634,28 +4215,42 @@ }, "ms": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "nanoid": { "version": "3.3.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", + "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", "dev": true }, "natural-compare": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, "node-addon-api": { - "version": "3.2.1" + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" }, "node-gyp-build": { - "version": "4.5.0" + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", + "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==" }, "normalize-path": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, "once": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "requires": { "wrappy": "1" @@ -3663,6 +4258,8 @@ }, "optionator": { "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "requires": { "deep-is": "^0.1.3", @@ -3675,6 +4272,8 @@ }, "p-limit": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "requires": { "yocto-queue": "^0.1.0" @@ -3682,6 +4281,8 @@ }, "p-locate": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "requires": { "p-limit": "^3.0.2" @@ -3689,6 +4290,8 @@ }, "parent-module": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "requires": { "callsites": "^3.0.0" @@ -3696,38 +4299,56 @@ }, "path-exists": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "path-is-absolute": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true }, "path-key": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "path-type": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, "pathval": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true }, "picomatch": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, "prelude-ls": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, "prettier": { - "version": "2.7.1", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz", + "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==", "dev": true }, "prettier-linter-helpers": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, "requires": { "fast-diff": "^1.1.2" @@ -3735,18 +4356,26 @@ }, "progress": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, "punycode": { - "version": "2.1.1", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true }, "queue-microtask": { "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, "randombytes": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, "requires": { "safe-buffer": "^5.1.0" @@ -3754,6 +4383,8 @@ }, "readdirp": { "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "requires": { "picomatch": "^2.2.1" @@ -3761,26 +4392,38 @@ }, "regexpp": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, "require-directory": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, "require-from-string": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true }, "resolve-from": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, "reusify": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true }, "rimraf": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { "glob": "^7.1.3" @@ -3788,6 +4431,8 @@ }, "run-parallel": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "requires": { "queue-microtask": "^1.2.2" @@ -3795,10 +4440,14 @@ }, "safe-buffer": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true }, "semver": { "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -3806,6 +4455,8 @@ }, "serialize-javascript": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dev": true, "requires": { "randombytes": "^2.1.0" @@ -3813,6 +4464,8 @@ }, "setimmediate-napi": { "version": "1.0.6", + "resolved": "https://registry.npmjs.org/setimmediate-napi/-/setimmediate-napi-1.0.6.tgz", + "integrity": "sha512-sdNXN15Av1jPXuSal4Mk4tEAKn0+8lfF9Z50/negaQMrAIO9c1qM0eiCh8fT6gctp0RiCObk+6/Xfn5RMGdZoA==", "requires": { "get-symbol-from-current-process-h": "^1.0.1", "get-uv-event-loop-napi-h": "^1.0.5" @@ -3820,6 +4473,8 @@ }, "shebang-command": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { "shebang-regex": "^3.0.0" @@ -3827,14 +4482,20 @@ }, "shebang-regex": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "slash": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, "slice-ansi": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "requires": { "ansi-styles": "^4.0.0", @@ -3844,10 +4505,14 @@ }, "sprintf-js": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, "string-width": { "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", @@ -3857,6 +4522,8 @@ }, "strip-ansi": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { "ansi-regex": "^5.0.1" @@ -3864,10 +4531,14 @@ }, "strip-json-comments": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, "supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -3875,6 +4546,8 @@ }, "table": { "version": "6.8.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", "dev": true, "requires": { "ajv": "^8.0.1", @@ -3885,7 +4558,9 @@ }, "dependencies": { "ajv": { - "version": "8.11.0", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -3896,16 +4571,22 @@ }, "json-schema-traverse": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true } } }, "text-table": { "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, "to-regex-range": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "requires": { "is-number": "^7.0.0" @@ -3913,6 +4594,8 @@ }, "ts-node": { "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, "requires": { "@cspotcode/source-map-support": "^0.8.0", @@ -3931,21 +4614,29 @@ }, "dependencies": { "acorn": { - "version": "8.8.1", + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "dev": true }, "diff": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true } } }, "tslib": { "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, "tsutils": { "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, "requires": { "tslib": "^1.8.1" @@ -3953,6 +4644,8 @@ }, "type-check": { "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "requires": { "prelude-ls": "^1.2.1" @@ -3960,39 +4653,57 @@ }, "type-detect": { "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, "type-fest": { "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, "typescript": { - "version": "4.8.4", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true }, "universalify": { - "version": "0.1.2" + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" }, "uri-js": { "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "requires": { "punycode": "^2.1.0" } }, "uuid": { - "version": "8.3.2" + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, "v8-compile-cache": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, "v8-compile-cache-lib": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, "weak-napi": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/weak-napi/-/weak-napi-2.0.2.tgz", + "integrity": "sha512-LcOSVFrghtVXf4QH+DLIy8iPiCktV7lVbqRDYP+bDPpLzC41RCHQPMyQOnPpWO41Ie4CmnDxS+mbL72r5xFMMQ==", "requires": { "node-addon-api": "^3.0.0", "node-gyp-build": "^4.2.1", @@ -4001,6 +4712,8 @@ }, "which": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -4008,14 +4721,20 @@ }, "word-wrap": { "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, "workerpool": { "version": "6.2.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", "dev": true }, "wrap-ansi": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { "ansi-styles": "^4.0.0", @@ -4025,18 +4744,26 @@ }, "wrappy": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, "y18n": { "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yallist": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "yargs": { "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { "cliui": "^7.0.2", @@ -4050,10 +4777,14 @@ }, "yargs-parser": { "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", "dev": true }, "yargs-unparser": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, "requires": { "camelcase": "^6.0.0", @@ -4064,10 +4795,14 @@ }, "yn": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true }, "yocto-queue": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true } } diff --git a/wrappers/node/test/suite1/ariesvcx-connection.test.ts b/wrappers/node/test/suite1/ariesvcx-connection.test.ts index 50b13a5f27..bfb4e289ed 100644 --- a/wrappers/node/test/suite1/ariesvcx-connection.test.ts +++ b/wrappers/node/test/suite1/ariesvcx-connection.test.ts @@ -13,10 +13,10 @@ describe('Nonmediated connection:', () => { const serviceEndpoint = 'http://localhost:8080'; const routingKeys = [ 'routingKey' ]; const connection = await NonmediatedConnection.createInviter(); - assert.equal(connection.getState(), ConnectionStateType.Invited); + assert.equal(connection.getState(), ConnectionStateType.Initial); await connection.createInvite({ serviceEndpoint, routingKeys }); - assert.equal(connection.getState(), ConnectionStateType.Initial); + assert.equal(connection.getState(), ConnectionStateType.Invited); const invite = JSON.parse(connection.getInvitation()); expect(invite.routingKeys).deep.equal(routingKeys); @@ -27,7 +27,7 @@ describe('Nonmediated connection:', () => { describe('serialize / deserialize:', () => { it('success', async () => { const connection = await NonmediatedConnection.createInviter(); - assert.equal(connection.getState(), ConnectionStateType.Invited); + assert.equal(connection.getState(), ConnectionStateType.Initial); const serialized = connection.serialize() const deserialized = NonmediatedConnection.deserialize(serialized); diff --git a/wrappers/vcx-napi-rs/package-lock.json b/wrappers/vcx-napi-rs/package-lock.json index 921f03c13c..fc018b4425 100644 --- a/wrappers/vcx-napi-rs/package-lock.json +++ b/wrappers/vcx-napi-rs/package-lock.json @@ -19,9 +19,9 @@ } }, "node_modules/@napi-rs/cli": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.14.1.tgz", - "integrity": "sha512-+mnge6gvdbOrwtYrBO7iMlTjXcaRk17wDqzxSG4SPBKPhI3HroWY+tRsx+OdluAuRyJZOkWTdsvGnMsGO1ff/A==", + "version": "2.14.5", + "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.14.5.tgz", + "integrity": "sha512-E7WYAS1y1sTkLbZsOtf9Xs6fx/aOJ05UIm6cs7q1vHxpycYJRGtvEU8ilFTw6TPke68Hq1c+6Yd7Lklr4sj9EQ==", "dev": true, "bin": { "napi": "scripts/index.js" @@ -41,9 +41,9 @@ "dev": true }, "node_modules/typescript": { - "version": "4.9.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", - "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -56,9 +56,9 @@ }, "dependencies": { "@napi-rs/cli": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.14.1.tgz", - "integrity": "sha512-+mnge6gvdbOrwtYrBO7iMlTjXcaRk17wDqzxSG4SPBKPhI3HroWY+tRsx+OdluAuRyJZOkWTdsvGnMsGO1ff/A==", + "version": "2.14.5", + "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.14.5.tgz", + "integrity": "sha512-E7WYAS1y1sTkLbZsOtf9Xs6fx/aOJ05UIm6cs7q1vHxpycYJRGtvEU8ilFTw6TPke68Hq1c+6Yd7Lklr4sj9EQ==", "dev": true }, "@types/node": { @@ -68,9 +68,9 @@ "dev": true }, "typescript": { - "version": "4.9.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", - "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true } } From f2f8e5a2ba6e3cb51cb0e3b7376007f4120b0b03 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Thu, 2 Feb 2023 17:04:03 +0200 Subject: [PATCH 38/66] Fixed accept_invitation log comment and added more explicit logs to libvcx Signed-off-by: Bogdan Mircea --- .../src/protocols/connection/invitee/mod.rs | 2 +- libvcx/src/api_vcx/api_handle/connection.rs | 57 ++++++++++++------- 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/aries_vcx/src/protocols/connection/invitee/mod.rs b/aries_vcx/src/protocols/connection/invitee/mod.rs index f5b1cd0159..052d1d9be7 100644 --- a/aries_vcx/src/protocols/connection/invitee/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/mod.rs @@ -48,7 +48,7 @@ impl InviteeConnection { profile: &Arc, invitation: &Invitation, ) -> VcxResult> { - trace!("Connection::into_invited >>> invitation: {:?}", &invitation); + trace!("Connection::accept_invitation >>> invitation: {:?}", &invitation); let thread_id = invitation.get_id().to_owned(); let did_doc = into_did_doc(profile, invitation).await?; diff --git a/libvcx/src/api_vcx/api_handle/connection.rs b/libvcx/src/api_vcx/api_handle/connection.rs index 984e803b24..af8e9c200c 100644 --- a/libvcx/src/api_vcx/api_handle/connection.rs +++ b/libvcx/src/api_vcx/api_handle/connection.rs @@ -1,8 +1,8 @@ -use std::{collections::HashMap, sync::RwLock}; +use std::{any::type_name, collections::HashMap, sync::RwLock}; use agency_client::httpclient::post_message; use aries_vcx::{ - errors::error::VcxResult, + errors::error::{AriesVcxError, VcxResult}, messages::protocols::basic_message::message::BasicMessage, protocols::connection::{ invitee::InviteeConnection, inviter::InviterConnection, pairwise_info::PairwiseInfo, Connection, @@ -48,37 +48,49 @@ fn get_cloned_generic_connection(handle: &u32) -> LibvcxResult(handle: &u32) -> LibvcxResult> where - Connection: TryFrom, + Connection: TryFrom, { - CONNECTION_MAP + let con = CONNECTION_MAP .write()? .get(handle) - .and_then(|c| c.clone().try_into().ok()) .ok_or_else(|| { LibvcxError::from_msg( LibvcxErrorKind::ObjectAccessError, - format!("Unable to retrieve expected connection for handle: {}", handle), + format!("No connection found for handle: {}", handle), ) - }) + })? + .clone() + .try_into()?; + + Ok(con) } -fn add_connection(connection: GenericConnection) -> LibvcxResult { +fn add_connection(connection: Connection) -> LibvcxResult +where + GenericConnection: From>, +{ let handle = new_handle()?; - CONNECTION_MAP.write()?.insert(handle, connection); + insert_connection(handle, connection)?; Ok(handle) } -fn insert_connection(handle: u32, connection: Connection) -> LibvcxResult<()> +pub fn insert_connection(handle: u32, connection: Connection) -> LibvcxResult<()> where GenericConnection: From>, { + trace!( + "Inserting connection; Handle: {} - Type: {}", + &handle, + type_name::>() + ); + CONNECTION_MAP.write()?.insert(handle, connection.into()); Ok(()) } @@ -111,7 +123,7 @@ pub async fn create_inviter(pw_info: Option) -> LibvcxResult let pw_info = pw_info.unwrap_or(PairwiseInfo::create(&profile.inject_wallet()).await?); let con = InviterConnection::new_inviter("".to_owned(), pw_info); - add_connection(con.into()) + add_connection(con) } pub async fn create_invitee(_invitation: &str) -> LibvcxResult { @@ -122,7 +134,7 @@ pub async fn create_invitee(_invitation: &str) -> LibvcxResult { let con = InviteeConnection::new_invitee("".to_owned(), pairwise_info); - add_connection(con.into()) + add_connection(con) } // ----------------------------- GETTERS ------------------------------------ @@ -133,7 +145,7 @@ pub fn get_thread_id(handle: u32) -> LibvcxResult { let con = lock.get(&handle).ok_or_else(|| { LibvcxError::from_msg( LibvcxErrorKind::ObjectAccessError, - format!("Unable to retrieve expected connection for handle: {}", handle), + format!("No connection found for handle: {}", handle), ) })?; @@ -152,7 +164,7 @@ pub fn get_pairwise_info(handle: u32) -> LibvcxResult { let con = lock.get(&handle).ok_or_else(|| { LibvcxError::from_msg( LibvcxErrorKind::ObjectAccessError, - format!("Unable to retrieve expected connection for handle: {}", handle), + format!("No connection found for handle: {}", handle), ) })?; @@ -166,7 +178,7 @@ pub fn get_remote_did(handle: u32) -> LibvcxResult { let con = lock.get(&handle).ok_or_else(|| { LibvcxError::from_msg( LibvcxErrorKind::ObjectAccessError, - format!("Unable to retrieve expected connection for handle: {}", handle), + format!("No connection found for handle: {}", handle), ) })?; @@ -185,7 +197,7 @@ pub fn get_remote_vk(handle: u32) -> LibvcxResult { let con = lock.get(&handle).ok_or_else(|| { LibvcxError::from_msg( LibvcxErrorKind::ObjectAccessError, - format!("Unable to retrieve expected connection for handle: {}", handle), + format!("No connection found for handle: {}", handle), ) })?; @@ -199,7 +211,7 @@ pub fn get_state(handle: u32) -> LibvcxResult { let con = lock.get(&handle).ok_or_else(|| { LibvcxError::from_msg( LibvcxErrorKind::ObjectAccessError, - format!("Unable to retrieve expected connection for handle: {}", handle), + format!("No connection found for handle: {}", handle), ) })?; @@ -218,7 +230,7 @@ pub fn get_invitation(handle: u32) -> LibvcxResult { let con = lock.get(&handle).ok_or_else(|| { LibvcxError::from_msg( LibvcxErrorKind::ObjectAccessError, - format!("Unable to retrieve expected connection for handle: {}", handle), + format!("No connection found for handle: {}", handle), ) })?; @@ -358,7 +370,12 @@ pub fn to_string(handle: u32) -> LibvcxResult { pub fn from_string(connection_data: &str) -> LibvcxResult { trace!("from_string >>>"); - add_connection(deserialize(connection_data)?) + + let connection = deserialize(connection_data)?; + let handle = new_handle()?; + CONNECTION_MAP.write()?.insert(handle, connection); + + Ok(handle) } // ------------------------------ CLEANUP --------------------------------------- From 5cb9f83e6c0f393f2b06891dfd562a0ff201f0e4 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Thu, 2 Feb 2023 17:40:12 +0200 Subject: [PATCH 39/66] processInvite is now a Promise Signed-off-by: Bogdan Mircea --- .../src/services/service-nonmediated-connections.js | 2 +- wrappers/node/src/api/connection.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/agents/node/vcxagent-core/src/services/service-nonmediated-connections.js b/agents/node/vcxagent-core/src/services/service-nonmediated-connections.js index f7e38dfe02..335bfbf92b 100644 --- a/agents/node/vcxagent-core/src/services/service-nonmediated-connections.js +++ b/agents/node/vcxagent-core/src/services/service-nonmediated-connections.js @@ -47,7 +47,7 @@ module.exports.createServiceNonmediatedConnections = function createServiceNonme logger.info(`inviteeConnectionCreateFromInvite >> connectionId=${connectionId}, invite: ${invite}`) const connection = await NonmediatedConnection.createInvitee(invite) logger.debug(`InviteeConnectionSM after created from invitation:\n${JSON.stringify(connection.serialize())}`) - connection.processInvite(invite) + await connection.processInvite(invite) await connection.sendRequest(endpointInfo) logger.debug(`InviteeConnectionSM after sending request:\n${JSON.stringify(connection.serialize())}`) await saveNonmediatedConnection(connectionId, connection) diff --git a/wrappers/node/src/api/connection.ts b/wrappers/node/src/api/connection.ts index c19d6da333..4bbc692672 100644 --- a/wrappers/node/src/api/connection.ts +++ b/wrappers/node/src/api/connection.ts @@ -58,9 +58,9 @@ export class NonmediatedConnection extends VcxBaseWithState { try { - ffiNapi.connectionProcessInvite(this.handle, invite); + await ffiNapi.connectionProcessInvite(this.handle, invite); } catch (err: any) { throw new VCXInternalError(err); } From 43c8c953a1c7dac298da91953bcdb1300e607f89 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Thu, 2 Feb 2023 18:26:03 +0200 Subject: [PATCH 40/66] Fixed thread_id handling when accepting invitation and sending request as an invitee Signed-off-by: Bogdan Mircea --- .../service-nonmediated-connections.js | 20 ++++--- .../src/protocols/connection/invitee/mod.rs | 58 ++++++++----------- .../connection/invitee/states/invited.rs | 11 +++- wrappers/vcx-napi-rs/package-lock.json | 12 ++-- 4 files changed, 50 insertions(+), 51 deletions(-) diff --git a/agents/node/vcxagent-core/src/services/service-nonmediated-connections.js b/agents/node/vcxagent-core/src/services/service-nonmediated-connections.js index 335bfbf92b..ebb213d100 100644 --- a/agents/node/vcxagent-core/src/services/service-nonmediated-connections.js +++ b/agents/node/vcxagent-core/src/services/service-nonmediated-connections.js @@ -1,8 +1,8 @@ const { NonmediatedConnection } = require('@hyperledger/node-vcx-wrapper') -module.exports.createServiceNonmediatedConnections = function createServiceNonmediatedConnections ({ logger, saveNonmediatedConnection, loadNonmediatedConnection, endpointInfo }) { +module.exports.createServiceNonmediatedConnections = function createServiceNonmediatedConnections({ logger, saveNonmediatedConnection, loadNonmediatedConnection, endpointInfo }) { - async function inviterConnectionCreatePwInvite (connectionId) { + async function inviterConnectionCreatePwInvite(connectionId) { logger.info(`inviterConnectionCreatePwInvite >> connectionId=${connectionId}`) const connection = await NonmediatedConnection.createInviter() logger.debug(`InviterConnectionSM after created connection:\n${JSON.stringify(connection.serialize())}`) @@ -14,10 +14,12 @@ module.exports.createServiceNonmediatedConnections = function createServiceNonme return invite } - async function inviterConnectionCreateFromRequest (connectionId, request, pwInfo) { + async function inviterConnectionCreateFromRequest(connectionId, request, pwInfo) { logger.info(`inviterConnectionCreateFromRequest >> connectionId=${connectionId}, request: ${request}, pwInfo: ${pwInfo}`) const connection = await NonmediatedConnection.createInviter(pwInfo) logger.debug(`InviterConnectionSM after created connection:\n${JSON.stringify(connection.serialize())}`) + await connection.createInvite(endpointInfo) + logger.debug(`InviterConnectionSM after create invite:\n${JSON.stringify(connection.serialize())}`) await connection.processRequest(request, endpointInfo) logger.debug(`InviterConnectionSM after processing request:\n${JSON.stringify(connection.serialize())}`) await connection.sendResponse() @@ -25,7 +27,7 @@ module.exports.createServiceNonmediatedConnections = function createServiceNonme await saveNonmediatedConnection(connectionId, connection) } - async function inviterConnectionProcessRequest (connectionId, request) { + async function inviterConnectionProcessRequest(connectionId, request) { logger.info(`inviterConnectionProcessRequest >> connectionId=${connectionId}, request: ${request}`) const connection = await loadNonmediatedConnection(connectionId) await connection.processRequest(request, endpointInfo) @@ -35,7 +37,7 @@ module.exports.createServiceNonmediatedConnections = function createServiceNonme await saveNonmediatedConnection(connectionId, connection) } - async function inviterConnectionProcessAck (connectionId, ack) { + async function inviterConnectionProcessAck(connectionId, ack) { logger.info(`inviterConnectionProcessAck >> connectionId=${connectionId}, ack: ${ack}`) const connection = await loadNonmediatedConnection(connectionId) await connection.processAck(ack) @@ -43,7 +45,7 @@ module.exports.createServiceNonmediatedConnections = function createServiceNonme await saveNonmediatedConnection(connectionId, connection) } - async function inviteeConnectionCreateFromInvite (connectionId, invite) { + async function inviteeConnectionCreateFromInvite(connectionId, invite) { logger.info(`inviteeConnectionCreateFromInvite >> connectionId=${connectionId}, invite: ${invite}`) const connection = await NonmediatedConnection.createInvitee(invite) logger.debug(`InviteeConnectionSM after created from invitation:\n${JSON.stringify(connection.serialize())}`) @@ -53,7 +55,7 @@ module.exports.createServiceNonmediatedConnections = function createServiceNonme await saveNonmediatedConnection(connectionId, connection) } - async function inviteeConnectionProcessResponse (connectionId, response) { + async function inviteeConnectionProcessResponse(connectionId, response) { logger.info(`inviteeConnectionProcessResponse >> connectionId=${connectionId}, response: ${response}`) const connection = await loadNonmediatedConnection(connectionId) await connection.processResponse(response) @@ -63,13 +65,13 @@ module.exports.createServiceNonmediatedConnections = function createServiceNonme await saveNonmediatedConnection(connectionId, connection) } - async function sendMessage (connectionId, content) { + async function sendMessage(connectionId, content) { logger.info(`nonmediatedConnectionSendMessage >> connectionId=${connectionId}, content: ${content}`) const connection = await loadNonmediatedConnection(connectionId) await connection.sendMessage(content) } - async function getState (connectionId) { + async function getState(connectionId) { const connection = await loadNonmediatedConnection(connectionId) return connection.getState() } diff --git a/aries_vcx/src/protocols/connection/invitee/mod.rs b/aries_vcx/src/protocols/connection/invitee/mod.rs index 052d1d9be7..1739231ef1 100644 --- a/aries_vcx/src/protocols/connection/invitee/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/mod.rs @@ -50,9 +50,25 @@ impl InviteeConnection { ) -> VcxResult> { trace!("Connection::accept_invitation >>> invitation: {:?}", &invitation); - let thread_id = invitation.get_id().to_owned(); + let invitation_id = invitation.get_id(); let did_doc = into_did_doc(profile, invitation).await?; - let state = Invited { did_doc, thread_id }; + let request = Request::create() + .set_label(self.source_id.to_string()) + .set_did(self.pairwise_info.pw_did.to_string()); + + let (thread_id, request) = match invitation { + Invitation::Pairwise(_) => (invitation_id.to_owned(), request.set_thread_id(invitation_id)), + Invitation::Public(_) => ( + request.id.0.clone(), + request.set_parent_thread_id(invitation_id).set_thread_id_matching_id(), + ), + Invitation::OutOfBand(_) => ( + request.id.0.clone(), + request.set_parent_thread_id(invitation_id).set_thread_id_matching_id(), + ), + }; + + let state = Invited::new(did_doc, thread_id, request); // Convert to `InvitedState` Ok(Connection { @@ -66,7 +82,7 @@ impl InviteeConnection { impl InviteeConnection { pub async fn send_request( - self, + mut self, wallet: &Arc, service_endpoint: String, routing_keys: Vec, @@ -79,42 +95,18 @@ impl InviteeConnection { let recipient_keys = vec![self.pairwise_info.pw_vk.clone()]; - let request = Request::create() - .set_label(self.source_id.to_string()) - .set_did(self.pairwise_info.pw_did.to_string()) + self.state.request = self + .state + .request .set_service_endpoint(service_endpoint) .set_keys(recipient_keys, routing_keys) .set_out_time(); - // Should be properly retrieved from Invitation. - // Also there's if this Request will just be serialized, it might as well take references. - let request = request.set_parent_thread_id(&self.state.thread_id); - - // The Invitation gets lost along the way when converting from Invited to Requested - // in previous implementations. Apart from these thread ID's, it's not used at all. - // - // Might as well implement it properly when accepting an Invitation in the `into_invited` method. - // - // let request_id = request.id.0.clone(); - // - // let (request, thread_id) = match &self.state.invitation { - // Invitation::Public(_) => ( - // request - // .set_parent_thread_id(&self.thread_id) - // .set_thread_id_matching_id(), - // request_id, - // ), - // Invitation::Pairwise(_) => (request.set_thread_id(&self.thread_id), self.thread_id().to_owned()), - // Invitation::OutOfBand(invite) => ( - // request.set_parent_thread_id(&invite.id.0).set_thread_id_matching_id(), - // request_id, - // ), - // }; - - self.send_message(wallet, &request.to_a2a_message(), transport).await?; + self.send_message(wallet, &self.state.request.to_a2a_message(), transport) + .await?; Ok(Connection { - state: Requested::new(self.state.did_doc, self.state.thread_id), + state: Requested::new(self.state.did_doc, self.state.request.id.0), source_id: self.source_id, pairwise_info: self.pairwise_info, initiation_type: Invitee, diff --git a/aries_vcx/src/protocols/connection/invitee/states/invited.rs b/aries_vcx/src/protocols/connection/invitee/states/invited.rs index 2e071590d6..3623f2f1d0 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/invited.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/invited.rs @@ -1,4 +1,4 @@ -use messages::diddoc::aries::diddoc::AriesDidDoc; +use messages::{diddoc::aries::diddoc::AriesDidDoc, protocols::connection::request::Request}; use crate::protocols::connection::trait_bounds::{TheirDidDoc, ThreadId}; @@ -6,11 +6,16 @@ use crate::protocols::connection::trait_bounds::{TheirDidDoc, ThreadId}; pub struct Invited { pub(crate) did_doc: AriesDidDoc, pub(crate) thread_id: String, + pub(crate) request: Request, } impl Invited { - pub fn new(did_doc: AriesDidDoc, thread_id: String) -> Self { - Self { did_doc, thread_id } + pub fn new(did_doc: AriesDidDoc, thread_id: String, request: Request) -> Self { + Self { + did_doc, + thread_id, + request, + } } } diff --git a/wrappers/vcx-napi-rs/package-lock.json b/wrappers/vcx-napi-rs/package-lock.json index fc018b4425..e7a0dbb763 100644 --- a/wrappers/vcx-napi-rs/package-lock.json +++ b/wrappers/vcx-napi-rs/package-lock.json @@ -19,9 +19,9 @@ } }, "node_modules/@napi-rs/cli": { - "version": "2.14.5", - "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.14.5.tgz", - "integrity": "sha512-E7WYAS1y1sTkLbZsOtf9Xs6fx/aOJ05UIm6cs7q1vHxpycYJRGtvEU8ilFTw6TPke68Hq1c+6Yd7Lklr4sj9EQ==", + "version": "2.14.6", + "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.14.6.tgz", + "integrity": "sha512-q63+fI0JB9LV3RDYQN7yyAzmWDrErz+5ZMM1EyB5RA7ZwTTRYvXxg204w9+xTuZnpQfSyLMxxKGz2mfDVqFing==", "dev": true, "bin": { "napi": "scripts/index.js" @@ -56,9 +56,9 @@ }, "dependencies": { "@napi-rs/cli": { - "version": "2.14.5", - "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.14.5.tgz", - "integrity": "sha512-E7WYAS1y1sTkLbZsOtf9Xs6fx/aOJ05UIm6cs7q1vHxpycYJRGtvEU8ilFTw6TPke68Hq1c+6Yd7Lklr4sj9EQ==", + "version": "2.14.6", + "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.14.6.tgz", + "integrity": "sha512-q63+fI0JB9LV3RDYQN7yyAzmWDrErz+5ZMM1EyB5RA7ZwTTRYvXxg204w9+xTuZnpQfSyLMxxKGz2mfDVqFing==", "dev": true }, "@types/node": { From 6e96c5580442943d60c6f3e6c907276728de028e Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Fri, 3 Feb 2023 11:03:08 +0200 Subject: [PATCH 41/66] More state retro-fitting with previous implementation Signed-off-by: Bogdan Mircea --- .../service-nonmediated-connections.js | 20 ++++---- .../src/services/connection.rs | 21 ++++++-- .../src/protocols/connection/generic/mod.rs | 1 + .../src/protocols/connection/invitee/mod.rs | 49 ++++++++----------- .../connection/invitee/states/invited.rs | 15 ++---- .../src/protocols/connection/inviter/mod.rs | 24 ++++++++- libvcx/src/api_vcx/api_handle/connection.rs | 25 ++++++++-- 7 files changed, 97 insertions(+), 58 deletions(-) diff --git a/agents/node/vcxagent-core/src/services/service-nonmediated-connections.js b/agents/node/vcxagent-core/src/services/service-nonmediated-connections.js index ebb213d100..335bfbf92b 100644 --- a/agents/node/vcxagent-core/src/services/service-nonmediated-connections.js +++ b/agents/node/vcxagent-core/src/services/service-nonmediated-connections.js @@ -1,8 +1,8 @@ const { NonmediatedConnection } = require('@hyperledger/node-vcx-wrapper') -module.exports.createServiceNonmediatedConnections = function createServiceNonmediatedConnections({ logger, saveNonmediatedConnection, loadNonmediatedConnection, endpointInfo }) { +module.exports.createServiceNonmediatedConnections = function createServiceNonmediatedConnections ({ logger, saveNonmediatedConnection, loadNonmediatedConnection, endpointInfo }) { - async function inviterConnectionCreatePwInvite(connectionId) { + async function inviterConnectionCreatePwInvite (connectionId) { logger.info(`inviterConnectionCreatePwInvite >> connectionId=${connectionId}`) const connection = await NonmediatedConnection.createInviter() logger.debug(`InviterConnectionSM after created connection:\n${JSON.stringify(connection.serialize())}`) @@ -14,12 +14,10 @@ module.exports.createServiceNonmediatedConnections = function createServiceNonme return invite } - async function inviterConnectionCreateFromRequest(connectionId, request, pwInfo) { + async function inviterConnectionCreateFromRequest (connectionId, request, pwInfo) { logger.info(`inviterConnectionCreateFromRequest >> connectionId=${connectionId}, request: ${request}, pwInfo: ${pwInfo}`) const connection = await NonmediatedConnection.createInviter(pwInfo) logger.debug(`InviterConnectionSM after created connection:\n${JSON.stringify(connection.serialize())}`) - await connection.createInvite(endpointInfo) - logger.debug(`InviterConnectionSM after create invite:\n${JSON.stringify(connection.serialize())}`) await connection.processRequest(request, endpointInfo) logger.debug(`InviterConnectionSM after processing request:\n${JSON.stringify(connection.serialize())}`) await connection.sendResponse() @@ -27,7 +25,7 @@ module.exports.createServiceNonmediatedConnections = function createServiceNonme await saveNonmediatedConnection(connectionId, connection) } - async function inviterConnectionProcessRequest(connectionId, request) { + async function inviterConnectionProcessRequest (connectionId, request) { logger.info(`inviterConnectionProcessRequest >> connectionId=${connectionId}, request: ${request}`) const connection = await loadNonmediatedConnection(connectionId) await connection.processRequest(request, endpointInfo) @@ -37,7 +35,7 @@ module.exports.createServiceNonmediatedConnections = function createServiceNonme await saveNonmediatedConnection(connectionId, connection) } - async function inviterConnectionProcessAck(connectionId, ack) { + async function inviterConnectionProcessAck (connectionId, ack) { logger.info(`inviterConnectionProcessAck >> connectionId=${connectionId}, ack: ${ack}`) const connection = await loadNonmediatedConnection(connectionId) await connection.processAck(ack) @@ -45,7 +43,7 @@ module.exports.createServiceNonmediatedConnections = function createServiceNonme await saveNonmediatedConnection(connectionId, connection) } - async function inviteeConnectionCreateFromInvite(connectionId, invite) { + async function inviteeConnectionCreateFromInvite (connectionId, invite) { logger.info(`inviteeConnectionCreateFromInvite >> connectionId=${connectionId}, invite: ${invite}`) const connection = await NonmediatedConnection.createInvitee(invite) logger.debug(`InviteeConnectionSM after created from invitation:\n${JSON.stringify(connection.serialize())}`) @@ -55,7 +53,7 @@ module.exports.createServiceNonmediatedConnections = function createServiceNonme await saveNonmediatedConnection(connectionId, connection) } - async function inviteeConnectionProcessResponse(connectionId, response) { + async function inviteeConnectionProcessResponse (connectionId, response) { logger.info(`inviteeConnectionProcessResponse >> connectionId=${connectionId}, response: ${response}`) const connection = await loadNonmediatedConnection(connectionId) await connection.processResponse(response) @@ -65,13 +63,13 @@ module.exports.createServiceNonmediatedConnections = function createServiceNonme await saveNonmediatedConnection(connectionId, connection) } - async function sendMessage(connectionId, content) { + async function sendMessage (connectionId, content) { logger.info(`nonmediatedConnectionSendMessage >> connectionId=${connectionId}, content: ${content}`) const connection = await loadNonmediatedConnection(connectionId) await connection.sendMessage(content) } - async function getState(connectionId) { + async function getState (connectionId) { const connection = await loadNonmediatedConnection(connectionId) return connection.getState() } diff --git a/agents/rust/aries-vcx-agent/src/services/connection.rs b/agents/rust/aries-vcx-agent/src/services/connection.rs index 04a473973b..5436692285 100644 --- a/agents/rust/aries-vcx-agent/src/services/connection.rs +++ b/agents/rust/aries-vcx-agent/src/services/connection.rs @@ -11,7 +11,7 @@ use aries_vcx::messages::protocols::connection::invite::Invitation; use aries_vcx::messages::protocols::connection::request::Request; use aries_vcx::messages::protocols::connection::response::SignedResponse; use aries_vcx::protocols::connection::pairwise_info::PairwiseInfo; -use aries_vcx::protocols::connection::{Connection, GenericConnection, State}; +use aries_vcx::protocols::connection::{Connection, GenericConnection, State, ThinState}; pub type ServiceEndpoint = String; @@ -45,7 +45,7 @@ impl ServiceConnections { pub async fn receive_invitation(&self, invite: Invitation) -> AgentResult { let pairwise_info = PairwiseInfo::create(&self.profile.inject_wallet()).await?; let invitee = Connection::new_invitee("".to_owned(), pairwise_info) - .accept_invitation(&self.profile, &invite) + .accept_invitation(&self.profile, invite) .await?; let thread_id = invitee.thread_id().to_owned(); @@ -69,7 +69,22 @@ impl ServiceConnections { } pub async fn accept_request(&self, thread_id: &str, request: Request) -> AgentResult<()> { - let inviter: Connection<_, _> = self.connections.get(thread_id)?.try_into()?; + let inviter = self.connections.get(thread_id)?; + + let inviter = match inviter.state() { + State::Inviter(ThinState::Initial) => Connection::try_from(inviter) + .map_err(From::from) + .map(|c| c.into_invited(&request.id.0)), + State::Inviter(ThinState::Invited) => Connection::try_from(inviter).map_err(From::from), + s => Err(AgentError::from_msg( + AgentErrorKind::GenericAriesVcxError, + &format!( + "Connection with handle {} cannot process a request; State: {:?}", + thread_id, s + ), + )), + }?; + let inviter = inviter .handle_request( &self.profile.inject_wallet(), diff --git a/aries_vcx/src/protocols/connection/generic/mod.rs b/aries_vcx/src/protocols/connection/generic/mod.rs index d7cbdb824c..58a593d3fc 100644 --- a/aries_vcx/src/protocols/connection/generic/mod.rs +++ b/aries_vcx/src/protocols/connection/generic/mod.rs @@ -148,6 +148,7 @@ impl GenericConnection { pub fn invitation(&self) -> Option<&Invitation> { match &self.state { GenericState::Inviter(InviterState::Invited(s)) => Some(&s.invitation), + GenericState::Invitee(InviteeState::Invited(s)) => Some(&s.invitation), _ => None, } } diff --git a/aries_vcx/src/protocols/connection/invitee/mod.rs b/aries_vcx/src/protocols/connection/invitee/mod.rs index 1739231ef1..cdcc7c3590 100644 --- a/aries_vcx/src/protocols/connection/invitee/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/mod.rs @@ -6,7 +6,7 @@ use messages::protocols::connection::invite::Invitation; use crate::{ common::ledger::transactions::into_did_doc, core::profile::profile::Profile, errors::error::VcxResult, - transport::Transport, + protocols::connection::trait_bounds::ThreadId, transport::Transport, }; use self::states::{invited::Invited, requested::Requested}; @@ -46,29 +46,12 @@ impl InviteeConnection { pub async fn accept_invitation( self, profile: &Arc, - invitation: &Invitation, + invitation: Invitation, ) -> VcxResult> { trace!("Connection::accept_invitation >>> invitation: {:?}", &invitation); - let invitation_id = invitation.get_id(); - let did_doc = into_did_doc(profile, invitation).await?; - let request = Request::create() - .set_label(self.source_id.to_string()) - .set_did(self.pairwise_info.pw_did.to_string()); - - let (thread_id, request) = match invitation { - Invitation::Pairwise(_) => (invitation_id.to_owned(), request.set_thread_id(invitation_id)), - Invitation::Public(_) => ( - request.id.0.clone(), - request.set_parent_thread_id(invitation_id).set_thread_id_matching_id(), - ), - Invitation::OutOfBand(_) => ( - request.id.0.clone(), - request.set_parent_thread_id(invitation_id).set_thread_id_matching_id(), - ), - }; - - let state = Invited::new(did_doc, thread_id, request); + let did_doc = into_did_doc(profile, &invitation).await?; + let state = Invited::new(did_doc, invitation); // Convert to `InvitedState` Ok(Connection { @@ -82,7 +65,7 @@ impl InviteeConnection { impl InviteeConnection { pub async fn send_request( - mut self, + self, wallet: &Arc, service_endpoint: String, routing_keys: Vec, @@ -95,18 +78,28 @@ impl InviteeConnection { let recipient_keys = vec![self.pairwise_info.pw_vk.clone()]; - self.state.request = self - .state - .request + let request = Request::create() + .set_label(self.source_id.to_string()) + .set_did(self.pairwise_info.pw_did.to_string()) + .set_thread_id(self.state.thread_id()); + + let (thread_id, request) = match &self.state.invitation { + Invitation::Public(_) | Invitation::OutOfBand(_) => ( + request.id.0.clone(), + request.set_parent_thread_id(self.state.thread_id()), + ), + _ => (self.state.thread_id().to_owned(), request), + }; + + let request = request .set_service_endpoint(service_endpoint) .set_keys(recipient_keys, routing_keys) .set_out_time(); - self.send_message(wallet, &self.state.request.to_a2a_message(), transport) - .await?; + self.send_message(wallet, &request.to_a2a_message(), transport).await?; Ok(Connection { - state: Requested::new(self.state.did_doc, self.state.request.id.0), + state: Requested::new(self.state.did_doc, thread_id), source_id: self.source_id, pairwise_info: self.pairwise_info, initiation_type: Invitee, diff --git a/aries_vcx/src/protocols/connection/invitee/states/invited.rs b/aries_vcx/src/protocols/connection/invitee/states/invited.rs index 3623f2f1d0..6362d1cc28 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/invited.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/invited.rs @@ -1,21 +1,16 @@ -use messages::{diddoc::aries::diddoc::AriesDidDoc, protocols::connection::request::Request}; +use messages::{diddoc::aries::diddoc::AriesDidDoc, protocols::connection::invite::Invitation}; use crate::protocols::connection::trait_bounds::{TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Invited { pub(crate) did_doc: AriesDidDoc, - pub(crate) thread_id: String, - pub(crate) request: Request, + pub(crate) invitation: Invitation, } impl Invited { - pub fn new(did_doc: AriesDidDoc, thread_id: String, request: Request) -> Self { - Self { - did_doc, - thread_id, - request, - } + pub fn new(did_doc: AriesDidDoc, invitation: Invitation) -> Self { + Self { did_doc, invitation } } } @@ -27,6 +22,6 @@ impl TheirDidDoc for Invited { impl ThreadId for Invited { fn thread_id(&self) -> &str { - &self.thread_id + self.invitation.get_id() } } diff --git a/aries_vcx/src/protocols/connection/inviter/mod.rs b/aries_vcx/src/protocols/connection/inviter/mod.rs index 4b588dc564..f7561f064e 100644 --- a/aries_vcx/src/protocols/connection/inviter/mod.rs +++ b/aries_vcx/src/protocols/connection/inviter/mod.rs @@ -36,7 +36,7 @@ impl InviterConnection { } pub fn create_invitation(self, routing_keys: Vec, service_endpoint: String) -> InviterConnection { - let invite: PairwiseInvitation = PairwiseInvitation::create() + let invite = PairwiseInvitation::create() .set_id(&uuid::uuid()) .set_label(&self.source_id) .set_recipient_keys(vec![self.pairwise_info.pw_vk.clone()]) @@ -52,6 +52,28 @@ impl InviterConnection { state: Invited::new(invitation), } } + + /// This is implemented for retro-fitting the previous implementation + /// where a [`Request`] could get processed directly from the initial state. + /// + /// If you want to generate a new inviter and not create an invitation through + /// [`InviterConnection::create_invitation`] then you can call this + /// to transition to the [`InviterConnection`] directly by passing the + /// expected thread_id (external's [`Invitation`] id). + // + // This is a workaround and it's not necessarily pretty, but is implemented + // for backwards compatibility. + pub fn into_invited(self, thread_id: &str) -> InviterConnection { + let invite = PairwiseInvitation::create().set_id(thread_id); + let invitation = Invitation::Pairwise(invite); + + Connection { + source_id: self.source_id, + pairwise_info: self.pairwise_info, + initiation_type: self.initiation_type, + state: Invited::new(invitation), + } + } } impl InviterConnection { diff --git a/libvcx/src/api_vcx/api_handle/connection.rs b/libvcx/src/api_vcx/api_handle/connection.rs index af8e9c200c..7184456b5e 100644 --- a/libvcx/src/api_vcx/api_handle/connection.rs +++ b/libvcx/src/api_vcx/api_handle/connection.rs @@ -3,10 +3,10 @@ use std::{any::type_name, collections::HashMap, sync::RwLock}; use agency_client::httpclient::post_message; use aries_vcx::{ errors::error::{AriesVcxError, VcxResult}, - messages::protocols::basic_message::message::BasicMessage, + messages::protocols::{basic_message::message::BasicMessage, connection::request::Request}, protocols::connection::{ invitee::InviteeConnection, inviter::InviterConnection, pairwise_info::PairwiseInfo, Connection, - GenericConnection, State, + GenericConnection, State, ThinState, }, transport::Transport, }; @@ -251,7 +251,7 @@ pub async fn process_invite(handle: u32, invitation: &str) -> LibvcxResult<()> { let profile = get_main_profile()?; let invitation = deserialize(invitation)?; let con = get_cloned_connection(&handle)? - .accept_invitation(&profile, &invitation) + .accept_invitation(&profile, invitation) .await?; insert_connection(handle, con) @@ -265,9 +265,24 @@ pub async fn process_request( ) -> LibvcxResult<()> { trace!("process_request >>>"); - let con = get_cloned_connection(&handle)?; + let con = get_cloned_generic_connection(&handle)?; let wallet = get_main_profile()?.inject_wallet(); - let request = deserialize(request)?; + let request: Request = deserialize(request)?; + + let con = match con.state() { + State::Inviter(ThinState::Initial) => Connection::try_from(con) + .map_err(From::from) + .map(|c| c.into_invited(&request.get_thread_id())), + State::Inviter(ThinState::Invited) => Connection::try_from(con).map_err(From::from), + s => Err(LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!( + "Connection with handle {} cannot process a request; State: {:?}", + handle, s + ), + )), + }?; + let con = con .handle_request(&wallet, request, service_endpoint, routing_keys, &HttpClient) .await?; From 88e66f2f10b6f6877b7714488be36993560b5486 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Fri, 3 Feb 2023 11:34:33 +0200 Subject: [PATCH 42/66] Fix thread_id usage in Request generation Signed-off-by: Bogdan Mircea --- .../src/protocols/connection/invitee/mod.rs | 17 ++++++++++++----- .../src/protocols/connection/inviter/mod.rs | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/aries_vcx/src/protocols/connection/invitee/mod.rs b/aries_vcx/src/protocols/connection/invitee/mod.rs index cdcc7c3590..c0fd671c7e 100644 --- a/aries_vcx/src/protocols/connection/invitee/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/mod.rs @@ -80,15 +80,19 @@ impl InviteeConnection { let request = Request::create() .set_label(self.source_id.to_string()) - .set_did(self.pairwise_info.pw_did.to_string()) - .set_thread_id(self.state.thread_id()); + .set_did(self.pairwise_info.pw_did.to_string()); let (thread_id, request) = match &self.state.invitation { Invitation::Public(_) | Invitation::OutOfBand(_) => ( request.id.0.clone(), - request.set_parent_thread_id(self.state.thread_id()), + request + .set_parent_thread_id(self.state.thread_id()) + .set_thread_id_matching_id(), + ), + _ => ( + self.state.thread_id().to_owned(), + request.set_thread_id(self.state.thread_id()), ), - _ => (self.state.thread_id().to_owned(), request), }; let request = request @@ -117,7 +121,10 @@ impl InviteeConnection { where T: Transport, { - verify_thread_id(&self.state.thread_id, &A2AMessage::ConnectionResponse(response.clone()))?; + verify_thread_id( + self.state.thread_id(), + &A2AMessage::ConnectionResponse(response.clone()), + )?; let keys = &self.state.did_doc.recipient_keys()?; let their_vk = keys.first().ok_or(AriesVcxError::from_msg( diff --git a/aries_vcx/src/protocols/connection/inviter/mod.rs b/aries_vcx/src/protocols/connection/inviter/mod.rs index f7561f064e..94987ad337 100644 --- a/aries_vcx/src/protocols/connection/inviter/mod.rs +++ b/aries_vcx/src/protocols/connection/inviter/mod.rs @@ -196,7 +196,7 @@ impl InviterConnection { impl InviterConnection { pub fn acknowledge_connection(self, msg: &A2AMessage) -> VcxResult> { - verify_thread_id(&self.state.thread_id, msg)?; + verify_thread_id(self.state.thread_id(), msg)?; let state = Complete::new(self.state.did_doc, self.state.thread_id, None); Ok(Connection { From 1324b590ab34d6ac87a20429bee217d804ccf27c Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Fri, 3 Feb 2023 14:10:12 +0200 Subject: [PATCH 43/66] Added comments Signed-off-by: Bogdan Mircea --- .../src/services/connection.rs | 6 +-- .../src/protocols/connection/generic/mod.rs | 14 +++--- .../connection/generic/thin_state.rs | 14 +++--- .../src/protocols/connection/invitee/mod.rs | 48 ++++++++++++++++--- .../src/protocols/connection/inviter/mod.rs | 31 +++++++++++- aries_vcx/src/protocols/connection/mod.rs | 1 + .../src/protocols/connection/trait_bounds.rs | 6 +-- aries_vcx/src/transport.rs | 5 +- libvcx/src/api_vcx/api_handle/connection.rs | 8 ++-- 9 files changed, 98 insertions(+), 35 deletions(-) diff --git a/agents/rust/aries-vcx-agent/src/services/connection.rs b/agents/rust/aries-vcx-agent/src/services/connection.rs index 5436692285..190aac8a40 100644 --- a/agents/rust/aries-vcx-agent/src/services/connection.rs +++ b/agents/rust/aries-vcx-agent/src/services/connection.rs @@ -72,10 +72,10 @@ impl ServiceConnections { let inviter = self.connections.get(thread_id)?; let inviter = match inviter.state() { - State::Inviter(ThinState::Initial) => Connection::try_from(inviter) + ThinState::Inviter(State::Initial) => Connection::try_from(inviter) .map_err(From::from) .map(|c| c.into_invited(&request.id.0)), - State::Inviter(ThinState::Invited) => Connection::try_from(inviter).map_err(From::from), + ThinState::Inviter(State::Invited) => Connection::try_from(inviter).map_err(From::from), s => Err(AgentError::from_msg( AgentErrorKind::GenericAriesVcxError, &format!( @@ -140,7 +140,7 @@ impl ServiceConnections { Ok(()) } - pub fn get_state(&self, thread_id: &str) -> AgentResult { + pub fn get_state(&self, thread_id: &str) -> AgentResult { Ok(self.connections.get(thread_id)?.state()) } diff --git a/aries_vcx/src/protocols/connection/generic/mod.rs b/aries_vcx/src/protocols/connection/generic/mod.rs index 58a593d3fc..3abebf9c19 100644 --- a/aries_vcx/src/protocols/connection/generic/mod.rs +++ b/aries_vcx/src/protocols/connection/generic/mod.rs @@ -54,9 +54,9 @@ use super::{basic_send_message, common::states::initial::Initial}; /// ``` #[derive(Clone, Debug, Serialize, Deserialize)] pub struct GenericConnection { - pub(super) source_id: String, - pub(super) pairwise_info: PairwiseInfo, - pub(super) state: GenericState, + source_id: String, + pairwise_info: PairwiseInfo, + state: GenericState, } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -84,10 +84,10 @@ pub enum InviteeState { } impl GenericConnection { - /// Returns the underlying [`super::Connection`]'s state as a thin [`State`]. + /// Returns the underlying [`super::Connection`]'s state as a [`ThinState`]. /// Used for pattern matching when there's no hint as to what connection type /// is expected from or stored into the [`GenericConnection`]. - pub fn state(&self) -> State { + pub fn state(&self) -> ThinState { (&self.state).into() } @@ -172,8 +172,8 @@ impl GenericConnection { } } -/// Compile-time assurance that the deserialization type -/// of the [`Connection`], if modified, will be modified along the serialization type. +/// Compile-time assurance that the [`GenericConnection`] and the hidden serialization type +/// of the [`crate::protocols::connection::Connection`], if modified, will be modified together. #[cfg(test)] mod tests { use crate::protocols::connection::serializable::*; diff --git a/aries_vcx/src/protocols/connection/generic/thin_state.rs b/aries_vcx/src/protocols/connection/generic/thin_state.rs index 7410c0b746..48967c2b00 100644 --- a/aries_vcx/src/protocols/connection/generic/thin_state.rs +++ b/aries_vcx/src/protocols/connection/generic/thin_state.rs @@ -3,15 +3,15 @@ use super::{GenericState, InviteeState, InviterState}; /// Small sized enum used for determining /// a connection's state in terms of initiation type. #[derive(Clone, Copy, Debug)] -pub enum State { - Invitee(ThinState), - Inviter(ThinState), +pub enum ThinState { + Invitee(State), + Inviter(State), } /// Small sized enum used for determining /// a connection's state in terms of connection stage. #[derive(Clone, Copy, Debug)] -pub enum ThinState { +pub enum State { Initial, Invited, Requested, @@ -19,7 +19,7 @@ pub enum ThinState { Complete, } -impl From<&GenericState> for State { +impl From<&GenericState> for ThinState { fn from(value: &GenericState) -> Self { match value { GenericState::Invitee(v) => Self::Invitee(v.into()), @@ -28,7 +28,7 @@ impl From<&GenericState> for State { } } -impl From<&InviterState> for ThinState { +impl From<&InviterState> for State { fn from(value: &InviterState) -> Self { match value { InviterState::Initial(_) => Self::Initial, @@ -40,7 +40,7 @@ impl From<&InviterState> for ThinState { } } -impl From<&InviteeState> for ThinState { +impl From<&InviteeState> for State { fn from(value: &InviteeState) -> Self { match value { InviteeState::Initial(_) => Self::Initial, diff --git a/aries_vcx/src/protocols/connection/invitee/mod.rs b/aries_vcx/src/protocols/connection/invitee/mod.rs index c0fd671c7e..958efa9e61 100644 --- a/aries_vcx/src/protocols/connection/invitee/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/mod.rs @@ -34,6 +34,7 @@ use crate::{ pub type InviteeConnection = Connection; impl InviteeConnection { + /// Creates a new [`InviteeConnection`]. pub fn new_invitee(source_id: String, pairwise_info: PairwiseInfo) -> Self { Self { source_id, @@ -43,6 +44,11 @@ impl InviteeConnection { } } + /// Accepts an [`Invitation`] and transitions to [`InviteeConnection`]. + /// + /// # Errors + /// + /// Will error out if a DidDoc could not be resolved from the [`Invitation`]. pub async fn accept_invitation( self, profile: &Arc, @@ -64,6 +70,11 @@ impl InviteeConnection { } impl InviteeConnection { + /// Sends a [`Request`] to the inviter and transitions to [`InviteeConnection`]. + /// + /// # Errors + /// + /// Will error out if sending the request fails. pub async fn send_request( self, wallet: &Arc, @@ -80,8 +91,23 @@ impl InviteeConnection { let request = Request::create() .set_label(self.source_id.to_string()) - .set_did(self.pairwise_info.pw_did.to_string()); + .set_did(self.pairwise_info.pw_did.to_string()) + .set_service_endpoint(service_endpoint) + .set_keys(recipient_keys, routing_keys) + .set_out_time(); + // Depending on the invitation type, we set the connection's thread ID + // and the request parent and thread ID differently. + // + // When using a Public or OOB invitation, the invitation's ID (current thread ID) + // is used as the parent thread ID, while the request ID is set as thread ID. + // + // Multiple invitees can use the same invitation in these cases, hence the common + // parent thread ID and different thread IDs (request IDs are unique). + // + // When the invitation is Pairwise, it is designed to be sent to a single invitee. + // In this case, we reuse the invitation ID (current thread ID) as the thread ID + // in both the connection and the request. let (thread_id, request) = match &self.state.invitation { Invitation::Public(_) | Invitation::OutOfBand(_) => ( request.id.0.clone(), @@ -89,17 +115,12 @@ impl InviteeConnection { .set_parent_thread_id(self.state.thread_id()) .set_thread_id_matching_id(), ), - _ => ( + Invitation::Pairwise(_) => ( self.state.thread_id().to_owned(), request.set_thread_id(self.state.thread_id()), ), }; - let request = request - .set_service_endpoint(service_endpoint) - .set_keys(recipient_keys, routing_keys) - .set_out_time(); - self.send_message(wallet, &request.to_a2a_message(), transport).await?; Ok(Connection { @@ -112,6 +133,14 @@ impl InviteeConnection { } impl InviteeConnection { + /// Processes a [`SignedResponse`] from the inviter and transitions to [`InviteeConnection`]. + /// + /// # Errors + /// + /// Will error out if: + /// * the thread ID of the response does not match the connection thread ID + /// * no recipient verkeys are provided in the response. + /// * decoding the signed response fails pub async fn handle_response( self, wallet: &Arc, @@ -156,6 +185,11 @@ impl InviteeConnection { } impl InviteeConnection { + /// Sends an acknolwedgement message to the inviter and transitions to [`InviteeConnection`]. + /// + /// # Errors + /// + /// Will error out if sending the message fails. pub async fn send_ack( self, wallet: &Arc, diff --git a/aries_vcx/src/protocols/connection/inviter/mod.rs b/aries_vcx/src/protocols/connection/inviter/mod.rs index 94987ad337..fc71e00f3e 100644 --- a/aries_vcx/src/protocols/connection/inviter/mod.rs +++ b/aries_vcx/src/protocols/connection/inviter/mod.rs @@ -26,6 +26,10 @@ use messages::protocols::connection::{ pub type InviterConnection = Connection; impl InviterConnection { + /// Creates a new [`InviterConnection`]. + /// + /// The connection can transition to [`InviterConnection`] by + /// either `create_invitation` or `into_invited`. pub fn new_inviter(source_id: String, pairwise_info: PairwiseInfo) -> Self { Self { source_id, @@ -35,6 +39,7 @@ impl InviterConnection { } } + /// Generates a pairwise [`Invitation`] and transitions to [`InviterConnection`]. pub fn create_invitation(self, routing_keys: Vec, service_endpoint: String) -> InviterConnection { let invite = PairwiseInvitation::create() .set_id(&uuid::uuid()) @@ -58,7 +63,7 @@ impl InviterConnection { /// /// If you want to generate a new inviter and not create an invitation through /// [`InviterConnection::create_invitation`] then you can call this - /// to transition to the [`InviterConnection`] directly by passing the + /// to transition to the [`InviterConnection`] directly by passing the /// expected thread_id (external's [`Invitation`] id). // // This is a workaround and it's not necessarily pretty, but is implemented @@ -77,7 +82,7 @@ impl InviterConnection { } impl InviterConnection { - // This should ideally belong in the Connection + // This should ideally belong in the Connection // but was placed here to retro-fit the previous API. async fn build_response( &self, @@ -99,6 +104,14 @@ impl InviterConnection { sign_connection_response(wallet, &self.pairwise_info.pw_vk, response).await } + /// Processes a [`Request`] and transitions to [`InviterConnection`]. + /// + /// # Errors + /// + /// Will return an error if either: + /// * the [`Request`]'s thread ID does not match with the expected thread ID from an invitation + /// * the [`Request`]'s DidDoc is not valid + /// * generating new [`PairwiseInfo`] fails pub async fn handle_request( self, wallet: &Arc, @@ -137,6 +150,8 @@ impl InviterConnection { Err(err)?; } + // Generate new pairwise info that will be used from this point on + // and incorporate that into the response. let new_pairwise_info = PairwiseInfo::create(wallet).await?; let signed_response = self .build_response( @@ -165,6 +180,11 @@ impl InviterConnection { } impl InviterConnection { + /// Sends a [`Response`] to the invitee and transitions to [`InviterConnection`]. + /// + /// # Errors + /// + /// Will return an error if sending the repsonse fails. pub async fn send_response( self, wallet: &Arc, @@ -195,6 +215,13 @@ impl InviterConnection { } impl InviterConnection { + /// Acknowledges an invitee's connection by processing their first message + /// and transitions to [`InviterConnection`]. + /// + /// # Errors + /// + /// Will error out if the message's thread ID does not match + /// the ID of the thread context used in this connection. pub fn acknowledge_connection(self, msg: &A2AMessage) -> VcxResult> { verify_thread_id(self.state.thread_id(), msg)?; let state = Complete::new(self.state.did_doc, self.state.thread_id, None); diff --git a/aries_vcx/src/protocols/connection/mod.rs b/aries_vcx/src/protocols/connection/mod.rs index 8ca6c24a88..d330f749a2 100644 --- a/aries_vcx/src/protocols/connection/mod.rs +++ b/aries_vcx/src/protocols/connection/mod.rs @@ -33,6 +33,7 @@ use self::{ pub use self::generic::{GenericConnection, State, ThinState}; +/// A state machine for progressing through the (connection protocol)[https://github.com/hyperledger/aries-rfcs/blob/main/features/0160-connection-protocol/README.md]. #[derive(Clone, Deserialize)] #[serde(try_from = "GenericConnection")] #[serde(bound = "(I, S): TryFrom")] diff --git a/aries_vcx/src/protocols/connection/trait_bounds.rs b/aries_vcx/src/protocols/connection/trait_bounds.rs index ad8a6fa46e..e5a1e2d521 100644 --- a/aries_vcx/src/protocols/connection/trait_bounds.rs +++ b/aries_vcx/src/protocols/connection/trait_bounds.rs @@ -1,13 +1,11 @@ use messages::diddoc::aries::diddoc::AriesDidDoc; -/// Trait used for implementing common [`super::Connection`] behavior based -/// on states implementing it. +/// Trait implemented for [`super::Connection`] states that store an [`AriesDidDoc`]. pub trait TheirDidDoc { fn their_did_doc(&self) -> &AriesDidDoc; } -/// Trait used for implementing common [`super::Connection`] behavior based -/// on states implementing it. +/// Trait implemented for [`super::Connection`] states that keep track of a thread ID. pub trait ThreadId { fn thread_id(&self) -> &str; } diff --git a/aries_vcx/src/transport.rs b/aries_vcx/src/transport.rs index 68488efbf4..506686ddc2 100644 --- a/aries_vcx/src/transport.rs +++ b/aries_vcx/src/transport.rs @@ -2,12 +2,15 @@ use async_trait::async_trait; use crate::errors::error::VcxResult; -/// Trait used for implementing a mechanism to send a message, used by [`super::Connection`]. +/// Trait used for implementing a mechanism to send a message, used by [`crate::protocols::connection::Connection`]. #[async_trait] pub trait Transport: Send + Sync { async fn send_message(&self, msg: Vec, service_endpoint: &str) -> VcxResult<()>; } +// While in many cases the auto-dereferencing does the trick, +// this implementation aids in using things such as a trait object +// when a generic parameter is expected. #[async_trait] impl Transport for &T where diff --git a/libvcx/src/api_vcx/api_handle/connection.rs b/libvcx/src/api_vcx/api_handle/connection.rs index 7184456b5e..2c61eee670 100644 --- a/libvcx/src/api_vcx/api_handle/connection.rs +++ b/libvcx/src/api_vcx/api_handle/connection.rs @@ -216,8 +216,8 @@ pub fn get_state(handle: u32) -> LibvcxResult { })?; let state_id = match con.state() { - State::Invitee(s) => s as u32, - State::Inviter(s) => s as u32, + ThinState::Invitee(s) => s as u32, + ThinState::Inviter(s) => s as u32, }; Ok(state_id) @@ -270,10 +270,10 @@ pub async fn process_request( let request: Request = deserialize(request)?; let con = match con.state() { - State::Inviter(ThinState::Initial) => Connection::try_from(con) + ThinState::Inviter(State::Initial) => Connection::try_from(con) .map_err(From::from) .map(|c| c.into_invited(&request.get_thread_id())), - State::Inviter(ThinState::Invited) => Connection::try_from(con).map_err(From::from), + ThinState::Inviter(State::Invited) => Connection::try_from(con).map_err(From::from), s => Err(LibvcxError::from_msg( LibvcxErrorKind::ObjectAccessError, format!( From ca3ddcc1e79baa9ca7838e50e6980e8bc2907ef1 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Fri, 3 Feb 2023 16:04:41 +0200 Subject: [PATCH 44/66] Added concrete and generic connection serialization and deserialization tests Signed-off-by: Bogdan Mircea --- .../src/protocols/connection/generic/mod.rs | 187 +++++++++++++++++- 1 file changed, 185 insertions(+), 2 deletions(-) diff --git a/aries_vcx/src/protocols/connection/generic/mod.rs b/aries_vcx/src/protocols/connection/generic/mod.rs index 3abebf9c19..0efcabe3dc 100644 --- a/aries_vcx/src/protocols/connection/generic/mod.rs +++ b/aries_vcx/src/protocols/connection/generic/mod.rs @@ -175,10 +175,21 @@ impl GenericConnection { /// Compile-time assurance that the [`GenericConnection`] and the hidden serialization type /// of the [`crate::protocols::connection::Connection`], if modified, will be modified together. #[cfg(test)] -mod tests { - use crate::protocols::connection::serializable::*; +mod connection_serde_tests { + #![allow(clippy::unwrap_used)] + + use async_trait::async_trait; + use messages::protocols::connection::invite::PairwiseInvitation; + use messages::protocols::connection::request::Request; + use messages::protocols::connection::response::Response; use super::*; + use crate::common::signing::sign_connection_response; + use crate::core::profile::profile::Profile; + use crate::protocols::connection::serializable::*; + use crate::protocols::connection::{invitee::InviteeConnection, inviter::InviterConnection, Connection}; + use crate::utils::mockdata::profile::mock_profile::MockProfile; + use std::sync::Arc; impl<'a> From> for InviteeState { fn from(value: RefInviteeState<'a>) -> Self { @@ -277,4 +288,176 @@ mod tests { } } } + + struct MockTransport; + + #[async_trait] + impl Transport for MockTransport { + async fn send_message(&self, _msg: Vec, _service_endpoint: &str) -> VcxResult<()> { + Ok(()) + } + } + + fn serde_test(con: Connection) + where + I: Clone, + S: Clone, + for<'a> SerializableConnection<'a>: From<&'a Connection>, + GenericConnection: From>, + Connection: TryFrom, + (I, S): TryFrom, + { + // Clone and convert to generic + let gen_con = GenericConnection::from(con.clone()); + + // Serialize concrete and generic connections, then compare. + let con_string = serde_json::to_string(&con).unwrap(); + let gen_con_string = serde_json::to_string(&gen_con).unwrap(); + assert_eq!(con_string, gen_con_string); + + // Deliberately reversing the strings that were serialized. + // The states are identical, so the cross-deserialization should work. + let con: Connection = serde_json::from_str(&gen_con_string).unwrap(); + let gen_con: GenericConnection = serde_json::from_str(&con_string).unwrap(); + + // Serialize and compare again. + let con_string = serde_json::to_string(&con).unwrap(); + let gen_con_string = serde_json::to_string(&gen_con).unwrap(); + assert_eq!(con_string, gen_con_string); + } + + const SOURCE_ID: &str = "connection_serde_tests"; + const PW_KEY: &str = "7Z9ZajGKvb6BMsZ9TBEqxMHktxGdts3FvAbKSJT5XgzK"; + const SERVICE_ENDPOINT: &str = "https://localhost:8080"; + + fn make_mock_profile() -> Arc { + Arc::new(MockProfile) + } + + async fn make_initial_parts() -> (String, PairwiseInfo) { + let source_id = SOURCE_ID.to_owned(); + let pairwise_info = PairwiseInfo::create(&make_mock_profile().inject_wallet()) + .await + .unwrap(); + + (source_id, pairwise_info) + } + + async fn make_invitee_initial() -> InviteeConnection { + let (source_id, pairwise_info) = make_initial_parts().await; + Connection::new_invitee(source_id, pairwise_info) + } + + async fn make_invitee_invited() -> InviteeConnection { + let profile = make_mock_profile(); + let pw_invite = PairwiseInvitation::default().set_recipient_keys(vec![PW_KEY.to_owned()]); + let invitation = Invitation::Pairwise(pw_invite); + + make_invitee_initial() + .await + .accept_invitation(&profile, invitation) + .await + .unwrap() + } + + async fn make_invitee_requested() -> InviteeConnection { + let wallet = make_mock_profile().inject_wallet(); + let service_endpoint = SERVICE_ENDPOINT.to_owned(); + let routing_keys = vec![]; + + make_invitee_invited() + .await + .send_request(&wallet, service_endpoint, routing_keys, &MockTransport) + .await + .unwrap() + } + + async fn make_invitee_responded() -> InviteeConnection { + let wallet = make_mock_profile().inject_wallet(); + let con = make_invitee_requested().await; + let response = Response::create() + .set_keys(vec![PW_KEY.to_owned()], vec![]) + .ask_for_ack() + .set_thread_id(con.thread_id()) + .set_out_time(); + + let response = sign_connection_response(&wallet, PW_KEY, response).await.unwrap(); + + con.handle_response(&wallet, response, &MockTransport).await.unwrap() + } + + async fn make_invitee_complete() -> InviteeConnection { + let wallet = make_mock_profile().inject_wallet(); + + make_invitee_responded() + .await + .send_ack(&wallet, &MockTransport) + .await + .unwrap() + } + + async fn make_inviter_initial() -> InviterConnection { + let (source_id, pairwise_info) = make_initial_parts().await; + Connection::new_inviter(source_id, pairwise_info) + } + + async fn make_inviter_invited() -> InviterConnection { + make_inviter_initial().await.into_invited(&String::default()) + } + + async fn make_inviter_requested() -> InviterConnection { + let wallet = make_mock_profile().inject_wallet(); + let con = make_inviter_invited().await; + let new_service_endpoint = SERVICE_ENDPOINT.to_owned(); + let new_routing_keys = vec![]; + let request = Request::create() + .set_service_endpoint(new_service_endpoint.clone()) + .set_label(SOURCE_ID.to_owned()) + .set_did(PW_KEY.to_owned()) + .set_keys(vec![PW_KEY.to_owned()], vec![]) + .set_thread_id(con.thread_id()) + .set_out_time(); + + con.handle_request(&wallet, request, new_service_endpoint, new_routing_keys, &MockTransport) + .await + .unwrap() + } + + async fn make_inviter_responded() -> InviterConnection { + let wallet = make_mock_profile().inject_wallet(); + + make_inviter_requested() + .await + .send_response(&wallet, &MockTransport) + .await + .unwrap() + } + + async fn make_inviter_complete() -> InviterConnection { + let msg = Request::create().to_a2a_message(); + + make_inviter_responded().await.acknowledge_connection(&msg).unwrap() + } + + macro_rules! generate_test { + ($name:ident, $func:ident) => { + #[tokio::test] + async fn $name() { + let con = $func().await; + serde_test(con); + } + }; + } + + generate_test!(invitee_connection_initial, make_invitee_initial); + generate_test!(invitee_connection_invited, make_invitee_invited); + generate_test!(invitee_connection_requested, make_invitee_requested); + generate_test!(invitee_connection_responded, make_invitee_responded); + generate_test!(invitee_connection_complete, make_invitee_complete); + + generate_test!(inviter_connection_initial, make_inviter_initial); + generate_test!(inviter_connection_invited, make_inviter_invited); + generate_test!(inviter_connection_requested, make_inviter_requested); + generate_test!(inviter_connection_responded, make_inviter_responded); + generate_test!(inviter_connection_complete, make_inviter_complete); } From 64fc633d5ef569aa9d2cbff3f040e732ab3c404c Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Fri, 3 Feb 2023 17:26:21 +0200 Subject: [PATCH 45/66] Added whitespace in libcx Signed-off-by: Bogdan Mircea --- libvcx/src/api_vcx/api_handle/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libvcx/src/api_vcx/api_handle/mod.rs b/libvcx/src/api_vcx/api_handle/mod.rs index 53e8210e30..a1c5b208f0 100644 --- a/libvcx/src/api_vcx/api_handle/mod.rs +++ b/libvcx/src/api_vcx/api_handle/mod.rs @@ -8,4 +8,4 @@ pub mod out_of_band; pub mod proof; pub mod revocation_registry; pub mod schema; -pub mod connection; \ No newline at end of file +pub mod connection; From 05f030352cb2ed7e27b99e3fcab042d6598fcd7f Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Fri, 3 Feb 2023 17:34:48 +0200 Subject: [PATCH 46/66] Ran cargo fmt Signed-off-by: Bogdan Mircea --- .../src/services/connection.rs | 2 +- .../connection/mediated_connection.rs | 8 ++++++-- aries_vcx/src/handlers/mod.rs | 4 ++-- .../src/protocols/connection/common/mod.rs | 2 +- .../protocols/connection/common/states/mod.rs | 2 +- .../protocols/connection/initiation_type.rs | 3 +-- .../src/protocols/connection/invitee/mod.rs | 8 ++++---- .../connection/invitee/states/mod.rs | 2 +- .../src/protocols/connection/inviter/mod.rs | 20 +++++++++---------- .../connection/inviter/states/mod.rs | 2 +- aries_vcx/src/protocols/mod.rs | 4 ++-- aries_vcx/tests/utils/devsetup_agent.rs | 4 ++-- aries_vcx/tests/utils/scenarios.rs | 4 ++-- libvcx/src/api_vcx/api_handle/mod.rs | 2 +- 14 files changed, 35 insertions(+), 32 deletions(-) diff --git a/agents/rust/aries-vcx-agent/src/services/connection.rs b/agents/rust/aries-vcx-agent/src/services/connection.rs index 190aac8a40..bde2ba8721 100644 --- a/agents/rust/aries-vcx-agent/src/services/connection.rs +++ b/agents/rust/aries-vcx-agent/src/services/connection.rs @@ -75,7 +75,7 @@ impl ServiceConnections { ThinState::Inviter(State::Initial) => Connection::try_from(inviter) .map_err(From::from) .map(|c| c.into_invited(&request.id.0)), - ThinState::Inviter(State::Invited) => Connection::try_from(inviter).map_err(From::from), + ThinState::Inviter(State::Invited) => Connection::try_from(inviter).map_err(From::from), s => Err(AgentError::from_msg( AgentErrorKind::GenericAriesVcxError, &format!( diff --git a/aries_vcx/src/handlers/connection/mediated_connection.rs b/aries_vcx/src/handlers/connection/mediated_connection.rs index 2655c691d6..93904d6bb7 100644 --- a/aries_vcx/src/handlers/connection/mediated_connection.rs +++ b/aries_vcx/src/handlers/connection/mediated_connection.rs @@ -19,8 +19,12 @@ use crate::handlers::connection::cloud_agent::CloudAgentInfo; use crate::handlers::connection::legacy_agent_info::LegacyAgentInfo; use crate::handlers::discovery::{respond_discovery_query, send_discovery_query}; use crate::handlers::trust_ping::TrustPingSender; -use crate::protocols::mediated_connection::invitee::state_machine::{InviteeFullState, InviteeState, SmConnectionInvitee}; -use crate::protocols::mediated_connection::inviter::state_machine::{InviterFullState, InviterState, SmConnectionInviter}; +use crate::protocols::mediated_connection::invitee::state_machine::{ + InviteeFullState, InviteeState, SmConnectionInvitee, +}; +use crate::protocols::mediated_connection::inviter::state_machine::{ + InviterFullState, InviterState, SmConnectionInviter, +}; use crate::protocols::mediated_connection::pairwise_info::PairwiseInfo; use crate::protocols::oob::{build_handshake_reuse_accepted_msg, build_handshake_reuse_msg}; use crate::protocols::trustping::build_ping_response; diff --git a/aries_vcx/src/handlers/mod.rs b/aries_vcx/src/handlers/mod.rs index e766b15d7a..065865dd8e 100644 --- a/aries_vcx/src/handlers/mod.rs +++ b/aries_vcx/src/handlers/mod.rs @@ -1,8 +1,8 @@ use crate::handlers::connection::mediated_connection::ConnectionState as MediatedConnectionState; -use crate::protocols::mediated_connection::invitee::state_machine::InviteeState; -use crate::protocols::mediated_connection::inviter::state_machine::InviterState; use crate::protocols::issuance::holder::state_machine::HolderState; use crate::protocols::issuance::issuer::state_machine::IssuerState; +use crate::protocols::mediated_connection::invitee::state_machine::InviteeState; +use crate::protocols::mediated_connection::inviter::state_machine::InviterState; use crate::protocols::proof_presentation::prover::state_machine::ProverState; use crate::protocols::proof_presentation::verifier::state_machine::VerifierState; diff --git a/aries_vcx/src/protocols/connection/common/mod.rs b/aries_vcx/src/protocols/connection/common/mod.rs index ad079970d7..20394784ae 100644 --- a/aries_vcx/src/protocols/connection/common/mod.rs +++ b/aries_vcx/src/protocols/connection/common/mod.rs @@ -1 +1 @@ -pub mod states; \ No newline at end of file +pub mod states; diff --git a/aries_vcx/src/protocols/connection/common/states/mod.rs b/aries_vcx/src/protocols/connection/common/states/mod.rs index 2f2acaa2f5..f97ca0ebe1 100644 --- a/aries_vcx/src/protocols/connection/common/states/mod.rs +++ b/aries_vcx/src/protocols/connection/common/states/mod.rs @@ -1,3 +1,3 @@ pub mod complete; +pub mod initial; pub mod responded; -pub mod initial; \ No newline at end of file diff --git a/aries_vcx/src/protocols/connection/initiation_type.rs b/aries_vcx/src/protocols/connection/initiation_type.rs index eda8e75cd2..459e3e2d3d 100644 --- a/aries_vcx/src/protocols/connection/initiation_type.rs +++ b/aries_vcx/src/protocols/connection/initiation_type.rs @@ -1,8 +1,7 @@ - /// Unit struct illustrating that the connection was initiated by an inviter. #[derive(Clone, Copy, Debug)] pub struct Inviter; /// Unit struct illustrating that the connection was initiated by an invitee. #[derive(Clone, Copy, Debug)] -pub struct Invitee; \ No newline at end of file +pub struct Invitee; diff --git a/aries_vcx/src/protocols/connection/invitee/mod.rs b/aries_vcx/src/protocols/connection/invitee/mod.rs index 958efa9e61..b696ebc27d 100644 --- a/aries_vcx/src/protocols/connection/invitee/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/mod.rs @@ -134,9 +134,9 @@ impl InviteeConnection { impl InviteeConnection { /// Processes a [`SignedResponse`] from the inviter and transitions to [`InviteeConnection`]. - /// + /// /// # Errors - /// + /// /// Will error out if: /// * the thread ID of the response does not match the connection thread ID /// * no recipient verkeys are provided in the response. @@ -186,9 +186,9 @@ impl InviteeConnection { impl InviteeConnection { /// Sends an acknolwedgement message to the inviter and transitions to [`InviteeConnection`]. - /// + /// /// # Errors - /// + /// /// Will error out if sending the message fails. pub async fn send_ack( self, diff --git a/aries_vcx/src/protocols/connection/invitee/states/mod.rs b/aries_vcx/src/protocols/connection/invitee/states/mod.rs index 0cbaf26c40..b0bec16a16 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/mod.rs @@ -1,2 +1,2 @@ pub mod invited; -pub mod requested; \ No newline at end of file +pub mod requested; diff --git a/aries_vcx/src/protocols/connection/inviter/mod.rs b/aries_vcx/src/protocols/connection/inviter/mod.rs index fc71e00f3e..fb3b17f264 100644 --- a/aries_vcx/src/protocols/connection/inviter/mod.rs +++ b/aries_vcx/src/protocols/connection/inviter/mod.rs @@ -27,7 +27,7 @@ pub type InviterConnection = Connection; impl InviterConnection { /// Creates a new [`InviterConnection`]. - /// + /// /// The connection can transition to [`InviterConnection`] by /// either `create_invitation` or `into_invited`. pub fn new_inviter(source_id: String, pairwise_info: PairwiseInfo) -> Self { @@ -60,8 +60,8 @@ impl InviterConnection { /// This is implemented for retro-fitting the previous implementation /// where a [`Request`] could get processed directly from the initial state. - /// - /// If you want to generate a new inviter and not create an invitation through + /// + /// If you want to generate a new inviter and not create an invitation through /// [`InviterConnection::create_invitation`] then you can call this /// to transition to the [`InviterConnection`] directly by passing the /// expected thread_id (external's [`Invitation`] id). @@ -105,9 +105,9 @@ impl InviterConnection { } /// Processes a [`Request`] and transitions to [`InviterConnection`]. - /// + /// /// # Errors - /// + /// /// Will return an error if either: /// * the [`Request`]'s thread ID does not match with the expected thread ID from an invitation /// * the [`Request`]'s DidDoc is not valid @@ -181,9 +181,9 @@ impl InviterConnection { impl InviterConnection { /// Sends a [`Response`] to the invitee and transitions to [`InviterConnection`]. - /// + /// /// # Errors - /// + /// /// Will return an error if sending the repsonse fails. pub async fn send_response( self, @@ -217,10 +217,10 @@ impl InviterConnection { impl InviterConnection { /// Acknowledges an invitee's connection by processing their first message /// and transitions to [`InviterConnection`]. - /// + /// /// # Errors - /// - /// Will error out if the message's thread ID does not match + /// + /// Will error out if the message's thread ID does not match /// the ID of the thread context used in this connection. pub fn acknowledge_connection(self, msg: &A2AMessage) -> VcxResult> { verify_thread_id(self.state.thread_id(), msg)?; diff --git a/aries_vcx/src/protocols/connection/inviter/states/mod.rs b/aries_vcx/src/protocols/connection/inviter/states/mod.rs index 0cbaf26c40..b0bec16a16 100644 --- a/aries_vcx/src/protocols/connection/inviter/states/mod.rs +++ b/aries_vcx/src/protocols/connection/inviter/states/mod.rs @@ -1,2 +1,2 @@ pub mod invited; -pub mod requested; \ No newline at end of file +pub mod requested; diff --git a/aries_vcx/src/protocols/mod.rs b/aries_vcx/src/protocols/mod.rs index 85fe22ae26..7e7a9747e4 100644 --- a/aries_vcx/src/protocols/mod.rs +++ b/aries_vcx/src/protocols/mod.rs @@ -5,13 +5,13 @@ use messages::diddoc::aries::diddoc::AriesDidDoc; use crate::errors::error::VcxResult; pub mod common; -pub mod mediated_connection; +pub mod connection; pub mod issuance; +pub mod mediated_connection; pub mod oob; pub mod proof_presentation; pub mod revocation_notification; pub mod trustping; -pub mod connection; pub type SendClosure = Box BoxFuture<'static, VcxResult<()>> + Send + Sync>; pub type SendClosureConnection = diff --git a/aries_vcx/tests/utils/devsetup_agent.rs b/aries_vcx/tests/utils/devsetup_agent.rs index 62e4420785..33bb282f0b 100644 --- a/aries_vcx/tests/utils/devsetup_agent.rs +++ b/aries_vcx/tests/utils/devsetup_agent.rs @@ -48,10 +48,10 @@ pub mod test_utils { use aries_vcx::messages::protocols::issuance::credential_offer::CredentialOffer; use aries_vcx::messages::protocols::issuance::credential_offer::OfferInfo; use aries_vcx::messages::protocols::proof_presentation::presentation_request::PresentationRequest; - use aries_vcx::protocols::mediated_connection::invitee::state_machine::InviteeState; - use aries_vcx::protocols::mediated_connection::inviter::state_machine::InviterState; use aries_vcx::protocols::issuance::holder::state_machine::HolderState; use aries_vcx::protocols::issuance::issuer::state_machine::IssuerState; + use aries_vcx::protocols::mediated_connection::invitee::state_machine::InviteeState; + use aries_vcx::protocols::mediated_connection::inviter::state_machine::InviterState; use aries_vcx::protocols::proof_presentation::prover::state_machine::ProverState; use aries_vcx::protocols::proof_presentation::verifier::state_machine::VerifierState; use aries_vcx::utils::devsetup::*; diff --git a/aries_vcx/tests/utils/scenarios.rs b/aries_vcx/tests/utils/scenarios.rs index c3104e674a..e481937bbc 100644 --- a/aries_vcx/tests/utils/scenarios.rs +++ b/aries_vcx/tests/utils/scenarios.rs @@ -35,10 +35,10 @@ pub mod test_utils { Attribute, PresentationProposalData, }; use aries_vcx::messages::protocols::proof_presentation::presentation_request::PresentationRequest; - use aries_vcx::protocols::mediated_connection::invitee::state_machine::InviteeState; - use aries_vcx::protocols::mediated_connection::inviter::state_machine::InviterState; use aries_vcx::protocols::issuance::holder::state_machine::HolderState; use aries_vcx::protocols::issuance::issuer::state_machine::IssuerState; + use aries_vcx::protocols::mediated_connection::invitee::state_machine::InviteeState; + use aries_vcx::protocols::mediated_connection::inviter::state_machine::InviterState; use aries_vcx::protocols::proof_presentation::prover::state_machine::ProverState; use aries_vcx::protocols::proof_presentation::verifier::state_machine::VerifierState; use aries_vcx::utils::constants::{DEFAULT_PROOF_NAME, TAILS_DIR, TEST_TAILS_URL}; diff --git a/libvcx/src/api_vcx/api_handle/mod.rs b/libvcx/src/api_vcx/api_handle/mod.rs index a1c5b208f0..4f173bb3ee 100644 --- a/libvcx/src/api_vcx/api_handle/mod.rs +++ b/libvcx/src/api_vcx/api_handle/mod.rs @@ -1,3 +1,4 @@ +pub mod connection; pub mod credential; pub mod credential_def; pub mod disclosed_proof; @@ -8,4 +9,3 @@ pub mod out_of_band; pub mod proof; pub mod revocation_registry; pub mod schema; -pub mod connection; From 2d5145a9626b0f52b2e1072fd4afb96ad3df644b Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Tue, 7 Feb 2023 09:33:35 +0200 Subject: [PATCH 47/66] Completely separated states between invitee and inviter Signed-off-by: Bogdan Mircea --- .../src/protocols/connection/common/mod.rs | 1 - .../protocols/connection/common/states/mod.rs | 3 -- .../connection/generic/conversions.rs | 37 ++++++++------- .../src/protocols/connection/generic/mod.rs | 39 +++++++++------- .../src/protocols/connection/invitee/mod.rs | 11 ++--- .../{common => invitee}/states/complete.rs | 20 +++++---- .../{common => invitee}/states/initial.rs | 0 .../connection/invitee/states/mod.rs | 3 ++ .../{common => invitee}/states/responded.rs | 0 .../src/protocols/connection/inviter/mod.rs | 7 ++- .../connection/inviter/states/complete.rs | 45 +++++++++++++++++++ .../connection/inviter/states/initial.rs | 2 + .../connection/inviter/states/mod.rs | 3 ++ .../connection/inviter/states/responded.rs | 27 +++++++++++ aries_vcx/src/protocols/connection/mod.rs | 9 ++-- .../src/protocols/connection/serializable.rs | 37 ++++++++------- .../src/protocols/connection/trait_bounds.rs | 9 +++- 17 files changed, 176 insertions(+), 77 deletions(-) delete mode 100644 aries_vcx/src/protocols/connection/common/mod.rs delete mode 100644 aries_vcx/src/protocols/connection/common/states/mod.rs rename aries_vcx/src/protocols/connection/{common => invitee}/states/complete.rs (78%) rename aries_vcx/src/protocols/connection/{common => invitee}/states/initial.rs (100%) rename aries_vcx/src/protocols/connection/{common => invitee}/states/responded.rs (100%) create mode 100644 aries_vcx/src/protocols/connection/inviter/states/complete.rs create mode 100644 aries_vcx/src/protocols/connection/inviter/states/initial.rs create mode 100644 aries_vcx/src/protocols/connection/inviter/states/responded.rs diff --git a/aries_vcx/src/protocols/connection/common/mod.rs b/aries_vcx/src/protocols/connection/common/mod.rs deleted file mode 100644 index 20394784ae..0000000000 --- a/aries_vcx/src/protocols/connection/common/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod states; diff --git a/aries_vcx/src/protocols/connection/common/states/mod.rs b/aries_vcx/src/protocols/connection/common/states/mod.rs deleted file mode 100644 index f97ca0ebe1..0000000000 --- a/aries_vcx/src/protocols/connection/common/states/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod complete; -pub mod initial; -pub mod responded; diff --git a/aries_vcx/src/protocols/connection/generic/conversions.rs b/aries_vcx/src/protocols/connection/generic/conversions.rs index 168d5922fb..eac5c58d25 100644 --- a/aries_vcx/src/protocols/connection/generic/conversions.rs +++ b/aries_vcx/src/protocols/connection/generic/conversions.rs @@ -2,10 +2,17 @@ use super::{GenericConnection, GenericState, InviteeState, InviterState}; use crate::{ errors::error::{AriesVcxError, AriesVcxErrorKind}, protocols::connection::{ - common::states::{complete::Complete, initial::Initial, responded::Responded}, initiation_type::{Invitee, Inviter}, - invitee::states::{invited::Invited as InviteeInvited, requested::Requested as InviteeRequested}, - inviter::states::{invited::Invited as InviterInvited, requested::Requested as InviterRequested}, + invitee::states::{ + complete::Complete as InviteeComplete, initial::Initial as InviteeInitial, + invited::Invited as InviteeInvited, requested::Requested as InviteeRequested, + responded::Responded as InviteeResponded, + }, + inviter::states::{ + complete::Complete as InviterComplete, initial::Initial as InviterInitial, + invited::Invited as InviterInvited, requested::Requested as InviterRequested, + responded::Responded as InviterResponded, + }, Connection, }, }; @@ -97,17 +104,17 @@ where from_concrete_to_vague!(Inviter, InviterState, Inviter, GenericState); from_concrete_to_vague!(Invitee, InviteeState, Invitee, GenericState); -from_concrete_to_vague!(Initial, Initial, InviterState); +from_concrete_to_vague!(InviterInitial, Initial, InviterState); from_concrete_to_vague!(InviterInvited, Invited, InviterState); from_concrete_to_vague!(InviterRequested, Requested, InviterState); -from_concrete_to_vague!(Responded, Responded, InviterState); -from_concrete_to_vague!(Complete, Complete, InviterState); +from_concrete_to_vague!(InviterResponded, Responded, InviterState); +from_concrete_to_vague!(InviterComplete, Complete, InviterState); -from_concrete_to_vague!(Initial, Initial, InviteeState); +from_concrete_to_vague!(InviteeInitial, Initial, InviteeState); from_concrete_to_vague!(InviteeInvited, Invited, InviteeState); from_concrete_to_vague!(InviteeRequested, Requested, InviteeState); -from_concrete_to_vague!(Responded, Responded, InviteeState); -from_concrete_to_vague!(Complete, Complete, InviteeState); +from_concrete_to_vague!(InviteeResponded, Responded, InviteeState); +from_concrete_to_vague!(InviteeComplete, Complete, InviteeState); // ---------------------------- Try From Vague State to Concrete State implementations ---------------------------- impl TryFrom for Connection @@ -126,14 +133,14 @@ where try_from_vague_to_concrete!(InviterState, Inviter, Invitee, Inviter); try_from_vague_to_concrete!(InviteeState, Invitee, Inviter, Invitee); -try_from_vague_to_concrete!(InviterState, Initial, Initial); +try_from_vague_to_concrete!(InviterState, Initial, InviterInitial); try_from_vague_to_concrete!(InviterState, Invited, InviterInvited); try_from_vague_to_concrete!(InviterState, Requested, InviterRequested); -try_from_vague_to_concrete!(InviterState, Responded, Responded); -try_from_vague_to_concrete!(InviterState, Complete, Complete); +try_from_vague_to_concrete!(InviterState, Responded, InviterResponded); +try_from_vague_to_concrete!(InviterState, Complete, InviterComplete); -try_from_vague_to_concrete!(InviteeState, Initial, Initial); +try_from_vague_to_concrete!(InviteeState, Initial, InviteeInitial); try_from_vague_to_concrete!(InviteeState, Invited, InviteeInvited); try_from_vague_to_concrete!(InviteeState, Requested, InviteeRequested); -try_from_vague_to_concrete!(InviteeState, Responded, Responded); -try_from_vague_to_concrete!(InviteeState, Complete, Complete); +try_from_vague_to_concrete!(InviteeState, Responded, InviteeResponded); +try_from_vague_to_concrete!(InviteeState, Complete, InviteeComplete); diff --git a/aries_vcx/src/protocols/connection/generic/mod.rs b/aries_vcx/src/protocols/connection/generic/mod.rs index 0efcabe3dc..49e5d51abc 100644 --- a/aries_vcx/src/protocols/connection/generic/mod.rs +++ b/aries_vcx/src/protocols/connection/generic/mod.rs @@ -11,16 +11,23 @@ use crate::{ errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult}, plugins::wallet::base_wallet::BaseWallet, protocols::connection::{ - common::states::{complete::Complete, responded::Responded}, - invitee::states::{invited::Invited as InviteeInvited, requested::Requested as InviteeRequested}, - inviter::states::{invited::Invited as InviterInvited, requested::Requested as InviterRequested}, + invitee::states::{ + complete::Complete as InviteeComplete, initial::Initial as InviteeInitial, + invited::Invited as InviteeInvited, requested::Requested as InviteeRequested, + responded::Responded as InviteeResponded, + }, + inviter::states::{ + complete::Complete as InviterComplete, initial::Initial as InviterInitial, + invited::Invited as InviterInvited, requested::Requested as InviterRequested, + responded::Responded as InviterResponded, + }, pairwise_info::PairwiseInfo, trait_bounds::{TheirDidDoc, ThreadId}, }, transport::Transport, }; -use super::{basic_send_message, common::states::initial::Initial}; +use super::basic_send_message; /// A type that can encapsulate a [`Connection`] of any state. /// While mainly used for deserialization, it exposes some methods for retrieving @@ -67,20 +74,20 @@ pub enum GenericState { #[derive(Clone, Debug, Serialize, Deserialize)] pub enum InviterState { - Initial(Initial), + Initial(InviterInitial), Invited(InviterInvited), Requested(InviterRequested), - Responded(Responded), - Complete(Complete), + Responded(InviterResponded), + Complete(InviterComplete), } #[derive(Clone, Debug, Serialize, Deserialize)] pub enum InviteeState { - Initial(Initial), + Initial(InviteeInitial), Invited(InviteeInvited), Requested(InviteeRequested), - Responded(Responded), - Complete(Complete), + Responded(InviteeResponded), + Complete(InviteeComplete), } impl GenericConnection { @@ -343,7 +350,7 @@ mod connection_serde_tests { (source_id, pairwise_info) } - async fn make_invitee_initial() -> InviteeConnection { + async fn make_invitee_initial() -> InviteeConnection { let (source_id, pairwise_info) = make_initial_parts().await; Connection::new_invitee(source_id, pairwise_info) } @@ -372,7 +379,7 @@ mod connection_serde_tests { .unwrap() } - async fn make_invitee_responded() -> InviteeConnection { + async fn make_invitee_responded() -> InviteeConnection { let wallet = make_mock_profile().inject_wallet(); let con = make_invitee_requested().await; let response = Response::create() @@ -386,7 +393,7 @@ mod connection_serde_tests { con.handle_response(&wallet, response, &MockTransport).await.unwrap() } - async fn make_invitee_complete() -> InviteeConnection { + async fn make_invitee_complete() -> InviteeConnection { let wallet = make_mock_profile().inject_wallet(); make_invitee_responded() @@ -396,7 +403,7 @@ mod connection_serde_tests { .unwrap() } - async fn make_inviter_initial() -> InviterConnection { + async fn make_inviter_initial() -> InviterConnection { let (source_id, pairwise_info) = make_initial_parts().await; Connection::new_inviter(source_id, pairwise_info) } @@ -423,7 +430,7 @@ mod connection_serde_tests { .unwrap() } - async fn make_inviter_responded() -> InviterConnection { + async fn make_inviter_responded() -> InviterConnection { let wallet = make_mock_profile().inject_wallet(); make_inviter_requested() @@ -433,7 +440,7 @@ mod connection_serde_tests { .unwrap() } - async fn make_inviter_complete() -> InviterConnection { + async fn make_inviter_complete() -> InviterConnection { let msg = Request::create().to_a2a_message(); make_inviter_responded().await.acknowledge_connection(&msg).unwrap() diff --git a/aries_vcx/src/protocols/connection/invitee/mod.rs b/aries_vcx/src/protocols/connection/invitee/mod.rs index b696ebc27d..38fa8ecd48 100644 --- a/aries_vcx/src/protocols/connection/invitee/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/mod.rs @@ -9,7 +9,9 @@ use crate::{ protocols::connection::trait_bounds::ThreadId, transport::Transport, }; -use self::states::{invited::Invited, requested::Requested}; +use self::states::{ + complete::Complete, initial::Initial, invited::Invited, requested::Requested, responded::Responded, +}; use messages::{ a2a::A2AMessage, @@ -17,12 +19,7 @@ use messages::{ protocols::connection::{request::Request, response::SignedResponse}, }; -use super::{ - common::states::{complete::Complete, initial::Initial, responded::Responded}, - initiation_type::Invitee, - pairwise_info::PairwiseInfo, - Connection, -}; +use super::{initiation_type::Invitee, pairwise_info::PairwiseInfo, Connection}; use crate::{ common::signing::decode_signed_connection_response, errors::error::{AriesVcxError, AriesVcxErrorKind}, diff --git a/aries_vcx/src/protocols/connection/common/states/complete.rs b/aries_vcx/src/protocols/connection/invitee/states/complete.rs similarity index 78% rename from aries_vcx/src/protocols/connection/common/states/complete.rs rename to aries_vcx/src/protocols/connection/invitee/states/complete.rs index d624d14ac1..b008248135 100644 --- a/aries_vcx/src/protocols/connection/common/states/complete.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/complete.rs @@ -3,7 +3,7 @@ use std::clone::Clone; use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::discovery::disclose::{Disclose, ProtocolDescriptor}; -use crate::protocols::connection::trait_bounds::{TheirDidDoc, ThreadId}; +use crate::protocols::connection::trait_bounds::{CompleteState, TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Complete { @@ -20,14 +20,6 @@ impl Complete { protocols, } } - - pub fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { - self.protocols.as_deref() - } - - pub fn handle_disclose(&mut self, disclose: Disclose) { - self.protocols = Some(disclose.protocols) - } } impl TheirDidDoc for Complete { @@ -41,3 +33,13 @@ impl ThreadId for Complete { &self.thread_id } } + +impl CompleteState for Complete { + fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { + self.protocols.as_deref() + } + + fn handle_disclose(&mut self, disclose: Disclose) { + self.protocols = Some(disclose.protocols) + } +} diff --git a/aries_vcx/src/protocols/connection/common/states/initial.rs b/aries_vcx/src/protocols/connection/invitee/states/initial.rs similarity index 100% rename from aries_vcx/src/protocols/connection/common/states/initial.rs rename to aries_vcx/src/protocols/connection/invitee/states/initial.rs diff --git a/aries_vcx/src/protocols/connection/invitee/states/mod.rs b/aries_vcx/src/protocols/connection/invitee/states/mod.rs index b0bec16a16..90e4ef629b 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/mod.rs @@ -1,2 +1,5 @@ +pub mod complete; +pub mod initial; pub mod invited; pub mod requested; +pub mod responded; diff --git a/aries_vcx/src/protocols/connection/common/states/responded.rs b/aries_vcx/src/protocols/connection/invitee/states/responded.rs similarity index 100% rename from aries_vcx/src/protocols/connection/common/states/responded.rs rename to aries_vcx/src/protocols/connection/invitee/states/responded.rs diff --git a/aries_vcx/src/protocols/connection/inviter/mod.rs b/aries_vcx/src/protocols/connection/inviter/mod.rs index fb3b17f264..17fce55c4f 100644 --- a/aries_vcx/src/protocols/connection/inviter/mod.rs +++ b/aries_vcx/src/protocols/connection/inviter/mod.rs @@ -10,10 +10,9 @@ use crate::{ common::signing::sign_connection_response, errors::error::VcxResult, plugins::wallet::base_wallet::BaseWallet, }; -use self::states::{invited::Invited, requested::Requested}; -use super::common::states::complete::Complete; -use super::common::states::initial::Initial; -use super::common::states::responded::Responded; +use self::states::{ + complete::Complete, initial::Initial, invited::Invited, requested::Requested, responded::Responded, +}; use super::{initiation_type::Inviter, pairwise_info::PairwiseInfo, Connection}; use messages::a2a::A2AMessage; use messages::protocols::connection::invite::PairwiseInvitation; diff --git a/aries_vcx/src/protocols/connection/inviter/states/complete.rs b/aries_vcx/src/protocols/connection/inviter/states/complete.rs new file mode 100644 index 0000000000..b008248135 --- /dev/null +++ b/aries_vcx/src/protocols/connection/inviter/states/complete.rs @@ -0,0 +1,45 @@ +use std::clone::Clone; + +use messages::diddoc::aries::diddoc::AriesDidDoc; +use messages::protocols::discovery::disclose::{Disclose, ProtocolDescriptor}; + +use crate::protocols::connection::trait_bounds::{CompleteState, TheirDidDoc, ThreadId}; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct Complete { + pub(crate) did_doc: AriesDidDoc, + pub(crate) thread_id: String, + pub(crate) protocols: Option>, +} + +impl Complete { + pub fn new(did_doc: AriesDidDoc, thread_id: String, protocols: Option>) -> Self { + Self { + did_doc, + thread_id, + protocols, + } + } +} + +impl TheirDidDoc for Complete { + fn their_did_doc(&self) -> &AriesDidDoc { + &self.did_doc + } +} + +impl ThreadId for Complete { + fn thread_id(&self) -> &str { + &self.thread_id + } +} + +impl CompleteState for Complete { + fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { + self.protocols.as_deref() + } + + fn handle_disclose(&mut self, disclose: Disclose) { + self.protocols = Some(disclose.protocols) + } +} diff --git a/aries_vcx/src/protocols/connection/inviter/states/initial.rs b/aries_vcx/src/protocols/connection/inviter/states/initial.rs new file mode 100644 index 0000000000..3bebf35de9 --- /dev/null +++ b/aries_vcx/src/protocols/connection/inviter/states/initial.rs @@ -0,0 +1,2 @@ +#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq)] +pub struct Initial; diff --git a/aries_vcx/src/protocols/connection/inviter/states/mod.rs b/aries_vcx/src/protocols/connection/inviter/states/mod.rs index b0bec16a16..90e4ef629b 100644 --- a/aries_vcx/src/protocols/connection/inviter/states/mod.rs +++ b/aries_vcx/src/protocols/connection/inviter/states/mod.rs @@ -1,2 +1,5 @@ +pub mod complete; +pub mod initial; pub mod invited; pub mod requested; +pub mod responded; diff --git a/aries_vcx/src/protocols/connection/inviter/states/responded.rs b/aries_vcx/src/protocols/connection/inviter/states/responded.rs new file mode 100644 index 0000000000..36d2f0a79a --- /dev/null +++ b/aries_vcx/src/protocols/connection/inviter/states/responded.rs @@ -0,0 +1,27 @@ +use messages::diddoc::aries::diddoc::AriesDidDoc; + +use crate::protocols::connection::trait_bounds::{TheirDidDoc, ThreadId}; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct Responded { + pub(crate) did_doc: AriesDidDoc, + pub(crate) thread_id: String, +} + +impl Responded { + pub fn new(did_doc: AriesDidDoc, thread_id: String) -> Self { + Self { did_doc, thread_id } + } +} + +impl TheirDidDoc for Responded { + fn their_did_doc(&self) -> &AriesDidDoc { + &self.did_doc + } +} + +impl ThreadId for Responded { + fn thread_id(&self) -> &str { + &self.thread_id + } +} diff --git a/aries_vcx/src/protocols/connection/mod.rs b/aries_vcx/src/protocols/connection/mod.rs index d330f749a2..d0d3591b58 100644 --- a/aries_vcx/src/protocols/connection/mod.rs +++ b/aries_vcx/src/protocols/connection/mod.rs @@ -1,4 +1,3 @@ -pub mod common; mod generic; pub mod initiation_type; pub mod invitee; @@ -25,10 +24,9 @@ use crate::{ }; use self::{ - common::states::complete::Complete, generic::GenericState, pairwise_info::PairwiseInfo, - trait_bounds::{HandleProblem, TheirDidDoc, ThreadId}, + trait_bounds::{CompleteState, HandleProblem, TheirDidDoc, ThreadId}, }; pub use self::generic::{GenericConnection, State, ThinState}; @@ -159,7 +157,10 @@ where } } -impl Connection { +impl Connection +where + S: CompleteState, +{ pub fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]> { self.state.remote_protocols() } diff --git a/aries_vcx/src/protocols/connection/serializable.rs b/aries_vcx/src/protocols/connection/serializable.rs index c49dff03b2..a225ca12ab 100644 --- a/aries_vcx/src/protocols/connection/serializable.rs +++ b/aries_vcx/src/protocols/connection/serializable.rs @@ -1,16 +1,19 @@ use serde::Serialize; use crate::protocols::connection::{ - common::states::{complete::Complete, responded::Responded}, initiation_type::{Invitee, Inviter}, - invitee::states::{invited::Invited as InviteeInvited, requested::Requested as InviteeRequested}, - inviter::states::{invited::Invited as InviterInvited, requested::Requested as InviterRequested}, + invitee::states::{ + complete::Complete as InviteeComplete, initial::Initial as InviteeInitial, invited::Invited as InviteeInvited, + requested::Requested as InviteeRequested, responded::Responded as InviteeResponded, + }, + inviter::states::{ + complete::Complete as InviterComplete, initial::Initial as InviterInitial, invited::Invited as InviterInvited, + requested::Requested as InviterRequested, responded::Responded as InviterResponded, + }, pairwise_info::PairwiseInfo, Connection, }; -use super::common::states::initial::Initial; - /// Macro used for boilerplace implementation of the /// [`From`] trait from a concrete connection state to the equivalent reference state /// used for serialization. @@ -56,20 +59,20 @@ pub enum RefState<'a> { #[derive(Debug, Serialize)] pub enum RefInviterState<'a> { - Initial(&'a Initial), + Initial(&'a InviterInitial), Invited(&'a InviterInvited), Requested(&'a InviterRequested), - Responded(&'a Responded), - Complete(&'a Complete), + Responded(&'a InviterResponded), + Complete(&'a InviterComplete), } #[derive(Debug, Serialize)] pub enum RefInviteeState<'a> { - Initial(&'a Initial), + Initial(&'a InviteeInitial), Invited(&'a InviteeInvited), Requested(&'a InviteeRequested), - Responded(&'a Responded), - Complete(&'a Complete), + Responded(&'a InviteeResponded), + Complete(&'a InviteeComplete), } impl<'a, I, S> From<&'a Connection> for SerializableConnection<'a> @@ -87,17 +90,17 @@ where from_concrete_to_serializable!(Inviter, RefInviterState, Inviter, RefState); from_concrete_to_serializable!(Invitee, RefInviteeState, Invitee, RefState); -from_concrete_to_serializable!(Initial, Initial, RefInviterState); +from_concrete_to_serializable!(InviterInitial, Initial, RefInviterState); from_concrete_to_serializable!(InviterInvited, Invited, RefInviterState); from_concrete_to_serializable!(InviterRequested, Requested, RefInviterState); -from_concrete_to_serializable!(Responded, Responded, RefInviterState); -from_concrete_to_serializable!(Complete, Complete, RefInviterState); +from_concrete_to_serializable!(InviterResponded, Responded, RefInviterState); +from_concrete_to_serializable!(InviterComplete, Complete, RefInviterState); -from_concrete_to_serializable!(Initial, Initial, RefInviteeState); +from_concrete_to_serializable!(InviteeInitial, Initial, RefInviteeState); from_concrete_to_serializable!(InviteeInvited, Invited, RefInviteeState); from_concrete_to_serializable!(InviteeRequested, Requested, RefInviteeState); -from_concrete_to_serializable!(Responded, Responded, RefInviteeState); -from_concrete_to_serializable!(Complete, Complete, RefInviteeState); +from_concrete_to_serializable!(InviteeResponded, Responded, RefInviteeState); +from_concrete_to_serializable!(InviteeComplete, Complete, RefInviteeState); impl<'a> SerializableConnection<'a> { fn new(source_id: &'a str, pairwise_info: &'a PairwiseInfo, state: RefState<'a>) -> Self { diff --git a/aries_vcx/src/protocols/connection/trait_bounds.rs b/aries_vcx/src/protocols/connection/trait_bounds.rs index e5a1e2d521..cd23fe6902 100644 --- a/aries_vcx/src/protocols/connection/trait_bounds.rs +++ b/aries_vcx/src/protocols/connection/trait_bounds.rs @@ -1,4 +1,4 @@ -use messages::diddoc::aries::diddoc::AriesDidDoc; +use messages::{diddoc::aries::diddoc::AriesDidDoc, protocols::discovery::disclose::{ProtocolDescriptor, Disclose}}; /// Trait implemented for [`super::Connection`] states that store an [`AriesDidDoc`]. pub trait TheirDidDoc { @@ -10,6 +10,13 @@ pub trait ThreadId { fn thread_id(&self) -> &str; } +/// Trait impletement for [`super::Connection`] in complete states. +pub trait CompleteState { + fn remote_protocols(&self) -> Option<&[ProtocolDescriptor]>; + + fn handle_disclose(&mut self, disclose: Disclose); +} + /// Marker trait used for implementing [`messages::protocols::connection::problem_report::ProblemReport`] /// handling on certain [`super::Connection`] types. pub trait HandleProblem {} From 1541771bd69ae673f4d5dbb4c8caf799f9154ada Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Tue, 7 Feb 2023 09:51:13 +0200 Subject: [PATCH 48/66] Added BootstrapDidDoc trait Signed-off-by: Bogdan Mircea --- .../src/protocols/connection/generic/mod.rs | 13 +++++++++++- .../src/protocols/connection/invitee/mod.rs | 20 +++++++++++++++---- .../connection/invitee/states/complete.rs | 17 ++++++++++++++-- .../connection/invitee/states/invited.rs | 4 +++- .../connection/invitee/states/requested.rs | 4 +++- .../connection/invitee/states/responded.rs | 17 +++++++++++++--- .../src/protocols/connection/trait_bounds.rs | 15 +++++++++++++- 7 files changed, 77 insertions(+), 13 deletions(-) diff --git a/aries_vcx/src/protocols/connection/generic/mod.rs b/aries_vcx/src/protocols/connection/generic/mod.rs index 49e5d51abc..8d2f24e27d 100644 --- a/aries_vcx/src/protocols/connection/generic/mod.rs +++ b/aries_vcx/src/protocols/connection/generic/mod.rs @@ -27,7 +27,7 @@ use crate::{ transport::Transport, }; -use super::basic_send_message; +use super::{basic_send_message, trait_bounds::BootstrapDidDoc}; /// A type that can encapsulate a [`Connection`] of any state. /// While mainly used for deserialization, it exposes some methods for retrieving @@ -132,6 +132,17 @@ impl GenericConnection { } } + pub fn bootstrap_did_doc(&self) -> Option<&AriesDidDoc> { + match &self.state { + GenericState::Inviter(_) => None, + GenericState::Invitee(InviteeState::Initial(_)) => None, + GenericState::Invitee(InviteeState::Invited(s)) => Some(s.bootstrap_did_doc()), + GenericState::Invitee(InviteeState::Requested(s)) => Some(s.bootstrap_did_doc()), + GenericState::Invitee(InviteeState::Responded(s)) => Some(s.bootstrap_did_doc()), + GenericState::Invitee(InviteeState::Complete(s)) => Some(s.bootstrap_did_doc()), + } + } + pub fn remote_did(&self) -> Option<&str> { self.their_did_doc().map(|d| d.id.as_str()) } diff --git a/aries_vcx/src/protocols/connection/invitee/mod.rs b/aries_vcx/src/protocols/connection/invitee/mod.rs index 38fa8ecd48..69bf22646f 100644 --- a/aries_vcx/src/protocols/connection/invitee/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/mod.rs @@ -2,7 +2,7 @@ pub mod states; use std::sync::Arc; -use messages::protocols::connection::invite::Invitation; +use messages::{protocols::connection::invite::Invitation, diddoc::aries::diddoc::AriesDidDoc}; use crate::{ common::ledger::transactions::into_did_doc, core::profile::profile::Profile, errors::error::VcxResult, @@ -19,7 +19,7 @@ use messages::{ protocols::connection::{request::Request, response::SignedResponse}, }; -use super::{initiation_type::Invitee, pairwise_info::PairwiseInfo, Connection}; +use super::{initiation_type::Invitee, pairwise_info::PairwiseInfo, Connection, trait_bounds::BootstrapDidDoc}; use crate::{ common::signing::decode_signed_connection_response, errors::error::{AriesVcxError, AriesVcxErrorKind}, @@ -170,7 +170,7 @@ impl InviteeConnection { } }?; - let state = Responded::new(did_doc, self.state.thread_id); + let state = Responded::new(did_doc, self.state.did_doc, self.state.thread_id); Ok(Connection { state, @@ -202,7 +202,12 @@ impl InviteeConnection { self.send_message(wallet, &msg, transport).await?; - let state = Complete::new(self.state.did_doc, self.state.thread_id, None); + let state = Complete::new( + self.state.did_doc, + self.state.bootstrap_did_doc, + self.state.thread_id, + None, + ); Ok(Connection { state, @@ -212,3 +217,10 @@ impl InviteeConnection { }) } } + +impl InviteeConnection +where S: BootstrapDidDoc { + pub fn bootstrap_did_doc(&self) -> &AriesDidDoc { + self.state.bootstrap_did_doc() + } +} \ No newline at end of file diff --git a/aries_vcx/src/protocols/connection/invitee/states/complete.rs b/aries_vcx/src/protocols/connection/invitee/states/complete.rs index b008248135..6e5cb6bb51 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/complete.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/complete.rs @@ -3,19 +3,26 @@ use std::clone::Clone; use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::discovery::disclose::{Disclose, ProtocolDescriptor}; -use crate::protocols::connection::trait_bounds::{CompleteState, TheirDidDoc, ThreadId}; +use crate::protocols::connection::trait_bounds::{CompleteState, TheirDidDoc, ThreadId, BootstrapDidDoc}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Complete { pub(crate) did_doc: AriesDidDoc, + pub(crate) bootstrap_did_doc: AriesDidDoc, pub(crate) thread_id: String, pub(crate) protocols: Option>, } impl Complete { - pub fn new(did_doc: AriesDidDoc, thread_id: String, protocols: Option>) -> Self { + pub fn new( + did_doc: AriesDidDoc, + bootstrap_did_doc: AriesDidDoc, + thread_id: String, + protocols: Option>, + ) -> Self { Self { did_doc, + bootstrap_did_doc, thread_id, protocols, } @@ -28,6 +35,12 @@ impl TheirDidDoc for Complete { } } +impl BootstrapDidDoc for Complete { + fn bootstrap_did_doc(&self) -> &AriesDidDoc { + &self.bootstrap_did_doc + } +} + impl ThreadId for Complete { fn thread_id(&self) -> &str { &self.thread_id diff --git a/aries_vcx/src/protocols/connection/invitee/states/invited.rs b/aries_vcx/src/protocols/connection/invitee/states/invited.rs index 6362d1cc28..7b299ab7f0 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/invited.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/invited.rs @@ -1,6 +1,6 @@ use messages::{diddoc::aries::diddoc::AriesDidDoc, protocols::connection::invite::Invitation}; -use crate::protocols::connection::trait_bounds::{TheirDidDoc, ThreadId}; +use crate::protocols::connection::trait_bounds::{TheirDidDoc, ThreadId, BootstrapDidDoc}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Invited { @@ -20,6 +20,8 @@ impl TheirDidDoc for Invited { } } +impl BootstrapDidDoc for Invited {} + impl ThreadId for Invited { fn thread_id(&self) -> &str { self.invitation.get_id() diff --git a/aries_vcx/src/protocols/connection/invitee/states/requested.rs b/aries_vcx/src/protocols/connection/invitee/states/requested.rs index 4716462716..c949290866 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/requested.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/requested.rs @@ -1,6 +1,6 @@ use messages::diddoc::aries::diddoc::AriesDidDoc; -use crate::protocols::connection::trait_bounds::{HandleProblem, TheirDidDoc, ThreadId}; +use crate::protocols::connection::trait_bounds::{BootstrapDidDoc, HandleProblem, TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Requested { @@ -20,6 +20,8 @@ impl TheirDidDoc for Requested { } } +impl BootstrapDidDoc for Requested {} + impl ThreadId for Requested { fn thread_id(&self) -> &str { &self.thread_id diff --git a/aries_vcx/src/protocols/connection/invitee/states/responded.rs b/aries_vcx/src/protocols/connection/invitee/states/responded.rs index 36d2f0a79a..70bd927271 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/responded.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/responded.rs @@ -1,16 +1,21 @@ use messages::diddoc::aries::diddoc::AriesDidDoc; -use crate::protocols::connection::trait_bounds::{TheirDidDoc, ThreadId}; +use crate::protocols::connection::trait_bounds::{BootstrapDidDoc, TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Responded { pub(crate) did_doc: AriesDidDoc, + pub(crate) bootstrap_did_doc: AriesDidDoc, pub(crate) thread_id: String, } impl Responded { - pub fn new(did_doc: AriesDidDoc, thread_id: String) -> Self { - Self { did_doc, thread_id } + pub fn new(did_doc: AriesDidDoc, bootstrap_did_doc: AriesDidDoc, thread_id: String) -> Self { + Self { + did_doc, + bootstrap_did_doc, + thread_id, + } } } @@ -20,6 +25,12 @@ impl TheirDidDoc for Responded { } } +impl BootstrapDidDoc for Responded { + fn bootstrap_did_doc(&self) -> &AriesDidDoc { + &self.bootstrap_did_doc + } +} + impl ThreadId for Responded { fn thread_id(&self) -> &str { &self.thread_id diff --git a/aries_vcx/src/protocols/connection/trait_bounds.rs b/aries_vcx/src/protocols/connection/trait_bounds.rs index cd23fe6902..ba50de9ef8 100644 --- a/aries_vcx/src/protocols/connection/trait_bounds.rs +++ b/aries_vcx/src/protocols/connection/trait_bounds.rs @@ -1,10 +1,23 @@ -use messages::{diddoc::aries::diddoc::AriesDidDoc, protocols::discovery::disclose::{ProtocolDescriptor, Disclose}}; +use messages::{ + diddoc::aries::diddoc::AriesDidDoc, + protocols::discovery::disclose::{Disclose, ProtocolDescriptor}, +}; /// Trait implemented for [`super::Connection`] states that store an [`AriesDidDoc`]. pub trait TheirDidDoc { + /// Returns the [`AriesDidDoc`] currently being used by a [`super::Connection`]. fn their_did_doc(&self) -> &AriesDidDoc; } +pub trait BootstrapDidDoc: TheirDidDoc { + /// Returns the [`AriesDidDoc`] used to bootstrap the connection. + /// By default, this will be the same as the [`AriesDidDoc`] currently being used + /// by the connection. + fn bootstrap_did_doc(&self) -> &AriesDidDoc { + self.their_did_doc() + } +} + /// Trait implemented for [`super::Connection`] states that keep track of a thread ID. pub trait ThreadId { fn thread_id(&self) -> &str; From 079f742abbdc02d8ae6af5cd5b2aac5b064349c3 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Tue, 7 Feb 2023 10:27:29 +0200 Subject: [PATCH 49/66] Added non-mediated connection OOB handling Signed-off-by: Bogdan Mircea --- .../connection/mediated_connection.rs | 4 +-- .../src/handlers/out_of_band/receiver.rs | 29 ++++++++++++++++++- .../invitee/state_machine.rs | 2 +- aries_vcx/src/protocols/trustping/mod.rs | 6 +++- 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/aries_vcx/src/handlers/connection/mediated_connection.rs b/aries_vcx/src/handlers/connection/mediated_connection.rs index 93904d6bb7..96f3e7adda 100644 --- a/aries_vcx/src/handlers/connection/mediated_connection.rs +++ b/aries_vcx/src/handlers/connection/mediated_connection.rs @@ -263,10 +263,10 @@ impl MediatedConnection { } } - pub async fn bootstrap_did_doc(&self) -> Option { + pub fn bootstrap_did_doc(&self) -> Option { match &self.connection_sm { SmConnection::Inviter(_sm_inviter) => None, // TODO: Inviter can remember bootstrap agent too, but we don't need it - SmConnection::Invitee(sm_invitee) => sm_invitee.bootstrap_did_doc().await, + SmConnection::Invitee(sm_invitee) => sm_invitee.bootstrap_did_doc(), } } diff --git a/aries_vcx/src/handlers/out_of_band/receiver.rs b/aries_vcx/src/handlers/out_of_band/receiver.rs index 6a733faa50..c243baa1ca 100644 --- a/aries_vcx/src/handlers/out_of_band/receiver.rs +++ b/aries_vcx/src/handlers/out_of_band/receiver.rs @@ -7,6 +7,7 @@ use crate::common::ledger::transactions::resolve_service; use crate::core::profile::profile::Profile; use crate::errors::error::prelude::*; use crate::handlers::connection::mediated_connection::MediatedConnection; +use crate::protocols::connection::GenericConnection; use messages::a2a::A2AMessage; use messages::concepts::attachment::AttachmentId; use messages::diddoc::aries::diddoc::AriesDidDoc; @@ -48,7 +49,33 @@ impl OutOfBandReceiver { trace!("OutOfBandReceiver::connection_exists >>>"); for service in &self.oob.services { for connection in connections { - match connection.bootstrap_did_doc().await { + match connection.bootstrap_did_doc() { + Some(did_doc) => { + if let ServiceOob::Did(did) = service { + if did.to_string() == did_doc.id { + return Ok(Some(connection)); + } + }; + if did_doc.get_service()? == resolve_service(profile, service).await? { + return Ok(Some(connection)); + }; + } + None => break, + } + } + } + Ok(None) + } + + pub async fn nonmediated_connection_exists<'a>( + &self, + profile: &Arc, + connections: &'a Vec<&'a GenericConnection>, + ) -> VcxResult> { + trace!("OutOfBandReceiver::connection_exists >>>"); + for service in &self.oob.services { + for connection in connections { + match connection.bootstrap_did_doc() { Some(did_doc) => { if let ServiceOob::Did(did) = service { if did.to_string() == did_doc.id { diff --git a/aries_vcx/src/protocols/mediated_connection/invitee/state_machine.rs b/aries_vcx/src/protocols/mediated_connection/invitee/state_machine.rs index fd65509e3b..4f4caf05b7 100644 --- a/aries_vcx/src/protocols/mediated_connection/invitee/state_machine.rs +++ b/aries_vcx/src/protocols/mediated_connection/invitee/state_machine.rs @@ -120,7 +120,7 @@ impl SmConnectionInvitee { } } - pub async fn bootstrap_did_doc(&self) -> Option { + pub fn bootstrap_did_doc(&self) -> Option { match self.state { InviteeFullState::Initial(ref state) => state.did_doc.clone(), InviteeFullState::Invited(ref state) => Some(state.did_doc.clone()), diff --git a/aries_vcx/src/protocols/trustping/mod.rs b/aries_vcx/src/protocols/trustping/mod.rs index 0dbac8e904..281e235e6b 100644 --- a/aries_vcx/src/protocols/trustping/mod.rs +++ b/aries_vcx/src/protocols/trustping/mod.rs @@ -1,5 +1,5 @@ use crate::utils::uuid; -use messages::a2a::MessageId; +use messages::a2a::{A2AMessage, MessageId}; use messages::protocols::trust_ping::ping::Ping; use messages::protocols::trust_ping::ping_response::PingResponse; @@ -19,6 +19,10 @@ pub fn build_ping_response(ping: &Ping) -> PingResponse { PingResponse::create().set_thread_id(&thread_id).set_out_time() } +pub fn build_ping_response_msg(ping: &Ping) -> A2AMessage { + build_ping_response(ping).to_a2a_message() +} + #[cfg(test)] #[cfg(feature = "general_test")] pub mod unit_tests { From 2fdef4f8cba40c58a959e0eb2b8c2d5c54a86871 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Tue, 7 Feb 2023 13:52:29 +0200 Subject: [PATCH 50/66] Improved OOB connection existence look-up and implemented libvcx non-mediated connection calls Signed-off-by: Bogdan Mircea --- .../src/handlers/out_of_band/receiver.rs | 66 +++++++++++++------ libvcx/src/api_vcx/api_handle/connection.rs | 27 ++++++-- .../api_vcx/api_handle/issuer_credential.rs | 66 +++++++++++++++++++ libvcx/src/api_vcx/api_handle/out_of_band.rs | 28 +++++++- libvcx/src/api_vcx/api_handle/proof.rs | 55 +++++++++++++++- 5 files changed, 216 insertions(+), 26 deletions(-) diff --git a/aries_vcx/src/handlers/out_of_band/receiver.rs b/aries_vcx/src/handlers/out_of_band/receiver.rs index c243baa1ca..16a3d74754 100644 --- a/aries_vcx/src/handlers/out_of_band/receiver.rs +++ b/aries_vcx/src/handlers/out_of_band/receiver.rs @@ -67,30 +67,58 @@ impl OutOfBandReceiver { Ok(None) } - pub async fn nonmediated_connection_exists<'a>( - &self, - profile: &Arc, - connections: &'a Vec<&'a GenericConnection>, - ) -> VcxResult> { + pub async fn nonmediated_connection_exists<'a, I, T>(&self, profile: &Arc, connections: I) -> Option + where + I: IntoIterator + Clone, + { trace!("OutOfBandReceiver::connection_exists >>>"); + for service in &self.oob.services { - for connection in connections { - match connection.bootstrap_did_doc() { - Some(did_doc) => { - if let ServiceOob::Did(did) = service { - if did.to_string() == did_doc.id { - return Ok(Some(connection)); - } - }; - if did_doc.get_service()? == resolve_service(profile, service).await? { - return Ok(Some(connection)); - }; - } - None => break, + for (idx, connection) in connections.clone() { + if Self::connection_matches_service(profile, connection, service).await { + return Some(idx); } } } - Ok(None) + + None + } + + pub async fn connection_matches_service( + profile: &Arc, + connection: &GenericConnection, + service: &ServiceOob, + ) -> bool { + match connection.bootstrap_did_doc() { + None => false, + Some(did_doc) => Self::did_doc_matches_service(profile, service, did_doc).await, + } + } + + async fn did_doc_matches_service(profile: &Arc, service: &ServiceOob, did_doc: &AriesDidDoc) -> bool { + // Ugly, but it's best to short-circuit. + Self::did_doc_matches_service_did(service, did_doc) + || Self::did_doc_matches_resolved_service(profile, service, did_doc) + .await + .unwrap_or(false) + } + + fn did_doc_matches_service_did(service: &ServiceOob, did_doc: &AriesDidDoc) -> bool { + match service { + ServiceOob::Did(did) => did.to_string() == did_doc.id, + _ => false, + } + } + + async fn did_doc_matches_resolved_service( + profile: &Arc, + service: &ServiceOob, + did_doc: &AriesDidDoc, + ) -> VcxResult { + let did_doc_service = did_doc.get_service()?; + let oob_service = resolve_service(profile, service).await?; + + Ok(did_doc_service == oob_service) } // TODO: There may be multiple A2AMessages in a single OoB msg diff --git a/libvcx/src/api_vcx/api_handle/connection.rs b/libvcx/src/api_vcx/api_handle/connection.rs index 2c61eee670..5e13beb618 100644 --- a/libvcx/src/api_vcx/api_handle/connection.rs +++ b/libvcx/src/api_vcx/api_handle/connection.rs @@ -22,10 +22,10 @@ type Map = HashMap; type Cache = RwLock; lazy_static! { - static ref CONNECTION_MAP: Cache = RwLock::new(HashMap::new()); + pub static ref CONNECTION_MAP: Cache = RwLock::new(HashMap::new()); } -struct HttpClient; +pub struct HttpClient; #[async_trait] impl Transport for HttpClient { @@ -44,7 +44,7 @@ fn new_handle() -> LibvcxResult { } } -fn get_cloned_generic_connection(handle: &u32) -> LibvcxResult { +pub fn get_cloned_generic_connection(handle: &u32) -> LibvcxResult { CONNECTION_MAP.write()?.get(handle).cloned().ok_or_else(|| { LibvcxError::from_msg( LibvcxErrorKind::ObjectAccessError, @@ -311,6 +311,25 @@ pub async fn process_ack(handle: u32, message: &str) -> LibvcxResult<()> { insert_connection(handle, con) } +// In the old implementation this only consumed the ProblemReport without doing +// anything with it and returned the connection in the initial state. +// +// We'll emulate that for backwards compatibility. +pub fn process_problem_report(handle: u32, _problem_report: &str) -> LibvcxResult<()> { + trace!("process_problem_report >>>"); + let con = get_cloned_generic_connection(&handle)?; + match con.state() { + ThinState::Invitee(_) => insert_connection( + handle, + Connection::new_invitee("".to_owned(), con.pairwise_info().to_owned()), + ), + ThinState::Inviter(_) => insert_connection( + handle, + Connection::new_inviter("".to_owned(), con.pairwise_info().to_owned()), + ), + } +} + pub async fn send_response(handle: u32) -> LibvcxResult<()> { trace!("send_response >>>"); @@ -393,7 +412,7 @@ pub fn from_string(connection_data: &str) -> LibvcxResult { Ok(handle) } -// ------------------------------ CLEANUP --------------------------------------- +// --------------------------------------- CLEANUP --------------------------------------- pub fn release(handle: u32) -> LibvcxResult<()> { trace!("release >>>"); diff --git a/libvcx/src/api_vcx/api_handle/issuer_credential.rs b/libvcx/src/api_vcx/api_handle/issuer_credential.rs index 8defe21468..f2c511ac7e 100644 --- a/libvcx/src/api_vcx/api_handle/issuer_credential.rs +++ b/libvcx/src/api_vcx/api_handle/issuer_credential.rs @@ -1,10 +1,14 @@ +use aries_vcx::protocols::SendClosure; use serde_json; use aries_vcx::handlers::issuance::issuer::Issuer; use aries_vcx::messages::a2a::A2AMessage; use aries_vcx::messages::protocols::issuance::credential_offer::OfferInfo; +use crate::api_vcx::api_global::profile::get_main_profile; use crate::api_vcx::api_global::profile::get_main_profile_optional_pool; +use crate::api_vcx::api_handle::connection; +use crate::api_vcx::api_handle::connection::HttpClient; use crate::api_vcx::api_handle::credential_def; use crate::api_vcx::api_handle::mediated_connection; use crate::api_vcx::api_handle::object_cache::ObjectCache; @@ -57,6 +61,38 @@ pub async fn update_state(handle: u32, message: Option<&str>, connection_handle: Ok(res) } +pub async fn update_state_with_message_nonmediated( + handle: u32, + connection_handle: u32, + message: &str, +) -> LibvcxResult { + trace!("issuer_credential::update_state_nonmediated >>> "); + let mut credential = ISSUER_CREDENTIAL_MAP.get_cloned(handle)?; + if credential.is_terminal_state() { + return Ok(credential.get_state().into()); + } + + let con = connection::get_cloned_generic_connection(&connection_handle)?; + let wallet = get_main_profile_optional_pool().inject_wallet(); + + let send_message: SendClosure = + Box::new(|msg: A2AMessage| Box::pin(async move { con.send_message(&wallet, &msg, &HttpClient).await })); + + let profile = get_main_profile_optional_pool(); // do not throw if pool is not open + + let message: A2AMessage = serde_json::from_str(message).map_err(|err| { + LibvcxError::from_msg( + LibvcxErrorKind::InvalidOption, + format!("Cannot update state: Message deserialization failed: {:?}", err), + ) + })?; + credential.step(&profile, message.into(), Some(send_message)).await?; + + let res: u32 = credential.get_state().into(); + ISSUER_CREDENTIAL_MAP.insert(handle, credential)?; + Ok(res) +} + pub fn get_state(handle: u32) -> LibvcxResult { ISSUER_CREDENTIAL_MAP.get(handle, |credential| Ok(credential.get_state().into())) } @@ -162,6 +198,20 @@ pub async fn send_credential_offer_v2(credential_handle: u32, connection_handle: Ok(()) } +pub async fn send_credential_offer_nonmediated(credential_handle: u32, connection_handle: u32) -> LibvcxResult<()> { + let mut credential = ISSUER_CREDENTIAL_MAP.get_cloned(credential_handle)?; + + let con = connection::get_cloned_generic_connection(&connection_handle)?; + let wallet = get_main_profile_optional_pool().inject_wallet(); + + let send_message: SendClosure = + Box::new(|msg: A2AMessage| Box::pin(async move { con.send_message(&wallet, &msg, &HttpClient).await })); + + credential.send_credential_offer(send_message).await?; + ISSUER_CREDENTIAL_MAP.insert(credential_handle, credential)?; + Ok(()) +} + pub async fn send_credential(handle: u32, connection_handle: u32) -> LibvcxResult { let mut credential = ISSUER_CREDENTIAL_MAP.get_cloned(handle)?; let profile = get_main_profile_optional_pool(); // do not throw if pool is not open @@ -176,6 +226,22 @@ pub async fn send_credential(handle: u32, connection_handle: u32) -> LibvcxResul Ok(state) } +pub async fn send_credential_nonmediated(handle: u32, connection_handle: u32) -> LibvcxResult { + let mut credential = ISSUER_CREDENTIAL_MAP.get_cloned(handle)?; + let profile = get_main_profile_optional_pool(); // do not throw if pool is not open + + let con = connection::get_cloned_generic_connection(&connection_handle)?; + let wallet = profile.inject_wallet(); + + let send_message: SendClosure = + Box::new(|msg: A2AMessage| Box::pin(async move { con.send_message(&wallet, &msg, &HttpClient).await })); + + credential.send_credential(&profile, send_message).await?; + let state: u32 = credential.get_state().into(); + ISSUER_CREDENTIAL_MAP.insert(handle, credential)?; + Ok(state) +} + pub async fn revoke_credential_local(handle: u32) -> LibvcxResult<()> { let credential = ISSUER_CREDENTIAL_MAP.get_cloned(handle)?; let profile = get_main_profile_optional_pool(); // do not throw if pool is not open diff --git a/libvcx/src/api_vcx/api_handle/out_of_band.rs b/libvcx/src/api_vcx/api_handle/out_of_band.rs index f9ea7f6031..2053415c7c 100644 --- a/libvcx/src/api_vcx/api_handle/out_of_band.rs +++ b/libvcx/src/api_vcx/api_handle/out_of_band.rs @@ -11,7 +11,8 @@ use aries_vcx::messages::protocols::out_of_band::{GoalCode, HandshakeProtocol}; use crate::api_vcx::api_global::agency_client::get_main_agency_client; use crate::api_vcx::api_global::profile::get_main_profile; -use crate::api_vcx::api_handle::mediated_connection::CONNECTION_MAP; +use crate::api_vcx::api_handle::connection::CONNECTION_MAP; +use crate::api_vcx::api_handle::mediated_connection::CONNECTION_MAP as MEDIATED_CONS_MAP; use crate::api_vcx::api_handle::object_cache::ObjectCache; use crate::errors::error::{LibvcxError, LibvcxErrorKind, LibvcxResult}; @@ -155,7 +156,7 @@ pub async fn connection_exists(handle: u32, conn_handles: &Vec) -> LibvcxRe let oob = OUT_OF_BAND_RECEIVER_MAP.get_cloned(handle)?; let mut conn_map = HashMap::new(); for conn_handle in conn_handles { - let connection = CONNECTION_MAP.get_cloned(*conn_handle)?; + let connection = MEDIATED_CONS_MAP.get_cloned(*conn_handle)?; conn_map.insert(*conn_handle, connection); } let connections = conn_map.values().collect(); @@ -175,6 +176,29 @@ pub async fn connection_exists(handle: u32, conn_handles: &Vec) -> LibvcxRe } } +// todo: remove this +pub async fn nonmediated_connection_exists(handle: u32, conn_handles: &[u32]) -> LibvcxResult<(u32, bool)> { + trace!( + "nonmediated_connection_exists >>> handle: {}, conn_handles: {:?}", + handle, + conn_handles + ); + let profile = get_main_profile()?; + let oob = OUT_OF_BAND_RECEIVER_MAP.get_cloned(handle)?; + + // Obtain read lock for the duration of the search + let locked_map = CONNECTION_MAP.read()?; + + // Filter through the map for references to connections that match the given handles + // and store them along their handles to be used in the search agains the OOB message. + let con_iter = conn_handles.iter().filter_map(|h| locked_map.get(h).map(|c| (h, c))); + + match oob.nonmediated_connection_exists::<_, &u32>(&profile, con_iter).await { + None => Ok((0, false)), + Some(h) => Ok((*h, true)), + } +} + pub async fn build_connection(handle: u32) -> LibvcxResult { trace!("build_connection >>> handle: {}", handle); let oob = OUT_OF_BAND_RECEIVER_MAP.get_cloned(handle)?; diff --git a/libvcx/src/api_vcx/api_handle/proof.rs b/libvcx/src/api_vcx/api_handle/proof.rs index fd5e172c93..884d1fe1a3 100644 --- a/libvcx/src/api_vcx/api_handle/proof.rs +++ b/libvcx/src/api_vcx/api_handle/proof.rs @@ -1,3 +1,4 @@ +use aries_vcx::protocols::SendClosure; use serde_json; use aries_vcx::common::proofs::proof_request::PresentationRequestData; @@ -5,8 +6,9 @@ use aries_vcx::handlers::proof_presentation::verifier::Verifier; use aries_vcx::messages::a2a::A2AMessage; use crate::api_vcx::api_global::profile::get_main_profile; -use crate::api_vcx::api_handle::mediated_connection; +use crate::api_vcx::api_handle::connection::HttpClient; use crate::api_vcx::api_handle::object_cache::ObjectCache; +use crate::api_vcx::api_handle::{connection, mediated_connection}; use crate::errors::error::{LibvcxError, LibvcxErrorKind, LibvcxResult}; @@ -85,6 +87,43 @@ pub async fn update_state(handle: u32, message: Option<&str>, connection_handle: Ok(state) } +pub async fn update_state_nonmediated(handle: u32, connection_handle: u32, message: &str) -> LibvcxResult { + let mut proof = PROOF_MAP.get_cloned(handle)?; + trace!( + "proof::update_state_nonmediated >>> handle: {}, message: {:?}, connection_handle: {}", + handle, + message, + connection_handle + ); + if !proof.progressable_by_message() { + return Ok(proof.get_state().into()); + } + + let profile = get_main_profile()?; + let con = connection::get_cloned_generic_connection(&connection_handle)?; + let wallet = profile.inject_wallet(); + + let send_message: SendClosure = + Box::new(|msg: A2AMessage| Box::pin(async move { con.send_message(&wallet, &msg, &HttpClient).await })); + + let message: A2AMessage = serde_json::from_str(message).map_err(|err| { + LibvcxError::from_msg( + LibvcxErrorKind::InvalidOption, + format!( + "Cannot updated state with message: Message deserialization failed: {:?}", + err + ), + ) + })?; + proof + .handle_message(&profile, message.into(), Some(send_message)) + .await?; + + let state: u32 = proof.get_state().into(); + PROOF_MAP.insert(handle, proof)?; + Ok(state) +} + pub fn get_state(handle: u32) -> LibvcxResult { PROOF_MAP.get(handle, |proof| Ok(proof.get_state().into())) } @@ -139,6 +178,20 @@ pub async fn send_proof_request(handle: u32, connection_handle: u32) -> LibvcxRe PROOF_MAP.insert(handle, proof) } +pub async fn send_proof_request_nonmediated(handle: u32, connection_handle: u32) -> LibvcxResult<()> { + let mut proof = PROOF_MAP.get_cloned(handle)?; + + let profile = get_main_profile()?; + let con = connection::get_cloned_generic_connection(&connection_handle)?; + let wallet = profile.inject_wallet(); + + let send_message: SendClosure = + Box::new(|msg: A2AMessage| Box::pin(async move { con.send_message(&wallet, &msg, &HttpClient).await })); + + proof.send_presentation_request(send_message).await?; + PROOF_MAP.insert(handle, proof) +} + pub fn mark_presentation_request_msg_sent(handle: u32) -> LibvcxResult<()> { let mut proof = PROOF_MAP.get_cloned(handle)?; proof.mark_presentation_request_msg_sent()?; From 6ee9d0955faff76a1f1d4f48afb31d629f5c71de Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Tue, 7 Feb 2023 14:11:38 +0200 Subject: [PATCH 51/66] Implemented necessary changes to node wrappers to expose non-mediated connections Signed-off-by: Bogdan Mircea --- libvcx/src/api_vcx/api_handle/out_of_band.rs | 12 +- wrappers/node/package-lock.json | 1397 ++++------------- wrappers/node/src/api/connection.ts | 20 +- wrappers/node/src/api/issuer-credential.ts | 31 +- wrappers/node/src/api/out-of-band-receiver.ts | 11 + wrappers/node/src/api/out-of-band.ts | 12 + wrappers/node/src/api/proof.ts | 21 + wrappers/node/src/api/trustping.ts | 25 + wrappers/node/src/index.ts | 2 + wrappers/vcx-napi-rs/index.d.ts | 13 +- wrappers/vcx-napi-rs/index.js | 13 +- wrappers/vcx-napi-rs/package-lock.json | 24 +- wrappers/vcx-napi-rs/src/api/connection.rs | 12 + .../vcx-napi-rs/src/api/issuer_credential.rs | 29 + wrappers/vcx-napi-rs/src/api/mod.rs | 2 + wrappers/vcx-napi-rs/src/api/out_of_band.rs | 24 + .../src/api/out_of_band_receiver.rs | 11 + wrappers/vcx-napi-rs/src/api/proof.rs | 18 + wrappers/vcx-napi-rs/src/api/trustping.rs | 26 + 19 files changed, 612 insertions(+), 1091 deletions(-) create mode 100644 wrappers/node/src/api/out-of-band.ts create mode 100644 wrappers/node/src/api/trustping.ts create mode 100644 wrappers/vcx-napi-rs/src/api/out_of_band.rs create mode 100644 wrappers/vcx-napi-rs/src/api/trustping.rs diff --git a/libvcx/src/api_vcx/api_handle/out_of_band.rs b/libvcx/src/api_vcx/api_handle/out_of_band.rs index 2053415c7c..8bf3654c96 100644 --- a/libvcx/src/api_vcx/api_handle/out_of_band.rs +++ b/libvcx/src/api_vcx/api_handle/out_of_band.rs @@ -11,7 +11,7 @@ use aries_vcx::messages::protocols::out_of_band::{GoalCode, HandshakeProtocol}; use crate::api_vcx::api_global::agency_client::get_main_agency_client; use crate::api_vcx::api_global::profile::get_main_profile; -use crate::api_vcx::api_handle::connection::CONNECTION_MAP; +use crate::api_vcx::api_handle::connection; use crate::api_vcx::api_handle::mediated_connection::CONNECTION_MAP as MEDIATED_CONS_MAP; use crate::api_vcx::api_handle::object_cache::ObjectCache; use crate::errors::error::{LibvcxError, LibvcxErrorKind, LibvcxResult}; @@ -186,14 +186,10 @@ pub async fn nonmediated_connection_exists(handle: u32, conn_handles: &[u32]) -> let profile = get_main_profile()?; let oob = OUT_OF_BAND_RECEIVER_MAP.get_cloned(handle)?; - // Obtain read lock for the duration of the search - let locked_map = CONNECTION_MAP.read()?; + let filter_closure = |h: &u32| connection::get_cloned_generic_connection(h).ok().map(|c| (*h, c)); + let connections: HashMap<_, _> = conn_handles.iter().filter_map(filter_closure).collect(); - // Filter through the map for references to connections that match the given handles - // and store them along their handles to be used in the search agains the OOB message. - let con_iter = conn_handles.iter().filter_map(|h| locked_map.get(h).map(|c| (h, c))); - - match oob.nonmediated_connection_exists::<_, &u32>(&profile, con_iter).await { + match oob.nonmediated_connection_exists::<_, &u32>(&profile, &connections).await { None => Ok((0, false)), Some(h) => Ok((*h, true)), } diff --git a/wrappers/node/package-lock.json b/wrappers/node/package-lock.json index 20bd644c6c..3016882f3f 100644 --- a/wrappers/node/package-lock.json +++ b/wrappers/node/package-lock.json @@ -40,6 +40,7 @@ } }, "../vcx-napi-rs": { + "name": "@hyperledger/vcx-napi-rs", "dev": true, "license": "Apache-2.0", "devDependencies": { @@ -56,27 +57,24 @@ }, "node_modules/@babel/code-frame": { "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/highlight": "^7.10.4" } }, "node_modules/@babel/helper-validator-identifier": { "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", @@ -88,9 +86,8 @@ }, "node_modules/@babel/highlight/node_modules/ansi-styles": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -100,9 +97,8 @@ }, "node_modules/@babel/highlight/node_modules/chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -114,42 +110,37 @@ }, "node_modules/@babel/highlight/node_modules/color-convert": { "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "1.1.3" } }, "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/@babel/highlight/node_modules/has-flag": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/highlight/node_modules/supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -159,9 +150,8 @@ }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -171,9 +161,8 @@ }, "node_modules/@eslint/eslintrc": { "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.1.1", @@ -191,18 +180,16 @@ }, "node_modules/@eslint/eslintrc/node_modules/ignore": { "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/@humanwhocodes/config-array": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@humanwhocodes/object-schema": "^1.2.0", "debug": "^4.1.1", @@ -214,9 +201,8 @@ }, "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@hyperledger/vcx-napi-rs": { "resolved": "../vcx-napi-rs", @@ -224,24 +210,21 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -249,9 +232,8 @@ }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -262,18 +244,16 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -284,84 +264,71 @@ }, "node_modules/@tsconfig/node10": { "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node16": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/app-module-path": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@types/app-module-path/-/app-module-path-2.2.0.tgz", - "integrity": "sha512-r47Kt3ApJDzUU2xCNzaBI25Au5Xfdvf0Gyomveqvg46nQ3J4PaDLicObhyX6cMhvMVWJMB/BnkXdv1E4zxP+6w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/chai": { "version": "4.3.4", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/json-schema": { "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/lodash": { - "version": "4.14.191", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", - "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==", - "dev": true + "version": "4.14.188", + "dev": true, + "license": "MIT" }, "node_modules/@types/mocha": { "version": "8.2.3", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", - "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/uuid": { "version": "8.3.4", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", - "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/weak-napi": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/weak-napi/-/weak-napi-1.0.1.tgz", - "integrity": "sha512-EqTeT7n+f6uxfLFRDcJEOu12dH0AT2fZlb8MTQKDG8E70T7uP//qG4CMdNKV3Ra/cxG7/Z1i04GT7Ll0QriWvQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", - "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/experimental-utils": "4.33.0", "@typescript-eslint/scope-manager": "4.33.0", @@ -391,9 +358,8 @@ }, "node_modules/@typescript-eslint/experimental-utils": { "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", - "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.7", "@typescript-eslint/scope-manager": "4.33.0", @@ -415,9 +381,8 @@ }, "node_modules/@typescript-eslint/parser": { "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", - "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/scope-manager": "4.33.0", "@typescript-eslint/types": "4.33.0", @@ -442,9 +407,8 @@ }, "node_modules/@typescript-eslint/scope-manager": { "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "4.33.0", "@typescript-eslint/visitor-keys": "4.33.0" @@ -459,9 +423,8 @@ }, "node_modules/@typescript-eslint/types": { "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", "dev": true, + "license": "MIT", "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" }, @@ -472,9 +435,8 @@ }, "node_modules/@typescript-eslint/typescript-estree": { "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/types": "4.33.0", "@typescript-eslint/visitor-keys": "4.33.0", @@ -499,9 +461,8 @@ }, "node_modules/@typescript-eslint/visitor-keys": { "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "4.33.0", "eslint-visitor-keys": "^2.0.0" @@ -516,15 +477,13 @@ }, "node_modules/@ungap/promise-all-settled": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/acorn": { "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -534,27 +493,24 @@ }, "node_modules/acorn-jsx": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/acorn-walk": { "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -568,27 +524,24 @@ }, "node_modules/ansi-colors": { "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -600,10 +553,9 @@ } }, "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "version": "3.1.2", "dev": true, + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -614,72 +566,63 @@ }, "node_modules/app-module-path": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz", - "integrity": "sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ==", - "dev": true + "dev": true, + "license": "BSD-2-Clause" }, "node_modules/arg": { "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/argparse": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, + "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } }, "node_modules/array-union": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/assertion-error": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true, + "license": "MIT", "engines": { "node": "*" } }, "node_modules/astral-regex": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/balanced-match": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/binary-extensions": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -687,9 +630,8 @@ }, "node_modules/braces": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, + "license": "MIT", "dependencies": { "fill-range": "^7.0.1" }, @@ -699,24 +641,21 @@ }, "node_modules/browser-stdout": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/callsites": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/camelcase": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -726,9 +665,8 @@ }, "node_modules/chai": { "version": "4.3.7", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", - "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", "dev": true, + "license": "MIT", "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.2", @@ -744,9 +682,8 @@ }, "node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -760,17 +697,14 @@ }, "node_modules/check-error": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", "dev": true, + "license": "MIT", "engines": { "node": "*" } }, "node_modules/chokidar": { "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "funding": [ { @@ -778,6 +712,7 @@ "url": "https://paulmillr.com/funding/" } ], + "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -796,9 +731,8 @@ }, "node_modules/cliui": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -807,9 +741,8 @@ }, "node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -819,27 +752,23 @@ }, "node_modules/color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/create-require": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cross-spawn": { "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -851,9 +780,8 @@ }, "node_modules/debug": { "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -868,9 +796,8 @@ }, "node_modules/decamelize": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -879,10 +806,9 @@ } }, "node_modules/deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "version": "4.1.2", "dev": true, + "license": "MIT", "dependencies": { "type-detect": "^4.0.0" }, @@ -892,24 +818,21 @@ }, "node_modules/deep-is": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/diff": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/dir-glob": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -919,9 +842,8 @@ }, "node_modules/doctrine": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -931,15 +853,13 @@ }, "node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/enquirer": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", "dev": true, + "license": "MIT", "dependencies": { "ansi-colors": "^4.1.1" }, @@ -949,18 +869,16 @@ }, "node_modules/escalade": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/escape-string-regexp": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -970,9 +888,8 @@ }, "node_modules/eslint": { "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.4.3", @@ -1027,9 +944,8 @@ }, "node_modules/eslint-config-prettier": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-7.2.0.tgz", - "integrity": "sha512-rV4Qu0C3nfJKPOAhFujFxB7RMP+URFyQqqOZW9DMRD7ZDTFyjaIlETU3xzHELt++4ugC0+Jm084HQYkkJe+Ivg==", "dev": true, + "license": "MIT", "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -1039,9 +955,8 @@ }, "node_modules/eslint-plugin-prettier": { "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", - "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", "dev": true, + "license": "MIT", "dependencies": { "prettier-linter-helpers": "^1.0.0" }, @@ -1060,9 +975,8 @@ }, "node_modules/eslint-scope": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -1073,9 +987,8 @@ }, "node_modules/eslint-utils": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, + "license": "MIT", "dependencies": { "eslint-visitor-keys": "^2.0.0" }, @@ -1091,18 +1004,16 @@ }, "node_modules/eslint-visitor-keys": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=10" } }, "node_modules/eslint/node_modules/eslint-utils": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, + "license": "MIT", "dependencies": { "eslint-visitor-keys": "^1.1.0" }, @@ -1115,27 +1026,24 @@ }, "node_modules/eslint/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=4" } }, "node_modules/eslint/node_modules/ignore": { "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/espree": { "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "acorn": "^7.4.0", "acorn-jsx": "^5.3.1", @@ -1147,18 +1055,16 @@ }, "node_modules/espree/node_modules/eslint-visitor-keys": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=4" } }, "node_modules/esprima": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, + "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -1169,9 +1075,8 @@ }, "node_modules/esquery": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -1181,18 +1086,16 @@ }, "node_modules/esquery/node_modules/estraverse": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/esrecurse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -1202,48 +1105,42 @@ }, "node_modules/esrecurse/node_modules/estraverse": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/estraverse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/esutils": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-diff": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/fast-glob": { "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -1257,30 +1154,26 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.13.0", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, "node_modules/file-entry-cache": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, + "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" }, @@ -1290,9 +1183,8 @@ }, "node_modules/fill-range": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -1302,9 +1194,8 @@ }, "node_modules/find-up": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -1318,18 +1209,16 @@ }, "node_modules/flat": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, + "license": "BSD-3-Clause", "bin": { "flat": "cli.js" } }, "node_modules/flat-cache": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, + "license": "MIT", "dependencies": { "flatted": "^3.1.0", "rimraf": "^3.0.2" @@ -1340,14 +1229,12 @@ }, "node_modules/flatted": { "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/fs-extra": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "license": "MIT", "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -1356,16 +1243,13 @@ }, "node_modules/fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/fsevents": { "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, - "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -1376,46 +1260,40 @@ }, "node_modules/functional-red-black-tree": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/get-caller-file": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-func-name": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", "dev": true, + "license": "MIT", "engines": { "node": "*" } }, "node_modules/get-symbol-from-current-process-h": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-from-current-process-h/-/get-symbol-from-current-process-h-1.0.2.tgz", - "integrity": "sha512-syloC6fsCt62ELLrr1VKBM1ggOpMdetX9hTrdW77UQdcApPHLmf7CI7OKcN1c9kYuNxKcDe4iJ4FY9sX3aw2xw==" + "license": "MIT" }, "node_modules/get-uv-event-loop-napi-h": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/get-uv-event-loop-napi-h/-/get-uv-event-loop-napi-h-1.0.6.tgz", - "integrity": "sha512-t5c9VNR84nRoF+eLiz6wFrEp1SE2Acg0wS+Ysa2zF0eROes+LzOfuTaVHxGy8AbS8rq7FHEJzjnCZo1BupwdJg==", + "license": "MIT", "dependencies": { "get-symbol-from-current-process-h": "^1.0.1" } }, "node_modules/glob": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -1433,9 +1311,8 @@ }, "node_modules/glob-parent": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -1444,10 +1321,9 @@ } }, "node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.17.0", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -1460,9 +1336,8 @@ }, "node_modules/globby": { "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -1480,50 +1355,44 @@ }, "node_modules/graceful-fs": { "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + "license": "ISC" }, "node_modules/growl": { "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4.x" } }, "node_modules/has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/he": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, + "license": "MIT", "bin": { "he": "bin/he" } }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.2.0", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/import-fresh": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -1537,18 +1406,16 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } }, "node_modules/inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -1556,15 +1423,13 @@ }, "node_modules/inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/is-binary-path": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, + "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -1574,27 +1439,24 @@ }, "node_modules/is-extglob": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-glob": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -1604,27 +1466,24 @@ }, "node_modules/is-number": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, "node_modules/is-plain-obj": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-unicode-supported": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -1634,21 +1493,18 @@ }, "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/js-tokens": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/js-yaml": { "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -1659,29 +1515,25 @@ }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/jsonfile": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "license": "MIT", "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "node_modules/levn": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -1692,9 +1544,8 @@ }, "node_modules/locate-path": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -1707,26 +1558,22 @@ }, "node_modules/lodash": { "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.truncate": { "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/log-symbols": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -1740,18 +1587,16 @@ }, "node_modules/loupe": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", - "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", "dev": true, + "license": "MIT", "dependencies": { "get-func-name": "^2.0.0" } }, "node_modules/lru-cache": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -1761,24 +1606,21 @@ }, "node_modules/make-error": { "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/merge2": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/micromatch": { "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, + "license": "MIT", "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -1789,9 +1631,8 @@ }, "node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1801,9 +1642,8 @@ }, "node_modules/mocha": { "version": "9.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", - "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", "dev": true, + "license": "MIT", "dependencies": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", @@ -1844,24 +1684,21 @@ }, "node_modules/mocha/node_modules/ansi-colors": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/mocha/node_modules/argparse": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "dev": true, + "license": "Python-2.0" }, "node_modules/mocha/node_modules/debug": { "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -1876,15 +1713,13 @@ }, "node_modules/mocha/node_modules/debug/node_modules/ms": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/mocha/node_modules/js-yaml": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -1894,9 +1729,8 @@ }, "node_modules/mocha/node_modules/minimatch": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", - "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1906,15 +1740,13 @@ }, "node_modules/mocha/node_modules/ms": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/mocha/node_modules/supports-color": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -1927,15 +1759,13 @@ }, "node_modules/ms": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/nanoid": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", "dev": true, + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -1945,19 +1775,16 @@ }, "node_modules/natural-compare": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-addon-api": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" + "license": "MIT" }, "node_modules/node-gyp-build": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", - "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", + "version": "4.5.0", + "license": "MIT", "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", @@ -1966,27 +1793,24 @@ }, "node_modules/normalize-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, + "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/optionator": { "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, + "license": "MIT", "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -2001,9 +1825,8 @@ }, "node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -2016,9 +1839,8 @@ }, "node_modules/p-locate": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -2031,9 +1853,8 @@ }, "node_modules/parent-module": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -2043,54 +1864,48 @@ }, "node_modules/path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-type": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/pathval": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true, + "license": "MIT", "engines": { "node": "*" } }, "node_modules/picomatch": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -2100,18 +1915,16 @@ }, "node_modules/prelude-ls": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } }, "node_modules/prettier": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz", - "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==", + "version": "2.7.1", "dev": true, + "license": "MIT", "bin": { "prettier": "bin-prettier.js" }, @@ -2124,9 +1937,8 @@ }, "node_modules/prettier-linter-helpers": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, + "license": "MIT", "dependencies": { "fast-diff": "^1.1.2" }, @@ -2136,26 +1948,22 @@ }, "node_modules/progress": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "version": "2.1.1", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/queue-microtask": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, "funding": [ { @@ -2170,22 +1978,21 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/randombytes": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } }, "node_modules/readdirp": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, + "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -2195,9 +2002,8 @@ }, "node_modules/regexpp": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -2207,36 +2013,32 @@ }, "node_modules/require-directory": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/require-from-string": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/resolve-from": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/reusify": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -2244,9 +2046,8 @@ }, "node_modules/rimraf": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, + "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -2259,8 +2060,6 @@ }, "node_modules/run-parallel": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { @@ -2276,14 +2075,13 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } }, "node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { @@ -2298,13 +2096,13 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/semver": { "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -2317,17 +2115,15 @@ }, "node_modules/serialize-javascript": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } }, "node_modules/setimmediate-napi": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/setimmediate-napi/-/setimmediate-napi-1.0.6.tgz", - "integrity": "sha512-sdNXN15Av1jPXuSal4Mk4tEAKn0+8lfF9Z50/negaQMrAIO9c1qM0eiCh8fT6gctp0RiCObk+6/Xfn5RMGdZoA==", + "license": "MIT", "dependencies": { "get-symbol-from-current-process-h": "^1.0.1", "get-uv-event-loop-napi-h": "^1.0.5" @@ -2335,9 +2131,8 @@ }, "node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -2347,27 +2142,24 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/slash": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/slice-ansi": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -2382,15 +2174,13 @@ }, "node_modules/sprintf-js": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -2402,9 +2192,8 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -2414,9 +2203,8 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -2426,9 +2214,8 @@ }, "node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -2438,9 +2225,8 @@ }, "node_modules/table": { "version": "6.8.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", - "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "ajv": "^8.0.1", "lodash.truncate": "^4.4.2", @@ -2453,10 +2239,9 @@ } }, "node_modules/table/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.11.0", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -2470,21 +2255,18 @@ }, "node_modules/table/node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/text-table": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/to-regex-range": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -2494,9 +2276,8 @@ }, "node_modules/ts-node": { "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, + "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -2536,10 +2317,9 @@ } }, "node_modules/ts-node/node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.8.1", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -2549,24 +2329,21 @@ }, "node_modules/ts-node/node_modules/diff": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/tslib": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/tsutils": { "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^1.8.1" }, @@ -2579,9 +2356,8 @@ }, "node_modules/type-check": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -2591,18 +2367,16 @@ }, "node_modules/type-detect": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/type-fest": { "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -2611,10 +2385,9 @@ } }, "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "4.8.4", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -2625,46 +2398,40 @@ }, "node_modules/universalify": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "license": "MIT", "engines": { "node": ">= 4.0.0" } }, "node_modules/uri-js": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } }, "node_modules/uuid": { "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/v8-compile-cache": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/weak-napi": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/weak-napi/-/weak-napi-2.0.2.tgz", - "integrity": "sha512-LcOSVFrghtVXf4QH+DLIy8iPiCktV7lVbqRDYP+bDPpLzC41RCHQPMyQOnPpWO41Ie4CmnDxS+mbL72r5xFMMQ==", "hasInstallScript": true, + "license": "MIT", "dependencies": { "node-addon-api": "^3.0.0", "node-gyp-build": "^4.2.1", @@ -2673,9 +2440,8 @@ }, "node_modules/which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -2688,24 +2454,21 @@ }, "node_modules/word-wrap": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/workerpool": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", - "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -2720,30 +2483,26 @@ }, "node_modules/wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/y18n": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/yargs": { "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, + "license": "MIT", "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -2759,18 +2518,16 @@ }, "node_modules/yargs-parser": { "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yargs-unparser": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, + "license": "MIT", "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", @@ -2783,18 +2540,16 @@ }, "node_modules/yn": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/yocto-queue": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -2806,8 +2561,6 @@ "dependencies": { "@babel/code-frame": { "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { "@babel/highlight": "^7.10.4" @@ -2815,14 +2568,10 @@ }, "@babel/helper-validator-identifier": { "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "dev": true }, "@babel/highlight": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.18.6", @@ -2832,8 +2581,6 @@ "dependencies": { "ansi-styles": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { "color-convert": "^1.9.0" @@ -2841,8 +2588,6 @@ }, "chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -2852,8 +2597,6 @@ }, "color-convert": { "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "requires": { "color-name": "1.1.3" @@ -2861,26 +2604,18 @@ }, "color-name": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "escape-string-regexp": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true }, "has-flag": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, "supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -2890,8 +2625,6 @@ }, "@cspotcode/source-map-support": { "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, "requires": { "@jridgewell/trace-mapping": "0.3.9" @@ -2899,8 +2632,6 @@ }, "@eslint/eslintrc": { "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -2916,16 +2647,12 @@ "dependencies": { "ignore": { "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true } } }, "@humanwhocodes/config-array": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.0", @@ -2935,8 +2662,6 @@ }, "@humanwhocodes/object-schema": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, "@hyperledger/vcx-napi-rs": { @@ -2953,20 +2678,14 @@ }, "@jridgewell/resolve-uri": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "dev": true }, "@jridgewell/sourcemap-codec": { "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", "dev": true }, "@jridgewell/trace-mapping": { "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, "requires": { "@jridgewell/resolve-uri": "^3.0.3", @@ -2975,8 +2694,6 @@ }, "@nodelib/fs.scandir": { "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "requires": { "@nodelib/fs.stat": "2.0.5", @@ -2985,14 +2702,10 @@ }, "@nodelib/fs.stat": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true }, "@nodelib/fs.walk": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "requires": { "@nodelib/fs.scandir": "2.1.5", @@ -3001,74 +2714,50 @@ }, "@tsconfig/node10": { "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", "dev": true }, "@tsconfig/node12": { "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", "dev": true }, "@tsconfig/node14": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", "dev": true }, "@tsconfig/node16": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "dev": true }, "@types/app-module-path": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@types/app-module-path/-/app-module-path-2.2.0.tgz", - "integrity": "sha512-r47Kt3ApJDzUU2xCNzaBI25Au5Xfdvf0Gyomveqvg46nQ3J4PaDLicObhyX6cMhvMVWJMB/BnkXdv1E4zxP+6w==", "dev": true }, "@types/chai": { "version": "4.3.4", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==", "dev": true }, "@types/json-schema": { "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, "@types/lodash": { - "version": "4.14.191", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", - "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==", + "version": "4.14.188", "dev": true }, "@types/mocha": { "version": "8.2.3", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", - "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", "dev": true }, "@types/node": { "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", "dev": true }, "@types/uuid": { "version": "8.3.4", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", - "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", "dev": true }, "@types/weak-napi": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/weak-napi/-/weak-napi-1.0.1.tgz", - "integrity": "sha512-EqTeT7n+f6uxfLFRDcJEOu12dH0AT2fZlb8MTQKDG8E70T7uP//qG4CMdNKV3Ra/cxG7/Z1i04GT7Ll0QriWvQ==", "dev": true, "requires": { "@types/node": "*" @@ -3076,8 +2765,6 @@ }, "@typescript-eslint/eslint-plugin": { "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", - "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", "dev": true, "requires": { "@typescript-eslint/experimental-utils": "4.33.0", @@ -3092,8 +2779,6 @@ }, "@typescript-eslint/experimental-utils": { "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", - "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", "dev": true, "requires": { "@types/json-schema": "^7.0.7", @@ -3106,8 +2791,6 @@ }, "@typescript-eslint/parser": { "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", - "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", "dev": true, "requires": { "@typescript-eslint/scope-manager": "4.33.0", @@ -3118,8 +2801,6 @@ }, "@typescript-eslint/scope-manager": { "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", "dev": true, "requires": { "@typescript-eslint/types": "4.33.0", @@ -3128,14 +2809,10 @@ }, "@typescript-eslint/types": { "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", "dev": true }, "@typescript-eslint/typescript-estree": { "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", "dev": true, "requires": { "@typescript-eslint/types": "4.33.0", @@ -3149,8 +2826,6 @@ }, "@typescript-eslint/visitor-keys": { "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", "dev": true, "requires": { "@typescript-eslint/types": "4.33.0", @@ -3159,33 +2834,23 @@ }, "@ungap/promise-all-settled": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", "dev": true }, "acorn": { "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true }, "acorn-jsx": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "requires": {} }, "acorn-walk": { "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true }, "ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -3196,29 +2861,21 @@ }, "ansi-colors": { "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true }, "ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { "color-convert": "^2.0.1" } }, "anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "version": "3.1.2", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -3227,20 +2884,14 @@ }, "app-module-path": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz", - "integrity": "sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ==", "dev": true }, "arg": { "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true }, "argparse": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { "sprintf-js": "~1.0.2" @@ -3248,38 +2899,26 @@ }, "array-union": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, "assertion-error": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true }, "astral-regex": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, "balanced-match": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "binary-extensions": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, "brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { "balanced-match": "^1.0.0", @@ -3288,8 +2927,6 @@ }, "braces": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { "fill-range": "^7.0.1" @@ -3297,26 +2934,18 @@ }, "browser-stdout": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, "callsites": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, "camelcase": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true }, "chai": { "version": "4.3.7", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", - "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", "dev": true, "requires": { "assertion-error": "^1.1.0", @@ -3330,8 +2959,6 @@ }, "chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -3340,14 +2967,10 @@ }, "check-error": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", "dev": true }, "chokidar": { "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "requires": { "anymatch": "~3.1.2", @@ -3362,8 +2985,6 @@ }, "cliui": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { "string-width": "^4.2.0", @@ -3373,8 +2994,6 @@ }, "color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" @@ -3382,26 +3001,18 @@ }, "color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, "create-require": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, "cross-spawn": { "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { "path-key": "^3.1.0", @@ -3411,8 +3022,6 @@ }, "debug": { "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -3420,14 +3029,10 @@ }, "decamelize": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true }, "deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "version": "4.1.2", "dev": true, "requires": { "type-detect": "^4.0.0" @@ -3435,20 +3040,14 @@ }, "deep-is": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, "diff": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, "dir-glob": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, "requires": { "path-type": "^4.0.0" @@ -3456,8 +3055,6 @@ }, "doctrine": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "requires": { "esutils": "^2.0.2" @@ -3465,14 +3062,10 @@ }, "emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "enquirer": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", "dev": true, "requires": { "ansi-colors": "^4.1.1" @@ -3480,20 +3073,14 @@ }, "escalade": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true }, "escape-string-regexp": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, "eslint": { "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "dev": true, "requires": { "@babel/code-frame": "7.12.11", @@ -3540,8 +3127,6 @@ "dependencies": { "eslint-utils": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" @@ -3549,31 +3134,23 @@ "dependencies": { "eslint-visitor-keys": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true } } }, "ignore": { "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true } } }, "eslint-config-prettier": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-7.2.0.tgz", - "integrity": "sha512-rV4Qu0C3nfJKPOAhFujFxB7RMP+URFyQqqOZW9DMRD7ZDTFyjaIlETU3xzHELt++4ugC0+Jm084HQYkkJe+Ivg==", "dev": true, "requires": {} }, "eslint-plugin-prettier": { "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", - "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", "dev": true, "requires": { "prettier-linter-helpers": "^1.0.0" @@ -3581,8 +3158,6 @@ }, "eslint-scope": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "requires": { "esrecurse": "^4.3.0", @@ -3591,8 +3166,6 @@ }, "eslint-utils": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, "requires": { "eslint-visitor-keys": "^2.0.0" @@ -3600,14 +3173,10 @@ }, "eslint-visitor-keys": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true }, "espree": { "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, "requires": { "acorn": "^7.4.0", @@ -3617,22 +3186,16 @@ "dependencies": { "eslint-visitor-keys": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true } } }, "esprima": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, "esquery": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -3640,16 +3203,12 @@ "dependencies": { "estraverse": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } }, "esrecurse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "requires": { "estraverse": "^5.2.0" @@ -3657,40 +3216,28 @@ "dependencies": { "estraverse": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } }, "estraverse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, "esutils": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, "fast-deep-equal": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "fast-diff": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", "dev": true }, "fast-glob": { "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -3702,20 +3249,14 @@ }, "fast-json-stable-stringify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, "fast-levenshtein": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.13.0", "dev": true, "requires": { "reusify": "^1.0.4" @@ -3723,8 +3264,6 @@ }, "file-entry-cache": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "requires": { "flat-cache": "^3.0.4" @@ -3732,8 +3271,6 @@ }, "fill-range": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "requires": { "to-regex-range": "^5.0.1" @@ -3741,8 +3278,6 @@ }, "find-up": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "requires": { "locate-path": "^6.0.0", @@ -3751,14 +3286,10 @@ }, "flat": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true }, "flat-cache": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "requires": { "flatted": "^3.1.0", @@ -3767,14 +3298,10 @@ }, "flatted": { "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, "fs-extra": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", "requires": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -3783,52 +3310,36 @@ }, "fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, "fsevents": { "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "optional": true }, "functional-red-black-tree": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", "dev": true }, "get-caller-file": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "get-func-name": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", "dev": true }, "get-symbol-from-current-process-h": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-from-current-process-h/-/get-symbol-from-current-process-h-1.0.2.tgz", - "integrity": "sha512-syloC6fsCt62ELLrr1VKBM1ggOpMdetX9hTrdW77UQdcApPHLmf7CI7OKcN1c9kYuNxKcDe4iJ4FY9sX3aw2xw==" + "version": "1.0.2" }, "get-uv-event-loop-napi-h": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/get-uv-event-loop-napi-h/-/get-uv-event-loop-napi-h-1.0.6.tgz", - "integrity": "sha512-t5c9VNR84nRoF+eLiz6wFrEp1SE2Acg0wS+Ysa2zF0eROes+LzOfuTaVHxGy8AbS8rq7FHEJzjnCZo1BupwdJg==", "requires": { "get-symbol-from-current-process-h": "^1.0.1" } }, "glob": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -3841,17 +3352,13 @@ }, "glob-parent": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { "is-glob": "^4.0.1" } }, "globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.17.0", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -3859,8 +3366,6 @@ }, "globby": { "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "requires": { "array-union": "^2.1.0", @@ -3872,38 +3377,26 @@ } }, "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + "version": "4.2.10" }, "growl": { "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, "has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "he": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, "ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.2.0", "dev": true }, "import-fresh": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "requires": { "parent-module": "^1.0.0", @@ -3912,14 +3405,10 @@ }, "imurmurhash": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true }, "inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "requires": { "once": "^1.3.0", @@ -3928,14 +3417,10 @@ }, "inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "is-binary-path": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "requires": { "binary-extensions": "^2.0.0" @@ -3943,20 +3428,14 @@ }, "is-extglob": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "is-glob": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "requires": { "is-extglob": "^2.1.1" @@ -3964,38 +3443,26 @@ }, "is-number": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, "is-plain-obj": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, "is-unicode-supported": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true }, "isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, "js-tokens": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, "js-yaml": { "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -4004,28 +3471,20 @@ }, "json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "jsonfile": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "requires": { "graceful-fs": "^4.1.6" } }, "levn": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "requires": { "prelude-ls": "^1.2.1", @@ -4034,34 +3493,24 @@ }, "locate-path": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "requires": { "p-locate": "^5.0.0" } }, "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "version": "4.17.21" }, "lodash.merge": { "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, "lodash.truncate": { "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", "dev": true }, "log-symbols": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "requires": { "chalk": "^4.1.0", @@ -4070,8 +3519,6 @@ }, "loupe": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", - "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", "dev": true, "requires": { "get-func-name": "^2.0.0" @@ -4079,8 +3526,6 @@ }, "lru-cache": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "requires": { "yallist": "^4.0.0" @@ -4088,20 +3533,14 @@ }, "make-error": { "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, "merge2": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true }, "micromatch": { "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "requires": { "braces": "^3.0.2", @@ -4110,8 +3549,6 @@ }, "minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -4119,8 +3556,6 @@ }, "mocha": { "version": "9.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", - "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", "dev": true, "requires": { "@ungap/promise-all-settled": "1.1.2", @@ -4151,20 +3586,14 @@ "dependencies": { "ansi-colors": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true }, "argparse": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, "debug": { "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "requires": { "ms": "2.1.2" @@ -4172,16 +3601,12 @@ "dependencies": { "ms": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } }, "js-yaml": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "requires": { "argparse": "^2.0.1" @@ -4189,8 +3614,6 @@ }, "minimatch": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", - "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -4198,14 +3621,10 @@ }, "ms": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "supports-color": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -4215,42 +3634,28 @@ }, "ms": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "nanoid": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", "dev": true }, "natural-compare": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, "node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" + "version": "3.2.1" }, "node-gyp-build": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", - "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==" + "version": "4.5.0" }, "normalize-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, "once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "requires": { "wrappy": "1" @@ -4258,8 +3663,6 @@ }, "optionator": { "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "requires": { "deep-is": "^0.1.3", @@ -4272,8 +3675,6 @@ }, "p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "requires": { "yocto-queue": "^0.1.0" @@ -4281,8 +3682,6 @@ }, "p-locate": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "requires": { "p-limit": "^3.0.2" @@ -4290,8 +3689,6 @@ }, "parent-module": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "requires": { "callsites": "^3.0.0" @@ -4299,56 +3696,38 @@ }, "path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true }, "path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "path-type": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, "pathval": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true }, "picomatch": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, "prelude-ls": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, "prettier": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz", - "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==", + "version": "2.7.1", "dev": true }, "prettier-linter-helpers": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, "requires": { "fast-diff": "^1.1.2" @@ -4356,26 +3735,18 @@ }, "progress": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, "punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "version": "2.1.1", "dev": true }, "queue-microtask": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, "randombytes": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, "requires": { "safe-buffer": "^5.1.0" @@ -4383,8 +3754,6 @@ }, "readdirp": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "requires": { "picomatch": "^2.2.1" @@ -4392,38 +3761,26 @@ }, "regexpp": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, "require-directory": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, "require-from-string": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true }, "resolve-from": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, "reusify": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true }, "rimraf": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { "glob": "^7.1.3" @@ -4431,8 +3788,6 @@ }, "run-parallel": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "requires": { "queue-microtask": "^1.2.2" @@ -4440,14 +3795,10 @@ }, "safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true }, "semver": { "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -4455,8 +3806,6 @@ }, "serialize-javascript": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dev": true, "requires": { "randombytes": "^2.1.0" @@ -4464,8 +3813,6 @@ }, "setimmediate-napi": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/setimmediate-napi/-/setimmediate-napi-1.0.6.tgz", - "integrity": "sha512-sdNXN15Av1jPXuSal4Mk4tEAKn0+8lfF9Z50/negaQMrAIO9c1qM0eiCh8fT6gctp0RiCObk+6/Xfn5RMGdZoA==", "requires": { "get-symbol-from-current-process-h": "^1.0.1", "get-uv-event-loop-napi-h": "^1.0.5" @@ -4473,8 +3820,6 @@ }, "shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { "shebang-regex": "^3.0.0" @@ -4482,20 +3827,14 @@ }, "shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "slash": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, "slice-ansi": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "requires": { "ansi-styles": "^4.0.0", @@ -4505,14 +3844,10 @@ }, "sprintf-js": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, "string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", @@ -4522,8 +3857,6 @@ }, "strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { "ansi-regex": "^5.0.1" @@ -4531,14 +3864,10 @@ }, "strip-json-comments": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, "supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -4546,8 +3875,6 @@ }, "table": { "version": "6.8.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", - "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", "dev": true, "requires": { "ajv": "^8.0.1", @@ -4558,9 +3885,7 @@ }, "dependencies": { "ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.11.0", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -4571,22 +3896,16 @@ }, "json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true } } }, "text-table": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, "to-regex-range": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "requires": { "is-number": "^7.0.0" @@ -4594,8 +3913,6 @@ }, "ts-node": { "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, "requires": { "@cspotcode/source-map-support": "^0.8.0", @@ -4614,29 +3931,21 @@ }, "dependencies": { "acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.8.1", "dev": true }, "diff": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true } } }, "tslib": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, "tsutils": { "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, "requires": { "tslib": "^1.8.1" @@ -4644,8 +3953,6 @@ }, "type-check": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "requires": { "prelude-ls": "^1.2.1" @@ -4653,57 +3960,39 @@ }, "type-detect": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, "type-fest": { "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, "typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "4.8.4", "dev": true }, "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + "version": "0.1.2" }, "uri-js": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "requires": { "punycode": "^2.1.0" } }, "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + "version": "8.3.2" }, "v8-compile-cache": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, "v8-compile-cache-lib": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, "weak-napi": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/weak-napi/-/weak-napi-2.0.2.tgz", - "integrity": "sha512-LcOSVFrghtVXf4QH+DLIy8iPiCktV7lVbqRDYP+bDPpLzC41RCHQPMyQOnPpWO41Ie4CmnDxS+mbL72r5xFMMQ==", "requires": { "node-addon-api": "^3.0.0", "node-gyp-build": "^4.2.1", @@ -4712,8 +4001,6 @@ }, "which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -4721,20 +4008,14 @@ }, "word-wrap": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, "workerpool": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", - "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", "dev": true }, "wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { "ansi-styles": "^4.0.0", @@ -4744,26 +4025,18 @@ }, "wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, "y18n": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "yargs": { "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { "cliui": "^7.0.2", @@ -4777,14 +4050,10 @@ }, "yargs-parser": { "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", "dev": true }, "yargs-unparser": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, "requires": { "camelcase": "^6.0.0", @@ -4795,14 +4064,10 @@ }, "yn": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true }, "yocto-queue": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true } } diff --git a/wrappers/node/src/api/connection.ts b/wrappers/node/src/api/connection.ts index 4bbc692672..53f4841e86 100644 --- a/wrappers/node/src/api/connection.ts +++ b/wrappers/node/src/api/connection.ts @@ -58,9 +58,17 @@ export class NonmediatedConnection extends VcxBaseWithState { + public getRemoteVerkey(): string { try { - await ffiNapi.connectionProcessInvite(this.handle, invite); + return ffiNapi.connectionGetRemoteVk(this.handle); + } catch (err: any) { + throw new VCXInternalError(err); + } + } + + public processInvite(invite: string): void { + try { + ffiNapi.connectionProcessInvite(this.handle, invite); } catch (err: any) { throw new VCXInternalError(err); } @@ -91,6 +99,14 @@ export class NonmediatedConnection extends VcxBaseWithState { try { await ffiNapi.connectionSendResponse(this.handle); diff --git a/wrappers/node/src/api/issuer-credential.ts b/wrappers/node/src/api/issuer-credential.ts index 126154266e..240b3c257f 100644 --- a/wrappers/node/src/api/issuer-credential.ts +++ b/wrappers/node/src/api/issuer-credential.ts @@ -1,6 +1,7 @@ import * as ffi from '@hyperledger/vcx-napi-rs'; import { ISerializedData, IssuerStateType } from './common'; import { Connection } from './mediated-connection'; +import { NonmediatedConnection } from './connection'; import { CredentialDef } from './credential-def'; import { RevocationRegistry } from './revocation-registry'; import { VcxBaseWithState } from './vcx-base-with-state'; @@ -71,6 +72,18 @@ export class IssuerCredential extends VcxBaseWithState { + try { + return await ffi.issuerCredentialUpdateStateWithMessageNonmediated( + this.handle, + connection.handle, + message, + ); + } catch (err: any) { + throw new VCXInternalError(err); + } + } + public async sendOfferV2(connection: Connection): Promise { try { return await ffi.issuerCredentialSendOfferV2(this.handle, connection.handle); @@ -79,9 +92,17 @@ export class IssuerCredential extends VcxBaseWithState { + try { + return await ffi.issuerCredentialSendOfferNonmediated(this.handle, connection.handle); + } catch (err: any) { + throw new VCXInternalError(err); + } + } + public async markCredentialOfferMsgSent(): Promise { try { - return await ffi.issuerCredentialMarkOfferMsgSent(this.handle); + return ffi.issuerCredentialMarkOfferMsgSent(this.handle); } catch (err: any) { throw new VCXInternalError(err); } @@ -130,6 +151,14 @@ export class IssuerCredential extends VcxBaseWithState { + try { + return await ffi.issuerCredentialSendCredentialNonmediated(this.handle, connection.handle); + } catch (err: any) { + throw new VCXInternalError(err); + } + } + public async revokeCredentialLocal() { try { return await ffi.issuerCredentialRevokeLocal(this.handle); diff --git a/wrappers/node/src/api/out-of-band-receiver.ts b/wrappers/node/src/api/out-of-band-receiver.ts index 96791621d1..b08e50bacc 100644 --- a/wrappers/node/src/api/out-of-band-receiver.ts +++ b/wrappers/node/src/api/out-of-band-receiver.ts @@ -2,6 +2,7 @@ import * as ffi from '@hyperledger/vcx-napi-rs'; import { VCXInternalError } from '../errors'; import { IOOBSerializedData } from './out-of-band-sender'; import { Connection } from './mediated-connection'; +import { NonmediatedConnection } from './connection'; import { VcxBase } from './vcx-base'; import { ISerializedData } from './common'; @@ -43,6 +44,16 @@ export class OutOfBandReceiver extends VcxBase { } } + public async nonmediatedConnectionExists(connections: [NonmediatedConnection]): Promise { + try { + const connHandles = connections.map((conn) => conn.handle); + const connHandle = await ffi.outOfBandReceiverNonmediatedConnectionExists(this.handle, connHandles); + return connections.find((conn) => conn.handle === connHandle); + } catch (err: any) { + throw new VCXInternalError(err); + } + } + public async buildConnection(): Promise { try { const connection = await ffi.outOfBandReceiverBuildConnection(this.handle); diff --git a/wrappers/node/src/api/out-of-band.ts b/wrappers/node/src/api/out-of-band.ts new file mode 100644 index 0000000000..72372c02a6 --- /dev/null +++ b/wrappers/node/src/api/out-of-band.ts @@ -0,0 +1,12 @@ +import * as ffi from '@hyperledger/vcx-napi-rs'; +import { VCXInternalError } from '../errors'; + +export class OutOfBand { + public static buildHandshakeReuseAcceptedMsg(handshakeReuse: string): string { + try { + return ffi.outOfBandBuildHandshakeReuseAcceptedMsg(handshakeReuse); + } catch (err: any) { + throw new VCXInternalError(err); + } + } +} diff --git a/wrappers/node/src/api/proof.ts b/wrappers/node/src/api/proof.ts index 7c1a91e4dc..c4ee71d774 100644 --- a/wrappers/node/src/api/proof.ts +++ b/wrappers/node/src/api/proof.ts @@ -1,6 +1,7 @@ import * as ffi from '@hyperledger/vcx-napi-rs'; import { ISerializedData, VerifierStateType } from './common'; import { Connection } from './mediated-connection'; +import { NonmediatedConnection } from './connection'; import { VcxBaseWithState } from './vcx-base-with-state'; import { VCXInternalError } from '../errors'; @@ -137,6 +138,18 @@ export class Proof extends VcxBaseWithState { } } + public async updateStateWithMessageNonmediated(connection: NonmediatedConnection, message: string): Promise { + try { + return await ffi.proofUpdateStateWithMessageNonmediated( + this.handle, + connection.handle, + message, + ); + } catch (err: any) { + throw new VCXInternalError(err); + } + } + public async requestProof(connection: Connection): Promise { try { return await ffi.proofSendRequest(this.handle, connection.handle); @@ -145,6 +158,14 @@ export class Proof extends VcxBaseWithState { } } + public async requestProofNonmediated(connection: NonmediatedConnection): Promise { + try { + return await ffi.proofSendRequestNonmediated(this.handle, connection.handle); + } catch (err: any) { + throw new VCXInternalError(err); + } + } + public getProofRequestMessage(): string { try { return ffi.proofGetRequestMsg(this.handle); diff --git a/wrappers/node/src/api/trustping.ts b/wrappers/node/src/api/trustping.ts new file mode 100644 index 0000000000..2067dd9632 --- /dev/null +++ b/wrappers/node/src/api/trustping.ts @@ -0,0 +1,25 @@ +import * as ffi from '@hyperledger/vcx-napi-rs'; +import { VCXInternalError } from '../errors'; + +export class Trustsping { + static buildResponse( + ping: string + ): string { + try { + return ffi.trustpingBuildResponseMsg(ping); + } catch (err: any) { + throw new VCXInternalError(err); + } + } + + static buildPing( + requestResponse: boolean, + comment?: string + ): string { + try { + return ffi.trustpingBuildPing(requestResponse, comment); + } catch (err: any) { + throw new VCXInternalError(err); + } + } +} diff --git a/wrappers/node/src/index.ts b/wrappers/node/src/index.ts index 58d1b03a5a..17aa048078 100644 --- a/wrappers/node/src/index.ts +++ b/wrappers/node/src/index.ts @@ -12,7 +12,9 @@ export * from './api/credential'; export * from './api/disclosed-proof'; export * from './api/utils'; export * from './api/wallet'; +export * from './api/out-of-band'; export * from './api/out-of-band-sender'; export * from './api/out-of-band-receiver'; export * from './errors'; export * from './api/logging'; +export * from './api/trustping'; diff --git a/wrappers/vcx-napi-rs/index.d.ts b/wrappers/vcx-napi-rs/index.d.ts index b633692a0c..fbd5fcdac0 100644 --- a/wrappers/vcx-napi-rs/index.d.ts +++ b/wrappers/vcx-napi-rs/index.d.ts @@ -13,12 +13,14 @@ export function connectionCreateInvitee(invitation: string): Promise export function connectionGetThreadId(handle: number): string export function connectionGetPairwiseInfo(handle: number): string export function connectionGetRemoteDid(handle: number): string +export function connectionGetRemoteVk(handle: number): string export function connectionGetState(handle: number): number export function connectionGetInvitation(handle: number): string -export function connectionProcessInvite(handle: number, invitation: string): Promise +export function connectionProcessInvite(handle: number, invitation: string): void export function connectionProcessRequest(handle: number, request: string, serviceEndpoint: string, routingKeys: Array): Promise export function connectionProcessResponse(handle: number, response: string): Promise export function connectionProcessAck(handle: number, message: string): Promise +export function connectionProcessProblemReport(handle: number, problemReport: string): void export function connectionSendResponse(handle: number): Promise export function connectionSendRequest(handle: number, serviceEndpoint: string, routingKeys: Array): Promise export function connectionSendAck(handle: number): Promise @@ -71,13 +73,16 @@ export function issuerCredentialDeserialize(credentialData: string): number export function issuerCredentialSerialize(handleCredential: number): string export function issuerCredentialUpdateStateV2(handleCredential: number, connectionHandle: number): Promise export function issuerCredentialUpdateStateWithMessageV2(handleCredential: number, connectionHandle: number, message: string): Promise +export function issuerCredentialUpdateStateWithMessageNonmediated(handleCredential: number, connectionHandle: number, message: string): Promise export function issuerCredentialGetState(handleCredential: number): number export function issuerCredentialGetRevRegId(handleCredential: number): string export function issuerCredentialCreate(sourceId: string): number export function issuerCredentialRevokeLocal(handleCredential: number): Promise export function issuerCredentialIsRevokable(handleCredential: number): boolean export function issuerCredentialSendCredential(handleCredential: number, handleConnection: number): Promise +export function issuerCredentialSendCredentialNonmediated(handleCredential: number, handleConnection: number): Promise export function issuerCredentialSendOfferV2(handleCredential: number, handleConnection: number): Promise +export function issuerCredentialSendOfferNonmediated(handleCredential: number, handleConnection: number): Promise export function issuerCredentialMarkOfferMsgSent(handleCredential: number): void export function issuerCredentialBuildOfferMsgV2(credentialHandle: number, credDefHandle: number, revRegHandle: number, credentialJson: string, comment?: string | undefined | null): Promise export function issuerCredentialGetOfferMsg(credentialHandle: number): string @@ -116,9 +121,11 @@ export function mediatedConnectionInfo(handle: number): Promise export function mediatedConnectionMessagesDownload(connHandles: Array, statusCodes?: string | undefined | null, uids?: string | undefined | null): Promise export function mediatedConnectionSignData(handle: number, data: Buffer): Promise export function mediatedConnectionVerifySignature(handle: number, data: Buffer, signature: Buffer): Promise +export function outOfBandBuildHandshakeReuseAcceptedMsg(handshakeReuse: string): string export function outOfBandReceiverCreate(msg: string): number export function outOfBandReceiverExtractMessage(handle: number): string export function outOfBandReceiverConnectionExists(handle: number, connHandles: Array): Promise +export function outOfBandReceiverNonmediatedConnectionExists(handle: number, connHandles: Array): Promise export function outOfBandReceiverBuildConnection(handle: number): Promise export function outOfBandReceiverGetThreadId(handle: number): string export function outOfBandReceiverSerialize(handle: number): string @@ -139,11 +146,13 @@ export function proofCreate(sourceId: string, requestedAttrs: string, requestedP export function proofGetProofMsg(handle: number): string export function proofRelease(handle: number): void export function proofSendRequest(handleProof: number, handleConnection: number): Promise +export function proofSendRequestNonmediated(handleProof: number, handleConnection: number): Promise export function proofGetRequestMsg(handle: number): string export function proofSerialize(handle: number): string export function proofDeserialize(data: string): number export function v2ProofUpdateState(handleProof: number, connectionHandle: number): Promise export function v2ProofUpdateStateWithMessage(handleProof: number, message: string, connectionHandle: number): Promise +export function proofUpdateStateWithMessageNonmediated(handleProof: number, connectionHandle: number, message: string): Promise export function proofGetState(handle: number): number export function proofGetProofState(handle: number): number export function proofGetThreadId(handle: number): string @@ -166,6 +175,8 @@ export function schemaRelease(handleSchema: number): void export function schemaUpdateState(handleSchema: number): Promise export function schemaGetState(handleSchema: number): number export function enableMocks(): void +export function trustpingBuildResponseMsg(ping: string): string +export function trustpingBuildPing(requestResponse: boolean, comment?: string | undefined | null): string export function shutdown(deleteAll?: boolean | undefined | null): void export function getVersion(): string export function walletOpenAsMain(walletConfig: string): Promise diff --git a/wrappers/vcx-napi-rs/index.js b/wrappers/vcx-napi-rs/index.js index 90913bc1e7..0a4f7ecd1d 100644 --- a/wrappers/vcx-napi-rs/index.js +++ b/wrappers/vcx-napi-rs/index.js @@ -246,7 +246,7 @@ if (!nativeBinding) { throw new Error(`Failed to load native binding`) } -const { updateWebhookUrl, createAgencyClientForMainWallet, provisionCloudAgent, messagesUpdateStatus, generatePublicInvitation, connectionCreateInviter, connectionCreateInvitee, connectionGetThreadId, connectionGetPairwiseInfo, connectionGetRemoteDid, connectionGetState, connectionGetInvitation, connectionProcessInvite, connectionProcessRequest, connectionProcessResponse, connectionProcessAck, connectionSendResponse, connectionSendRequest, connectionSendAck, connectionSendGenericMessage, connectionCreateInvite, connectionSerialize, connectionDeserialize, connectionRelease, credentialCreateWithOffer, credentialRelease, credentialSendRequest, credentialDeclineOffer, credentialSerialize, credentialDeserialize, v2CredentialUpdateStateWithMessage, v2CredentialUpdateState, credentialGetState, credentialGetOffers, credentialGetAttributes, credentialGetAttachment, credentialGetTailsLocation, credentialGetTailsHash, credentialGetRevRegId, credentialGetThreadId, credentialdefCreateV2, credentialdefPublish, credentialdefDeserialize, credentialdefRelease, credentialdefSerialize, credentialdefGetCredDefId, credentialdefUpdateState, credentialdefGetState, disclosedProofCreateWithRequest, disclosedProofRelease, disclosedProofSendProof, disclosedProofRejectProof, disclosedProofGetProofMsg, disclosedProofSerialize, disclosedProofDeserialize, v2DisclosedProofUpdateState, v2DisclosedProofUpdateStateWithMessage, disclosedProofGetState, disclosedProofGetRequests, disclosedProofRetrieveCredentials, disclosedProofGetProofRequestAttachment, disclosedProofGenerateProof, disclosedProofDeclinePresentationRequest, disclosedProofGetThreadId, issuerCredentialDeserialize, issuerCredentialSerialize, issuerCredentialUpdateStateV2, issuerCredentialUpdateStateWithMessageV2, issuerCredentialGetState, issuerCredentialGetRevRegId, issuerCredentialCreate, issuerCredentialRevokeLocal, issuerCredentialIsRevokable, issuerCredentialSendCredential, issuerCredentialSendOfferV2, issuerCredentialMarkOfferMsgSent, issuerCredentialBuildOfferMsgV2, issuerCredentialGetOfferMsg, issuerCredentialRelease, issuerCredentialGetThreadId, getLedgerAuthorAgreement, setActiveTxnAuthorAgreementMeta, createService, getServiceFromLedger, getVerkeyFromLedger, getLedgerTxn, initDefaultLogger, mediatedConnectionGeneratePublicInvite, mediatedConnectionGetPwDid, mediatedConnectionGetTheirPwDid, mediatedConnectionGetThreadId, mediatedConnectionGetState, mediatedConnectionGetSourceId, mediatedConnectionCreate, mediatedConnectionCreateWithInvite, mediatedConnectionSendMessage, mediatedConnectionCreateWithConnectionRequestV2, mediatedConnectionSendHandshakeReuse, mediatedConnectionUpdateStateWithMessage, mediatedConnectionHandleMessage, mediatedConnectionUpdateState, mediatedConnectionDeleteConnection, mediatedConnectionConnect, mediatedConnectionSerialize, mediatedConnectionDeserialize, mediatedConnectionRelease, mediatedConnectionInviteDetails, mediatedConnectionSendPing, mediatedConnectionSendDiscoveryFeatures, mediatedConnectionInfo, mediatedConnectionMessagesDownload, mediatedConnectionSignData, mediatedConnectionVerifySignature, outOfBandReceiverCreate, outOfBandReceiverExtractMessage, outOfBandReceiverConnectionExists, outOfBandReceiverBuildConnection, outOfBandReceiverGetThreadId, outOfBandReceiverSerialize, outOfBandReceiverDeserialize, outOfBandReceiverRelease, outOfBandSenderCreate, outOfBandSenderAppendMessage, outOfBandSenderAppendService, outOfBandSenderAppendServiceDid, outOfBandSenderToMessage, outOfBandSenderGetThreadId, outOfBandSenderSerialize, outOfBandSenderDeserialize, outOfBandSenderRelease, openMainPool, closeMainPool, proofCreate, proofGetProofMsg, proofRelease, proofSendRequest, proofGetRequestMsg, proofSerialize, proofDeserialize, v2ProofUpdateState, v2ProofUpdateStateWithMessage, proofGetState, proofGetProofState, proofGetThreadId, markPresentationRequestMsgSent, revocationRegistryCreate, revocationRegistryPublish, revocationRegistryPublishRevocations, revocationRegistryGetRevRegId, revocationRegistryGetTailsHash, revocationRegistrySerialize, revocationRegistryDeserialize, revocationRegistryRelease, schemaGetAttributes, schemaPrepareForEndorser, schemaCreate, schemaGetSchemaId, schemaDeserialize, schemaSerialize, schemaRelease, schemaUpdateState, schemaGetState, enableMocks, shutdown, getVersion, walletOpenAsMain, walletCreateMain, walletCloseMain, vcxInitIssuerConfig, configureIssuerWallet, unpack, createPairwiseInfo, walletImport, walletExport, getVerkeyFromWallet, rotateVerkey, rotateVerkeyStart, rotateVerkeyApply } = nativeBinding +const { updateWebhookUrl, createAgencyClientForMainWallet, provisionCloudAgent, messagesUpdateStatus, generatePublicInvitation, connectionCreateInviter, connectionCreateInvitee, connectionGetThreadId, connectionGetPairwiseInfo, connectionGetRemoteDid, connectionGetRemoteVk, connectionGetState, connectionGetInvitation, connectionProcessInvite, connectionProcessRequest, connectionProcessResponse, connectionProcessAck, connectionProcessProblemReport, connectionSendResponse, connectionSendRequest, connectionSendAck, connectionSendGenericMessage, connectionCreateInvite, connectionSerialize, connectionDeserialize, connectionRelease, credentialCreateWithOffer, credentialRelease, credentialSendRequest, credentialDeclineOffer, credentialSerialize, credentialDeserialize, v2CredentialUpdateStateWithMessage, v2CredentialUpdateState, credentialGetState, credentialGetOffers, credentialGetAttributes, credentialGetAttachment, credentialGetTailsLocation, credentialGetTailsHash, credentialGetRevRegId, credentialGetThreadId, credentialdefCreateV2, credentialdefPublish, credentialdefDeserialize, credentialdefRelease, credentialdefSerialize, credentialdefGetCredDefId, credentialdefUpdateState, credentialdefGetState, disclosedProofCreateWithRequest, disclosedProofRelease, disclosedProofSendProof, disclosedProofRejectProof, disclosedProofGetProofMsg, disclosedProofSerialize, disclosedProofDeserialize, v2DisclosedProofUpdateState, v2DisclosedProofUpdateStateWithMessage, disclosedProofGetState, disclosedProofGetRequests, disclosedProofRetrieveCredentials, disclosedProofGetProofRequestAttachment, disclosedProofGenerateProof, disclosedProofDeclinePresentationRequest, disclosedProofGetThreadId, issuerCredentialDeserialize, issuerCredentialSerialize, issuerCredentialUpdateStateV2, issuerCredentialUpdateStateWithMessageV2, issuerCredentialUpdateStateWithMessageNonmediated, issuerCredentialGetState, issuerCredentialGetRevRegId, issuerCredentialCreate, issuerCredentialRevokeLocal, issuerCredentialIsRevokable, issuerCredentialSendCredential, issuerCredentialSendCredentialNonmediated, issuerCredentialSendOfferV2, issuerCredentialSendOfferNonmediated, issuerCredentialMarkOfferMsgSent, issuerCredentialBuildOfferMsgV2, issuerCredentialGetOfferMsg, issuerCredentialRelease, issuerCredentialGetThreadId, getLedgerAuthorAgreement, setActiveTxnAuthorAgreementMeta, createService, getServiceFromLedger, getVerkeyFromLedger, getLedgerTxn, initDefaultLogger, mediatedConnectionGeneratePublicInvite, mediatedConnectionGetPwDid, mediatedConnectionGetTheirPwDid, mediatedConnectionGetThreadId, mediatedConnectionGetState, mediatedConnectionGetSourceId, mediatedConnectionCreate, mediatedConnectionCreateWithInvite, mediatedConnectionSendMessage, mediatedConnectionCreateWithConnectionRequestV2, mediatedConnectionSendHandshakeReuse, mediatedConnectionUpdateStateWithMessage, mediatedConnectionHandleMessage, mediatedConnectionUpdateState, mediatedConnectionDeleteConnection, mediatedConnectionConnect, mediatedConnectionSerialize, mediatedConnectionDeserialize, mediatedConnectionRelease, mediatedConnectionInviteDetails, mediatedConnectionSendPing, mediatedConnectionSendDiscoveryFeatures, mediatedConnectionInfo, mediatedConnectionMessagesDownload, mediatedConnectionSignData, mediatedConnectionVerifySignature, outOfBandBuildHandshakeReuseAcceptedMsg, outOfBandReceiverCreate, outOfBandReceiverExtractMessage, outOfBandReceiverConnectionExists, outOfBandReceiverNonmediatedConnectionExists, outOfBandReceiverBuildConnection, outOfBandReceiverGetThreadId, outOfBandReceiverSerialize, outOfBandReceiverDeserialize, outOfBandReceiverRelease, outOfBandSenderCreate, outOfBandSenderAppendMessage, outOfBandSenderAppendService, outOfBandSenderAppendServiceDid, outOfBandSenderToMessage, outOfBandSenderGetThreadId, outOfBandSenderSerialize, outOfBandSenderDeserialize, outOfBandSenderRelease, openMainPool, closeMainPool, proofCreate, proofGetProofMsg, proofRelease, proofSendRequest, proofSendRequestNonmediated, proofGetRequestMsg, proofSerialize, proofDeserialize, v2ProofUpdateState, v2ProofUpdateStateWithMessage, proofUpdateStateWithMessageNonmediated, proofGetState, proofGetProofState, proofGetThreadId, markPresentationRequestMsgSent, revocationRegistryCreate, revocationRegistryPublish, revocationRegistryPublishRevocations, revocationRegistryGetRevRegId, revocationRegistryGetTailsHash, revocationRegistrySerialize, revocationRegistryDeserialize, revocationRegistryRelease, schemaGetAttributes, schemaPrepareForEndorser, schemaCreate, schemaGetSchemaId, schemaDeserialize, schemaSerialize, schemaRelease, schemaUpdateState, schemaGetState, enableMocks, trustpingBuildResponseMsg, trustpingBuildPing, shutdown, getVersion, walletOpenAsMain, walletCreateMain, walletCloseMain, vcxInitIssuerConfig, configureIssuerWallet, unpack, createPairwiseInfo, walletImport, walletExport, getVerkeyFromWallet, rotateVerkey, rotateVerkeyStart, rotateVerkeyApply } = nativeBinding module.exports.updateWebhookUrl = updateWebhookUrl module.exports.createAgencyClientForMainWallet = createAgencyClientForMainWallet @@ -258,12 +258,14 @@ module.exports.connectionCreateInvitee = connectionCreateInvitee module.exports.connectionGetThreadId = connectionGetThreadId module.exports.connectionGetPairwiseInfo = connectionGetPairwiseInfo module.exports.connectionGetRemoteDid = connectionGetRemoteDid +module.exports.connectionGetRemoteVk = connectionGetRemoteVk module.exports.connectionGetState = connectionGetState module.exports.connectionGetInvitation = connectionGetInvitation module.exports.connectionProcessInvite = connectionProcessInvite module.exports.connectionProcessRequest = connectionProcessRequest module.exports.connectionProcessResponse = connectionProcessResponse module.exports.connectionProcessAck = connectionProcessAck +module.exports.connectionProcessProblemReport = connectionProcessProblemReport module.exports.connectionSendResponse = connectionSendResponse module.exports.connectionSendRequest = connectionSendRequest module.exports.connectionSendAck = connectionSendAck @@ -316,13 +318,16 @@ module.exports.issuerCredentialDeserialize = issuerCredentialDeserialize module.exports.issuerCredentialSerialize = issuerCredentialSerialize module.exports.issuerCredentialUpdateStateV2 = issuerCredentialUpdateStateV2 module.exports.issuerCredentialUpdateStateWithMessageV2 = issuerCredentialUpdateStateWithMessageV2 +module.exports.issuerCredentialUpdateStateWithMessageNonmediated = issuerCredentialUpdateStateWithMessageNonmediated module.exports.issuerCredentialGetState = issuerCredentialGetState module.exports.issuerCredentialGetRevRegId = issuerCredentialGetRevRegId module.exports.issuerCredentialCreate = issuerCredentialCreate module.exports.issuerCredentialRevokeLocal = issuerCredentialRevokeLocal module.exports.issuerCredentialIsRevokable = issuerCredentialIsRevokable module.exports.issuerCredentialSendCredential = issuerCredentialSendCredential +module.exports.issuerCredentialSendCredentialNonmediated = issuerCredentialSendCredentialNonmediated module.exports.issuerCredentialSendOfferV2 = issuerCredentialSendOfferV2 +module.exports.issuerCredentialSendOfferNonmediated = issuerCredentialSendOfferNonmediated module.exports.issuerCredentialMarkOfferMsgSent = issuerCredentialMarkOfferMsgSent module.exports.issuerCredentialBuildOfferMsgV2 = issuerCredentialBuildOfferMsgV2 module.exports.issuerCredentialGetOfferMsg = issuerCredentialGetOfferMsg @@ -361,9 +366,11 @@ module.exports.mediatedConnectionInfo = mediatedConnectionInfo module.exports.mediatedConnectionMessagesDownload = mediatedConnectionMessagesDownload module.exports.mediatedConnectionSignData = mediatedConnectionSignData module.exports.mediatedConnectionVerifySignature = mediatedConnectionVerifySignature +module.exports.outOfBandBuildHandshakeReuseAcceptedMsg = outOfBandBuildHandshakeReuseAcceptedMsg module.exports.outOfBandReceiverCreate = outOfBandReceiverCreate module.exports.outOfBandReceiverExtractMessage = outOfBandReceiverExtractMessage module.exports.outOfBandReceiverConnectionExists = outOfBandReceiverConnectionExists +module.exports.outOfBandReceiverNonmediatedConnectionExists = outOfBandReceiverNonmediatedConnectionExists module.exports.outOfBandReceiverBuildConnection = outOfBandReceiverBuildConnection module.exports.outOfBandReceiverGetThreadId = outOfBandReceiverGetThreadId module.exports.outOfBandReceiverSerialize = outOfBandReceiverSerialize @@ -384,11 +391,13 @@ module.exports.proofCreate = proofCreate module.exports.proofGetProofMsg = proofGetProofMsg module.exports.proofRelease = proofRelease module.exports.proofSendRequest = proofSendRequest +module.exports.proofSendRequestNonmediated = proofSendRequestNonmediated module.exports.proofGetRequestMsg = proofGetRequestMsg module.exports.proofSerialize = proofSerialize module.exports.proofDeserialize = proofDeserialize module.exports.v2ProofUpdateState = v2ProofUpdateState module.exports.v2ProofUpdateStateWithMessage = v2ProofUpdateStateWithMessage +module.exports.proofUpdateStateWithMessageNonmediated = proofUpdateStateWithMessageNonmediated module.exports.proofGetState = proofGetState module.exports.proofGetProofState = proofGetProofState module.exports.proofGetThreadId = proofGetThreadId @@ -411,6 +420,8 @@ module.exports.schemaRelease = schemaRelease module.exports.schemaUpdateState = schemaUpdateState module.exports.schemaGetState = schemaGetState module.exports.enableMocks = enableMocks +module.exports.trustpingBuildResponseMsg = trustpingBuildResponseMsg +module.exports.trustpingBuildPing = trustpingBuildPing module.exports.shutdown = shutdown module.exports.getVersion = getVersion module.exports.walletOpenAsMain = walletOpenAsMain diff --git a/wrappers/vcx-napi-rs/package-lock.json b/wrappers/vcx-napi-rs/package-lock.json index e7a0dbb763..921f03c13c 100644 --- a/wrappers/vcx-napi-rs/package-lock.json +++ b/wrappers/vcx-napi-rs/package-lock.json @@ -19,9 +19,9 @@ } }, "node_modules/@napi-rs/cli": { - "version": "2.14.6", - "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.14.6.tgz", - "integrity": "sha512-q63+fI0JB9LV3RDYQN7yyAzmWDrErz+5ZMM1EyB5RA7ZwTTRYvXxg204w9+xTuZnpQfSyLMxxKGz2mfDVqFing==", + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.14.1.tgz", + "integrity": "sha512-+mnge6gvdbOrwtYrBO7iMlTjXcaRk17wDqzxSG4SPBKPhI3HroWY+tRsx+OdluAuRyJZOkWTdsvGnMsGO1ff/A==", "dev": true, "bin": { "napi": "scripts/index.js" @@ -41,9 +41,9 @@ "dev": true }, "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -56,9 +56,9 @@ }, "dependencies": { "@napi-rs/cli": { - "version": "2.14.6", - "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.14.6.tgz", - "integrity": "sha512-q63+fI0JB9LV3RDYQN7yyAzmWDrErz+5ZMM1EyB5RA7ZwTTRYvXxg204w9+xTuZnpQfSyLMxxKGz2mfDVqFing==", + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.14.1.tgz", + "integrity": "sha512-+mnge6gvdbOrwtYrBO7iMlTjXcaRk17wDqzxSG4SPBKPhI3HroWY+tRsx+OdluAuRyJZOkWTdsvGnMsGO1ff/A==", "dev": true }, "@types/node": { @@ -68,9 +68,9 @@ "dev": true }, "typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", "dev": true } } diff --git a/wrappers/vcx-napi-rs/src/api/connection.rs b/wrappers/vcx-napi-rs/src/api/connection.rs index e5f31afee6..3922b1d4a5 100644 --- a/wrappers/vcx-napi-rs/src/api/connection.rs +++ b/wrappers/vcx-napi-rs/src/api/connection.rs @@ -51,6 +51,12 @@ pub fn connection_get_remote_did(handle: u32) -> napi::Result { connection::get_remote_did(handle).map_err(to_napi_err) } +#[napi] +pub fn connection_get_remote_vk(handle: u32) -> napi::Result { + trace!("connection_get_remote_vk >>> handle: {:?}", handle); + connection::get_remote_vk(handle).map_err(to_napi_err) +} + #[napi] pub fn connection_get_state(handle: u32) -> napi::Result { trace!("connection_get_state >>> handle: {:?}", handle); @@ -98,6 +104,12 @@ pub async fn connection_process_ack(handle: u32, message: String) -> napi::Resul connection::process_ack(handle, &message).await.map_err(to_napi_err) } +#[napi] +pub fn connection_process_problem_report(handle: u32, problem_report: String) -> napi::Result<()> { + trace!("connection_process_problem_report >>> handle: {:?}", handle); + connection::process_problem_report(handle, &problem_report).map_err(to_napi_err) +} + #[napi] pub async fn connection_send_response(handle: u32) -> napi::Result<()> { trace!("connection_send_response >>> handle: {:?}", handle); diff --git a/wrappers/vcx-napi-rs/src/api/issuer_credential.rs b/wrappers/vcx-napi-rs/src/api/issuer_credential.rs index 9c990790a7..aa898aae8d 100644 --- a/wrappers/vcx-napi-rs/src/api/issuer_credential.rs +++ b/wrappers/vcx-napi-rs/src/api/issuer_credential.rs @@ -32,6 +32,17 @@ async fn issuer_credential_update_state_with_message_v2( .map_err(to_napi_err) } +#[napi] +async fn issuer_credential_update_state_with_message_nonmediated( + handle_credential: u32, + connection_handle: u32, + message: String, +) -> napi::Result { + issuer_credential::update_state_with_message_nonmediated(handle_credential, connection_handle, &message) + .await + .map_err(to_napi_err) +} + #[napi] fn issuer_credential_get_state(handle_credential: u32) -> napi::Result { issuer_credential::get_state(handle_credential).map_err(to_napi_err) @@ -66,6 +77,16 @@ async fn issuer_credential_send_credential(handle_credential: u32, handle_connec .map_err(to_napi_err) } +#[napi] +async fn issuer_credential_send_credential_nonmediated( + handle_credential: u32, + handle_connection: u32, +) -> napi::Result { + issuer_credential::send_credential_nonmediated(handle_credential, handle_connection) + .await + .map_err(to_napi_err) +} + #[napi] async fn issuer_credential_send_offer_v2(handle_credential: u32, handle_connection: u32) -> napi::Result<()> { issuer_credential::send_credential_offer_v2(handle_credential, handle_connection) @@ -74,6 +95,14 @@ async fn issuer_credential_send_offer_v2(handle_credential: u32, handle_connecti Ok(()) } +#[napi] +async fn issuer_credential_send_offer_nonmediated(handle_credential: u32, handle_connection: u32) -> napi::Result<()> { + issuer_credential::send_credential_offer_nonmediated(handle_credential, handle_connection) + .await + .map_err(to_napi_err)?; + Ok(()) +} + #[napi] fn issuer_credential_mark_offer_msg_sent(handle_credential: u32) -> napi::Result<()> { issuer_credential::mark_credential_offer_msg_sent(handle_credential).map_err(to_napi_err) diff --git a/wrappers/vcx-napi-rs/src/api/mod.rs b/wrappers/vcx-napi-rs/src/api/mod.rs index 0d62c57be6..bb94976c21 100644 --- a/wrappers/vcx-napi-rs/src/api/mod.rs +++ b/wrappers/vcx-napi-rs/src/api/mod.rs @@ -8,6 +8,7 @@ pub mod issuer_credential; pub mod ledger; pub mod logging; pub mod mediated_connection; +pub mod out_of_band; pub mod out_of_band_receiver; pub mod out_of_band_sender; pub mod pool; @@ -15,5 +16,6 @@ pub mod proof; pub mod revocation_registry; pub mod schema; pub mod testing; +pub mod trustping; pub mod utils; pub mod wallet; diff --git a/wrappers/vcx-napi-rs/src/api/out_of_band.rs b/wrappers/vcx-napi-rs/src/api/out_of_band.rs new file mode 100644 index 0000000000..fa30e6e131 --- /dev/null +++ b/wrappers/vcx-napi-rs/src/api/out_of_band.rs @@ -0,0 +1,24 @@ +use napi_derive::napi; +use vcx::aries_vcx::messages::protocols::out_of_band::handshake_reuse::OutOfBandHandshakeReuse; +use vcx::aries_vcx::protocols::oob::build_handshake_reuse_accepted_msg; +use vcx::errors::error::{LibvcxError, LibvcxErrorKind}; +use vcx::serde_json; + +use crate::error::to_napi_err; + +#[napi] +pub fn out_of_band_build_handshake_reuse_accepted_msg(handshake_reuse: String) -> napi::Result { + let handshake_reuse = serde_json::from_str::(&handshake_reuse) + .map_err(|err| { + LibvcxError::from_msg( + LibvcxErrorKind::InvalidJson, + format!("Cannot deserialize handshake reuse: {:?}", err), + ) + }) + .map_err(to_napi_err)?; + Ok(serde_json::json!(build_handshake_reuse_accepted_msg(&handshake_reuse) + .map_err(|err| err.into()) + .map_err(to_napi_err)? + .to_a2a_message()) + .to_string()) +} diff --git a/wrappers/vcx-napi-rs/src/api/out_of_band_receiver.rs b/wrappers/vcx-napi-rs/src/api/out_of_band_receiver.rs index ff51a33c5d..522b3e0415 100644 --- a/wrappers/vcx-napi-rs/src/api/out_of_band_receiver.rs +++ b/wrappers/vcx-napi-rs/src/api/out_of_band_receiver.rs @@ -21,6 +21,17 @@ pub async fn out_of_band_receiver_connection_exists(handle: u32, conn_handles: V .map_err(to_napi_err) } +#[napi] +pub async fn out_of_band_receiver_nonmediated_connection_exists( + handle: u32, + conn_handles: Vec, +) -> napi::Result { + out_of_band::nonmediated_connection_exists(handle, &conn_handles) + .await + .map(|res| res.0) + .map_err(to_napi_err) +} + #[napi] pub async fn out_of_band_receiver_build_connection(handle: u32) -> napi::Result { out_of_band::build_connection(handle).await.map_err(to_napi_err) diff --git a/wrappers/vcx-napi-rs/src/api/proof.rs b/wrappers/vcx-napi-rs/src/api/proof.rs index 264166cadc..6cb81b7d41 100644 --- a/wrappers/vcx-napi-rs/src/api/proof.rs +++ b/wrappers/vcx-napi-rs/src/api/proof.rs @@ -40,6 +40,13 @@ async fn proof_send_request(handle_proof: u32, handle_connection: u32) -> napi:: .map_err(to_napi_err) } +#[napi] +async fn proof_send_request_nonmediated(handle_proof: u32, handle_connection: u32) -> napi::Result<()> { + proof::send_proof_request_nonmediated(handle_proof, handle_connection) + .await + .map_err(to_napi_err) +} + #[napi] fn proof_get_request_msg(handle: u32) -> napi::Result { proof::get_presentation_request_msg(handle).map_err(to_napi_err) @@ -74,6 +81,17 @@ async fn v2_proof_update_state_with_message( .map_err(to_napi_err) } +#[napi] +async fn proof_update_state_with_message_nonmediated( + handle_proof: u32, + connection_handle: u32, + message: String, +) -> napi::Result { + proof::update_state_nonmediated(handle_proof, connection_handle, &message) + .await + .map_err(to_napi_err) +} + #[napi] fn proof_get_state(handle: u32) -> napi::Result { proof::get_state(handle).map_err(to_napi_err) diff --git a/wrappers/vcx-napi-rs/src/api/trustping.rs b/wrappers/vcx-napi-rs/src/api/trustping.rs new file mode 100644 index 0000000000..b85b716f21 --- /dev/null +++ b/wrappers/vcx-napi-rs/src/api/trustping.rs @@ -0,0 +1,26 @@ +use napi_derive::napi; + +use vcx::aries_vcx::messages::protocols::trust_ping::ping::Ping; +use vcx::aries_vcx::protocols::trustping; +use vcx::errors::error::{LibvcxError, LibvcxErrorKind}; +use vcx::serde_json; + +use crate::error::to_napi_err; + +#[napi] +fn trustping_build_response_msg(ping: String) -> napi::Result { + let ping = serde_json::from_str::(&ping) + .map_err(|err| { + LibvcxError::from_msg( + LibvcxErrorKind::InvalidJson, + format!("Cannot deserialize Ping: {:?}", err), + ) + }) + .map_err(to_napi_err)?; + Ok(serde_json::json!(trustping::build_ping_response_msg(&ping)).to_string()) +} + +#[napi] +fn trustping_build_ping(request_response: bool, comment: Option) -> String { + serde_json::json!(trustping::build_ping(request_response, comment)).to_string() +} From 98e4a50d5f983ed2189ff21183e39867833990ad Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Tue, 7 Feb 2023 14:16:40 +0200 Subject: [PATCH 52/66] Unexposed internal OOB method Signed-off-by: Bogdan Mircea --- .../src/handlers/out_of_band/receiver.rs | 2 +- ...Q6Ef6E2LQQb85jb8kATZPHTZwiKBsCC9PAPtr5kbQx | Bin 642 -> 0 bytes ...534m78fJiVNAj2q1qBxQPKjmNPhXYjrJyNXLsRP44M | Bin 642 -> 0 bytes ...kgu2n6Vu6kPygbNj8z5vxV722opVxnFx7waHRDUcKK | Bin 642 -> 0 bytes ...EM3wbxe1x4GoaX3xyyts6MSDs1ixyYmTQKkE4b7PQ1 | Bin 642 -> 0 bytes ...pMG1o8JK4tkcVyryFuJ73RZ4gShjwEjfNVGccRCckZ | Bin 642 -> 0 bytes ...PW4UTEAXfPJJkszuBkFxvEGNzEF9bp44WCpHcab5K1 | Bin 642 -> 0 bytes wrappers/node/package-lock.json | 1397 +++++++++++++---- wrappers/vcx-napi-rs/index.d.ts | 2 +- wrappers/vcx-napi-rs/package-lock.json | 36 +- 10 files changed, 1086 insertions(+), 351 deletions(-) delete mode 100644 aries_vcx/tails.txt/3KQ6Ef6E2LQQb85jb8kATZPHTZwiKBsCC9PAPtr5kbQx delete mode 100644 aries_vcx/tails.txt/5b534m78fJiVNAj2q1qBxQPKjmNPhXYjrJyNXLsRP44M delete mode 100644 aries_vcx/tails.txt/Azkgu2n6Vu6kPygbNj8z5vxV722opVxnFx7waHRDUcKK delete mode 100644 aries_vcx/tails.txt/BpEM3wbxe1x4GoaX3xyyts6MSDs1ixyYmTQKkE4b7PQ1 delete mode 100644 aries_vcx/tails.txt/HcpMG1o8JK4tkcVyryFuJ73RZ4gShjwEjfNVGccRCckZ delete mode 100644 aries_vcx/tails.txt/HfPW4UTEAXfPJJkszuBkFxvEGNzEF9bp44WCpHcab5K1 diff --git a/aries_vcx/src/handlers/out_of_band/receiver.rs b/aries_vcx/src/handlers/out_of_band/receiver.rs index 16a3d74754..5e801d7e68 100644 --- a/aries_vcx/src/handlers/out_of_band/receiver.rs +++ b/aries_vcx/src/handlers/out_of_band/receiver.rs @@ -84,7 +84,7 @@ impl OutOfBandReceiver { None } - pub async fn connection_matches_service( + async fn connection_matches_service( profile: &Arc, connection: &GenericConnection, service: &ServiceOob, diff --git a/aries_vcx/tails.txt/3KQ6Ef6E2LQQb85jb8kATZPHTZwiKBsCC9PAPtr5kbQx b/aries_vcx/tails.txt/3KQ6Ef6E2LQQb85jb8kATZPHTZwiKBsCC9PAPtr5kbQx deleted file mode 100644 index fc8be8192083b1835ed8bda13510c70ee647fba8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 642 zcmV-|0)71e0tSUxTmdI~jrsCCgpArkKExM&r9nm*xpC)w+Aw=lLkB)Gf%C(tl&GDe zv#Cq%zfV|HKS2T86N?}9YC}OE(hWKnnqCf`W20Wx;S6>cn`9h4gL@vdVbvz!_G2W9 zrx$QKbbo?+pC|w($$>EQ*CHnN%^6 zc_qFm>B&kpR!kt7 zLspa<_uVw5oB^PJ@7&&({-tGI ztUzfA=m?qL459hQJHoHd@1ZD4HYzA@?Dh&!Lg8Yy=B;o9+TrV41Vg~W788+vivjS><_l$ zD23(8vP*57YYWLV8ILG#6gXF>uU!=whr3pgAxYRJS@-JYQtUfUoRSpt6kY7B3H<^3lCTJVjs)DZ89Cg cr*(tSDN?M8c;+p$hAL%J;ZwIypWnE(I) diff --git a/aries_vcx/tails.txt/5b534m78fJiVNAj2q1qBxQPKjmNPhXYjrJyNXLsRP44M b/aries_vcx/tails.txt/5b534m78fJiVNAj2q1qBxQPKjmNPhXYjrJyNXLsRP44M deleted file mode 100644 index f579ee4b69173fcef4c4d6b43f7f06359f0b51d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 642 zcmV-|0)71e0tM)I#t=+vs9~3sYYQd8fN%I$6EDY_*MC<|Zp(MU5*3q-V z*qHGBN6^IlLyxDFs>;;UO?&Dw6dVatF-vrOOnSD$n4}?U!;uITL1l|5_lYa4R;$2% zQ53nCWD^qE#Fa54Xsa*TDqo_9kc}iLeC!!?uR113%>w(4wTiM4DO3W}3C1)yIxngH ze2D=HlVEj5ra?=Zwi^VV3DZpn=XO2UyJ`|WrtlUQG36n!Eh&bd_eAJN!6eDFe7G#B zVzL1`D#C3+Azy8-P`8L(C|GA;3mm*VP7&RGqc5xO_8ec;YM(rHT}U5==^;$QG*DAy zh9F*RmI60@Szgi4C4FA4Ox48b{H1aX5ybH?BfMn8uTgFvh#{0VhNqwDBF=!5QSR*M zera9p1P}Qvg`$hUlGx)XZD*d5A$VURqmhZ9w7So0?WZ%&= ziL;}#V3aDe&KxZu8SbD_2|S?>ipIjRyPszM7C=m&ii00;jHOKy5`$3 zTPSafuTJ3h3H6{%h_Bc|HEtytK?kC7%TzD~Hh`Xj%?hHyujO$B4GB#lG6nIPkHE1O zYXFQ$C*J>ktW&=#mqaJ`wpZWd(u52WLUnAKdRht(Zy!WEEzF c>TVYZ6q;m2F*CN+V#g#u&EhZNW%DF30TBx>^8f$< diff --git a/aries_vcx/tails.txt/Azkgu2n6Vu6kPygbNj8z5vxV722opVxnFx7waHRDUcKK b/aries_vcx/tails.txt/Azkgu2n6Vu6kPygbNj8z5vxV722opVxnFx7waHRDUcKK deleted file mode 100644 index 2f4ab85243e34ba5a9a860d29728fde4577a8541..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 642 zcmV-|0)71e0t}29{bb^pkV$dXM&qqR*CMwL%;VrRtoAIiVdwd%76}jiLnZ1OBStnb z*3UXz*r8fW{GSKtTbBi>kX_yg|3ZHHSC$CVj)(G>{nTlIlW3SKeg#T{Y>@0>@VhS{Lv+&FZ4Jwd^? z53A^x@TE-doDB=ds0mk@c`=|aQKt(S!dk0MCyyd8Pawvu!lNO1rdXm@M;!#!|KpMs zN2B(ozO6mU{(<46>B-^z`rFe4m-;@0jRt89S3M(c%!;a3md<*52E07!rs+{7`l8yZ z*9YJf$_N4{I!F@}B&Uq|rP0}BJ5$=GBjJZ-+58V|^+-VFgauUMN^D!r&)45k?INff z>1nFo7nQ>lSmq{F@tjQ=yA_hvqdz~$-E&a~&oS`T^kJB2;n*#VE(`O^{9H*rr6J5P zNgAK3EG%9l0SsnmUe$qmo}8mESWb{V*fxo*h8-Afx$uv@^WtLqm~Bn1UNS*2|jtf&hw zxWuCZ#@yV306`@Oi@E+LHs^dhHwWLehB|cEa@3&!uT3fk`d<@}=@{4g16opCP*m;& zr4G;}i0rr>duuc4-*b|mVr(aVT9CX7(td!#Fo%>xJ|X-@ct5*zI5~aXffKzoIqzxi zV=0Pz+WC^oOnJevff_6TD5ue!FdTu9b#jrWsBRWAwcuRKff6q0d}Qvt>L4a5+3)-$ cI!b1PiP3sYxUBEqqL)1w^K|!z)c}*tdEg^Ct^fc4 diff --git a/aries_vcx/tails.txt/BpEM3wbxe1x4GoaX3xyyts6MSDs1ixyYmTQKkE4b7PQ1 b/aries_vcx/tails.txt/BpEM3wbxe1x4GoaX3xyyts6MSDs1ixyYmTQKkE4b7PQ1 deleted file mode 100644 index 7cd79962d326a5a16e3fd30cc3f043b4d7364293..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 642 zcmV-|0)71e0v3bzQ|55Kx9t1)gd8YCS-r&}IW!QRX)szh00o%vG6H>=Dn6FAY%Z6q z8IlT1)qfgJ)f~wO;&R5rm}|m|O$CFNxC#{lKQM#(hwm)c6OM;Jh%u&?6lIVlVSYML z=mjy4f+5)4U5|eT6k5o2`_Uc~^&vH?0&aL;Nhu1Q1S9l>LX`|ek#79kzIU~^_m637 zt4ixJvS^#Ju_9TYHyMOU6VD;uoc3JnI;NPSKVyTmX21^|y|GN7KW6PmlOZNe!jM!h zzut98Ye;6yAv=XL0UhPLQ7yIc;u-wNWd)n%*GKD`i^)Y|>)SgNs>-%h9P*hbc^tqjwS95K;4b?B0@-l#2&b z3R9Z`h4=djP!+53hBYK*zHZ2^GptMJ4X{PmV|?(N3TU`oU)qEBI3(Shj}VT8ee{>K zXbwL1RC^jerqZ0v_zYa;G6NhgrXdKpp31}a>8cp=q)j}Mzo*`n#E`i%TZe&5*Cx{6 zR~bUT4zE^0pw{Uyuka&{5>DkrLJL7jG9*$1?ME4rh8YWdsq|I(FI`bkcmiDyZ|dfe zYYzF$Z}3OQk;VieW*sa~dI|DXEBOwR0f;dz9>_csG3qT#NtM_955k5+&>ff0$guNK c3C*E^LFUQA>vpVb#x{j^OT;X3y8uen36(G{8~^|S diff --git a/aries_vcx/tails.txt/HcpMG1o8JK4tkcVyryFuJ73RZ4gShjwEjfNVGccRCckZ b/aries_vcx/tails.txt/HcpMG1o8JK4tkcVyryFuJ73RZ4gShjwEjfNVGccRCckZ deleted file mode 100644 index ad8392d01b6729841e90175776e0fa6baaab7d40..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 642 zcmV-|0)71e0vvplos)83T9ct$&MiK;3EB_-*y@c8h6n~F9*drPK<=5zu8%8SQKRVW<@fT-`wKPqw zQUb(bF|`X!I>BH=ahoND()*1xvlN`rQy&d(%*C#NyCw!}NHqTY;LS0;sQ)^@QAGK! zRaV%G&lpzn+xU|{QjZvEtXL+-MDdh?Sw`Q^05Q|^1;OG!4jluiL+Ls}KZMF(frZqw zePPxWXzOG+{;||)nduQ7-Up#FMl%NtSRpgNikt|VU{1-f;84l7J?rsNWZ)*`Js&)z z382$|V>hZM(-T{qQ8KH~c%s8EK z5K#d?JgZvL_6;7bKtH{7H{cqP7%V|Jn4xuZ(Sm5>7eccChs)$Oz?Z+;v>G4%Y!cwnO0^pQWe{RE@KSt z%T=FpTMmXkcVHy0Iv0c|%B%mEOk0pUt-iSuG2~Qxu}kHyxhf5Jk3I)j0lV-BcXxe zgp*%7L8Vp?nHv7F2Q3`vGqE;e0|ShPf8;QX;GprB@vd*bJtsU&66c1Qd4;$={*Rz&#tI1GXw=8+h z^e1tugm9=*{IE^g6G!Z!aTA*{+<^`NaKw_j_7-G_%hv45^ti9(g22^IRWv? zP%A<^3fwU0zIw(esS~!kt&uH03|r3?$`JT(Ko+!J=B*6y`Dyt3H&)mxXD8Y=DP*mr zFD`wmb(FKt;tG9F)uX;StTHkmg1lFq3=xL+xksi!8ZCTdk%@w^8x*AY{f0)!@kpO# ze3UMDpEv|BfJcj*7l11gzD-i z!~j!mt; ceHKYPk%Tt{-$awP4B%sMhfBWKnCS^E+7@0kB>(^b diff --git a/wrappers/node/package-lock.json b/wrappers/node/package-lock.json index 3016882f3f..20bd644c6c 100644 --- a/wrappers/node/package-lock.json +++ b/wrappers/node/package-lock.json @@ -40,7 +40,6 @@ } }, "../vcx-napi-rs": { - "name": "@hyperledger/vcx-napi-rs", "dev": true, "license": "Apache-2.0", "devDependencies": { @@ -57,24 +56,27 @@ }, "node_modules/@babel/code-frame": { "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/highlight": "^7.10.4" } }, "node_modules/@babel/helper-validator-identifier": { "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", @@ -86,8 +88,9 @@ }, "node_modules/@babel/highlight/node_modules/ansi-styles": { "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -97,8 +100,9 @@ }, "node_modules/@babel/highlight/node_modules/chalk": { "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -110,37 +114,42 @@ }, "node_modules/@babel/highlight/node_modules/color-convert": { "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "1.1.3" } }, "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/@babel/highlight/node_modules/has-flag": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/highlight/node_modules/supports-color": { "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -150,8 +159,9 @@ }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -161,8 +171,9 @@ }, "node_modules/@eslint/eslintrc": { "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "dev": true, - "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.1.1", @@ -180,16 +191,18 @@ }, "node_modules/@eslint/eslintrc/node_modules/ignore": { "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/@humanwhocodes/config-array": { "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@humanwhocodes/object-schema": "^1.2.0", "debug": "^4.1.1", @@ -201,8 +214,9 @@ }, "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", - "dev": true, - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true }, "node_modules/@hyperledger/vcx-napi-rs": { "resolved": "../vcx-napi-rs", @@ -210,21 +224,24 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.14", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -232,8 +249,9 @@ }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, - "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -244,16 +262,18 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, - "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, - "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -264,71 +284,84 @@ }, "node_modules/@tsconfig/node10": { "version": "1.0.9", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true }, "node_modules/@tsconfig/node12": { "version": "1.0.11", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true }, "node_modules/@tsconfig/node14": { "version": "1.0.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true }, "node_modules/@tsconfig/node16": { "version": "1.0.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true }, "node_modules/@types/app-module-path": { "version": "2.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/app-module-path/-/app-module-path-2.2.0.tgz", + "integrity": "sha512-r47Kt3ApJDzUU2xCNzaBI25Au5Xfdvf0Gyomveqvg46nQ3J4PaDLicObhyX6cMhvMVWJMB/BnkXdv1E4zxP+6w==", + "dev": true }, "node_modules/@types/chai": { "version": "4.3.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz", + "integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==", + "dev": true }, "node_modules/@types/json-schema": { "version": "7.0.11", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true }, "node_modules/@types/lodash": { - "version": "4.14.188", - "dev": true, - "license": "MIT" + "version": "4.14.191", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", + "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==", + "dev": true }, "node_modules/@types/mocha": { "version": "8.2.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", + "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", + "dev": true }, "node_modules/@types/node": { "version": "12.20.55", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true }, "node_modules/@types/uuid": { "version": "8.3.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", + "dev": true }, "node_modules/@types/weak-napi": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/weak-napi/-/weak-napi-1.0.1.tgz", + "integrity": "sha512-EqTeT7n+f6uxfLFRDcJEOu12dH0AT2fZlb8MTQKDG8E70T7uP//qG4CMdNKV3Ra/cxG7/Z1i04GT7Ll0QriWvQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", + "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", "dev": true, - "license": "MIT", "dependencies": { "@typescript-eslint/experimental-utils": "4.33.0", "@typescript-eslint/scope-manager": "4.33.0", @@ -358,8 +391,9 @@ }, "node_modules/@typescript-eslint/experimental-utils": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", + "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", "dev": true, - "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.7", "@typescript-eslint/scope-manager": "4.33.0", @@ -381,8 +415,9 @@ }, "node_modules/@typescript-eslint/parser": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", + "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/scope-manager": "4.33.0", "@typescript-eslint/types": "4.33.0", @@ -407,8 +442,9 @@ }, "node_modules/@typescript-eslint/scope-manager": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", + "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", "dev": true, - "license": "MIT", "dependencies": { "@typescript-eslint/types": "4.33.0", "@typescript-eslint/visitor-keys": "4.33.0" @@ -423,8 +459,9 @@ }, "node_modules/@typescript-eslint/types": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", + "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", "dev": true, - "license": "MIT", "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" }, @@ -435,8 +472,9 @@ }, "node_modules/@typescript-eslint/typescript-estree": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", + "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/types": "4.33.0", "@typescript-eslint/visitor-keys": "4.33.0", @@ -461,8 +499,9 @@ }, "node_modules/@typescript-eslint/visitor-keys": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", + "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", "dev": true, - "license": "MIT", "dependencies": { "@typescript-eslint/types": "4.33.0", "eslint-visitor-keys": "^2.0.0" @@ -477,13 +516,15 @@ }, "node_modules/@ungap/promise-all-settled": { "version": "1.1.2", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true }, "node_modules/acorn": { "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true, - "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -493,24 +534,27 @@ }, "node_modules/acorn-jsx": { "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/acorn-walk": { "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/ajv": { "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -524,24 +568,27 @@ }, "node_modules/ansi-colors": { "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/ansi-regex": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -553,9 +600,10 @@ } }, "node_modules/anymatch": { - "version": "3.1.2", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, - "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -566,63 +614,72 @@ }, "node_modules/app-module-path": { "version": "2.2.0", - "dev": true, - "license": "BSD-2-Clause" + "resolved": "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz", + "integrity": "sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ==", + "dev": true }, "node_modules/arg": { "version": "4.1.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true }, "node_modules/argparse": { "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, - "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } }, "node_modules/array-union": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/assertion-error": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true, - "license": "MIT", "engines": { "node": "*" } }, "node_modules/astral-regex": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/balanced-match": { "version": "1.0.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "node_modules/binary-extensions": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/brace-expansion": { "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -630,8 +687,9 @@ }, "node_modules/braces": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, - "license": "MIT", "dependencies": { "fill-range": "^7.0.1" }, @@ -641,21 +699,24 @@ }, "node_modules/browser-stdout": { "version": "1.3.1", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true }, "node_modules/callsites": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/camelcase": { "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -665,8 +726,9 @@ }, "node_modules/chai": { "version": "4.3.7", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", + "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", "dev": true, - "license": "MIT", "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.2", @@ -682,8 +744,9 @@ }, "node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -697,14 +760,17 @@ }, "node_modules/check-error": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", "dev": true, - "license": "MIT", "engines": { "node": "*" } }, "node_modules/chokidar": { "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "funding": [ { @@ -712,7 +778,6 @@ "url": "https://paulmillr.com/funding/" } ], - "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -731,8 +796,9 @@ }, "node_modules/cliui": { "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, - "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -741,8 +807,9 @@ }, "node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -752,23 +819,27 @@ }, "node_modules/color-name": { "version": "1.1.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/concat-map": { "version": "0.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true }, "node_modules/create-require": { "version": "1.1.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true }, "node_modules/cross-spawn": { "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, - "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -780,8 +851,9 @@ }, "node_modules/debug": { "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, - "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -796,8 +868,9 @@ }, "node_modules/decamelize": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -806,9 +879,10 @@ } }, "node_modules/deep-eql": { - "version": "4.1.2", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", "dev": true, - "license": "MIT", "dependencies": { "type-detect": "^4.0.0" }, @@ -818,21 +892,24 @@ }, "node_modules/deep-is": { "version": "0.1.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true }, "node_modules/diff": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/dir-glob": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, - "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -842,8 +919,9 @@ }, "node_modules/doctrine": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, - "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -853,13 +931,15 @@ }, "node_modules/emoji-regex": { "version": "8.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/enquirer": { "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", "dev": true, - "license": "MIT", "dependencies": { "ansi-colors": "^4.1.1" }, @@ -869,16 +949,18 @@ }, "node_modules/escalade": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/escape-string-regexp": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -888,8 +970,9 @@ }, "node_modules/eslint": { "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.4.3", @@ -944,8 +1027,9 @@ }, "node_modules/eslint-config-prettier": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-7.2.0.tgz", + "integrity": "sha512-rV4Qu0C3nfJKPOAhFujFxB7RMP+URFyQqqOZW9DMRD7ZDTFyjaIlETU3xzHELt++4ugC0+Jm084HQYkkJe+Ivg==", "dev": true, - "license": "MIT", "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -955,8 +1039,9 @@ }, "node_modules/eslint-plugin-prettier": { "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", + "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", "dev": true, - "license": "MIT", "dependencies": { "prettier-linter-helpers": "^1.0.0" }, @@ -975,8 +1060,9 @@ }, "node_modules/eslint-scope": { "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -987,8 +1073,9 @@ }, "node_modules/eslint-utils": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, - "license": "MIT", "dependencies": { "eslint-visitor-keys": "^2.0.0" }, @@ -1004,16 +1091,18 @@ }, "node_modules/eslint-visitor-keys": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=10" } }, "node_modules/eslint/node_modules/eslint-utils": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, - "license": "MIT", "dependencies": { "eslint-visitor-keys": "^1.1.0" }, @@ -1026,24 +1115,27 @@ }, "node_modules/eslint/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=4" } }, "node_modules/eslint/node_modules/ignore": { "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/espree": { "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "acorn": "^7.4.0", "acorn-jsx": "^5.3.1", @@ -1055,16 +1147,18 @@ }, "node_modules/espree/node_modules/eslint-visitor-keys": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=4" } }, "node_modules/esprima": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, - "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -1075,8 +1169,9 @@ }, "node_modules/esquery": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -1086,16 +1181,18 @@ }, "node_modules/esquery/node_modules/estraverse": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/esrecurse": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -1105,42 +1202,48 @@ }, "node_modules/esrecurse/node_modules/estraverse": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/estraverse": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/esutils": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true }, "node_modules/fast-diff": { "version": "1.2.0", - "dev": true, - "license": "Apache-2.0" + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true }, "node_modules/fast-glob": { "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, - "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -1154,26 +1257,30 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true }, "node_modules/fastq": { - "version": "1.13.0", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, - "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, "node_modules/file-entry-cache": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, - "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" }, @@ -1183,8 +1290,9 @@ }, "node_modules/fill-range": { "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, - "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -1194,8 +1302,9 @@ }, "node_modules/find-up": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, - "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -1209,16 +1318,18 @@ }, "node_modules/flat": { "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, - "license": "BSD-3-Clause", "bin": { "flat": "cli.js" } }, "node_modules/flat-cache": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, - "license": "MIT", "dependencies": { "flatted": "^3.1.0", "rimraf": "^3.0.2" @@ -1229,12 +1340,14 @@ }, "node_modules/flatted": { "version": "3.2.7", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true }, "node_modules/fs-extra": { "version": "4.0.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -1243,13 +1356,16 @@ }, "node_modules/fs.realpath": { "version": "1.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true }, "node_modules/fsevents": { "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, - "license": "MIT", + "hasInstallScript": true, "optional": true, "os": [ "darwin" @@ -1260,40 +1376,46 @@ }, "node_modules/functional-red-black-tree": { "version": "1.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true }, "node_modules/get-caller-file": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, - "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-func-name": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", "dev": true, - "license": "MIT", "engines": { "node": "*" } }, "node_modules/get-symbol-from-current-process-h": { "version": "1.0.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/get-symbol-from-current-process-h/-/get-symbol-from-current-process-h-1.0.2.tgz", + "integrity": "sha512-syloC6fsCt62ELLrr1VKBM1ggOpMdetX9hTrdW77UQdcApPHLmf7CI7OKcN1c9kYuNxKcDe4iJ4FY9sX3aw2xw==" }, "node_modules/get-uv-event-loop-napi-h": { "version": "1.0.6", - "license": "MIT", + "resolved": "https://registry.npmjs.org/get-uv-event-loop-napi-h/-/get-uv-event-loop-napi-h-1.0.6.tgz", + "integrity": "sha512-t5c9VNR84nRoF+eLiz6wFrEp1SE2Acg0wS+Ysa2zF0eROes+LzOfuTaVHxGy8AbS8rq7FHEJzjnCZo1BupwdJg==", "dependencies": { "get-symbol-from-current-process-h": "^1.0.1" } }, "node_modules/glob": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, - "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -1311,8 +1433,9 @@ }, "node_modules/glob-parent": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -1321,9 +1444,10 @@ } }, "node_modules/globals": { - "version": "13.17.0", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, - "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -1336,8 +1460,9 @@ }, "node_modules/globby": { "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, - "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -1355,44 +1480,50 @@ }, "node_modules/graceful-fs": { "version": "4.2.10", - "license": "ISC" + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "node_modules/growl": { "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true, - "license": "MIT", "engines": { "node": ">=4.x" } }, "node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/he": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, - "license": "MIT", "bin": { "he": "bin/he" } }, "node_modules/ignore": { - "version": "5.2.0", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true, - "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/import-fresh": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, - "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -1406,16 +1537,18 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.8.19" } }, "node_modules/inflight": { "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, - "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -1423,13 +1556,15 @@ }, "node_modules/inherits": { "version": "2.0.4", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "node_modules/is-binary-path": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, - "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -1439,24 +1574,27 @@ }, "node_modules/is-extglob": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-glob": { "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, - "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -1466,24 +1604,27 @@ }, "node_modules/is-number": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.12.0" } }, "node_modules/is-plain-obj": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-unicode-supported": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -1493,18 +1634,21 @@ }, "node_modules/isexe": { "version": "2.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, "node_modules/js-tokens": { "version": "4.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, "node_modules/js-yaml": { "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, - "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -1515,25 +1659,29 @@ }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true }, "node_modules/jsonfile": { "version": "4.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "node_modules/levn": { "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, - "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -1544,8 +1692,9 @@ }, "node_modules/locate-path": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, - "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -1558,22 +1707,26 @@ }, "node_modules/lodash": { "version": "4.17.21", - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "node_modules/lodash.merge": { "version": "4.6.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true }, "node_modules/lodash.truncate": { "version": "4.4.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true }, "node_modules/log-symbols": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, - "license": "MIT", "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -1587,16 +1740,18 @@ }, "node_modules/loupe": { "version": "2.3.6", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", + "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", "dev": true, - "license": "MIT", "dependencies": { "get-func-name": "^2.0.0" } }, "node_modules/lru-cache": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, - "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -1606,21 +1761,24 @@ }, "node_modules/make-error": { "version": "1.3.6", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true }, "node_modules/merge2": { "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/micromatch": { "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, - "license": "MIT", "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -1631,8 +1789,9 @@ }, "node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1642,8 +1801,9 @@ }, "node_modules/mocha": { "version": "9.2.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", + "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", "dev": true, - "license": "MIT", "dependencies": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", @@ -1684,21 +1844,24 @@ }, "node_modules/mocha/node_modules/ansi-colors": { "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/mocha/node_modules/argparse": { "version": "2.0.1", - "dev": true, - "license": "Python-2.0" + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "node_modules/mocha/node_modules/debug": { "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, - "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -1713,13 +1876,15 @@ }, "node_modules/mocha/node_modules/debug/node_modules/ms": { "version": "2.1.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "node_modules/mocha/node_modules/js-yaml": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -1729,8 +1894,9 @@ }, "node_modules/mocha/node_modules/minimatch": { "version": "4.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", + "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1740,13 +1906,15 @@ }, "node_modules/mocha/node_modules/ms": { "version": "2.1.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true }, "node_modules/mocha/node_modules/supports-color": { "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -1759,13 +1927,15 @@ }, "node_modules/ms": { "version": "2.1.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "node_modules/nanoid": { "version": "3.3.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", + "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", "dev": true, - "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -1775,16 +1945,19 @@ }, "node_modules/natural-compare": { "version": "1.4.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true }, "node_modules/node-addon-api": { "version": "3.2.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" }, "node_modules/node-gyp-build": { - "version": "4.5.0", - "license": "MIT", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", + "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", @@ -1793,24 +1966,27 @@ }, "node_modules/normalize-path": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/once": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, - "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/optionator": { "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, - "license": "MIT", "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -1825,8 +2001,9 @@ }, "node_modules/p-limit": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, - "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -1839,8 +2016,9 @@ }, "node_modules/p-locate": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, - "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -1853,8 +2031,9 @@ }, "node_modules/parent-module": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, - "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -1864,48 +2043,54 @@ }, "node_modules/path-exists": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/path-key": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-type": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/pathval": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true, - "license": "MIT", "engines": { "node": "*" } }, "node_modules/picomatch": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8.6" }, @@ -1915,16 +2100,18 @@ }, "node_modules/prelude-ls": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.8.0" } }, "node_modules/prettier": { - "version": "2.7.1", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz", + "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==", "dev": true, - "license": "MIT", "bin": { "prettier": "bin-prettier.js" }, @@ -1937,8 +2124,9 @@ }, "node_modules/prettier-linter-helpers": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, - "license": "MIT", "dependencies": { "fast-diff": "^1.1.2" }, @@ -1948,22 +2136,26 @@ }, "node_modules/progress": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/punycode": { - "version": "2.1.1", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/queue-microtask": { "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, "funding": [ { @@ -1978,21 +2170,22 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/randombytes": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, - "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } }, "node_modules/readdirp": { "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, - "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -2002,8 +2195,9 @@ }, "node_modules/regexpp": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" }, @@ -2013,32 +2207,36 @@ }, "node_modules/require-directory": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/require-from-string": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/resolve-from": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/reusify": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, - "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -2046,8 +2244,9 @@ }, "node_modules/rimraf": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, - "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -2060,6 +2259,8 @@ }, "node_modules/run-parallel": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { @@ -2075,13 +2276,14 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } }, "node_modules/safe-buffer": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { @@ -2096,13 +2298,13 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/semver": { "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, - "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -2115,15 +2317,17 @@ }, "node_modules/serialize-javascript": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } }, "node_modules/setimmediate-napi": { "version": "1.0.6", - "license": "MIT", + "resolved": "https://registry.npmjs.org/setimmediate-napi/-/setimmediate-napi-1.0.6.tgz", + "integrity": "sha512-sdNXN15Av1jPXuSal4Mk4tEAKn0+8lfF9Z50/negaQMrAIO9c1qM0eiCh8fT6gctp0RiCObk+6/Xfn5RMGdZoA==", "dependencies": { "get-symbol-from-current-process-h": "^1.0.1", "get-uv-event-loop-napi-h": "^1.0.5" @@ -2131,8 +2335,9 @@ }, "node_modules/shebang-command": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -2142,24 +2347,27 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/slash": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/slice-ansi": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -2174,13 +2382,15 @@ }, "node_modules/sprintf-js": { "version": "1.0.3", - "dev": true, - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true }, "node_modules/string-width": { "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -2192,8 +2402,9 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -2203,8 +2414,9 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" }, @@ -2214,8 +2426,9 @@ }, "node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -2225,8 +2438,9 @@ }, "node_modules/table": { "version": "6.8.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "ajv": "^8.0.1", "lodash.truncate": "^4.4.2", @@ -2239,9 +2453,10 @@ } }, "node_modules/table/node_modules/ajv": { - "version": "8.11.0", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -2255,18 +2470,21 @@ }, "node_modules/table/node_modules/json-schema-traverse": { "version": "1.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true }, "node_modules/text-table": { "version": "0.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true }, "node_modules/to-regex-range": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -2276,8 +2494,9 @@ }, "node_modules/ts-node": { "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, - "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -2317,9 +2536,10 @@ } }, "node_modules/ts-node/node_modules/acorn": { - "version": "8.8.1", + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "dev": true, - "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -2329,21 +2549,24 @@ }, "node_modules/ts-node/node_modules/diff": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/tslib": { "version": "1.14.1", - "dev": true, - "license": "0BSD" + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true }, "node_modules/tsutils": { "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, - "license": "MIT", "dependencies": { "tslib": "^1.8.1" }, @@ -2356,8 +2579,9 @@ }, "node_modules/type-check": { "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, - "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -2367,16 +2591,18 @@ }, "node_modules/type-detect": { "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/type-fest": { "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, - "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -2385,9 +2611,10 @@ } }, "node_modules/typescript": { - "version": "4.8.4", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, - "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -2398,40 +2625,46 @@ }, "node_modules/universalify": { "version": "0.1.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "engines": { "node": ">= 4.0.0" } }, "node_modules/uri-js": { "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } }, "node_modules/uuid": { "version": "8.3.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/v8-compile-cache": { "version": "2.3.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true }, "node_modules/weak-napi": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/weak-napi/-/weak-napi-2.0.2.tgz", + "integrity": "sha512-LcOSVFrghtVXf4QH+DLIy8iPiCktV7lVbqRDYP+bDPpLzC41RCHQPMyQOnPpWO41Ie4CmnDxS+mbL72r5xFMMQ==", "hasInstallScript": true, - "license": "MIT", "dependencies": { "node-addon-api": "^3.0.0", "node-gyp-build": "^4.2.1", @@ -2440,8 +2673,9 @@ }, "node_modules/which": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -2454,21 +2688,24 @@ }, "node_modules/word-wrap": { "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/workerpool": { "version": "6.2.0", - "dev": true, - "license": "Apache-2.0" + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "dev": true }, "node_modules/wrap-ansi": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -2483,26 +2720,30 @@ }, "node_modules/wrappy": { "version": "1.0.2", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true }, "node_modules/y18n": { "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, - "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yallist": { "version": "4.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "node_modules/yargs": { "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, - "license": "MIT", "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -2518,16 +2759,18 @@ }, "node_modules/yargs-parser": { "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", "dev": true, - "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yargs-unparser": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, - "license": "MIT", "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", @@ -2540,16 +2783,18 @@ }, "node_modules/yn": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/yocto-queue": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -2561,6 +2806,8 @@ "dependencies": { "@babel/code-frame": { "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { "@babel/highlight": "^7.10.4" @@ -2568,10 +2815,14 @@ }, "@babel/helper-validator-identifier": { "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "dev": true }, "@babel/highlight": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.18.6", @@ -2581,6 +2832,8 @@ "dependencies": { "ansi-styles": { "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { "color-convert": "^1.9.0" @@ -2588,6 +2841,8 @@ }, "chalk": { "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -2597,6 +2852,8 @@ }, "color-convert": { "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "requires": { "color-name": "1.1.3" @@ -2604,18 +2861,26 @@ }, "color-name": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "escape-string-regexp": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true }, "has-flag": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, "supports-color": { "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -2625,6 +2890,8 @@ }, "@cspotcode/source-map-support": { "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, "requires": { "@jridgewell/trace-mapping": "0.3.9" @@ -2632,6 +2899,8 @@ }, "@eslint/eslintrc": { "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -2647,12 +2916,16 @@ "dependencies": { "ignore": { "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true } } }, "@humanwhocodes/config-array": { "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.0", @@ -2662,6 +2935,8 @@ }, "@humanwhocodes/object-schema": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, "@hyperledger/vcx-napi-rs": { @@ -2678,14 +2953,20 @@ }, "@jridgewell/resolve-uri": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "dev": true }, "@jridgewell/sourcemap-codec": { "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", "dev": true }, "@jridgewell/trace-mapping": { "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, "requires": { "@jridgewell/resolve-uri": "^3.0.3", @@ -2694,6 +2975,8 @@ }, "@nodelib/fs.scandir": { "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "requires": { "@nodelib/fs.stat": "2.0.5", @@ -2702,10 +2985,14 @@ }, "@nodelib/fs.stat": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true }, "@nodelib/fs.walk": { "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "requires": { "@nodelib/fs.scandir": "2.1.5", @@ -2714,50 +3001,74 @@ }, "@tsconfig/node10": { "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", "dev": true }, "@tsconfig/node12": { "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", "dev": true }, "@tsconfig/node14": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", "dev": true }, "@tsconfig/node16": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "dev": true }, "@types/app-module-path": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@types/app-module-path/-/app-module-path-2.2.0.tgz", + "integrity": "sha512-r47Kt3ApJDzUU2xCNzaBI25Au5Xfdvf0Gyomveqvg46nQ3J4PaDLicObhyX6cMhvMVWJMB/BnkXdv1E4zxP+6w==", "dev": true }, "@types/chai": { "version": "4.3.4", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz", + "integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==", "dev": true }, "@types/json-schema": { "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, "@types/lodash": { - "version": "4.14.188", + "version": "4.14.191", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", + "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==", "dev": true }, "@types/mocha": { "version": "8.2.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", + "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", "dev": true }, "@types/node": { "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", "dev": true }, "@types/uuid": { "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", "dev": true }, "@types/weak-napi": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/weak-napi/-/weak-napi-1.0.1.tgz", + "integrity": "sha512-EqTeT7n+f6uxfLFRDcJEOu12dH0AT2fZlb8MTQKDG8E70T7uP//qG4CMdNKV3Ra/cxG7/Z1i04GT7Ll0QriWvQ==", "dev": true, "requires": { "@types/node": "*" @@ -2765,6 +3076,8 @@ }, "@typescript-eslint/eslint-plugin": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", + "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", "dev": true, "requires": { "@typescript-eslint/experimental-utils": "4.33.0", @@ -2779,6 +3092,8 @@ }, "@typescript-eslint/experimental-utils": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", + "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", "dev": true, "requires": { "@types/json-schema": "^7.0.7", @@ -2791,6 +3106,8 @@ }, "@typescript-eslint/parser": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", + "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", "dev": true, "requires": { "@typescript-eslint/scope-manager": "4.33.0", @@ -2801,6 +3118,8 @@ }, "@typescript-eslint/scope-manager": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", + "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", "dev": true, "requires": { "@typescript-eslint/types": "4.33.0", @@ -2809,10 +3128,14 @@ }, "@typescript-eslint/types": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", + "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", "dev": true }, "@typescript-eslint/typescript-estree": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", + "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", "dev": true, "requires": { "@typescript-eslint/types": "4.33.0", @@ -2826,6 +3149,8 @@ }, "@typescript-eslint/visitor-keys": { "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", + "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", "dev": true, "requires": { "@typescript-eslint/types": "4.33.0", @@ -2834,23 +3159,33 @@ }, "@ungap/promise-all-settled": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", "dev": true }, "acorn": { "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true }, "acorn-jsx": { "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "requires": {} }, "acorn-walk": { "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true }, "ajv": { "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -2861,21 +3196,29 @@ }, "ansi-colors": { "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true }, "ansi-regex": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { "color-convert": "^2.0.1" } }, "anymatch": { - "version": "3.1.2", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -2884,14 +3227,20 @@ }, "app-module-path": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz", + "integrity": "sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ==", "dev": true }, "arg": { "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true }, "argparse": { "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { "sprintf-js": "~1.0.2" @@ -2899,26 +3248,38 @@ }, "array-union": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, "assertion-error": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true }, "astral-regex": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, "balanced-match": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "binary-extensions": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, "brace-expansion": { "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { "balanced-match": "^1.0.0", @@ -2927,6 +3288,8 @@ }, "braces": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { "fill-range": "^7.0.1" @@ -2934,18 +3297,26 @@ }, "browser-stdout": { "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, "callsites": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, "camelcase": { "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true }, "chai": { "version": "4.3.7", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", + "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", "dev": true, "requires": { "assertion-error": "^1.1.0", @@ -2959,6 +3330,8 @@ }, "chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -2967,10 +3340,14 @@ }, "check-error": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", "dev": true }, "chokidar": { "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "requires": { "anymatch": "~3.1.2", @@ -2985,6 +3362,8 @@ }, "cliui": { "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { "string-width": "^4.2.0", @@ -2994,6 +3373,8 @@ }, "color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" @@ -3001,18 +3382,26 @@ }, "color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "concat-map": { "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, "create-require": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, "cross-spawn": { "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { "path-key": "^3.1.0", @@ -3022,6 +3411,8 @@ }, "debug": { "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -3029,10 +3420,14 @@ }, "decamelize": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true }, "deep-eql": { - "version": "4.1.2", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", "dev": true, "requires": { "type-detect": "^4.0.0" @@ -3040,14 +3435,20 @@ }, "deep-is": { "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, "diff": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, "dir-glob": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, "requires": { "path-type": "^4.0.0" @@ -3055,6 +3456,8 @@ }, "doctrine": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "requires": { "esutils": "^2.0.2" @@ -3062,10 +3465,14 @@ }, "emoji-regex": { "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "enquirer": { "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", "dev": true, "requires": { "ansi-colors": "^4.1.1" @@ -3073,14 +3480,20 @@ }, "escalade": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true }, "escape-string-regexp": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, "eslint": { "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "dev": true, "requires": { "@babel/code-frame": "7.12.11", @@ -3127,6 +3540,8 @@ "dependencies": { "eslint-utils": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" @@ -3134,23 +3549,31 @@ "dependencies": { "eslint-visitor-keys": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true } } }, "ignore": { "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true } } }, "eslint-config-prettier": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-7.2.0.tgz", + "integrity": "sha512-rV4Qu0C3nfJKPOAhFujFxB7RMP+URFyQqqOZW9DMRD7ZDTFyjaIlETU3xzHELt++4ugC0+Jm084HQYkkJe+Ivg==", "dev": true, "requires": {} }, "eslint-plugin-prettier": { "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", + "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", "dev": true, "requires": { "prettier-linter-helpers": "^1.0.0" @@ -3158,6 +3581,8 @@ }, "eslint-scope": { "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "requires": { "esrecurse": "^4.3.0", @@ -3166,6 +3591,8 @@ }, "eslint-utils": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, "requires": { "eslint-visitor-keys": "^2.0.0" @@ -3173,10 +3600,14 @@ }, "eslint-visitor-keys": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true }, "espree": { "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, "requires": { "acorn": "^7.4.0", @@ -3186,16 +3617,22 @@ "dependencies": { "eslint-visitor-keys": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true } } }, "esprima": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, "esquery": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -3203,12 +3640,16 @@ "dependencies": { "estraverse": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } }, "esrecurse": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "requires": { "estraverse": "^5.2.0" @@ -3216,28 +3657,40 @@ "dependencies": { "estraverse": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } }, "estraverse": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, "esutils": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, "fast-deep-equal": { "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "fast-diff": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", "dev": true }, "fast-glob": { "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -3249,14 +3702,20 @@ }, "fast-json-stable-stringify": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, "fast-levenshtein": { "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "fastq": { - "version": "1.13.0", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -3264,6 +3723,8 @@ }, "file-entry-cache": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "requires": { "flat-cache": "^3.0.4" @@ -3271,6 +3732,8 @@ }, "fill-range": { "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "requires": { "to-regex-range": "^5.0.1" @@ -3278,6 +3741,8 @@ }, "find-up": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "requires": { "locate-path": "^6.0.0", @@ -3286,10 +3751,14 @@ }, "flat": { "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true }, "flat-cache": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "requires": { "flatted": "^3.1.0", @@ -3298,10 +3767,14 @@ }, "flatted": { "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, "fs-extra": { "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", "requires": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -3310,36 +3783,52 @@ }, "fs.realpath": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, "fsevents": { "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "optional": true }, "functional-red-black-tree": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", "dev": true }, "get-caller-file": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "get-func-name": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", "dev": true }, "get-symbol-from-current-process-h": { - "version": "1.0.2" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-from-current-process-h/-/get-symbol-from-current-process-h-1.0.2.tgz", + "integrity": "sha512-syloC6fsCt62ELLrr1VKBM1ggOpMdetX9hTrdW77UQdcApPHLmf7CI7OKcN1c9kYuNxKcDe4iJ4FY9sX3aw2xw==" }, "get-uv-event-loop-napi-h": { "version": "1.0.6", + "resolved": "https://registry.npmjs.org/get-uv-event-loop-napi-h/-/get-uv-event-loop-napi-h-1.0.6.tgz", + "integrity": "sha512-t5c9VNR84nRoF+eLiz6wFrEp1SE2Acg0wS+Ysa2zF0eROes+LzOfuTaVHxGy8AbS8rq7FHEJzjnCZo1BupwdJg==", "requires": { "get-symbol-from-current-process-h": "^1.0.1" } }, "glob": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -3352,13 +3841,17 @@ }, "glob-parent": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { "is-glob": "^4.0.1" } }, "globals": { - "version": "13.17.0", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -3366,6 +3859,8 @@ }, "globby": { "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "requires": { "array-union": "^2.1.0", @@ -3377,26 +3872,38 @@ } }, "graceful-fs": { - "version": "4.2.10" + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "growl": { "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, "has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "he": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, "ignore": { - "version": "5.2.0", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true }, "import-fresh": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "requires": { "parent-module": "^1.0.0", @@ -3405,10 +3912,14 @@ }, "imurmurhash": { "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true }, "inflight": { "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "requires": { "once": "^1.3.0", @@ -3417,10 +3928,14 @@ }, "inherits": { "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "is-binary-path": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "requires": { "binary-extensions": "^2.0.0" @@ -3428,14 +3943,20 @@ }, "is-extglob": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "is-glob": { "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "requires": { "is-extglob": "^2.1.1" @@ -3443,26 +3964,38 @@ }, "is-number": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, "is-plain-obj": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, "is-unicode-supported": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true }, "isexe": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, "js-tokens": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, "js-yaml": { "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -3471,20 +4004,28 @@ }, "json-schema-traverse": { "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "jsonfile": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "requires": { "graceful-fs": "^4.1.6" } }, "levn": { "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "requires": { "prelude-ls": "^1.2.1", @@ -3493,24 +4034,34 @@ }, "locate-path": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "requires": { "p-locate": "^5.0.0" } }, "lodash": { - "version": "4.17.21" + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash.merge": { "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, "lodash.truncate": { "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", "dev": true }, "log-symbols": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "requires": { "chalk": "^4.1.0", @@ -3519,6 +4070,8 @@ }, "loupe": { "version": "2.3.6", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", + "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", "dev": true, "requires": { "get-func-name": "^2.0.0" @@ -3526,6 +4079,8 @@ }, "lru-cache": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "requires": { "yallist": "^4.0.0" @@ -3533,14 +4088,20 @@ }, "make-error": { "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, "merge2": { "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true }, "micromatch": { "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "requires": { "braces": "^3.0.2", @@ -3549,6 +4110,8 @@ }, "minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -3556,6 +4119,8 @@ }, "mocha": { "version": "9.2.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", + "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", "dev": true, "requires": { "@ungap/promise-all-settled": "1.1.2", @@ -3586,14 +4151,20 @@ "dependencies": { "ansi-colors": { "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true }, "argparse": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, "debug": { "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "requires": { "ms": "2.1.2" @@ -3601,12 +4172,16 @@ "dependencies": { "ms": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } }, "js-yaml": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "requires": { "argparse": "^2.0.1" @@ -3614,6 +4189,8 @@ }, "minimatch": { "version": "4.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", + "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -3621,10 +4198,14 @@ }, "ms": { "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "supports-color": { "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -3634,28 +4215,42 @@ }, "ms": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "nanoid": { "version": "3.3.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", + "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", "dev": true }, "natural-compare": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, "node-addon-api": { - "version": "3.2.1" + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" }, "node-gyp-build": { - "version": "4.5.0" + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", + "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==" }, "normalize-path": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, "once": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "requires": { "wrappy": "1" @@ -3663,6 +4258,8 @@ }, "optionator": { "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "requires": { "deep-is": "^0.1.3", @@ -3675,6 +4272,8 @@ }, "p-limit": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "requires": { "yocto-queue": "^0.1.0" @@ -3682,6 +4281,8 @@ }, "p-locate": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "requires": { "p-limit": "^3.0.2" @@ -3689,6 +4290,8 @@ }, "parent-module": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "requires": { "callsites": "^3.0.0" @@ -3696,38 +4299,56 @@ }, "path-exists": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "path-is-absolute": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true }, "path-key": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "path-type": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, "pathval": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true }, "picomatch": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, "prelude-ls": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, "prettier": { - "version": "2.7.1", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz", + "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==", "dev": true }, "prettier-linter-helpers": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, "requires": { "fast-diff": "^1.1.2" @@ -3735,18 +4356,26 @@ }, "progress": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, "punycode": { - "version": "2.1.1", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true }, "queue-microtask": { "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, "randombytes": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, "requires": { "safe-buffer": "^5.1.0" @@ -3754,6 +4383,8 @@ }, "readdirp": { "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "requires": { "picomatch": "^2.2.1" @@ -3761,26 +4392,38 @@ }, "regexpp": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, "require-directory": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, "require-from-string": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true }, "resolve-from": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, "reusify": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true }, "rimraf": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { "glob": "^7.1.3" @@ -3788,6 +4431,8 @@ }, "run-parallel": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "requires": { "queue-microtask": "^1.2.2" @@ -3795,10 +4440,14 @@ }, "safe-buffer": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true }, "semver": { "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -3806,6 +4455,8 @@ }, "serialize-javascript": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dev": true, "requires": { "randombytes": "^2.1.0" @@ -3813,6 +4464,8 @@ }, "setimmediate-napi": { "version": "1.0.6", + "resolved": "https://registry.npmjs.org/setimmediate-napi/-/setimmediate-napi-1.0.6.tgz", + "integrity": "sha512-sdNXN15Av1jPXuSal4Mk4tEAKn0+8lfF9Z50/negaQMrAIO9c1qM0eiCh8fT6gctp0RiCObk+6/Xfn5RMGdZoA==", "requires": { "get-symbol-from-current-process-h": "^1.0.1", "get-uv-event-loop-napi-h": "^1.0.5" @@ -3820,6 +4473,8 @@ }, "shebang-command": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { "shebang-regex": "^3.0.0" @@ -3827,14 +4482,20 @@ }, "shebang-regex": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "slash": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, "slice-ansi": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "requires": { "ansi-styles": "^4.0.0", @@ -3844,10 +4505,14 @@ }, "sprintf-js": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, "string-width": { "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", @@ -3857,6 +4522,8 @@ }, "strip-ansi": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { "ansi-regex": "^5.0.1" @@ -3864,10 +4531,14 @@ }, "strip-json-comments": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, "supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -3875,6 +4546,8 @@ }, "table": { "version": "6.8.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", "dev": true, "requires": { "ajv": "^8.0.1", @@ -3885,7 +4558,9 @@ }, "dependencies": { "ajv": { - "version": "8.11.0", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -3896,16 +4571,22 @@ }, "json-schema-traverse": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true } } }, "text-table": { "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, "to-regex-range": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "requires": { "is-number": "^7.0.0" @@ -3913,6 +4594,8 @@ }, "ts-node": { "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, "requires": { "@cspotcode/source-map-support": "^0.8.0", @@ -3931,21 +4614,29 @@ }, "dependencies": { "acorn": { - "version": "8.8.1", + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "dev": true }, "diff": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true } } }, "tslib": { "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, "tsutils": { "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, "requires": { "tslib": "^1.8.1" @@ -3953,6 +4644,8 @@ }, "type-check": { "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "requires": { "prelude-ls": "^1.2.1" @@ -3960,39 +4653,57 @@ }, "type-detect": { "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, "type-fest": { "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, "typescript": { - "version": "4.8.4", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true }, "universalify": { - "version": "0.1.2" + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" }, "uri-js": { "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "requires": { "punycode": "^2.1.0" } }, "uuid": { - "version": "8.3.2" + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, "v8-compile-cache": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, "v8-compile-cache-lib": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, "weak-napi": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/weak-napi/-/weak-napi-2.0.2.tgz", + "integrity": "sha512-LcOSVFrghtVXf4QH+DLIy8iPiCktV7lVbqRDYP+bDPpLzC41RCHQPMyQOnPpWO41Ie4CmnDxS+mbL72r5xFMMQ==", "requires": { "node-addon-api": "^3.0.0", "node-gyp-build": "^4.2.1", @@ -4001,6 +4712,8 @@ }, "which": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -4008,14 +4721,20 @@ }, "word-wrap": { "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, "workerpool": { "version": "6.2.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", "dev": true }, "wrap-ansi": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { "ansi-styles": "^4.0.0", @@ -4025,18 +4744,26 @@ }, "wrappy": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, "y18n": { "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yallist": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "yargs": { "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { "cliui": "^7.0.2", @@ -4050,10 +4777,14 @@ }, "yargs-parser": { "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", "dev": true }, "yargs-unparser": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, "requires": { "camelcase": "^6.0.0", @@ -4064,10 +4795,14 @@ }, "yn": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true }, "yocto-queue": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true } } diff --git a/wrappers/vcx-napi-rs/index.d.ts b/wrappers/vcx-napi-rs/index.d.ts index fbd5fcdac0..987b8627d4 100644 --- a/wrappers/vcx-napi-rs/index.d.ts +++ b/wrappers/vcx-napi-rs/index.d.ts @@ -16,7 +16,7 @@ export function connectionGetRemoteDid(handle: number): string export function connectionGetRemoteVk(handle: number): string export function connectionGetState(handle: number): number export function connectionGetInvitation(handle: number): string -export function connectionProcessInvite(handle: number, invitation: string): void +export function connectionProcessInvite(handle: number, invitation: string): Promise export function connectionProcessRequest(handle: number, request: string, serviceEndpoint: string, routingKeys: Array): Promise export function connectionProcessResponse(handle: number, response: string): Promise export function connectionProcessAck(handle: number, message: string): Promise diff --git a/wrappers/vcx-napi-rs/package-lock.json b/wrappers/vcx-napi-rs/package-lock.json index 921f03c13c..1badc6beb0 100644 --- a/wrappers/vcx-napi-rs/package-lock.json +++ b/wrappers/vcx-napi-rs/package-lock.json @@ -19,9 +19,9 @@ } }, "node_modules/@napi-rs/cli": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.14.1.tgz", - "integrity": "sha512-+mnge6gvdbOrwtYrBO7iMlTjXcaRk17wDqzxSG4SPBKPhI3HroWY+tRsx+OdluAuRyJZOkWTdsvGnMsGO1ff/A==", + "version": "2.14.6", + "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.14.6.tgz", + "integrity": "sha512-q63+fI0JB9LV3RDYQN7yyAzmWDrErz+5ZMM1EyB5RA7ZwTTRYvXxg204w9+xTuZnpQfSyLMxxKGz2mfDVqFing==", "dev": true, "bin": { "napi": "scripts/index.js" @@ -35,15 +35,15 @@ } }, "node_modules/@types/node": { - "version": "18.11.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", - "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", + "version": "18.13.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.13.0.tgz", + "integrity": "sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg==", "dev": true }, "node_modules/typescript": { - "version": "4.9.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", - "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -56,21 +56,21 @@ }, "dependencies": { "@napi-rs/cli": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.14.1.tgz", - "integrity": "sha512-+mnge6gvdbOrwtYrBO7iMlTjXcaRk17wDqzxSG4SPBKPhI3HroWY+tRsx+OdluAuRyJZOkWTdsvGnMsGO1ff/A==", + "version": "2.14.6", + "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.14.6.tgz", + "integrity": "sha512-q63+fI0JB9LV3RDYQN7yyAzmWDrErz+5ZMM1EyB5RA7ZwTTRYvXxg204w9+xTuZnpQfSyLMxxKGz2mfDVqFing==", "dev": true }, "@types/node": { - "version": "18.11.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", - "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", + "version": "18.13.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.13.0.tgz", + "integrity": "sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg==", "dev": true }, "typescript": { - "version": "4.9.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", - "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true } } From 26a2441ff505d8ffb56b02e1f6c8dc529ab79afa Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Tue, 7 Feb 2023 14:18:45 +0200 Subject: [PATCH 53/66] Added re-export of PairwiseInfo to mediatedconnection to avoid struct duplication Signed-off-by: Bogdan Mircea --- .../mediated_connection/pairwise_info.rs | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/aries_vcx/src/protocols/mediated_connection/pairwise_info.rs b/aries_vcx/src/protocols/mediated_connection/pairwise_info.rs index 4c1821a73b..a248c58483 100644 --- a/aries_vcx/src/protocols/mediated_connection/pairwise_info.rs +++ b/aries_vcx/src/protocols/mediated_connection/pairwise_info.rs @@ -1,17 +1,2 @@ -use std::sync::Arc; - -use crate::errors::error::VcxResult; -use crate::plugins::wallet::base_wallet::BaseWallet; - -#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -pub struct PairwiseInfo { - pub pw_did: String, - pub pw_vk: String, -} - -impl PairwiseInfo { - pub async fn create(wallet: &Arc) -> VcxResult { - let (pw_did, pw_vk) = wallet.create_and_store_my_did(None, None).await?; - Ok(PairwiseInfo { pw_did, pw_vk }) - } -} +/// Making it easy to remove this in the future without duplicating the struct. +pub use crate::protocols::connection::pairwise_info::PairwiseInfo; From 4675cb5885e9a09b0b508c4837e48695f56dad17 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Tue, 7 Feb 2023 14:19:13 +0200 Subject: [PATCH 54/66] Ran cargo fmt Signed-off-by: Bogdan Mircea --- aries_vcx/src/protocols/connection/invitee/mod.rs | 10 ++++++---- .../protocols/connection/invitee/states/complete.rs | 2 +- .../src/protocols/connection/invitee/states/invited.rs | 2 +- libvcx/src/api_vcx/api_handle/out_of_band.rs | 5 ++++- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/aries_vcx/src/protocols/connection/invitee/mod.rs b/aries_vcx/src/protocols/connection/invitee/mod.rs index 69bf22646f..da4f28eac5 100644 --- a/aries_vcx/src/protocols/connection/invitee/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/mod.rs @@ -2,7 +2,7 @@ pub mod states; use std::sync::Arc; -use messages::{protocols::connection::invite::Invitation, diddoc::aries::diddoc::AriesDidDoc}; +use messages::{diddoc::aries::diddoc::AriesDidDoc, protocols::connection::invite::Invitation}; use crate::{ common::ledger::transactions::into_did_doc, core::profile::profile::Profile, errors::error::VcxResult, @@ -19,7 +19,7 @@ use messages::{ protocols::connection::{request::Request, response::SignedResponse}, }; -use super::{initiation_type::Invitee, pairwise_info::PairwiseInfo, Connection, trait_bounds::BootstrapDidDoc}; +use super::{initiation_type::Invitee, pairwise_info::PairwiseInfo, trait_bounds::BootstrapDidDoc, Connection}; use crate::{ common::signing::decode_signed_connection_response, errors::error::{AriesVcxError, AriesVcxErrorKind}, @@ -219,8 +219,10 @@ impl InviteeConnection { } impl InviteeConnection -where S: BootstrapDidDoc { +where + S: BootstrapDidDoc, +{ pub fn bootstrap_did_doc(&self) -> &AriesDidDoc { self.state.bootstrap_did_doc() } -} \ No newline at end of file +} diff --git a/aries_vcx/src/protocols/connection/invitee/states/complete.rs b/aries_vcx/src/protocols/connection/invitee/states/complete.rs index 6e5cb6bb51..6220dd4e1c 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/complete.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/complete.rs @@ -3,7 +3,7 @@ use std::clone::Clone; use messages::diddoc::aries::diddoc::AriesDidDoc; use messages::protocols::discovery::disclose::{Disclose, ProtocolDescriptor}; -use crate::protocols::connection::trait_bounds::{CompleteState, TheirDidDoc, ThreadId, BootstrapDidDoc}; +use crate::protocols::connection::trait_bounds::{BootstrapDidDoc, CompleteState, TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Complete { diff --git a/aries_vcx/src/protocols/connection/invitee/states/invited.rs b/aries_vcx/src/protocols/connection/invitee/states/invited.rs index 7b299ab7f0..aa9d81983b 100644 --- a/aries_vcx/src/protocols/connection/invitee/states/invited.rs +++ b/aries_vcx/src/protocols/connection/invitee/states/invited.rs @@ -1,6 +1,6 @@ use messages::{diddoc::aries::diddoc::AriesDidDoc, protocols::connection::invite::Invitation}; -use crate::protocols::connection::trait_bounds::{TheirDidDoc, ThreadId, BootstrapDidDoc}; +use crate::protocols::connection::trait_bounds::{BootstrapDidDoc, TheirDidDoc, ThreadId}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Invited { diff --git a/libvcx/src/api_vcx/api_handle/out_of_band.rs b/libvcx/src/api_vcx/api_handle/out_of_band.rs index 8bf3654c96..9b821e4162 100644 --- a/libvcx/src/api_vcx/api_handle/out_of_band.rs +++ b/libvcx/src/api_vcx/api_handle/out_of_band.rs @@ -189,7 +189,10 @@ pub async fn nonmediated_connection_exists(handle: u32, conn_handles: &[u32]) -> let filter_closure = |h: &u32| connection::get_cloned_generic_connection(h).ok().map(|c| (*h, c)); let connections: HashMap<_, _> = conn_handles.iter().filter_map(filter_closure).collect(); - match oob.nonmediated_connection_exists::<_, &u32>(&profile, &connections).await { + match oob + .nonmediated_connection_exists::<_, &u32>(&profile, &connections) + .await + { None => Ok((0, false)), Some(h) => Ok((*h, true)), } From ece4d8aa46db96ffdff9d86c434b2f8ef36560d4 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Tue, 7 Feb 2023 14:41:33 +0200 Subject: [PATCH 55/66] Fixed GenericConnection doc test and comment Signed-off-by: Bogdan Mircea --- .../src/protocols/connection/generic/mod.rs | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/aries_vcx/src/protocols/connection/generic/mod.rs b/aries_vcx/src/protocols/connection/generic/mod.rs index 8d2f24e27d..7dbc8b4bca 100644 --- a/aries_vcx/src/protocols/connection/generic/mod.rs +++ b/aries_vcx/src/protocols/connection/generic/mod.rs @@ -29,34 +29,43 @@ use crate::{ use super::{basic_send_message, trait_bounds::BootstrapDidDoc}; -/// A type that can encapsulate a [`Connection`] of any state. +/// A type that can encapsulate a [`super::Connection`] of any state. /// While mainly used for deserialization, it exposes some methods for retrieving /// connection information. /// -/// However, using methods directly from [`Connection`], if possible, comes with certain +/// However, using methods directly from [`super::Connection`], if possible, comes with certain /// benefits such as being able to obtain an [`AriesDidDoc`] directly (if the state contains it) /// and not an [`Option`] (which is what [`GenericConnection`] provides). /// -/// [`GenericConnection`] implements [`From`] for all [`Connection`] states and -/// [`Connection`] implements [`TryFrom`] from [`GenericConnection`], with the conversion failing +/// [`GenericConnection`] implements [`From`] for all [`super::Connection`] states and +/// [`super::Connection`] implements [`TryFrom`] from [`GenericConnection`], with the conversion failing /// if the [`GenericConnection`] is in a different state than the requested one. -/// This is also the mechanism used for direct deserialization of a [`Connection`]. +/// This is also the mechanism used for direct deserialization of a [`super::Connection`]. /// -/// Because a [`TryFrom`] conversion is fallible and consumes the [`GenericConnection`], a thin [`State`] +/// Because a [`TryFrom`] conversion is fallible and consumes the [`GenericConnection`], a [`ThinState`] /// can be retrieved through [`GenericConnection::state`] method at runtime. In that case, a more dynamic conversion /// could be done this way: /// -/// ``` ignore -/// // Assume the `con` variable stores a `GenericConnection`: +/// ``` +/// # use aries_vcx::protocols::connection::invitee::states::{complete::Complete, initial::Initial}; +/// # use aries_vcx::protocols::connection::initiation_type::Invitee; +/// # use aries_vcx::protocols::mediated_connection::pairwise_info::PairwiseInfo; +/// # use aries_vcx::protocols::connection::{GenericConnection, ThinState, State, Connection}; +/// # +/// # let con_inviter = Connection::new_invitee(String::new(), PairwiseInfo::default()); +/// +/// // We get a GenericConnection somehow +/// let con: GenericConnection = con_inviter.into(); /// -/// let initial_connections = Vec::new(); -/// let completed_connections = Vec::new(); +/// let mut initial_connections: Vec> = Vec::new(); +/// let mut completed_connections: Vec> = Vec::new(); /// /// // Unwrapping after the match is sound /// // because we can guarantee the conversion will work /// match con.state() { -/// State::Invitee(Stage::Initial) => initial_connections.push(con.try_into().unwrap()), -/// State::Invitee(Stage::Complete) => completed_connections.push(con.try_into().unwrap()) +/// ThinState::Invitee(State::Initial) => initial_connections.push(con.try_into().unwrap()), +/// ThinState::Invitee(State::Complete) => completed_connections.push(con.try_into().unwrap()), +/// _ => todo!() /// } /// ``` #[derive(Clone, Debug, Serialize, Deserialize)] From 307ae05d4775e9bdb54701f5dc43809e34a04121 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Tue, 7 Feb 2023 15:17:48 +0200 Subject: [PATCH 56/66] Made processInvite in node wrapper async Signed-off-by: Bogdan Mircea --- wrappers/node/src/api/connection.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wrappers/node/src/api/connection.ts b/wrappers/node/src/api/connection.ts index 53f4841e86..42a98078e6 100644 --- a/wrappers/node/src/api/connection.ts +++ b/wrappers/node/src/api/connection.ts @@ -66,9 +66,9 @@ export class NonmediatedConnection extends VcxBaseWithState { try { - ffiNapi.connectionProcessInvite(this.handle, invite); + await ffiNapi.connectionProcessInvite(this.handle, invite); } catch (err: any) { throw new VCXInternalError(err); } From a34ff897d4a41c7058dd688e4c245f738b33a8a1 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Wed, 8 Feb 2023 09:53:59 +0200 Subject: [PATCH 57/66] Fixed comments typos Signed-off-by: Bogdan Mircea --- aries_vcx/src/protocols/connection/invitee/mod.rs | 2 +- aries_vcx/src/protocols/connection/inviter/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aries_vcx/src/protocols/connection/invitee/mod.rs b/aries_vcx/src/protocols/connection/invitee/mod.rs index da4f28eac5..e9bffab160 100644 --- a/aries_vcx/src/protocols/connection/invitee/mod.rs +++ b/aries_vcx/src/protocols/connection/invitee/mod.rs @@ -182,7 +182,7 @@ impl InviteeConnection { } impl InviteeConnection { - /// Sends an acknolwedgement message to the inviter and transitions to [`InviteeConnection`]. + /// Sends an acknowledgement message to the inviter and transitions to [`InviteeConnection`]. /// /// # Errors /// diff --git a/aries_vcx/src/protocols/connection/inviter/mod.rs b/aries_vcx/src/protocols/connection/inviter/mod.rs index 17fce55c4f..632507bb6b 100644 --- a/aries_vcx/src/protocols/connection/inviter/mod.rs +++ b/aries_vcx/src/protocols/connection/inviter/mod.rs @@ -183,7 +183,7 @@ impl InviterConnection { /// /// # Errors /// - /// Will return an error if sending the repsonse fails. + /// Will return an error if sending the response fails. pub async fn send_response( self, wallet: &Arc, From c9608303932222c3ed2799a3152ee88c3b668514 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Wed, 8 Feb 2023 09:56:17 +0200 Subject: [PATCH 58/66] Added more comments to Connection::into_invited Signed-off-by: Bogdan Mircea --- aries_vcx/src/protocols/connection/inviter/mod.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/aries_vcx/src/protocols/connection/inviter/mod.rs b/aries_vcx/src/protocols/connection/inviter/mod.rs index 632507bb6b..12a00d99ac 100644 --- a/aries_vcx/src/protocols/connection/inviter/mod.rs +++ b/aries_vcx/src/protocols/connection/inviter/mod.rs @@ -64,6 +64,11 @@ impl InviterConnection { /// [`InviterConnection::create_invitation`] then you can call this /// to transition to the [`InviterConnection`] directly by passing the /// expected thread_id (external's [`Invitation`] id). + /// + /// However, the advised method of handling connection requests is to clone + /// the [`InviterConnection`] and continue the protocol for every + /// [`Request`] received for the generated invitation, assuming more than one + /// invitees are expected. // // This is a workaround and it's not necessarily pretty, but is implemented // for backwards compatibility. From 674015b09188d9d44b91cba9b0cf5c92ac529778 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Wed, 8 Feb 2023 09:58:23 +0200 Subject: [PATCH 59/66] Added comments to Connection::get_invitation Signed-off-by: Bogdan Mircea --- aries_vcx/src/protocols/connection/inviter/mod.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/aries_vcx/src/protocols/connection/inviter/mod.rs b/aries_vcx/src/protocols/connection/inviter/mod.rs index 12a00d99ac..2af82fb412 100644 --- a/aries_vcx/src/protocols/connection/inviter/mod.rs +++ b/aries_vcx/src/protocols/connection/inviter/mod.rs @@ -178,6 +178,14 @@ impl InviterConnection { }) } + /// Returns the [`Invitation`] generated by this inviter. + /// + /// NOTE: Calling [`InviterConnection::into_invited()`] + /// creates a dummy invitation behind the scenes. + /// + /// So this method will return garbage in that case. + /// `into_invited` is implemented for backwards compatibility + /// and should be avoided when possible. pub fn get_invitation(&self) -> &Invitation { &self.state.invitation } From 607b1dd2c1410c3fa640a5fe9f0d2bb9194c445c Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Wed, 8 Feb 2023 10:54:49 +0200 Subject: [PATCH 60/66] Accommodated previous send_message behavior Signed-off-by: Bogdan Mircea --- .../src/protocols/connection/generic/mod.rs | 4 ++-- aries_vcx/src/protocols/connection/mod.rs | 6 +++--- libvcx/src/api_vcx/api_handle/connection.rs | 9 ++------- wrappers/vcx-napi-rs/src/api/connection.rs | 17 +++++++++++++++++ 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/aries_vcx/src/protocols/connection/generic/mod.rs b/aries_vcx/src/protocols/connection/generic/mod.rs index 7dbc8b4bca..7a2e5e9f0a 100644 --- a/aries_vcx/src/protocols/connection/generic/mod.rs +++ b/aries_vcx/src/protocols/connection/generic/mod.rs @@ -27,7 +27,7 @@ use crate::{ transport::Transport, }; -use super::{basic_send_message, trait_bounds::BootstrapDidDoc}; +use super::{trait_bounds::BootstrapDidDoc, wrap_and_send_msg}; /// A type that can encapsulate a [`super::Connection`] of any state. /// While mainly used for deserialization, it exposes some methods for retrieving @@ -195,7 +195,7 @@ impl GenericConnection { "No DidDoc present", ))?; - basic_send_message(wallet, message, sender_verkey, did_doc, transport).await + wrap_and_send_msg(wallet, message, sender_verkey, did_doc, transport).await } } diff --git a/aries_vcx/src/protocols/connection/mod.rs b/aries_vcx/src/protocols/connection/mod.rs index d0d3591b58..f2d7d833e7 100644 --- a/aries_vcx/src/protocols/connection/mod.rs +++ b/aries_vcx/src/protocols/connection/mod.rs @@ -108,7 +108,7 @@ where { let sender_verkey = &self.pairwise_info().pw_vk; let did_doc = self.their_did_doc(); - basic_send_message(wallet, message, sender_verkey, did_doc, transport).await + wrap_and_send_msg(wallet, message, sender_verkey, did_doc, transport).await } } @@ -140,7 +140,7 @@ where { let sender_verkey = &self.pairwise_info().pw_vk; let problem_report = self.create_problem_report(err, thread_id); - let res = basic_send_message( + let res = wrap_and_send_msg( wallet, &problem_report.to_a2a_message(), sender_verkey, @@ -170,7 +170,7 @@ where } } -pub(crate) async fn basic_send_message( +pub(crate) async fn wrap_and_send_msg( wallet: &Arc, message: &A2AMessage, sender_verkey: &str, diff --git a/libvcx/src/api_vcx/api_handle/connection.rs b/libvcx/src/api_vcx/api_handle/connection.rs index 5e13beb618..2d8dd397ab 100644 --- a/libvcx/src/api_vcx/api_handle/connection.rs +++ b/libvcx/src/api_vcx/api_handle/connection.rs @@ -3,7 +3,7 @@ use std::{any::type_name, collections::HashMap, sync::RwLock}; use agency_client::httpclient::post_message; use aries_vcx::{ errors::error::{AriesVcxError, VcxResult}, - messages::protocols::{basic_message::message::BasicMessage, connection::request::Request}, + messages::protocols::connection::request::Request, protocols::connection::{ invitee::InviteeConnection, inviter::InviterConnection, pairwise_info::PairwiseInfo, Connection, GenericConnection, State, ThinState, @@ -366,12 +366,7 @@ pub async fn send_generic_message(handle: u32, content: String) -> LibvcxResult< trace!("send_generic_message >>>"); let wallet = get_main_profile()?.inject_wallet(); - let message = BasicMessage::create() - .set_content(content) - .set_time() - .set_out_time() - .to_a2a_message(); - + let message = serde_json::from_str(&content)?; let con = get_cloned_generic_connection(&handle)?; con.send_message(&wallet, &message, &HttpClient).await?; Ok(()) diff --git a/wrappers/vcx-napi-rs/src/api/connection.rs b/wrappers/vcx-napi-rs/src/api/connection.rs index 3922b1d4a5..594167f97d 100644 --- a/wrappers/vcx-napi-rs/src/api/connection.rs +++ b/wrappers/vcx-napi-rs/src/api/connection.rs @@ -1,6 +1,8 @@ +use napi::Error; use napi_derive::napi; use vcx::api_vcx::api_handle::connection; +use vcx::aries_vcx::messages::protocols::basic_message::message::BasicMessage; use vcx::aries_vcx::protocols::connection::pairwise_info::PairwiseInfo; use vcx::errors::error::{LibvcxError, LibvcxErrorKind}; use vcx::serde_json; @@ -136,6 +138,21 @@ pub async fn connection_send_ack(handle: u32) -> napi::Result<()> { #[napi] pub async fn connection_send_generic_message(handle: u32, content: String) -> napi::Result<()> { + trace!("connection_send_generic_message >>> handle: {:?}", handle); + let message = BasicMessage::create() + .set_content(content) + .set_time() + .set_out_time() + .to_a2a_message(); + + let basic_message = serde_json::to_string(&message).map_err(From::from).map_err(to_napi_err)?; + connection::send_generic_message(handle, basic_message) + .await + .map_err(to_napi_err) +} + +#[napi] +pub async fn connection_send_aries_message(handle: u32, content: String) -> napi::Result<()> { trace!("connection_send_generic_message >>> handle: {:?}", handle); connection::send_generic_message(handle, content) .await From 8ff504145ba1a8aa9625d026ca039f1ce8a8a822 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Wed, 8 Feb 2023 11:15:12 +0200 Subject: [PATCH 61/66] Factored out read access to CONNECTION_MAP in libvcx into a closure accepting function Signed-off-by: Bogdan Mircea --- libvcx/src/api_vcx/api_handle/connection.rs | 116 +++++++++----------- 1 file changed, 52 insertions(+), 64 deletions(-) diff --git a/libvcx/src/api_vcx/api_handle/connection.rs b/libvcx/src/api_vcx/api_handle/connection.rs index 2d8dd397ab..d1d24d1c52 100644 --- a/libvcx/src/api_vcx/api_handle/connection.rs +++ b/libvcx/src/api_vcx/api_handle/connection.rs @@ -53,6 +53,21 @@ pub fn get_cloned_generic_connection(handle: &u32) -> LibvcxResult(handle: &u32, closure: F) -> LibvcxResult +where + F: Fn(&GenericConnection) -> LibvcxResult, +{ + let lock = CONNECTION_MAP.read()?; + let con = lock.get(handle).ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("No connection found for handle: {}", handle), + ) + })?; + + closure(con) +} + fn get_cloned_connection(handle: &u32) -> LibvcxResult> where Connection: TryFrom, @@ -141,81 +156,58 @@ pub async fn create_invitee(_invitation: &str) -> LibvcxResult { pub fn get_thread_id(handle: u32) -> LibvcxResult { trace!("get_thread_id >>> handle: {}", handle); - let lock = CONNECTION_MAP.read()?; - let con = lock.get(&handle).ok_or_else(|| { - LibvcxError::from_msg( - LibvcxErrorKind::ObjectAccessError, - format!("No connection found for handle: {}", handle), - ) - })?; + let closure = |con: &GenericConnection| { + GenericConnection::thread_id(con).map(ToOwned::to_owned).ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("No thread ID for connection with handle: {}", &handle), + ) + }) + }; - con.thread_id().map(ToOwned::to_owned).ok_or_else(|| { - LibvcxError::from_msg( - LibvcxErrorKind::ObjectAccessError, - format!("No thread ID for connection with handle: {}", handle), - ) - }) + get_con_attribute_with_closure(&handle, closure) } pub fn get_pairwise_info(handle: u32) -> LibvcxResult { trace!("get_pairwise_info >>> handle: {}", handle); - let lock = CONNECTION_MAP.read()?; - let con = lock.get(&handle).ok_or_else(|| { - LibvcxError::from_msg( - LibvcxErrorKind::ObjectAccessError, - format!("No connection found for handle: {}", handle), - ) - })?; + let closure = |con: &GenericConnection| serialize(GenericConnection::pairwise_info(con)); - serialize(con.pairwise_info()) + get_con_attribute_with_closure(&handle, closure) } pub fn get_remote_did(handle: u32) -> LibvcxResult { trace!("get_remote_did >>> handle: {}", handle); - let lock = CONNECTION_MAP.read()?; - let con = lock.get(&handle).ok_or_else(|| { - LibvcxError::from_msg( - LibvcxErrorKind::ObjectAccessError, - format!("No connection found for handle: {}", handle), - ) - })?; + let closure = |con: &GenericConnection| { + GenericConnection::remote_did(con) + .map(ToOwned::to_owned) + .ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("No remote DID for connection with handle: {}", handle), + ) + }) + }; - con.remote_did().map(ToOwned::to_owned).ok_or_else(|| { - LibvcxError::from_msg( - LibvcxErrorKind::ObjectAccessError, - format!("No remote DID for connection with handle: {}", handle), - ) - }) + get_con_attribute_with_closure(&handle, closure) } pub fn get_remote_vk(handle: u32) -> LibvcxResult { trace!("get_remote_vk >>> handle: {}", handle); - let lock = CONNECTION_MAP.read()?; - let con = lock.get(&handle).ok_or_else(|| { - LibvcxError::from_msg( - LibvcxErrorKind::ObjectAccessError, - format!("No connection found for handle: {}", handle), - ) - })?; + let closure = |con: &GenericConnection| GenericConnection::remote_vk(con).map_err(From::from); - con.remote_vk().map_err(From::from) + get_con_attribute_with_closure(&handle, closure) } pub fn get_state(handle: u32) -> LibvcxResult { trace!("get_state >>> handle: {}", handle); - let lock = CONNECTION_MAP.read()?; - let con = lock.get(&handle).ok_or_else(|| { - LibvcxError::from_msg( - LibvcxErrorKind::ObjectAccessError, - format!("No connection found for handle: {}", handle), - ) - })?; + let closure = |con: &GenericConnection| Ok(GenericConnection::state(con)); + let state = get_con_attribute_with_closure(&handle, closure)?; - let state_id = match con.state() { + let state_id = match state { ThinState::Invitee(s) => s as u32, ThinState::Inviter(s) => s as u32, }; @@ -226,22 +218,18 @@ pub fn get_state(handle: u32) -> LibvcxResult { pub fn get_invitation(handle: u32) -> LibvcxResult { trace!("get_invitation >>> handle: {}", handle); - let lock = CONNECTION_MAP.read()?; - let con = lock.get(&handle).ok_or_else(|| { - LibvcxError::from_msg( - LibvcxErrorKind::ObjectAccessError, - format!("No connection found for handle: {}", handle), - ) - })?; + let closure = |con: &GenericConnection| { + let invitation = GenericConnection::invitation(con).ok_or_else(|| { + LibvcxError::from_msg( + LibvcxErrorKind::ObjectAccessError, + format!("No invitation for connection with handle: {}", handle), + ) + })?; - let invitation = con.invitation().ok_or_else(|| { - LibvcxError::from_msg( - LibvcxErrorKind::ObjectAccessError, - format!("No invitation for connection with handle: {}", handle), - ) - })?; + serialize(invitation) + }; - serialize(invitation) + get_con_attribute_with_closure(&handle, closure) } // ----------------------------- MSG PROCESSING ------------------------------------ From 3eba85b45e595dcc2c9104b4e96860413a30ca62 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Wed, 8 Feb 2023 12:35:06 +0200 Subject: [PATCH 62/66] Fixed wrapper send_message and added send_aries_message Signed-off-by: Bogdan Mircea --- .../src/protocols/connection/inviter/mod.rs | 12 +-- .../crypto/chacha20poly1305_ietf/sodium.rs | 13 ++-- .../src/crypto/ed25519_box/sodium.rs | 3 +- .../src/crypto/ed25519_sign/sodium.rs | 6 +- .../src/crypto/pwhash_argon2i13/sodium.rs | 3 +- .../indy-utils/src/crypto/sealedbox/sodium.rs | 6 +- .../indy-utils/src/crypto/xsalsa20/sodium.rs | 3 +- libvdrtools/indy-utils/src/environment.rs | 3 +- libvdrtools/indy-utils/src/test.rs | 4 +- libvdrtools/indy-utils/src/wql.rs | 13 ++-- libvdrtools/indy-wallet/src/cache/lru.rs | 6 +- .../indy-wallet/src/cache/wallet_cache.rs | 6 +- libvdrtools/indy-wallet/src/encryption.rs | 3 +- libvdrtools/indy-wallet/src/export_import.rs | 3 +- .../indy-wallet/src/query_encryption.rs | 8 +- .../indy-wallet/src/storage/mysql/mod.rs | 3 +- libvdrtools/indy-wallet/src/wallet.rs | 11 ++- .../src/controllers/anoncreds/prover.rs | 14 ++-- libvdrtools/src/controllers/did.rs | 20 +++-- .../src/domain/anoncreds/credential.rs | 7 +- .../domain/anoncreds/credential_definition.rs | 6 +- .../anoncreds/credential_for_proof_request.rs | 3 +- .../src/domain/anoncreds/credential_offer.rs | 3 +- .../src/domain/anoncreds/indy_identifiers.rs | 8 +- libvdrtools/src/domain/anoncreds/proof.rs | 7 +- .../src/domain/anoncreds/proof_request.rs | 13 ++-- .../revocation_registry_definition.rs | 6 +- libvdrtools/src/domain/anoncreds/schema.rs | 6 +- libvdrtools/src/domain/ledger/attrib.rs | 8 +- libvdrtools/src/domain/ledger/cred_def.rs | 21 +++-- libvdrtools/src/domain/ledger/ddo.rs | 3 +- libvdrtools/src/domain/ledger/did.rs | 8 +- libvdrtools/src/domain/ledger/rev_reg.rs | 12 ++- libvdrtools/src/domain/ledger/rev_reg_def.rs | 14 ++-- libvdrtools/src/domain/ledger/schema.rs | 9 ++- libvdrtools/src/lib.rs | 3 +- libvdrtools/src/services/anoncreds/helpers.rs | 12 +-- libvdrtools/src/services/anoncreds/issuer.rs | 22 +++--- libvdrtools/src/services/anoncreds/prover.rs | 9 ++- libvdrtools/src/services/crypto/ed25519.rs | 4 +- .../services/ledger/merkletree/merkletree.rs | 6 +- .../src/services/ledger/merkletree/mod.rs | 3 +- libvdrtools/src/services/ledger/mod.rs | 78 ++++++++++--------- libvdrtools/src/services/pool/catchup.rs | 19 +++-- libvdrtools/src/services/pool/events.rs | 13 ++-- .../src/services/pool/merkle_tree_factory.rs | 32 ++++---- libvdrtools/src/services/pool/mod.rs | 4 +- libvdrtools/src/services/pool/networker.rs | 29 ++++--- libvdrtools/src/services/pool/pool.rs | 71 ++++++++++------- .../src/services/pool/request_handler.rs | 67 ++++++++-------- .../src/services/pool/state_proof/mod.rs | 18 +++-- .../src/services/pool/state_proof/node.rs | 3 +- libvdrtools/src/services/pool/types.rs | 11 +-- .../src/utils/crypto/verkey_builder.rs | 6 +- wrappers/node/package-lock.json | 12 +-- wrappers/node/src/api/connection.ts | 8 ++ wrappers/vcx-napi-rs/index.d.ts | 1 + wrappers/vcx-napi-rs/index.js | 3 +- wrappers/vcx-napi-rs/package-lock.json | 12 +-- wrappers/vcx-napi-rs/src/api/connection.rs | 4 +- 60 files changed, 395 insertions(+), 329 deletions(-) diff --git a/aries_vcx/src/protocols/connection/inviter/mod.rs b/aries_vcx/src/protocols/connection/inviter/mod.rs index 2af82fb412..c04ce6749e 100644 --- a/aries_vcx/src/protocols/connection/inviter/mod.rs +++ b/aries_vcx/src/protocols/connection/inviter/mod.rs @@ -64,7 +64,7 @@ impl InviterConnection { /// [`InviterConnection::create_invitation`] then you can call this /// to transition to the [`InviterConnection`] directly by passing the /// expected thread_id (external's [`Invitation`] id). - /// + /// /// However, the advised method of handling connection requests is to clone /// the [`InviterConnection`] and continue the protocol for every /// [`Request`] received for the generated invitation, assuming more than one @@ -179,12 +179,12 @@ impl InviterConnection { } /// Returns the [`Invitation`] generated by this inviter. - /// - /// NOTE: Calling [`InviterConnection::into_invited()`] - /// creates a dummy invitation behind the scenes. - /// + /// + /// NOTE: Calling [`InviterConnection::into_invited()`] + /// creates a dummy invitation behind the scenes. + /// /// So this method will return garbage in that case. - /// `into_invited` is implemented for backwards compatibility + /// `into_invited` is implemented for backwards compatibility /// and should be avoided when possible. pub fn get_invitation(&self) -> &Invitation { &self.state.invitation diff --git a/libvdrtools/indy-utils/src/crypto/chacha20poly1305_ietf/sodium.rs b/libvdrtools/indy-utils/src/crypto/chacha20poly1305_ietf/sodium.rs index d36c00441e..20c47b8158 100644 --- a/libvdrtools/indy-utils/src/crypto/chacha20poly1305_ietf/sodium.rs +++ b/libvdrtools/indy-utils/src/crypto/chacha20poly1305_ietf/sodium.rs @@ -1,13 +1,12 @@ extern crate sodiumoxide; -use self::sodiumoxide::crypto::aead::chacha20poly1305_ietf; -use self::sodiumoxide::utils; +use self::sodiumoxide::{crypto::aead::chacha20poly1305_ietf, utils}; use super::pwhash_argon2i13; -use indy_api_types::domain::wallet::KeyDerivationMethod; -use indy_api_types::errors::prelude::*; -use std::cmp; -use std::io; -use std::io::{Read, Write}; +use indy_api_types::{domain::wallet::KeyDerivationMethod, errors::prelude::*}; +use std::{ + cmp, io, + io::{Read, Write}, +}; pub const KEYBYTES: usize = chacha20poly1305_ietf::KEYBYTES; pub const NONCEBYTES: usize = chacha20poly1305_ietf::NONCEBYTES; diff --git a/libvdrtools/indy-utils/src/crypto/ed25519_box/sodium.rs b/libvdrtools/indy-utils/src/crypto/ed25519_box/sodium.rs index 28c5f1a30b..4d6c1a0392 100644 --- a/libvdrtools/indy-utils/src/crypto/ed25519_box/sodium.rs +++ b/libvdrtools/indy-utils/src/crypto/ed25519_box/sodium.rs @@ -41,8 +41,7 @@ pub fn gen_nonce() -> Nonce { #[cfg(test)] mod tests { use super::*; - use crate::crypto::ed25519_sign; - use crate::crypto::randombytes::randombytes; + use crate::crypto::{ed25519_sign, randombytes::randombytes}; #[test] fn encrypt_decrypt_works() { diff --git a/libvdrtools/indy-utils/src/crypto/ed25519_sign/sodium.rs b/libvdrtools/indy-utils/src/crypto/ed25519_sign/sodium.rs index 81b4159d04..5f7ad758b1 100644 --- a/libvdrtools/indy-utils/src/crypto/ed25519_sign/sodium.rs +++ b/libvdrtools/indy-utils/src/crypto/ed25519_sign/sodium.rs @@ -1,11 +1,9 @@ use indy_api_types::errors::prelude::*; use libc::c_int; -use sodiumoxide::crypto::box_; -use sodiumoxide::crypto::sign; +use sodiumoxide::crypto::{box_, sign}; -use super::ed25519_box; -use super::randombytes::randombytes; +use super::{ed25519_box, randombytes::randombytes}; pub const SEEDBYTES: usize = sign::SEEDBYTES; pub const SIG_PUBLICKEYBYTES: usize = sign::PUBLICKEYBYTES; diff --git a/libvdrtools/indy-utils/src/crypto/pwhash_argon2i13/sodium.rs b/libvdrtools/indy-utils/src/crypto/pwhash_argon2i13/sodium.rs index f15eab7c99..2989810302 100644 --- a/libvdrtools/indy-utils/src/crypto/pwhash_argon2i13/sodium.rs +++ b/libvdrtools/indy-utils/src/crypto/pwhash_argon2i13/sodium.rs @@ -2,8 +2,7 @@ extern crate serde; extern crate sodiumoxide; use self::sodiumoxide::crypto::pwhash; -use indy_api_types::domain::wallet::KeyDerivationMethod; -use indy_api_types::errors::prelude::*; +use indy_api_types::{domain::wallet::KeyDerivationMethod, errors::prelude::*}; use libc::{c_int, c_ulonglong, size_t}; pub const SALTBYTES: usize = pwhash::SALTBYTES; diff --git a/libvdrtools/indy-utils/src/crypto/sealedbox/sodium.rs b/libvdrtools/indy-utils/src/crypto/sealedbox/sodium.rs index 7076c69949..0acc7abc4f 100644 --- a/libvdrtools/indy-utils/src/crypto/sealedbox/sodium.rs +++ b/libvdrtools/indy-utils/src/crypto/sealedbox/sodium.rs @@ -25,8 +25,10 @@ pub fn decrypt( mod tests { use self::sodiumoxide::crypto::box_; use super::*; - use crate::crypto::ed25519_box::{PublicKey, SecretKey}; - use crate::crypto::randombytes::randombytes; + use crate::crypto::{ + ed25519_box::{PublicKey, SecretKey}, + randombytes::randombytes, + }; #[test] fn encrypt_decrypt_works() { diff --git a/libvdrtools/indy-utils/src/crypto/xsalsa20/sodium.rs b/libvdrtools/indy-utils/src/crypto/xsalsa20/sodium.rs index 70a18e1792..7278c6966c 100644 --- a/libvdrtools/indy-utils/src/crypto/xsalsa20/sodium.rs +++ b/libvdrtools/indy-utils/src/crypto/xsalsa20/sodium.rs @@ -1,7 +1,6 @@ extern crate sodiumoxide; -use self::sodiumoxide::crypto::secretbox; -use self::sodiumoxide::crypto::secretbox::xsalsa20poly1305; +use self::sodiumoxide::crypto::{secretbox, secretbox::xsalsa20poly1305}; use failure::{err_msg, ResultExt}; use indy_api_types::errors::prelude::*; diff --git a/libvdrtools/indy-utils/src/environment.rs b/libvdrtools/indy-utils/src/environment.rs index 6d153bc081..e15e5d5a0a 100755 --- a/libvdrtools/indy-utils/src/environment.rs +++ b/libvdrtools/indy-utils/src/environment.rs @@ -1,5 +1,4 @@ -use std::env; -use std::path::PathBuf; +use std::{env, path::PathBuf}; pub fn indy_home_path() -> PathBuf { // TODO: FIXME: Provide better handling for the unknown home path case!!! diff --git a/libvdrtools/indy-utils/src/test.rs b/libvdrtools/indy-utils/src/test.rs index 87714e372c..d12c84e0c4 100644 --- a/libvdrtools/indy-utils/src/test.rs +++ b/libvdrtools/indy-utils/src/test.rs @@ -1,8 +1,6 @@ use super::environment; -use std::fs; -use std::fs::File; -use std::path::PathBuf; +use std::{fs, fs::File, path::PathBuf}; pub fn cleanup_files(dir: &PathBuf, name: &str) { let mut path = dir.clone(); diff --git a/libvdrtools/indy-utils/src/wql.rs b/libvdrtools/indy-utils/src/wql.rs index e2140aa1d9..8ad57f63cc 100644 --- a/libvdrtools/indy-utils/src/wql.rs +++ b/libvdrtools/indy-utils/src/wql.rs @@ -1,9 +1,11 @@ use std::string; -use serde::ser::{Serialize, Serializer}; -use serde::{de, Deserialize, Deserializer}; -use serde_json; -use serde_json::Value; +use serde::{ + de, + ser::{Serialize, Serializer}, + Deserialize, Deserializer, +}; +use serde_json::{self, Value}; #[derive(Debug, Hash, Clone, PartialEq, Eq)] pub enum Query { @@ -266,8 +268,7 @@ fn parse_single_operator( #[cfg(test)] mod tests { use super::*; - use rand::distributions::Alphanumeric; - use rand::{thread_rng, Rng}; + use rand::{distributions::Alphanumeric, thread_rng, Rng}; fn _random_string(len: usize) -> String { thread_rng() diff --git a/libvdrtools/indy-wallet/src/cache/lru.rs b/libvdrtools/indy-wallet/src/cache/lru.rs index b6288dd232..8ce1b709b7 100644 --- a/libvdrtools/indy-wallet/src/cache/lru.rs +++ b/libvdrtools/indy-wallet/src/cache/lru.rs @@ -1,5 +1,7 @@ -use crate::cache::cache::Cache; -use crate::cache::wallet_cache::{WalletCacheKey, WalletCacheValue}; +use crate::cache::{ + cache::Cache, + wallet_cache::{WalletCacheKey, WalletCacheValue}, +}; use lru::LruCache as InnerCache; pub struct LruCache { diff --git a/libvdrtools/indy-wallet/src/cache/wallet_cache.rs b/libvdrtools/indy-wallet/src/cache/wallet_cache.rs index b29c23747c..8d9bc01294 100644 --- a/libvdrtools/indy-wallet/src/cache/wallet_cache.rs +++ b/libvdrtools/indy-wallet/src/cache/wallet_cache.rs @@ -10,11 +10,13 @@ use crate::{ RecordOptions, }; use indy_api_types::domain::wallet::{CacheConfig, CachingAlgorithm}; -use std::sync::{Mutex, RwLock}; use std::{ collections::{HashMap, HashSet}, iter::FromIterator, - sync::atomic::{AtomicUsize, Ordering}, + sync::{ + atomic::{AtomicUsize, Ordering}, + Mutex, RwLock, + }, }; #[derive(PartialEq, Eq, Hash)] diff --git a/libvdrtools/indy-wallet/src/encryption.rs b/libvdrtools/indy-wallet/src/encryption.rs index 3f93d0f4ee..0d1717cae9 100644 --- a/libvdrtools/indy-wallet/src/encryption.rs +++ b/libvdrtools/indy-wallet/src/encryption.rs @@ -1,5 +1,4 @@ -use std::collections::HashMap; -use std::str; +use std::{collections::HashMap, str}; use indy_api_types::{domain::wallet::KeyDerivationMethod, errors::prelude::*}; use indy_utils::crypto::{chacha20poly1305_ietf, hmacsha256, pwhash_argon2i13}; diff --git a/libvdrtools/indy-wallet/src/export_import.rs b/libvdrtools/indy-wallet/src/export_import.rs index eeafe1f701..e1820596ff 100644 --- a/libvdrtools/indy-wallet/src/export_import.rs +++ b/libvdrtools/indy-wallet/src/export_import.rs @@ -7,7 +7,8 @@ use std::{ use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use indy_api_types::{ - domain::wallet::KeyDerivationMethod, domain::wallet::Record, errors::prelude::*, + domain::wallet::{KeyDerivationMethod, Record}, + errors::prelude::*, }; use indy_utils::crypto::{ diff --git a/libvdrtools/indy-wallet/src/query_encryption.rs b/libvdrtools/indy-wallet/src/query_encryption.rs index af68e17fdc..e710e061ef 100644 --- a/libvdrtools/indy-wallet/src/query_encryption.rs +++ b/libvdrtools/indy-wallet/src/query_encryption.rs @@ -1,8 +1,10 @@ use indy_api_types::errors::prelude::*; -use super::encryption::encrypt_as_searchable; -use super::language::{Operator, TagName, TargetValue}; -use super::wallet::Keys; +use super::{ + encryption::encrypt_as_searchable, + language::{Operator, TagName, TargetValue}, + wallet::Keys, +}; use indy_utils::wql::Query; // Performs encryption of WQL query diff --git a/libvdrtools/indy-wallet/src/storage/mysql/mod.rs b/libvdrtools/indy-wallet/src/storage/mysql/mod.rs index d3a47196da..9461429914 100644 --- a/libvdrtools/indy-wallet/src/storage/mysql/mod.rs +++ b/libvdrtools/indy-wallet/src/storage/mysql/mod.rs @@ -909,8 +909,7 @@ impl WalletStorageType for MySqlStorageType { mod tests { use indy_utils::{assert_kind, environment}; - use super::super::Tag; - use super::*; + use super::{super::Tag, *}; // docker run --name indy-mysql -e MYSQL_ROOT_PASSWORD=pass@word1 -p 3306:3306 -d mysql:latest diff --git a/libvdrtools/indy-wallet/src/wallet.rs b/libvdrtools/indy-wallet/src/wallet.rs index 0629ae8f03..ebb3381024 100644 --- a/libvdrtools/indy-wallet/src/wallet.rs +++ b/libvdrtools/indy-wallet/src/wallet.rs @@ -10,11 +10,14 @@ use indy_utils::{ use serde::{Deserialize, Serialize}; use zeroize::Zeroize; -use crate::cache::wallet_cache::WalletCacheHitMetrics; -use crate::storage::StorageRecord; use crate::{ - cache::wallet_cache::WalletCache, encryption::*, iterator::WalletIterator, - query_encryption::encrypt_query, storage, RecordOptions, WalletRecord, + cache::wallet_cache::{WalletCache, WalletCacheHitMetrics}, + encryption::*, + iterator::WalletIterator, + query_encryption::encrypt_query, + storage, + storage::StorageRecord, + RecordOptions, WalletRecord, }; use futures::future::join; diff --git a/libvdrtools/src/controllers/anoncreds/prover.rs b/libvdrtools/src/controllers/anoncreds/prover.rs index 6d74c08ca9..de3ab83252 100644 --- a/libvdrtools/src/controllers/anoncreds/prover.rs +++ b/libvdrtools/src/controllers/anoncreds/prover.rs @@ -22,6 +22,12 @@ use crate::{ CredentialDefinitionV1, CredentialDefinitions, }, credential_for_proof_request::{CredentialsForProofRequest, RequestedCredential}, + credential_offer::CredentialOffer, + credential_request::{CredentialRequest, CredentialRequestMetadata}, + master_secret::MasterSecret, + proof_request::{ + NonRevocedInterval, PredicateInfo, ProofRequest, ProofRequestExtraQuery, + }, requested_credential::RequestedCredentials, revocation_registry_definition::{ RevocationRegistryDefinition, RevocationRegistryDefinitionV1, @@ -30,14 +36,6 @@ use crate::{ revocation_state::{RevocationState, RevocationStates}, schema::{schemas_map_to_schemas_v1_map, Schemas}, }, - anoncreds::{ - credential_offer::CredentialOffer, - credential_request::{CredentialRequest, CredentialRequestMetadata}, - master_secret::MasterSecret, - proof_request::{ - NonRevocedInterval, PredicateInfo, ProofRequest, ProofRequestExtraQuery, - }, - }, crypto::did::DidValue, }, services::{AnoncredsHelpers, BlobStorageService, CryptoService, ProverService}, diff --git a/libvdrtools/src/controllers/did.rs b/libvdrtools/src/controllers/did.rs index cb52e2d785..49a10a2932 100644 --- a/libvdrtools/src/controllers/did.rs +++ b/libvdrtools/src/controllers/did.rs @@ -5,15 +5,19 @@ use indy_api_types::{errors::prelude::*, PoolHandle, WalletHandle}; use indy_wallet::{RecordOptions, SearchOptions, WalletService}; use crate::{ - domain::crypto::did::{ - Did, DidMetadata, DidMethod, DidValue, DidWithMeta, MyDidInfo, TemporaryDid, TheirDid, - TheirDidInfo, - }, - domain::crypto::key::KeyInfo, domain::{ - ledger::attrib::{AttribData, Endpoint, GetAttrReplyResult}, - ledger::did::{GetNymReplyResult, GetNymResultDataV0}, - ledger::response::Reply, + crypto::{ + did::{ + Did, DidMetadata, DidMethod, DidValue, DidWithMeta, MyDidInfo, TemporaryDid, + TheirDid, TheirDidInfo, + }, + key::KeyInfo, + }, + ledger::{ + attrib::{AttribData, Endpoint, GetAttrReplyResult}, + did::{GetNymReplyResult, GetNymResultDataV0}, + response::Reply, + }, pairwise::Pairwise, }, services::{CryptoService, LedgerService, PoolService}, diff --git a/libvdrtools/src/domain/anoncreds/credential.rs b/libvdrtools/src/domain/anoncreds/credential.rs index 8357570d1e..dd0a07905a 100644 --- a/libvdrtools/src/domain/anoncreds/credential.rs +++ b/libvdrtools/src/domain/anoncreds/credential.rs @@ -4,9 +4,10 @@ use ursa::cl::{CredentialSignature, RevocationRegistry, SignatureCorrectnessProo use indy_api_types::validation::Validatable; -use super::credential_definition::CredentialDefinitionId; -use super::revocation_registry_definition::RevocationRegistryId; -use super::schema::SchemaId; +use super::{ + credential_definition::CredentialDefinitionId, + revocation_registry_definition::RevocationRegistryId, schema::SchemaId, +}; #[derive(Debug, Deserialize, Serialize)] pub struct Credential { diff --git a/libvdrtools/src/domain/anoncreds/credential_definition.rs b/libvdrtools/src/domain/anoncreds/credential_definition.rs index e9f3a5e67b..e3221a4e01 100644 --- a/libvdrtools/src/domain/anoncreds/credential_definition.rs +++ b/libvdrtools/src/domain/anoncreds/credential_definition.rs @@ -1,5 +1,7 @@ -use indy_api_types::errors::{IndyErrorKind, IndyResult}; -use indy_api_types::IndyError; +use indy_api_types::{ + errors::{IndyErrorKind, IndyResult}, + IndyError, +}; use std::collections::HashMap; use indy_api_types::validation::Validatable; diff --git a/libvdrtools/src/domain/anoncreds/credential_for_proof_request.rs b/libvdrtools/src/domain/anoncreds/credential_for_proof_request.rs index 790eb1f6aa..41f15442ae 100644 --- a/libvdrtools/src/domain/anoncreds/credential_for_proof_request.rs +++ b/libvdrtools/src/domain/anoncreds/credential_for_proof_request.rs @@ -1,7 +1,6 @@ use std::collections::HashMap; -use super::credential::CredentialInfo; -use super::proof_request::NonRevocedInterval; +use super::{credential::CredentialInfo, proof_request::NonRevocedInterval}; #[derive(Debug, Deserialize, Serialize)] pub struct CredentialsForProofRequest { diff --git a/libvdrtools/src/domain/anoncreds/credential_offer.rs b/libvdrtools/src/domain/anoncreds/credential_offer.rs index 68a2afb78a..a4ff5d3365 100644 --- a/libvdrtools/src/domain/anoncreds/credential_offer.rs +++ b/libvdrtools/src/domain/anoncreds/credential_offer.rs @@ -1,7 +1,6 @@ use ursa::cl::{CredentialKeyCorrectnessProof, Nonce}; -use super::credential_definition::CredentialDefinitionId; -use super::schema::SchemaId; +use super::{credential_definition::CredentialDefinitionId, schema::SchemaId}; use indy_api_types::validation::Validatable; diff --git a/libvdrtools/src/domain/anoncreds/indy_identifiers.rs b/libvdrtools/src/domain/anoncreds/indy_identifiers.rs index 0ded24b364..f32c13f15c 100644 --- a/libvdrtools/src/domain/anoncreds/indy_identifiers.rs +++ b/libvdrtools/src/domain/anoncreds/indy_identifiers.rs @@ -1,7 +1,7 @@ -use super::super::crypto::did::DidValue; -use super::credential_definition::CredentialDefinitionId; -use super::revocation_registry_definition::CL_ACCUM; -use super::schema::SchemaId; +use super::{ + super::crypto::did::DidValue, credential_definition::CredentialDefinitionId, + revocation_registry_definition::CL_ACCUM, schema::SchemaId, +}; use lazy_static::lazy_static; use regex::Regex; diff --git a/libvdrtools/src/domain/anoncreds/proof.rs b/libvdrtools/src/domain/anoncreds/proof.rs index 70aa3f6ae7..7879788641 100644 --- a/libvdrtools/src/domain/anoncreds/proof.rs +++ b/libvdrtools/src/domain/anoncreds/proof.rs @@ -2,9 +2,10 @@ use std::collections::HashMap; use ursa::cl::Proof as CryptoProof; -use super::credential_definition::CredentialDefinitionId; -use super::revocation_registry_definition::RevocationRegistryId; -use super::schema::SchemaId; +use super::{ + credential_definition::CredentialDefinitionId, + revocation_registry_definition::RevocationRegistryId, schema::SchemaId, +}; use indy_api_types::validation::Validatable; #[derive(Debug, Serialize, Deserialize)] diff --git a/libvdrtools/src/domain/anoncreds/proof_request.rs b/libvdrtools/src/domain/anoncreds/proof_request.rs index 4763f65de7..cad13d1a9e 100644 --- a/libvdrtools/src/domain/anoncreds/proof_request.rs +++ b/libvdrtools/src/domain/anoncreds/proof_request.rs @@ -1,5 +1,4 @@ -use std::collections::HashMap; -use std::fmt; +use std::{collections::HashMap, fmt}; use ursa::cl::Nonce; use indy_api_types::validation::Validatable; @@ -8,11 +7,11 @@ use crate::utils::wql::Query; use serde::{de, ser, Deserialize, Deserializer, Serialize, Serializer}; use serde_json::Value; -use super::super::crypto::did::DidValue; -use super::credential::Credential; -use super::credential_definition::CredentialDefinitionId; -use super::revocation_registry_definition::RevocationRegistryId; -use super::schema::SchemaId; +use super::{ + super::crypto::did::DidValue, credential::Credential, + credential_definition::CredentialDefinitionId, + revocation_registry_definition::RevocationRegistryId, schema::SchemaId, +}; use crate::utils::qualifier; #[derive(Debug, Deserialize, Serialize)] diff --git a/libvdrtools/src/domain/anoncreds/revocation_registry_definition.rs b/libvdrtools/src/domain/anoncreds/revocation_registry_definition.rs index 26598586cc..7548cb00d6 100644 --- a/libvdrtools/src/domain/anoncreds/revocation_registry_definition.rs +++ b/libvdrtools/src/domain/anoncreds/revocation_registry_definition.rs @@ -6,8 +6,10 @@ use lazy_static::lazy_static; use regex::Regex; use ursa::cl::{RevocationKeyPrivate, RevocationKeyPublic}; -use super::super::crypto::did::DidValue; -use super::{credential_definition::CredentialDefinitionId, indy_identifiers, DELIMITER}; +use super::{ + super::crypto::did::DidValue, credential_definition::CredentialDefinitionId, indy_identifiers, + DELIMITER, +}; use crate::utils::qualifier; diff --git a/libvdrtools/src/domain/anoncreds/schema.rs b/libvdrtools/src/domain/anoncreds/schema.rs index 4581100e6a..b5035cf677 100644 --- a/libvdrtools/src/domain/anoncreds/schema.rs +++ b/libvdrtools/src/domain/anoncreds/schema.rs @@ -2,8 +2,10 @@ use super::DELIMITER; use super::super::crypto::did::DidValue; -use indy_api_types::errors::{IndyErrorKind, IndyResult}; -use indy_api_types::IndyError; +use indy_api_types::{ + errors::{IndyErrorKind, IndyResult}, + IndyError, +}; use std::collections::{HashMap, HashSet}; use super::indy_identifiers; diff --git a/libvdrtools/src/domain/ledger/attrib.rs b/libvdrtools/src/domain/ledger/attrib.rs index 61b0297042..b95906d8c0 100644 --- a/libvdrtools/src/domain/ledger/attrib.rs +++ b/libvdrtools/src/domain/ledger/attrib.rs @@ -1,6 +1,8 @@ -use super::super::crypto::did::ShortDidValue; -use super::constants::{ATTRIB, GET_ATTR}; -use super::response::GetReplyResultV1; +use super::{ + super::crypto::did::ShortDidValue, + constants::{ATTRIB, GET_ATTR}, + response::GetReplyResultV1, +}; #[derive(Serialize, PartialEq, Debug)] pub struct AttribOperation { diff --git a/libvdrtools/src/domain/ledger/cred_def.rs b/libvdrtools/src/domain/ledger/cred_def.rs index 7b8b4a9e74..34bf36c1c5 100644 --- a/libvdrtools/src/domain/ledger/cred_def.rs +++ b/libvdrtools/src/domain/ledger/cred_def.rs @@ -1,11 +1,18 @@ -use super::super::anoncreds::credential_definition::{ - CredentialDefinitionData, CredentialDefinitionId, CredentialDefinitionV1, SignatureType, +use super::{ + super::{ + anoncreds::{ + credential_definition::{ + CredentialDefinitionData, CredentialDefinitionId, CredentialDefinitionV1, + SignatureType, + }, + schema::SchemaId, + }, + crypto::did::ShortDidValue, + ledger::request::ProtocolVersion, + }, + constants::{CRED_DEF, GET_CRED_DEF}, + response::{GetReplyResultV1, ReplyType}, }; -use super::super::anoncreds::schema::SchemaId; -use super::super::crypto::did::ShortDidValue; -use super::super::ledger::request::ProtocolVersion; -use super::constants::{CRED_DEF, GET_CRED_DEF}; -use super::response::{GetReplyResultV1, ReplyType}; #[derive(Serialize, Debug)] pub struct CredDefOperation { diff --git a/libvdrtools/src/domain/ledger/ddo.rs b/libvdrtools/src/domain/ledger/ddo.rs index 3d3fe3dc7a..827b3e74ea 100644 --- a/libvdrtools/src/domain/ledger/ddo.rs +++ b/libvdrtools/src/domain/ledger/ddo.rs @@ -1,5 +1,4 @@ -use super::super::crypto::did::ShortDidValue; -use super::constants::GET_DDO; +use super::{super::crypto::did::ShortDidValue, constants::GET_DDO}; #[derive(Serialize, PartialEq, Debug)] pub struct GetDdoOperation { diff --git a/libvdrtools/src/domain/ledger/did.rs b/libvdrtools/src/domain/ledger/did.rs index 79c8a9b4cb..a2d175df38 100644 --- a/libvdrtools/src/domain/ledger/did.rs +++ b/libvdrtools/src/domain/ledger/did.rs @@ -1,6 +1,8 @@ -use super::super::crypto::did::{DidValue, ShortDidValue}; -use super::constants::{GET_NYM, NYM}; -use super::response::{GetReplyResultV0, GetReplyResultV1, ReplyType}; +use super::{ + super::crypto::did::{DidValue, ShortDidValue}, + constants::{GET_NYM, NYM}, + response::{GetReplyResultV0, GetReplyResultV1, ReplyType}, +}; #[derive(Serialize, PartialEq, Debug)] pub struct NymOperation { diff --git a/libvdrtools/src/domain/ledger/rev_reg.rs b/libvdrtools/src/domain/ledger/rev_reg.rs index 0ca9eb1a8d..14ebd679f5 100644 --- a/libvdrtools/src/domain/ledger/rev_reg.rs +++ b/libvdrtools/src/domain/ledger/rev_reg.rs @@ -2,10 +2,14 @@ use super::constants::{GET_REVOC_REG, GET_REVOC_REG_DELTA, REVOC_REG_ENTRY}; use ursa::cl::{RevocationRegistry, RevocationRegistryDelta}; -use super::super::anoncreds::revocation_registry::RevocationRegistryV1; -use super::super::anoncreds::revocation_registry_definition::RevocationRegistryId; -use super::super::anoncreds::revocation_registry_delta::RevocationRegistryDeltaV1; -use super::response::{GetReplyResultV1, ReplyType}; +use super::{ + super::anoncreds::{ + revocation_registry::RevocationRegistryV1, + revocation_registry_definition::RevocationRegistryId, + revocation_registry_delta::RevocationRegistryDeltaV1, + }, + response::{GetReplyResultV1, ReplyType}, +}; use std::collections::HashSet; diff --git a/libvdrtools/src/domain/ledger/rev_reg_def.rs b/libvdrtools/src/domain/ledger/rev_reg_def.rs index f2add70c0d..56ac00f159 100644 --- a/libvdrtools/src/domain/ledger/rev_reg_def.rs +++ b/libvdrtools/src/domain/ledger/rev_reg_def.rs @@ -1,9 +1,13 @@ -use super::super::anoncreds::credential_definition::CredentialDefinitionId; -use super::super::anoncreds::revocation_registry_definition::{ - RevocationRegistryDefinitionV1, RevocationRegistryDefinitionValue, RevocationRegistryId, +use super::{ + super::anoncreds::{ + credential_definition::CredentialDefinitionId, + revocation_registry_definition::{ + RevocationRegistryDefinitionV1, RevocationRegistryDefinitionValue, RevocationRegistryId, + }, + }, + constants::{GET_REVOC_REG_DEF, REVOC_REG_DEF}, + response::{GetReplyResultV1, ReplyType}, }; -use super::constants::{GET_REVOC_REG_DEF, REVOC_REG_DEF}; -use super::response::{GetReplyResultV1, ReplyType}; #[derive(Serialize, Debug)] #[serde(rename_all = "camelCase")] diff --git a/libvdrtools/src/domain/ledger/schema.rs b/libvdrtools/src/domain/ledger/schema.rs index 08e6b37d75..f2a286f583 100644 --- a/libvdrtools/src/domain/ledger/schema.rs +++ b/libvdrtools/src/domain/ledger/schema.rs @@ -1,7 +1,8 @@ -use super::super::anoncreds::schema::SchemaId; -use super::super::crypto::did::ShortDidValue; -use super::constants::{GET_SCHEMA, SCHEMA}; -use super::response::{GetReplyResultV1, ReplyType}; +use super::{ + super::{anoncreds::schema::SchemaId, crypto::did::ShortDidValue}, + constants::{GET_SCHEMA, SCHEMA}, + response::{GetReplyResultV1, ReplyType}, +}; use std::collections::HashSet; diff --git a/libvdrtools/src/lib.rs b/libvdrtools/src/lib.rs index c36e60044e..aa0c9e94f0 100644 --- a/libvdrtools/src/lib.rs +++ b/libvdrtools/src/lib.rs @@ -59,8 +59,7 @@ pub use domain::{ RevocationRegistryId, }, revocation_state::RevocationStates, - schema::AttributeNames, - schema::{Schema, SchemaId}, + schema::{AttributeNames, Schema, SchemaId}, }, crypto::{ did::{DidMethod, DidValue, MyDidInfo}, diff --git a/libvdrtools/src/services/anoncreds/helpers.rs b/libvdrtools/src/services/anoncreds/helpers.rs index dcfb4ec919..479826d4d2 100644 --- a/libvdrtools/src/services/anoncreds/helpers.rs +++ b/libvdrtools/src/services/anoncreds/helpers.rs @@ -10,16 +10,12 @@ use ursa::cl::{ use crate::domain::{ anoncreds::{ credential::AttributeValues, - credential_definition::CredentialDefinition, - credential_definition::CredentialDefinitionId, + credential_definition::{CredentialDefinition, CredentialDefinitionId}, credential_offer::CredentialOffer, credential_request::CredentialRequest, - proof_request::ProofRequest, - proof_request::{AttributeInfo, NonRevocedInterval, PredicateInfo}, - revocation_registry_definition::RevocationRegistryDefinition, - revocation_registry_definition::RevocationRegistryId, - schema::Schema, - schema::SchemaId, + proof_request::{AttributeInfo, NonRevocedInterval, PredicateInfo, ProofRequest}, + revocation_registry_definition::{RevocationRegistryDefinition, RevocationRegistryId}, + schema::{Schema, SchemaId}, }, crypto::did::DidValue, }; diff --git a/libvdrtools/src/services/anoncreds/issuer.rs b/libvdrtools/src/services/anoncreds/issuer.rs index a9698768c6..16348f7e48 100644 --- a/libvdrtools/src/services/anoncreds/issuer.rs +++ b/libvdrtools/src/services/anoncreds/issuer.rs @@ -8,18 +8,20 @@ use ursa::cl::{ }; use crate::{ - domain::anoncreds::{ - credential::CredentialValues, - credential_definition::{ - CredentialDefinitionData, CredentialDefinitionV1 as CredentialDefinition, + domain::{ + anoncreds::{ + credential::CredentialValues, + credential_definition::{ + CredentialDefinitionData, CredentialDefinitionV1 as CredentialDefinition, + }, + credential_request::CredentialRequest, + revocation_registry_definition::{ + RevocationRegistryDefinitionV1, RevocationRegistryDefinitionValuePublicKeys, + }, + schema::AttributeNames, }, - credential_request::CredentialRequest, - revocation_registry_definition::{ - RevocationRegistryDefinitionV1, RevocationRegistryDefinitionValuePublicKeys, - }, - schema::AttributeNames, + crypto::did::DidValue, }, - domain::crypto::did::DidValue, services::AnoncredsHelpers, }; diff --git a/libvdrtools/src/services/anoncreds/prover.rs b/libvdrtools/src/services/anoncreds/prover.rs index cbc770e7b2..0f1a3390f5 100644 --- a/libvdrtools/src/services/anoncreds/prover.rs +++ b/libvdrtools/src/services/anoncreds/prover.rs @@ -26,8 +26,7 @@ use crate::{ ProofRequestPayload, ProofRequestsVersion, RequestedAttributeInfo, RequestedPredicateInfo, }, - requested_credential::ProvingCredentialKey, - requested_credential::RequestedCredentials, + requested_credential::{ProvingCredentialKey, RequestedCredentials}, revocation_registry_definition::RevocationRegistryDefinitionV1, revocation_state::RevocationState, schema::{SchemaId, SchemaV1}, @@ -1137,8 +1136,10 @@ mod tests { } mod prepare_credentials_for_proving { - use crate::domain::anoncreds::proof_request::{AttributeInfo, PredicateInfo}; - use crate::domain::anoncreds::requested_credential::RequestedAttribute; + use crate::domain::anoncreds::{ + proof_request::{AttributeInfo, PredicateInfo}, + requested_credential::RequestedAttribute, + }; use super::*; diff --git a/libvdrtools/src/services/crypto/ed25519.rs b/libvdrtools/src/services/crypto/ed25519.rs index 99075e6e0d..98029ea06f 100644 --- a/libvdrtools/src/services/crypto/ed25519.rs +++ b/libvdrtools/src/services/crypto/ed25519.rs @@ -1,8 +1,6 @@ use super::CryptoType; use indy_api_types::errors::IndyError; -use indy_utils::crypto::ed25519_box; -use indy_utils::crypto::ed25519_sign; -use indy_utils::crypto::sealedbox; +use indy_utils::crypto::{ed25519_box, ed25519_sign, sealedbox}; pub struct ED25519CryptoType {} diff --git a/libvdrtools/src/services/ledger/merkletree/merkletree.rs b/libvdrtools/src/services/ledger/merkletree/merkletree.rs index a1becca6d2..5d384df3c0 100644 --- a/libvdrtools/src/services/ledger/merkletree/merkletree.rs +++ b/libvdrtools/src/services/ledger/merkletree/merkletree.rs @@ -1,6 +1,6 @@ -use crate::services::ledger::merkletree::proof::{Lemma, Proof}; -use crate::services::ledger::merkletree::tree::{ - LeavesIntoIterator, LeavesIterator, Tree, TreeLeafData, +use crate::services::ledger::merkletree::{ + proof::{Lemma, Proof}, + tree::{LeavesIntoIterator, LeavesIterator, Tree, TreeLeafData}, }; use indy_api_types::errors::prelude::*; use indy_utils::crypto::hash::{Hash, EMPTY_HASH_BYTES}; diff --git a/libvdrtools/src/services/ledger/merkletree/mod.rs b/libvdrtools/src/services/ledger/merkletree/mod.rs index e0bc7ec137..caede38198 100644 --- a/libvdrtools/src/services/ledger/merkletree/mod.rs +++ b/libvdrtools/src/services/ledger/merkletree/mod.rs @@ -2,8 +2,7 @@ pub mod merkletree; pub mod proof; pub mod tree; -use self::merkletree::*; -use self::tree::*; +use self::{merkletree::*, tree::*}; use indy_api_types::errors::prelude::*; use indy_utils::crypto::hash::Hash; diff --git a/libvdrtools/src/services/ledger/mod.rs b/libvdrtools/src/services/ledger/mod.rs index 3dddc95b58..feb2fca81b 100644 --- a/libvdrtools/src/services/ledger/mod.rs +++ b/libvdrtools/src/services/ledger/mod.rs @@ -8,48 +8,50 @@ use serde::de::DeserializeOwned; use serde_json::{self, Value}; use ursa::cl::RevocationRegistryDelta as CryproRevocationRegistryDelta; -use crate::domain::{ - anoncreds::{ - credential_definition::{ - CredentialDefinition, CredentialDefinitionId, CredentialDefinitionV1, - }, - revocation_registry::RevocationRegistry, - revocation_registry_definition::{ - RevocationRegistryDefinition, RevocationRegistryDefinitionV1, RevocationRegistryId, - }, - revocation_registry_delta::{RevocationRegistryDelta, RevocationRegistryDeltaV1}, - schema::{Schema, SchemaId, SchemaV1}, - }, - crypto::did::{DidValue, ShortDidValue}, - ledger::{ - attrib::{AttribOperation, GetAttribOperation}, - auth_rule::*, - author_agreement::*, - constants::{ - txn_name_to_code, ENDORSER, GET_VALIDATOR_INFO, NETWORK_MONITOR, POOL_RESTART, ROLES, - ROLE_REMOVE, STEWARD, TRUSTEE, - }, - cred_def::{CredDefOperation, GetCredDefOperation, GetCredDefReplyResult}, - ddo::GetDdoOperation, - did::{GetNymOperation, GetNymReplyResult, GetNymResultDataV0, NymData, NymOperation}, - node::{NodeOperation, NodeOperationData}, - pool::{PoolConfigOperation, PoolRestartOperation, PoolUpgradeOperation, Schedule}, - request::{Request, TxnAuthrAgrmtAcceptanceData}, - response::{Message, Reply, ReplyType}, - rev_reg::{ - GetRevRegDeltaOperation, GetRevRegOperation, GetRevocRegDeltaReplyResult, - GetRevocRegReplyResult, RevRegEntryOperation, +use crate::{ + domain::{ + anoncreds::{ + credential_definition::{ + CredentialDefinition, CredentialDefinitionId, CredentialDefinitionV1, + }, + revocation_registry::RevocationRegistry, + revocation_registry_definition::{ + RevocationRegistryDefinition, RevocationRegistryDefinitionV1, RevocationRegistryId, + }, + revocation_registry_delta::{RevocationRegistryDelta, RevocationRegistryDeltaV1}, + schema::{Schema, SchemaId, SchemaV1}, }, - rev_reg_def::{GetRevRegDefOperation, GetRevocRegDefReplyResult, RevRegDefOperation}, - schema::{ - GetSchemaOperation, GetSchemaOperationData, GetSchemaReplyResult, SchemaOperation, - SchemaOperationData, + crypto::did::{DidValue, ShortDidValue}, + ledger::{ + attrib::{AttribOperation, GetAttribOperation}, + auth_rule::*, + author_agreement::*, + constants::{ + txn_name_to_code, ENDORSER, GET_VALIDATOR_INFO, NETWORK_MONITOR, POOL_RESTART, + ROLES, ROLE_REMOVE, STEWARD, TRUSTEE, + }, + cred_def::{CredDefOperation, GetCredDefOperation, GetCredDefReplyResult}, + ddo::GetDdoOperation, + did::{GetNymOperation, GetNymReplyResult, GetNymResultDataV0, NymData, NymOperation}, + node::{NodeOperation, NodeOperationData}, + pool::{PoolConfigOperation, PoolRestartOperation, PoolUpgradeOperation, Schedule}, + request::{Request, TxnAuthrAgrmtAcceptanceData}, + response::{Message, Reply, ReplyType}, + rev_reg::{ + GetRevRegDeltaOperation, GetRevRegOperation, GetRevocRegDeltaReplyResult, + GetRevocRegReplyResult, RevRegEntryOperation, + }, + rev_reg_def::{GetRevRegDefOperation, GetRevocRegDefReplyResult, RevRegDefOperation}, + schema::{ + GetSchemaOperation, GetSchemaOperationData, GetSchemaReplyResult, SchemaOperation, + SchemaOperationData, + }, + txn::{GetTxnOperation, LedgerType}, + validator_info::GetValidatorInfoOperation, }, - txn::{GetTxnOperation, LedgerType}, - validator_info::GetValidatorInfoOperation, }, + utils::crypto::signature_serializer::serialize_signature, }; -use crate::utils::crypto::signature_serializer::serialize_signature; macro_rules! build_result { ($operation:ident, $submitter_did:expr) => ({ diff --git a/libvdrtools/src/services/pool/catchup.rs b/libvdrtools/src/services/pool/catchup.rs index ed9caf9049..570d06ebb2 100644 --- a/libvdrtools/src/services/pool/catchup.rs +++ b/libvdrtools/src/services/pool/catchup.rs @@ -1,14 +1,19 @@ -use std::collections::HashMap; -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; use failure::Context; use serde_json; -use crate::domain::pool::PoolMode; -use crate::services::ledger::merkletree::merkletree::MerkleTree; -use crate::services::pool::merkle_tree_factory; -use crate::services::pool::types::{CatchupReq, Message}; -use crate::utils::crypto::base58::{FromBase58, ToBase58}; +use crate::{ + domain::pool::PoolMode, + services::{ + ledger::merkletree::merkletree::MerkleTree, + pool::{ + merkle_tree_factory, + types::{CatchupReq, Message}, + }, + }, + utils::crypto::base58::{FromBase58, ToBase58}, +}; use indy_api_types::errors::prelude::*; pub enum CatchupProgress { diff --git a/libvdrtools/src/services/pool/events.rs b/libvdrtools/src/services/pool/events.rs index 9d763987f4..fb34c1ed14 100644 --- a/libvdrtools/src/services/pool/events.rs +++ b/libvdrtools/src/services/pool/events.rs @@ -1,11 +1,10 @@ -use serde_json; -use serde_json::Value as SJsonValue; +use serde_json::{self, Value as SJsonValue}; -use crate::domain::ledger::constants; -use crate::services::ledger::merkletree::merkletree::MerkleTree; -use crate::services::pool::types::*; -use indy_api_types::errors::prelude::*; -use indy_api_types::CommandHandle; +use crate::{ + domain::ledger::constants, + services::{ledger::merkletree::merkletree::MerkleTree, pool::types::*}, +}; +use indy_api_types::{errors::prelude::*, CommandHandle}; pub const REQUESTS_FOR_STATE_PROOFS: [&str; 11] = [ constants::GET_NYM, diff --git a/libvdrtools/src/services/pool/merkle_tree_factory.rs b/libvdrtools/src/services/pool/merkle_tree_factory.rs index 6c6d4af82e..e496e97330 100644 --- a/libvdrtools/src/services/pool/merkle_tree_factory.rs +++ b/libvdrtools/src/services/pool/merkle_tree_factory.rs @@ -1,15 +1,20 @@ -use std::collections::HashMap; -use std::io::{BufRead, Read, Write}; -use std::path::PathBuf; -use std::{fs, io}; - -use serde_json; -use serde_json::Value as SJsonValue; - -use crate::domain::ledger::request::ProtocolVersion; -use crate::services::ledger::merkletree::merkletree::MerkleTree; -use crate::services::pool::types::{NodeTransaction, NodeTransactionV0, NodeTransactionV1}; -use crate::utils::environment; +use std::{ + collections::HashMap, + fs, io, + io::{BufRead, Read, Write}, + path::PathBuf, +}; + +use serde_json::{self, Value as SJsonValue}; + +use crate::{ + domain::ledger::request::ProtocolVersion, + services::{ + ledger::merkletree::merkletree::MerkleTree, + pool::types::{NodeTransaction, NodeTransactionV0, NodeTransactionV1}, + }, + utils::environment, +}; use indy_api_types::errors::prelude::*; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; @@ -316,8 +321,7 @@ mod tests { use byteorder::LittleEndian; - use crate::domain::ledger::request::ProtocolVersion; - use crate::utils::test; + use crate::{domain::ledger::request::ProtocolVersion, utils::test}; use super::*; diff --git a/libvdrtools/src/services/pool/mod.rs b/libvdrtools/src/services/pool/mod.rs index 84db7c3777..fb1c5a27a3 100644 --- a/libvdrtools/src/services/pool/mod.rs +++ b/libvdrtools/src/services/pool/mod.rs @@ -543,9 +543,7 @@ pub mod tests { use futures::executor::block_on; - use crate::domain::ledger::request::ProtocolVersion; - use crate::services::pool::types::*; - use crate::utils::test; + use crate::{domain::ledger::request::ProtocolVersion, services::pool::types::*, utils::test}; use super::*; diff --git a/libvdrtools/src/services/pool/networker.rs b/libvdrtools/src/services/pool/networker.rs index e6bc28869c..e58594ad5f 100644 --- a/libvdrtools/src/services/pool/networker.rs +++ b/libvdrtools/src/services/pool/networker.rs @@ -1,20 +1,18 @@ -use std::collections::{BTreeMap, HashMap, HashSet}; -use std::sync::Mutex; +use std::{ + collections::{BTreeMap, HashMap, HashSet}, + sync::Mutex, +}; -use rand::prelude::SliceRandom; -use rand::thread_rng; +use rand::{prelude::SliceRandom, thread_rng}; use time::Tm; -use crate::services::pool::events::*; -use crate::services::pool::types::*; +use crate::services::pool::{events::*, types::*}; use indy_api_types::errors::prelude::*; -use indy_utils::crypto::base64; -use indy_utils::sequence; +use indy_utils::{crypto::base64, sequence}; use time::Duration; -use zmq::PollItem; -use zmq::Socket as ZSocket; +use zmq::{PollItem, Socket as ZSocket}; pub trait Networker { fn new(active_timeout: i64, conn_limit: usize, preordered_nodes: Vec) -> Self; @@ -458,13 +456,14 @@ impl Networker for MockNetworker { #[cfg(test)] pub mod networker_tests { - use std; - use std::thread; + use std::{self, thread}; - use crate::domain::pool::{ - MAX_REQ_PER_POOL_CON, POOL_ACK_TIMEOUT, POOL_CON_ACTIVE_TO, POOL_REPLY_TIMEOUT, + use crate::{ + domain::pool::{ + MAX_REQ_PER_POOL_CON, POOL_ACK_TIMEOUT, POOL_CON_ACTIVE_TO, POOL_REPLY_TIMEOUT, + }, + services::pool::tests::nodes_emulator, }; - use crate::services::pool::tests::nodes_emulator; use indy_utils::crypto::ed25519_sign; use super::*; diff --git a/libvdrtools/src/services/pool/pool.rs b/libvdrtools/src/services/pool/pool.rs index b912b0e615..90438777fc 100644 --- a/libvdrtools/src/services/pool/pool.rs +++ b/libvdrtools/src/services/pool/pool.rs @@ -1,23 +1,33 @@ -use std::collections::HashMap; -use std::collections::VecDeque; -use std::marker::PhantomData; -use std::sync::{Arc, Mutex}; -use std::thread; -use std::thread::JoinHandle; +use std::{ + collections::{HashMap, VecDeque}, + marker::PhantomData, + sync::{Arc, Mutex}, + thread, + thread::JoinHandle, +}; use failure::Context; -use crate::domain::ledger::request::ProtocolVersion; -use crate::domain::pool::{PoolMode, PoolOpenConfig}; -use crate::services::ledger::merkletree::merkletree::MerkleTree; -use crate::services::pool::commander::Commander; -use crate::services::pool::events::*; -use crate::services::pool::merkle_tree_factory::dump_to_json_string; -use crate::services::pool::networker::{Networker, ZMQNetworker}; -use crate::services::pool::request_handler::{RequestHandler, RequestHandlerImpl}; -use crate::services::pool::types::{LedgerStatus, RemoteNode}; -use crate::services::pool::{merkle_tree_factory, Nodes, PoolService}; -use crate::utils::crypto::base58::{FromBase58, ToBase58}; +use crate::{ + domain::{ + ledger::request::ProtocolVersion, + pool::{PoolMode, PoolOpenConfig}, + }, + services::{ + ledger::merkletree::merkletree::MerkleTree, + pool::{ + commander::Commander, + events::*, + merkle_tree_factory, + merkle_tree_factory::dump_to_json_string, + networker::{Networker, ZMQNetworker}, + request_handler::{RequestHandler, RequestHandlerImpl}, + types::{LedgerStatus, RemoteNode}, + Nodes, PoolService, + }, + }, + utils::crypto::base58::{FromBase58, ToBase58}, +}; use indy_api_types::errors::prelude::*; use indy_utils::crypto::ed25519_sign; @@ -1115,13 +1125,14 @@ impl Drop for ZMQPool { #[cfg(test)] mod tests { - use crate::services::pool::networker::MockNetworker; - use crate::services::pool::request_handler::tests::MockRequestHandler; - use crate::services::pool::types::{ - Message, Reply, ReplyResultV1, ReplyTxnV1, ReplyV1, ResponseMetadata, + use crate::{ + services::pool::{ + networker::MockNetworker, + request_handler::tests::MockRequestHandler, + types::{Message, Reply, ReplyResultV1, ReplyTxnV1, ReplyV1, ResponseMetadata}, + }, + utils::{test, test::test_pool_create_poolfile}, }; - use crate::utils::test; - use crate::utils::test::test_pool_create_poolfile; use indy_utils::next_command_handle; @@ -1164,9 +1175,11 @@ mod tests { use serde_json; use super::*; - use crate::domain::pool::NUMBER_READ_NODES; - use crate::services::pool::test_utils::{ - fake_cmd_id, fake_pool_handle_for_close_cmd, fake_pool_handle_for_poolsm, + use crate::{ + domain::pool::NUMBER_READ_NODES, + services::pool::test_utils::{ + fake_cmd_id, fake_pool_handle_for_close_cmd, fake_pool_handle_for_poolsm, + }, }; use futures::executor::block_on; use indy_utils::next_pool_handle; @@ -1910,8 +1923,10 @@ mod tests { mod pool_sm_in_memory { use super::*; - use crate::domain::pool::NUMBER_READ_NODES; - use crate::services::pool::test_utils::fake_pool_handle_for_poolsm; + use crate::{ + domain::pool::NUMBER_READ_NODES, + services::pool::test_utils::fake_pool_handle_for_poolsm, + }; use indy_utils::next_pool_handle; const IN_MEMORY_MODE: PoolMode = PoolMode::InMemory; diff --git a/libvdrtools/src/services/pool/request_handler.rs b/libvdrtools/src/services/pool/request_handler.rs index e352e9e1e6..ffda30fcc4 100644 --- a/libvdrtools/src/services/pool/request_handler.rs +++ b/libvdrtools/src/services/pool/request_handler.rs @@ -1,34 +1,34 @@ -use std::collections::HashMap; -use std::collections::HashSet; -use std::iter::FromIterator; -use std::sync::{Arc, Mutex}; -use std::time::{SystemTime, UNIX_EPOCH}; -use std::u64; +use std::{ + collections::{HashMap, HashSet}, + iter::FromIterator, + sync::{Arc, Mutex}, + time::{SystemTime, UNIX_EPOCH}, + u64, +}; use self::super::THRESHOLD; use rmp_serde; -use serde_json; -use serde_json::Value as SJsonValue; - -use crate::services::ledger::merkletree::merkletree::MerkleTree; -use crate::services::pool::catchup::{ - build_catchup_req, check_cons_proofs, check_nodes_responses_on_status, CatchupProgress, +use serde_json::{self, Value as SJsonValue}; + +use crate::services::{ + ledger::merkletree::merkletree::MerkleTree, + pool::{ + catchup::{ + build_catchup_req, check_cons_proofs, check_nodes_responses_on_status, CatchupProgress, + }, + events::{NetworkerEvent, PoolEvent, RequestEvent}, + merkle_tree_factory, + networker::Networker, + state_proof, + types::{CatchupRep, HashableValue}, + Nodes, PoolService, + }, }; -use crate::services::pool::events::NetworkerEvent; -use crate::services::pool::events::PoolEvent; -use crate::services::pool::events::RequestEvent; -use crate::services::pool::merkle_tree_factory; -use crate::services::pool::networker::Networker; -use crate::services::pool::state_proof; -use crate::services::pool::types::CatchupRep; -use crate::services::pool::types::HashableValue; -use crate::services::pool::{Nodes, PoolService}; use indy_api_types::errors::prelude::*; use ursa::bls::Generator; -use crate::domain::pool::PoolMode; -use crate::utils::crypto::base58::FromBase58; +use crate::{domain::pool::PoolMode, utils::crypto::base58::FromBase58}; use indy_api_types::CommandHandle; use log_derive::logfn; use std::hash::{Hash, Hasher}; @@ -1271,15 +1271,20 @@ fn _get_cur_time() -> u64 { #[cfg(test)] pub mod tests { - use crate::domain::pool::NUMBER_READ_NODES; - use crate::services::ledger::merkletree::tree::Tree; - use crate::services::pool::networker::MockNetworker; - use crate::services::pool::types::{ - ConsistencyProof, LedgerStatus, Reply, ReplyResultV1, ReplyTxnV1, ReplyV1, Response, - ResponseMetadata, ResponseV1, + use crate::{ + domain::pool::NUMBER_READ_NODES, + services::{ + ledger::merkletree::tree::Tree, + pool::{ + networker::MockNetworker, + types::{ + ConsistencyProof, LedgerStatus, Reply, ReplyResultV1, ReplyTxnV1, ReplyV1, + Response, ResponseMetadata, ResponseV1, + }, + }, + }, + utils::{test, test::test_pool_create_poolfile}, }; - use crate::utils::test; - use crate::utils::test::test_pool_create_poolfile; use super::*; use std::io::Write; diff --git a/libvdrtools/src/services/pool/state_proof/mod.rs b/libvdrtools/src/services/pool/state_proof/mod.rs index 9d8bc610da..41180a97ec 100644 --- a/libvdrtools/src/services/pool/state_proof/mod.rs +++ b/libvdrtools/src/services/pool/state_proof/mod.rs @@ -7,20 +7,22 @@ use std::collections::HashMap; use indy_utils::crypto::base64; use rlp::UntrustedRlp; -use serde_json; -use serde_json::Value as SJsonValue; +use serde_json::{self, Value as SJsonValue}; -use crate::domain::ledger::{constants, request::ProtocolVersion}; -use crate::services::pool::events::{REQUESTS_FOR_MULTI_STATE_PROOFS, REQUESTS_FOR_STATE_PROOFS}; +use crate::{ + domain::ledger::{constants, request::ProtocolVersion}, + services::pool::events::{REQUESTS_FOR_MULTI_STATE_PROOFS, REQUESTS_FOR_STATE_PROOFS}, +}; use indy_api_types::errors::prelude::*; use indy_utils::crypto::hash::hash as openssl_hash; use super::types::*; -use self::log_derive::logfn; -use self::node::{Node, TrieDB}; -use crate::services::pool::Nodes; -use crate::utils::crypto::base58::FromBase58; +use self::{ + log_derive::logfn, + node::{Node, TrieDB}, +}; +use crate::{services::pool::Nodes, utils::crypto::base58::FromBase58}; use ursa::bls::{Bls, Generator, MultiSignature, VerKey}; mod node; diff --git a/libvdrtools/src/services/pool/state_proof/node.rs b/libvdrtools/src/services/pool/state_proof/node.rs index b0922360c3..6c556d2346 100644 --- a/libvdrtools/src/services/pool/state_proof/node.rs +++ b/libvdrtools/src/services/pool/state_proof/node.rs @@ -148,8 +148,7 @@ pub type TrieDB<'a> = HashMap; impl Node { pub fn get_hash(&self) -> NodeHash { use rlp::encode as rlp_encode; - use sha3::digest::FixedOutput; - use sha3::Digest; + use sha3::{digest::FixedOutput, Digest}; let encoded = rlp_encode(self); let mut hasher = sha3::Sha3_256::default(); hasher.update(encoded.to_vec().as_slice()); diff --git a/libvdrtools/src/services/pool/types.rs b/libvdrtools/src/services/pool/types.rs index 6344d7655d..5a29eb36f5 100644 --- a/libvdrtools/src/services/pool/types.rs +++ b/libvdrtools/src/services/pool/types.rs @@ -1,10 +1,11 @@ -use std::cmp::Eq; -use std::collections::HashMap; -use std::hash::{Hash, Hasher}; +use std::{ + cmp::Eq, + collections::HashMap, + hash::{Hash, Hasher}, +}; use crate::utils::crypto::verkey_builder::build_full_verkey; -use indy_api_types::errors::prelude::*; -use indy_api_types::CommandHandle; +use indy_api_types::{errors::prelude::*, CommandHandle}; #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] pub struct NodeData { diff --git a/libvdrtools/src/utils/crypto/verkey_builder.rs b/libvdrtools/src/utils/crypto/verkey_builder.rs index 50dafae310..4acb3c98e6 100644 --- a/libvdrtools/src/utils/crypto/verkey_builder.rs +++ b/libvdrtools/src/utils/crypto/verkey_builder.rs @@ -1,5 +1,7 @@ -use crate::services::CryptoService; -use crate::utils::crypto::base58::{FromBase58, ToBase58}; +use crate::{ + services::CryptoService, + utils::crypto::base58::{FromBase58, ToBase58}, +}; use indy_api_types::errors::prelude::*; pub fn build_full_verkey(dest: &str, verkey: Option<&str>) -> Result { diff --git a/wrappers/node/package-lock.json b/wrappers/node/package-lock.json index 20bd644c6c..36ec918813 100644 --- a/wrappers/node/package-lock.json +++ b/wrappers/node/package-lock.json @@ -2108,9 +2108,9 @@ } }, "node_modules/prettier": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz", - "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==", + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz", + "integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==", "dev": true, "bin": { "prettier": "bin-prettier.js" @@ -4340,9 +4340,9 @@ "dev": true }, "prettier": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz", - "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==", + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz", + "integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==", "dev": true }, "prettier-linter-helpers": { diff --git a/wrappers/node/src/api/connection.ts b/wrappers/node/src/api/connection.ts index 42a98078e6..65d9301301 100644 --- a/wrappers/node/src/api/connection.ts +++ b/wrappers/node/src/api/connection.ts @@ -139,6 +139,14 @@ export class NonmediatedConnection extends VcxBaseWithState { + try { + return await ffiNapi.connectionSendAriesMessage(this.handle, content); + } catch (err: any) { + throw new VCXInternalError(err); + } + } public async createInvite(endpointInfo: IEndpointInfo): Promise { try { diff --git a/wrappers/vcx-napi-rs/index.d.ts b/wrappers/vcx-napi-rs/index.d.ts index 987b8627d4..9bbb18519c 100644 --- a/wrappers/vcx-napi-rs/index.d.ts +++ b/wrappers/vcx-napi-rs/index.d.ts @@ -25,6 +25,7 @@ export function connectionSendResponse(handle: number): Promise export function connectionSendRequest(handle: number, serviceEndpoint: string, routingKeys: Array): Promise export function connectionSendAck(handle: number): Promise export function connectionSendGenericMessage(handle: number, content: string): Promise +export function connectionSendAriesMessage(handle: number, content: string): Promise export function connectionCreateInvite(handle: number, serviceEndpoint: string, routingKeys: Array): Promise export function connectionSerialize(handle: number): string export function connectionDeserialize(connectionData: string): number diff --git a/wrappers/vcx-napi-rs/index.js b/wrappers/vcx-napi-rs/index.js index 0a4f7ecd1d..4422c17542 100644 --- a/wrappers/vcx-napi-rs/index.js +++ b/wrappers/vcx-napi-rs/index.js @@ -246,7 +246,7 @@ if (!nativeBinding) { throw new Error(`Failed to load native binding`) } -const { updateWebhookUrl, createAgencyClientForMainWallet, provisionCloudAgent, messagesUpdateStatus, generatePublicInvitation, connectionCreateInviter, connectionCreateInvitee, connectionGetThreadId, connectionGetPairwiseInfo, connectionGetRemoteDid, connectionGetRemoteVk, connectionGetState, connectionGetInvitation, connectionProcessInvite, connectionProcessRequest, connectionProcessResponse, connectionProcessAck, connectionProcessProblemReport, connectionSendResponse, connectionSendRequest, connectionSendAck, connectionSendGenericMessage, connectionCreateInvite, connectionSerialize, connectionDeserialize, connectionRelease, credentialCreateWithOffer, credentialRelease, credentialSendRequest, credentialDeclineOffer, credentialSerialize, credentialDeserialize, v2CredentialUpdateStateWithMessage, v2CredentialUpdateState, credentialGetState, credentialGetOffers, credentialGetAttributes, credentialGetAttachment, credentialGetTailsLocation, credentialGetTailsHash, credentialGetRevRegId, credentialGetThreadId, credentialdefCreateV2, credentialdefPublish, credentialdefDeserialize, credentialdefRelease, credentialdefSerialize, credentialdefGetCredDefId, credentialdefUpdateState, credentialdefGetState, disclosedProofCreateWithRequest, disclosedProofRelease, disclosedProofSendProof, disclosedProofRejectProof, disclosedProofGetProofMsg, disclosedProofSerialize, disclosedProofDeserialize, v2DisclosedProofUpdateState, v2DisclosedProofUpdateStateWithMessage, disclosedProofGetState, disclosedProofGetRequests, disclosedProofRetrieveCredentials, disclosedProofGetProofRequestAttachment, disclosedProofGenerateProof, disclosedProofDeclinePresentationRequest, disclosedProofGetThreadId, issuerCredentialDeserialize, issuerCredentialSerialize, issuerCredentialUpdateStateV2, issuerCredentialUpdateStateWithMessageV2, issuerCredentialUpdateStateWithMessageNonmediated, issuerCredentialGetState, issuerCredentialGetRevRegId, issuerCredentialCreate, issuerCredentialRevokeLocal, issuerCredentialIsRevokable, issuerCredentialSendCredential, issuerCredentialSendCredentialNonmediated, issuerCredentialSendOfferV2, issuerCredentialSendOfferNonmediated, issuerCredentialMarkOfferMsgSent, issuerCredentialBuildOfferMsgV2, issuerCredentialGetOfferMsg, issuerCredentialRelease, issuerCredentialGetThreadId, getLedgerAuthorAgreement, setActiveTxnAuthorAgreementMeta, createService, getServiceFromLedger, getVerkeyFromLedger, getLedgerTxn, initDefaultLogger, mediatedConnectionGeneratePublicInvite, mediatedConnectionGetPwDid, mediatedConnectionGetTheirPwDid, mediatedConnectionGetThreadId, mediatedConnectionGetState, mediatedConnectionGetSourceId, mediatedConnectionCreate, mediatedConnectionCreateWithInvite, mediatedConnectionSendMessage, mediatedConnectionCreateWithConnectionRequestV2, mediatedConnectionSendHandshakeReuse, mediatedConnectionUpdateStateWithMessage, mediatedConnectionHandleMessage, mediatedConnectionUpdateState, mediatedConnectionDeleteConnection, mediatedConnectionConnect, mediatedConnectionSerialize, mediatedConnectionDeserialize, mediatedConnectionRelease, mediatedConnectionInviteDetails, mediatedConnectionSendPing, mediatedConnectionSendDiscoveryFeatures, mediatedConnectionInfo, mediatedConnectionMessagesDownload, mediatedConnectionSignData, mediatedConnectionVerifySignature, outOfBandBuildHandshakeReuseAcceptedMsg, outOfBandReceiverCreate, outOfBandReceiverExtractMessage, outOfBandReceiverConnectionExists, outOfBandReceiverNonmediatedConnectionExists, outOfBandReceiverBuildConnection, outOfBandReceiverGetThreadId, outOfBandReceiverSerialize, outOfBandReceiverDeserialize, outOfBandReceiverRelease, outOfBandSenderCreate, outOfBandSenderAppendMessage, outOfBandSenderAppendService, outOfBandSenderAppendServiceDid, outOfBandSenderToMessage, outOfBandSenderGetThreadId, outOfBandSenderSerialize, outOfBandSenderDeserialize, outOfBandSenderRelease, openMainPool, closeMainPool, proofCreate, proofGetProofMsg, proofRelease, proofSendRequest, proofSendRequestNonmediated, proofGetRequestMsg, proofSerialize, proofDeserialize, v2ProofUpdateState, v2ProofUpdateStateWithMessage, proofUpdateStateWithMessageNonmediated, proofGetState, proofGetProofState, proofGetThreadId, markPresentationRequestMsgSent, revocationRegistryCreate, revocationRegistryPublish, revocationRegistryPublishRevocations, revocationRegistryGetRevRegId, revocationRegistryGetTailsHash, revocationRegistrySerialize, revocationRegistryDeserialize, revocationRegistryRelease, schemaGetAttributes, schemaPrepareForEndorser, schemaCreate, schemaGetSchemaId, schemaDeserialize, schemaSerialize, schemaRelease, schemaUpdateState, schemaGetState, enableMocks, trustpingBuildResponseMsg, trustpingBuildPing, shutdown, getVersion, walletOpenAsMain, walletCreateMain, walletCloseMain, vcxInitIssuerConfig, configureIssuerWallet, unpack, createPairwiseInfo, walletImport, walletExport, getVerkeyFromWallet, rotateVerkey, rotateVerkeyStart, rotateVerkeyApply } = nativeBinding +const { updateWebhookUrl, createAgencyClientForMainWallet, provisionCloudAgent, messagesUpdateStatus, generatePublicInvitation, connectionCreateInviter, connectionCreateInvitee, connectionGetThreadId, connectionGetPairwiseInfo, connectionGetRemoteDid, connectionGetRemoteVk, connectionGetState, connectionGetInvitation, connectionProcessInvite, connectionProcessRequest, connectionProcessResponse, connectionProcessAck, connectionProcessProblemReport, connectionSendResponse, connectionSendRequest, connectionSendAck, connectionSendGenericMessage, connectionSendAriesMessage, connectionCreateInvite, connectionSerialize, connectionDeserialize, connectionRelease, credentialCreateWithOffer, credentialRelease, credentialSendRequest, credentialDeclineOffer, credentialSerialize, credentialDeserialize, v2CredentialUpdateStateWithMessage, v2CredentialUpdateState, credentialGetState, credentialGetOffers, credentialGetAttributes, credentialGetAttachment, credentialGetTailsLocation, credentialGetTailsHash, credentialGetRevRegId, credentialGetThreadId, credentialdefCreateV2, credentialdefPublish, credentialdefDeserialize, credentialdefRelease, credentialdefSerialize, credentialdefGetCredDefId, credentialdefUpdateState, credentialdefGetState, disclosedProofCreateWithRequest, disclosedProofRelease, disclosedProofSendProof, disclosedProofRejectProof, disclosedProofGetProofMsg, disclosedProofSerialize, disclosedProofDeserialize, v2DisclosedProofUpdateState, v2DisclosedProofUpdateStateWithMessage, disclosedProofGetState, disclosedProofGetRequests, disclosedProofRetrieveCredentials, disclosedProofGetProofRequestAttachment, disclosedProofGenerateProof, disclosedProofDeclinePresentationRequest, disclosedProofGetThreadId, issuerCredentialDeserialize, issuerCredentialSerialize, issuerCredentialUpdateStateV2, issuerCredentialUpdateStateWithMessageV2, issuerCredentialUpdateStateWithMessageNonmediated, issuerCredentialGetState, issuerCredentialGetRevRegId, issuerCredentialCreate, issuerCredentialRevokeLocal, issuerCredentialIsRevokable, issuerCredentialSendCredential, issuerCredentialSendCredentialNonmediated, issuerCredentialSendOfferV2, issuerCredentialSendOfferNonmediated, issuerCredentialMarkOfferMsgSent, issuerCredentialBuildOfferMsgV2, issuerCredentialGetOfferMsg, issuerCredentialRelease, issuerCredentialGetThreadId, getLedgerAuthorAgreement, setActiveTxnAuthorAgreementMeta, createService, getServiceFromLedger, getVerkeyFromLedger, getLedgerTxn, initDefaultLogger, mediatedConnectionGeneratePublicInvite, mediatedConnectionGetPwDid, mediatedConnectionGetTheirPwDid, mediatedConnectionGetThreadId, mediatedConnectionGetState, mediatedConnectionGetSourceId, mediatedConnectionCreate, mediatedConnectionCreateWithInvite, mediatedConnectionSendMessage, mediatedConnectionCreateWithConnectionRequestV2, mediatedConnectionSendHandshakeReuse, mediatedConnectionUpdateStateWithMessage, mediatedConnectionHandleMessage, mediatedConnectionUpdateState, mediatedConnectionDeleteConnection, mediatedConnectionConnect, mediatedConnectionSerialize, mediatedConnectionDeserialize, mediatedConnectionRelease, mediatedConnectionInviteDetails, mediatedConnectionSendPing, mediatedConnectionSendDiscoveryFeatures, mediatedConnectionInfo, mediatedConnectionMessagesDownload, mediatedConnectionSignData, mediatedConnectionVerifySignature, outOfBandBuildHandshakeReuseAcceptedMsg, outOfBandReceiverCreate, outOfBandReceiverExtractMessage, outOfBandReceiverConnectionExists, outOfBandReceiverNonmediatedConnectionExists, outOfBandReceiverBuildConnection, outOfBandReceiverGetThreadId, outOfBandReceiverSerialize, outOfBandReceiverDeserialize, outOfBandReceiverRelease, outOfBandSenderCreate, outOfBandSenderAppendMessage, outOfBandSenderAppendService, outOfBandSenderAppendServiceDid, outOfBandSenderToMessage, outOfBandSenderGetThreadId, outOfBandSenderSerialize, outOfBandSenderDeserialize, outOfBandSenderRelease, openMainPool, closeMainPool, proofCreate, proofGetProofMsg, proofRelease, proofSendRequest, proofSendRequestNonmediated, proofGetRequestMsg, proofSerialize, proofDeserialize, v2ProofUpdateState, v2ProofUpdateStateWithMessage, proofUpdateStateWithMessageNonmediated, proofGetState, proofGetProofState, proofGetThreadId, markPresentationRequestMsgSent, revocationRegistryCreate, revocationRegistryPublish, revocationRegistryPublishRevocations, revocationRegistryGetRevRegId, revocationRegistryGetTailsHash, revocationRegistrySerialize, revocationRegistryDeserialize, revocationRegistryRelease, schemaGetAttributes, schemaPrepareForEndorser, schemaCreate, schemaGetSchemaId, schemaDeserialize, schemaSerialize, schemaRelease, schemaUpdateState, schemaGetState, enableMocks, trustpingBuildResponseMsg, trustpingBuildPing, shutdown, getVersion, walletOpenAsMain, walletCreateMain, walletCloseMain, vcxInitIssuerConfig, configureIssuerWallet, unpack, createPairwiseInfo, walletImport, walletExport, getVerkeyFromWallet, rotateVerkey, rotateVerkeyStart, rotateVerkeyApply } = nativeBinding module.exports.updateWebhookUrl = updateWebhookUrl module.exports.createAgencyClientForMainWallet = createAgencyClientForMainWallet @@ -270,6 +270,7 @@ module.exports.connectionSendResponse = connectionSendResponse module.exports.connectionSendRequest = connectionSendRequest module.exports.connectionSendAck = connectionSendAck module.exports.connectionSendGenericMessage = connectionSendGenericMessage +module.exports.connectionSendAriesMessage = connectionSendAriesMessage module.exports.connectionCreateInvite = connectionCreateInvite module.exports.connectionSerialize = connectionSerialize module.exports.connectionDeserialize = connectionDeserialize diff --git a/wrappers/vcx-napi-rs/package-lock.json b/wrappers/vcx-napi-rs/package-lock.json index 1badc6beb0..9fca1d59e9 100644 --- a/wrappers/vcx-napi-rs/package-lock.json +++ b/wrappers/vcx-napi-rs/package-lock.json @@ -19,9 +19,9 @@ } }, "node_modules/@napi-rs/cli": { - "version": "2.14.6", - "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.14.6.tgz", - "integrity": "sha512-q63+fI0JB9LV3RDYQN7yyAzmWDrErz+5ZMM1EyB5RA7ZwTTRYvXxg204w9+xTuZnpQfSyLMxxKGz2mfDVqFing==", + "version": "2.14.7", + "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.14.7.tgz", + "integrity": "sha512-H+YCgdbBNMWn8c878C3RsRYcMxamWI7rB0H+1TqOy9n6u31isikcRyW1VDyoNHp7ApfmzV0+tpPopVi0W7WHAA==", "dev": true, "bin": { "napi": "scripts/index.js" @@ -56,9 +56,9 @@ }, "dependencies": { "@napi-rs/cli": { - "version": "2.14.6", - "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.14.6.tgz", - "integrity": "sha512-q63+fI0JB9LV3RDYQN7yyAzmWDrErz+5ZMM1EyB5RA7ZwTTRYvXxg204w9+xTuZnpQfSyLMxxKGz2mfDVqFing==", + "version": "2.14.7", + "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.14.7.tgz", + "integrity": "sha512-H+YCgdbBNMWn8c878C3RsRYcMxamWI7rB0H+1TqOy9n6u31isikcRyW1VDyoNHp7ApfmzV0+tpPopVi0W7WHAA==", "dev": true }, "@types/node": { diff --git a/wrappers/vcx-napi-rs/src/api/connection.rs b/wrappers/vcx-napi-rs/src/api/connection.rs index 594167f97d..1d32f03ea4 100644 --- a/wrappers/vcx-napi-rs/src/api/connection.rs +++ b/wrappers/vcx-napi-rs/src/api/connection.rs @@ -145,7 +145,9 @@ pub async fn connection_send_generic_message(handle: u32, content: String) -> na .set_out_time() .to_a2a_message(); - let basic_message = serde_json::to_string(&message).map_err(From::from).map_err(to_napi_err)?; + let basic_message = serde_json::to_string(&message) + .map_err(From::from) + .map_err(to_napi_err)?; connection::send_generic_message(handle, basic_message) .await .map_err(to_napi_err) From eacc08d9459a4eab5ac32ff9300ddcfbc3787929 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Wed, 8 Feb 2023 15:18:37 +0200 Subject: [PATCH 63/66] Fixed comment link Signed-off-by: Bogdan Mircea --- aries_vcx/src/protocols/connection/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aries_vcx/src/protocols/connection/mod.rs b/aries_vcx/src/protocols/connection/mod.rs index f2d7d833e7..9b6355e02f 100644 --- a/aries_vcx/src/protocols/connection/mod.rs +++ b/aries_vcx/src/protocols/connection/mod.rs @@ -31,7 +31,7 @@ use self::{ pub use self::generic::{GenericConnection, State, ThinState}; -/// A state machine for progressing through the (connection protocol)[https://github.com/hyperledger/aries-rfcs/blob/main/features/0160-connection-protocol/README.md]. +/// A state machine for progressing through the [connection protocol](https://github.com/hyperledger/aries-rfcs/blob/main/features/0160-connection-protocol/README.md). #[derive(Clone, Deserialize)] #[serde(try_from = "GenericConnection")] #[serde(bound = "(I, S): TryFrom")] From 735c302cd6a33f7ccfd1860a6d46084ce7bcf95f Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Wed, 8 Feb 2023 17:39:11 +0200 Subject: [PATCH 64/66] Updated napi and napi-derive dependencies version Signed-off-by: Bogdan Mircea --- Cargo.lock | 16 ++++++++-------- wrappers/vcx-napi-rs/Cargo.toml | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 46e1d44cc8..e97973067f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2457,9 +2457,9 @@ checksum = "4330eca86d39f2b52d0481aa1e90fe21bfa61f11b0bf9b48ab95595013cefe48" [[package]] name = "napi" -version = "2.9.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743fece4c26c5132f8559080145fde9ba88700c0f1aa30a1ab3e057ab105814d" +checksum = "12ebacf7adce379df316ada032ae1705248194a20fb5a36d9c0bf651e24f1464" dependencies = [ "bitflags", "ctor", @@ -2477,9 +2477,9 @@ checksum = "882a73d9ef23e8dc2ebbffb6a6ae2ef467c0f18ac10711e4cc59c5485d41df0e" [[package]] name = "napi-derive" -version = "2.9.3" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af4e44e34e70aa61be9036ae652e27c20db5bca80e006be0f482419f6601352a" +checksum = "03f15c1ac0eac01eca2a24c27905ab47f7411acefd829d0d01fb131dc39befd7" dependencies = [ "convert_case 0.6.0", "napi-derive-backend", @@ -2490,9 +2490,9 @@ dependencies = [ [[package]] name = "napi-derive-backend" -version = "1.0.40" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17925fff04b6fa636f8e4b4608cc1a4f1360b64ac8ecbfdb7da1be1dc74f6843" +checksum = "4930d5fa70f5663b9e7d6b4f0816b70d095574ee7f3c865fdb8c43b0f7e6406d" dependencies = [ "convert_case 0.6.0", "once_cell", @@ -2504,9 +2504,9 @@ dependencies = [ [[package]] name = "napi-sys" -version = "2.2.2" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "529671ebfae679f2ce9630b62dd53c72c56b3eb8b2c852e7e2fa91704ff93d67" +checksum = "166b5ef52a3ab5575047a9fe8d4a030cdd0f63c96f071cd6907674453b07bae3" dependencies = [ "libloading 0.7.4", ] diff --git a/wrappers/vcx-napi-rs/Cargo.toml b/wrappers/vcx-napi-rs/Cargo.toml index 38b4575473..55f5c147d7 100644 --- a/wrappers/vcx-napi-rs/Cargo.toml +++ b/wrappers/vcx-napi-rs/Cargo.toml @@ -17,8 +17,8 @@ test_utils = [ "libvcx/test_utils" ] [dependencies] libvcx = { path = "../../libvcx", default-features = false } log = "0.4.16" -napi = { version = "=2.9.1", default-features = false, features = [ "async" ] } -napi-derive = { version = "=2.9.3" } +napi = { version = "2.10.14", default-features = false, features = [ "async" ] } +napi-derive = { version = "2.10.1" } [build-dependencies] napi-build = "2.0.1" From afd198d506b81a33174785b6c1f6508bf85dbcec Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Thu, 9 Feb 2023 13:38:24 +0200 Subject: [PATCH 65/66] Made from_parts public and added into_parts method on Connection Signed-off-by: Bogdan Mircea --- aries_vcx/src/protocols/connection/mod.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/aries_vcx/src/protocols/connection/mod.rs b/aries_vcx/src/protocols/connection/mod.rs index 9b6355e02f..d2cfc6afdb 100644 --- a/aries_vcx/src/protocols/connection/mod.rs +++ b/aries_vcx/src/protocols/connection/mod.rs @@ -43,7 +43,7 @@ pub struct Connection { } impl Connection { - pub(crate) fn from_parts(source_id: String, pairwise_info: PairwiseInfo, initiation_type: I, state: S) -> Self { + pub fn from_parts(source_id: String, pairwise_info: PairwiseInfo, initiation_type: I, state: S) -> Self { Self { source_id, pairwise_info, @@ -52,6 +52,16 @@ impl Connection { } } + pub fn into_parts(self) -> (String, PairwiseInfo, I, S) { + let Self { + source_id, + pairwise_info, + initiation_type, + state, + } = self; + (source_id, pairwise_info, initiation_type, state) + } + pub fn pairwise_info(&self) -> &PairwiseInfo { &self.pairwise_info } From 3cb83fb6b47eb5ec8975b305762c65bdb392c7a3 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Thu, 9 Feb 2023 13:47:42 +0200 Subject: [PATCH 66/66] Made node wrapper serialize a connection as a JSON object instead of string Signed-off-by: Bogdan Mircea --- wrappers/node/src/api/connection.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wrappers/node/src/api/connection.ts b/wrappers/node/src/api/connection.ts index 65d9301301..dd03cbbe8f 100644 --- a/wrappers/node/src/api/connection.ts +++ b/wrappers/node/src/api/connection.ts @@ -139,7 +139,7 @@ export class NonmediatedConnection extends VcxBaseWithState { try { return await ffiNapi.connectionSendAriesMessage(this.handle, content); @@ -190,7 +190,7 @@ export class NonmediatedConnection extends VcxBaseWithState { - const data = ffiNapi.connectionSerialize(handle); + const data = JSON.parse(ffiNapi.connectionSerialize(handle)); return JSON.stringify({ data, source_id: this.sourceId, version: '1.0' }); } protected _deserializeFn = ffiNapi.connectionDeserialize;