From 2835fa3210450ec8232a9a6812a2bf28f20a1b7a Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Mon, 29 Nov 2021 12:22:55 -0500 Subject: [PATCH 01/15] rename clchain -> b2b --- contracts/eden/CMakeLists.txt | 4 +- contracts/eden/src/eden-micro-chain.cpp | 93 +++++++++---------- contracts/eden/tests/include/tester-base.hpp | 2 +- libraries/CMakeLists.txt | 2 +- libraries/{clchain => btb}/CMakeLists.txt | 12 +-- .../include/btb}/chainbase.hpp | 2 +- .../include/btb/chainbase_undo_index.hpp} | 0 .../clchain => btb/include/btb}/crypto.hpp | 2 +- .../clchain => btb/include/btb}/graphql.hpp | 16 ++-- .../include/btb}/graphql_connection.hpp | 6 +- .../clchain => btb/include/btb}/subchain.hpp | 10 +- .../include/btb}/subchain_tester_dfuse.hpp | 2 +- libraries/{clchain => btb}/src/crypto.cpp | 6 +- .../wasi-polyfill/__wasi_environ_get.cpp | 0 .../__wasi_environ_sizes_get.cpp | 0 .../wasi-polyfill/__wasi_fd_read.cpp | 0 .../wasi-polyfill/__wasi_proc_exit.cpp | 2 +- .../wasi-polyfill/eosio_assert.cpp | 0 .../wasi-polyfill/polyfill_helpers.hpp | 2 +- .../{clchain => btb}/wasi-polyfill/print.cpp | 4 +- .../eden-subchain-client/src/EdenSubchain.ts | 2 +- 21 files changed, 80 insertions(+), 87 deletions(-) rename libraries/{clchain => btb}/CMakeLists.txt (57%) rename libraries/{clchain/include/chainbase => btb/include/btb}/chainbase.hpp (99%) rename libraries/{clchain/include/chainbase/undo_index.hpp => btb/include/btb/chainbase_undo_index.hpp} (100%) rename libraries/{clchain/include/clchain => btb/include/btb}/crypto.hpp (86%) rename libraries/{clchain/include/clchain => btb/include/btb}/graphql.hpp (98%) rename libraries/{clchain/include/clchain => btb/include/btb}/graphql_connection.hpp (98%) rename libraries/{clchain/include/clchain => btb/include/btb}/subchain.hpp (95%) rename libraries/{clchain/include/clchain => btb/include/btb}/subchain_tester_dfuse.hpp (99%) rename libraries/{clchain => btb}/src/crypto.cpp (76%) rename libraries/{clchain => btb}/wasi-polyfill/__wasi_environ_get.cpp (100%) rename libraries/{clchain => btb}/wasi-polyfill/__wasi_environ_sizes_get.cpp (100%) rename libraries/{clchain => btb}/wasi-polyfill/__wasi_fd_read.cpp (100%) rename libraries/{clchain => btb}/wasi-polyfill/__wasi_proc_exit.cpp (71%) rename libraries/{clchain => btb}/wasi-polyfill/eosio_assert.cpp (100%) rename libraries/{clchain => btb}/wasi-polyfill/polyfill_helpers.hpp (74%) rename libraries/{clchain => btb}/wasi-polyfill/print.cpp (77%) diff --git a/contracts/eden/CMakeLists.txt b/contracts/eden/CMakeLists.txt index 769d64dbe..5c321f002 100644 --- a/contracts/eden/CMakeLists.txt +++ b/contracts/eden/CMakeLists.txt @@ -49,7 +49,7 @@ function(add_test_eden test_file suffix) ../token/include ../boot/include ../../external/atomicassets-contract/include - ../../libraries/clchain/include + ../../libraries/btb/include ./tests/include ) target_link_libraries(${test_file}${suffix} catch2 cltestlib${suffix}) @@ -70,7 +70,7 @@ function(add_eden_microchain suffix) add_executable(eden-micro-chain${suffix} src/eden-micro-chain.cpp ) - target_link_libraries(eden-micro-chain${suffix} clchain${suffix} eosio-contracts-wasi-polyfill${suffix}) + target_link_libraries(eden-micro-chain${suffix} btb${suffix} eosio-contracts-wasi-polyfill${suffix}) target_include_directories(eden-micro-chain${suffix} PRIVATE include ../../libraries/eosiolib/contracts/include diff --git a/contracts/eden/src/eden-micro-chain.cpp b/contracts/eden/src/eden-micro-chain.cpp index 603ab85e1..86eb7550e 100644 --- a/contracts/eden/src/eden-micro-chain.cpp +++ b/contracts/eden/src/eden-micro-chain.cpp @@ -2,10 +2,10 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include #include @@ -171,37 +171,34 @@ enum tables struct Induction; constexpr const char InductionConnection_name[] = "InductionConnection"; constexpr const char InductionEdge_name[] = "InductionEdge"; -using InductionConnection = clchain::Connection< - clchain::ConnectionConfig>; +using InductionConnection = + btb::Connection>; struct MemberElection; constexpr const char MemberElectionConnection_name[] = "MemberElectionConnection"; constexpr const char MemberElectionEdge_name[] = "MemberElectionEdge"; -using MemberElectionConnection = - clchain::Connection>; +using MemberElectionConnection = btb::Connection< + btb::ConnectionConfig>; struct Vote; using vote_key = std::tuple; constexpr const char VoteConnection_name[] = "VoteConnection"; constexpr const char VoteEdge_name[] = "VoteEdge"; using VoteConnection = - clchain::Connection>; + btb::Connection>; struct DistributionFund; constexpr const char DistributionFundConnection_name[] = "DistributionFundConnection"; constexpr const char DistributionFundEdge_name[] = "DistributionFundEdge"; using DistributionFundConnection = - clchain::Connection>; + btb::Connection>; struct Nft; constexpr const char NftConnection_name[] = "NftConnection"; constexpr const char NftEdge_name[] = "NftEdge"; -using NftConnection = - clchain::Connection>; +using NftConnection = btb::Connection>; struct status { @@ -626,10 +623,8 @@ std::vector get_members(const std::vector& v); struct BalanceHistory; constexpr const char BalanceHistoryConnection_name[] = "BalanceHistoryConnection"; constexpr const char BalanceHistoryEdge_name[] = "BalanceHistoryEdge"; -using BalanceHistoryConnection = - clchain::Connection>; +using BalanceHistoryConnection = btb::Connection< + btb::ConnectionConfig>; struct Balance { @@ -657,8 +652,8 @@ EOSIO_REFLECT2(Balance, constexpr const char BalanceConnection_name[] = "BalanceConnection"; constexpr const char BalanceEdge_name[] = "BalanceEdge"; -using BalanceConnection = clchain::Connection< - clchain::ConnectionConfig>; +using BalanceConnection = + btb::Connection>; Balance get_balance(eosio::name account) { @@ -690,7 +685,7 @@ BalanceHistoryConnection Balance::history(std::optional std::optional before, std::optional after) const { - return clchain::make_connection( + return btb::make_connection( gt ? std::optional{balance_history_key{_account, *gt, ~uint64_t(0)}} // : std::nullopt, // ge ? std::optional{balance_history_key{_account, *ge, 0}} // @@ -870,14 +865,14 @@ EOSIO_REFLECT2(Status, struct ElectionRound; constexpr const char ElectionRoundConnection_name[] = "ElectionRoundConnection"; constexpr const char ElectionRoundEdge_name[] = "ElectionRoundEdge"; -using ElectionRoundConnection = clchain::Connection< - clchain::ConnectionConfig>; +using ElectionRoundConnection = btb::Connection< + btb::ConnectionConfig>; struct ElectionGroup; constexpr const char ElectionGroupConnection_name[] = "ElectionGroupConnection"; constexpr const char ElectionGroupEdge_name[] = "ElectionGroupEdge"; -using ElectionGroupConnection = clchain::Connection< - clchain::ConnectionConfig>; +using ElectionGroupConnection = btb::Connection< + btb::ConnectionConfig>; struct Election { @@ -940,7 +935,7 @@ MemberElectionConnection Member::elections(std::optional std::optional before, std::optional after) const { - return clchain::make_connection( + return btb::make_connection( gt, ge, lt, le, first, last, before, after, // db.elections.get(), // [](auto& obj) { return obj.time; }, // @@ -995,7 +990,7 @@ ElectionRoundConnection Election::rounds(std::optional gt, std::optional before, std::optional after) const { - return clchain::make_connection( + return btb::make_connection( gt ? std::optional{ElectionRoundKey{obj->time, *gt}} // : std::nullopt, // ge ? std::optional{ElectionRoundKey{obj->time, *ge}} // @@ -1031,7 +1026,7 @@ ElectionGroupConnection ElectionRound::groups(std::optional first, std::optional before, std::optional after) const { - return clchain::make_connection( + return btb::make_connection( std::nullopt, // gt std::optional{ElectionGroupByRoundKey{obj->election_time, obj->round, 0}}, // ge std::nullopt, // lt @@ -1079,7 +1074,7 @@ VoteConnection MemberElection::votes(std::optional first, std::optional before, std::optional after) const { - return clchain::make_connection( + return btb::make_connection( std::nullopt, // gt vote_key{account, election->time, 0}, // ge std::nullopt, // lt @@ -1124,7 +1119,7 @@ DistributionFundConnection Member::distributionFunds(std::optional before, std::optional after) const { - return clchain::make_connection( + return btb::make_connection( gt ? std::optional{distribution_fund_key{account, *gt, ~uint8_t(0)}} // : std::nullopt, // ge ? std::optional{distribution_fund_key{account, *ge, 0}} // @@ -1176,7 +1171,7 @@ NftConnection Member::nfts(std::optional gt, std::optional before, std::optional after) const { - return clchain::make_connection( + return btb::make_connection( gt ? std::optional{nft_account_key{account, *gt, ~uint64_t(0)}} // : std::nullopt, // ge ? std::optional{nft_account_key{account, *ge, 0}} // @@ -1203,7 +1198,7 @@ NftConnection Member::collectedNfts(std::optional gt, std::optional before, std::optional after) const { - return clchain::make_connection( + return btb::make_connection( gt ? std::optional{nft_account_key{account, *gt, ~uint64_t(0)}} // : std::nullopt, // ge ? std::optional{nft_account_key{account, *ge, 0}} // @@ -2072,7 +2067,7 @@ bool add_block(subchain::block&& eden_block, uint32_t eosio_irreversible) auto bin = eosio::convert_to_bin(eden_block); subchain::block_with_id bi; static_cast(bi) = std::move(eden_block); - bi.id = clchain::sha256(bin.data(), bin.size()); + bi.id = btb::sha256(bin.data(), bin.size()); auto bin_with_id = eosio::convert_to_bin(bi.id); bin_with_id.insert(bin_with_id.end(), bin.begin(), bin.end()); result = std::move(bin_with_id); @@ -2218,17 +2213,17 @@ bool add_block(eosio::ship_protocol::block_position block, constexpr const char MemberConnection_name[] = "MemberConnection"; constexpr const char MemberEdge_name[] = "MemberEdge"; using MemberConnection = - clchain::Connection>; + btb::Connection>; constexpr const char ElectionConnection_name[] = "ElectionConnection"; constexpr const char ElectionEdge_name[] = "ElectionEdge"; -using ElectionConnection = clchain::Connection< - clchain::ConnectionConfig>; +using ElectionConnection = + btb::Connection>; constexpr const char DistributionConnection_name[] = "DistributionConnection"; constexpr const char DistributionEdge_name[] = "DistributionEdge"; -using DistributionConnection = clchain::Connection< - clchain::ConnectionConfig>; +using DistributionConnection = btb::Connection< + btb::ConnectionConfig>; struct Query { @@ -2251,7 +2246,7 @@ struct Query std::optional before, std::optional after) const { - return clchain::make_connection( + return btb::make_connection( gt, ge, lt, le, first, last, before, after, // db.balances.get(), // [](auto& obj) { return obj.account; }, // @@ -2274,7 +2269,7 @@ struct Query std::optional before, std::optional after) const { - return clchain::make_connection( + return btb::make_connection( gt, ge, lt, le, first, last, before, after, // db.members.get(), // [](auto& obj) { return obj.member.account; }, // @@ -2294,7 +2289,7 @@ struct Query std::optional before, std::optional after) const { - return clchain::make_connection( + return btb::make_connection( gt ? std::optional{MemberCreatedAtKey{*gt, account_max}} // : std::nullopt, // ge ? std::optional{MemberCreatedAtKey{*ge, account_min}} // @@ -2322,7 +2317,7 @@ struct Query std::optional before, std::optional after) const { - return clchain::make_connection( + return btb::make_connection( gt, ge, lt, le, first, last, before, after, // db.inductions.get(), // [](auto& obj) { return obj.induction.id; }, // @@ -2342,7 +2337,7 @@ struct Query std::optional before, std::optional after) const { - return clchain::make_connection( + return btb::make_connection( gt ? std::optional{InductionCreatedAtKey{*gt, ~uint64_t(0)}} // : std::nullopt, // ge ? std::optional{InductionCreatedAtKey{*ge, 0}} // @@ -2370,7 +2365,7 @@ struct Query std::optional before, std::optional after) const { - return clchain::make_connection( + return btb::make_connection( gt, ge, lt, le, first, last, before, after, // db.elections.get(), // [](auto& obj) { return obj.time; }, // @@ -2388,7 +2383,7 @@ struct Query std::optional before, std::optional after) const { - return clchain::make_connection( + return btb::make_connection( gt, ge, lt, le, first, last, before, after, // db.distributions.get(), // [](auto& obj) { return obj.time; }, // @@ -2411,7 +2406,7 @@ EOSIO_REFLECT2( method(elections, "gt", "ge", "lt", "le", "first", "last", "before", "after"), method(distributions, "gt", "ge", "lt", "le", "first", "last", "before", "after")) -auto schema = clchain::get_gql_schema(); +auto schema = btb::get_gql_schema(); [[clang::export_name("getSchemaSize")]] uint32_t getSchemaSize() { return schema.size(); @@ -2427,5 +2422,5 @@ auto schema = clchain::get_gql_schema(); uint32_t variables_size) { Query root{block_log}; - result = clchain::gql_query(root, {query, size}, {variables, variables_size}); + result = btb::gql_query(root, {query, size}, {variables, variables_size}); } diff --git a/contracts/eden/tests/include/tester-base.hpp b/contracts/eden/tests/include/tester-base.hpp index 3bf2178a0..4d372c57c 100644 --- a/contracts/eden/tests/include/tester-base.hpp +++ b/contracts/eden/tests/include/tester-base.hpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include #include diff --git a/libraries/CMakeLists.txt b/libraries/CMakeLists.txt index d672beaae..e35cfb8db 100644 --- a/libraries/CMakeLists.txt +++ b/libraries/CMakeLists.txt @@ -11,5 +11,5 @@ if(DEFINED IS_NATIVE) add_subdirectory(state_history) endif() -add_subdirectory(clchain) +add_subdirectory(btb) add_subdirectory(rodeos) diff --git a/libraries/clchain/CMakeLists.txt b/libraries/btb/CMakeLists.txt similarity index 57% rename from libraries/clchain/CMakeLists.txt rename to libraries/btb/CMakeLists.txt index 6f7285de1..e4afcd625 100644 --- a/libraries/clchain/CMakeLists.txt +++ b/libraries/btb/CMakeLists.txt @@ -1,15 +1,15 @@ find_package(OpenSSL REQUIRED Crypto) function(add suffix) - add_library(clchain${suffix}) - target_link_libraries(clchain${suffix} PUBLIC abieos${suffix} boost OpenSSL::Crypto) - target_include_directories(clchain${suffix} PUBLIC include) - target_sources(clchain${suffix} PRIVATE + add_library(btb${suffix}) + target_link_libraries(btb${suffix} PUBLIC abieos${suffix} boost OpenSSL::Crypto) + target_include_directories(btb${suffix} PUBLIC include) + target_sources(btb${suffix} PRIVATE src/crypto.cpp ) if(DEFINED IS_WASM) - target_link_libraries(clchain${suffix} PUBLIC wasm-base${suffix}) - target_sources(clchain${suffix} PRIVATE + target_link_libraries(btb${suffix} PUBLIC wasm-base${suffix}) + target_sources(btb${suffix} PRIVATE wasi-polyfill/__wasi_environ_get.cpp wasi-polyfill/__wasi_environ_sizes_get.cpp wasi-polyfill/__wasi_fd_read.cpp diff --git a/libraries/clchain/include/chainbase/chainbase.hpp b/libraries/btb/include/btb/chainbase.hpp similarity index 99% rename from libraries/clchain/include/chainbase/chainbase.hpp rename to libraries/btb/include/btb/chainbase.hpp index cd6487471..0d21f00bb 100644 --- a/libraries/clchain/include/chainbase/chainbase.hpp +++ b/libraries/btb/include/btb/chainbase.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include diff --git a/libraries/clchain/include/chainbase/undo_index.hpp b/libraries/btb/include/btb/chainbase_undo_index.hpp similarity index 100% rename from libraries/clchain/include/chainbase/undo_index.hpp rename to libraries/btb/include/btb/chainbase_undo_index.hpp diff --git a/libraries/clchain/include/clchain/crypto.hpp b/libraries/btb/include/btb/crypto.hpp similarity index 86% rename from libraries/clchain/include/clchain/crypto.hpp rename to libraries/btb/include/btb/crypto.hpp index 3279b6860..e59187e14 100644 --- a/libraries/clchain/include/clchain/crypto.hpp +++ b/libraries/btb/include/btb/crypto.hpp @@ -2,7 +2,7 @@ #include -namespace clchain +namespace btb { eosio::checksum256 sha256(const char* data, uint32_t length); } diff --git a/libraries/clchain/include/clchain/graphql.hpp b/libraries/btb/include/btb/graphql.hpp similarity index 98% rename from libraries/clchain/include/clchain/graphql.hpp rename to libraries/btb/include/btb/graphql.hpp index cc92af90b..669479bd6 100644 --- a/libraries/clchain/include/clchain/graphql.hpp +++ b/libraries/btb/include/btb/graphql.hpp @@ -14,7 +14,7 @@ #include #include -namespace clchain +namespace btb { struct gql_stream; } @@ -48,17 +48,15 @@ namespace eosio } template - auto gql_query(const T& value, - clchain::gql_stream& input_stream, - OS& output_stream, - const E& error) -> std::enable_if_t + auto gql_query(const T& value, btb::gql_stream& input_stream, OS& output_stream, const E& error) + -> std::enable_if_t { to_json(value, output_stream); return true; } } // namespace eosio -namespace clchain +namespace btb { template struct has_get_gql_name @@ -824,15 +822,15 @@ namespace clchain eosio::time_point_include_z_stream>>(value, query); } -} // namespace clchain +} // namespace btb namespace eosio { template - auto gql_parse_arg(T& arg, clchain::gql_stream& input_stream, const E& error) + auto gql_parse_arg(T& arg, btb::gql_stream& input_stream, const E& error) -> std::enable_if_t { - if (input_stream.current_type == clchain::gql_stream::string) + if (input_stream.current_type == btb::gql_stream::string) { // TODO: prevent abort arg = eosio::convert_from_string(input_stream.current_value); diff --git a/libraries/clchain/include/clchain/graphql_connection.hpp b/libraries/btb/include/btb/graphql_connection.hpp similarity index 98% rename from libraries/clchain/include/clchain/graphql_connection.hpp rename to libraries/btb/include/btb/graphql_connection.hpp index ef42b74d0..2903c00b5 100644 --- a/libraries/clchain/include/clchain/graphql_connection.hpp +++ b/libraries/btb/include/btb/graphql_connection.hpp @@ -1,11 +1,11 @@ #pragma once -#include +#include #include #include #include -namespace clchain +namespace btb { struct PageInfo { @@ -158,4 +158,4 @@ namespace clchain } return result; } -} // namespace clchain +} // namespace btb diff --git a/libraries/clchain/include/clchain/subchain.hpp b/libraries/btb/include/btb/subchain.hpp similarity index 95% rename from libraries/clchain/include/clchain/subchain.hpp rename to libraries/btb/include/btb/subchain.hpp index d62449287..ddd67574a 100644 --- a/libraries/clchain/include/clchain/subchain.hpp +++ b/libraries/btb/include/btb/subchain.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include @@ -186,9 +186,9 @@ namespace subchain constexpr inline const char BlockConnection_name[] = "BlockConnection"; constexpr inline const char BlockEdge_name[] = "BlockEdge"; using BlockConnection = - clchain::Connection, - BlockConnection_name, - BlockEdge_name>>; + btb::Connection, + BlockConnection_name, + BlockEdge_name>>; struct BlockLog { @@ -203,7 +203,7 @@ namespace subchain std::optional before, std::optional after) const { - return clchain::make_connection( + return btb::make_connection( gt, ge, lt, le, first, last, before, after, // log.blocks, // [](auto& block) { return block->num; }, // diff --git a/libraries/clchain/include/clchain/subchain_tester_dfuse.hpp b/libraries/btb/include/btb/subchain_tester_dfuse.hpp similarity index 99% rename from libraries/clchain/include/clchain/subchain_tester_dfuse.hpp rename to libraries/btb/include/btb/subchain_tester_dfuse.hpp index 70c2964d8..c8ec27d15 100644 --- a/libraries/clchain/include/clchain/subchain_tester_dfuse.hpp +++ b/libraries/btb/include/btb/subchain_tester_dfuse.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include diff --git a/libraries/clchain/src/crypto.cpp b/libraries/btb/src/crypto.cpp similarity index 76% rename from libraries/clchain/src/crypto.cpp rename to libraries/btb/src/crypto.cpp index 230279a4e..1e14580c8 100644 --- a/libraries/clchain/src/crypto.cpp +++ b/libraries/btb/src/crypto.cpp @@ -1,8 +1,8 @@ -#include +#include #include -namespace clchain +namespace btb { eosio::checksum256 sha256(const char* data, uint32_t length) { @@ -10,4 +10,4 @@ namespace clchain SHA256((const unsigned char*)data, length, result.data()); return result; } -} // namespace clchain +} // namespace btb diff --git a/libraries/clchain/wasi-polyfill/__wasi_environ_get.cpp b/libraries/btb/wasi-polyfill/__wasi_environ_get.cpp similarity index 100% rename from libraries/clchain/wasi-polyfill/__wasi_environ_get.cpp rename to libraries/btb/wasi-polyfill/__wasi_environ_get.cpp diff --git a/libraries/clchain/wasi-polyfill/__wasi_environ_sizes_get.cpp b/libraries/btb/wasi-polyfill/__wasi_environ_sizes_get.cpp similarity index 100% rename from libraries/clchain/wasi-polyfill/__wasi_environ_sizes_get.cpp rename to libraries/btb/wasi-polyfill/__wasi_environ_sizes_get.cpp diff --git a/libraries/clchain/wasi-polyfill/__wasi_fd_read.cpp b/libraries/btb/wasi-polyfill/__wasi_fd_read.cpp similarity index 100% rename from libraries/clchain/wasi-polyfill/__wasi_fd_read.cpp rename to libraries/btb/wasi-polyfill/__wasi_fd_read.cpp diff --git a/libraries/clchain/wasi-polyfill/__wasi_proc_exit.cpp b/libraries/btb/wasi-polyfill/__wasi_proc_exit.cpp similarity index 71% rename from libraries/clchain/wasi-polyfill/__wasi_proc_exit.cpp rename to libraries/btb/wasi-polyfill/__wasi_proc_exit.cpp index a998498d8..2386d833b 100644 --- a/libraries/clchain/wasi-polyfill/__wasi_proc_exit.cpp +++ b/libraries/btb/wasi-polyfill/__wasi_proc_exit.cpp @@ -3,7 +3,7 @@ extern "C" _Noreturn void __wasi_proc_exit(__wasi_exitcode_t code) __attribute__((__import_module__("wasi_snapshot_preview1"), __import_name__("proc_exit"))) { - [[clang::import_module("clchain"), clang::import_name("exit"), noreturn]] void import_exit( + [[clang::import_module("btb"), clang::import_name("exit"), noreturn]] void import_exit( int32_t code); import_exit(code); } diff --git a/libraries/clchain/wasi-polyfill/eosio_assert.cpp b/libraries/btb/wasi-polyfill/eosio_assert.cpp similarity index 100% rename from libraries/clchain/wasi-polyfill/eosio_assert.cpp rename to libraries/btb/wasi-polyfill/eosio_assert.cpp diff --git a/libraries/clchain/wasi-polyfill/polyfill_helpers.hpp b/libraries/btb/wasi-polyfill/polyfill_helpers.hpp similarity index 74% rename from libraries/clchain/wasi-polyfill/polyfill_helpers.hpp rename to libraries/btb/wasi-polyfill/polyfill_helpers.hpp index 8001a38c4..02cfe7465 100644 --- a/libraries/clchain/wasi-polyfill/polyfill_helpers.hpp +++ b/libraries/btb/wasi-polyfill/polyfill_helpers.hpp @@ -4,7 +4,7 @@ namespace polyfill { - [[noreturn, clang::import_module("clchain"), clang::import_name("abort_message")]] void + [[noreturn, clang::import_module("btb"), clang::import_name("abort_message")]] void abort_message(const char*, uint32_t); template diff --git a/libraries/clchain/wasi-polyfill/print.cpp b/libraries/btb/wasi-polyfill/print.cpp similarity index 77% rename from libraries/clchain/wasi-polyfill/print.cpp rename to libraries/btb/wasi-polyfill/print.cpp index 710c54166..ee9bf98e3 100644 --- a/libraries/clchain/wasi-polyfill/print.cpp +++ b/libraries/btb/wasi-polyfill/print.cpp @@ -2,8 +2,8 @@ extern "C" void prints_l(const char* str, uint32_t len) { - [[clang::import_module("clchain"), clang::import_name("console")]] void import_console( - const char*, uint32_t); + [[clang::import_module("btb"), clang::import_name("console")]] void import_console(const char*, + uint32_t); import_console(str, len); } diff --git a/packages/eden-subchain-client/src/EdenSubchain.ts b/packages/eden-subchain-client/src/EdenSubchain.ts index 3756b88a2..6ecf45006 100644 --- a/packages/eden-subchain-client/src/EdenSubchain.ts +++ b/packages/eden-subchain-client/src/EdenSubchain.ts @@ -34,7 +34,7 @@ export class EdenSubchain { } imports = { - clchain: { + btb: { abort_message: (pos: number, len: number) => { throw new Error("abort: " + this.decodeStr(pos, len)); }, From b64633f41b960380225c134f996edc4213447cec Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Mon, 29 Nov 2021 14:11:15 -0500 Subject: [PATCH 02/15] Add b2b to clsdk --- libraries/btb/CMakeLists.txt | 1 + libraries/eosiolib/sdk/clsdk-config.cmake | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/libraries/btb/CMakeLists.txt b/libraries/btb/CMakeLists.txt index e4afcd625..49488a0a8 100644 --- a/libraries/btb/CMakeLists.txt +++ b/libraries/btb/CMakeLists.txt @@ -23,4 +23,5 @@ endfunction() add("") if(DEFINED IS_WASM) add("-debug") + copy_headers(include/btb btb/include/btb) endif() diff --git a/libraries/eosiolib/sdk/clsdk-config.cmake b/libraries/eosiolib/sdk/clsdk-config.cmake index eca76fc89..4b77c0bec 100644 --- a/libraries/eosiolib/sdk/clsdk-config.cmake +++ b/libraries/eosiolib/sdk/clsdk-config.cmake @@ -122,6 +122,11 @@ function(add_libs suffix) -DCATCH_CONFIG_DISABLE_EXCEPTIONS ) target_link_options(cltestlib${suffix} INTERFACE -Wl,--export-table) + + add_library(btb${suffix} INTERFACE) + target_include_directories(btb${suffix} INTERFACE ${clsdk_DIR}/btb/include) + target_link_libraries(btb${suffix} INTERFACE eosio-core${suffix}) + endfunction(add_libs) add_libs("") From e2bc8cb78c86f690b9522e72ea4252d057cff858 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Mon, 29 Nov 2021 15:50:51 -0500 Subject: [PATCH 03/15] doc graphql --- doc/clsdk/src/SUMMARY.md | 2 + doc/clsdk/src/graphql/README.md | 3 + .../starting/.vscode/c_cpp_properties.json | 15 +++ .../graphql/starting/.vscode/settings.json | 12 ++ doc/clsdk/src/graphql/starting/CMakeLists.txt | 41 +++++++ doc/clsdk/src/graphql/starting/README.md | 111 ++++++++++++++++++ .../src/graphql/starting/example-graphql.cpp | 42 +++++++ doc/clsdk/src/graphql/starting/example.cpp | 59 ++++++++++ doc/clsdk/src/graphql/starting/example.hpp | 58 +++++++++ doc/clsdk/src/graphql/starting/tests.cpp | 86 ++++++++++++++ 10 files changed, 429 insertions(+) create mode 100644 doc/clsdk/src/graphql/README.md create mode 100644 doc/clsdk/src/graphql/starting/.vscode/c_cpp_properties.json create mode 100644 doc/clsdk/src/graphql/starting/.vscode/settings.json create mode 100644 doc/clsdk/src/graphql/starting/CMakeLists.txt create mode 100644 doc/clsdk/src/graphql/starting/README.md create mode 100644 doc/clsdk/src/graphql/starting/example-graphql.cpp create mode 100644 doc/clsdk/src/graphql/starting/example.cpp create mode 100644 doc/clsdk/src/graphql/starting/example.hpp create mode 100644 doc/clsdk/src/graphql/starting/tests.cpp diff --git a/doc/clsdk/src/SUMMARY.md b/doc/clsdk/src/SUMMARY.md index 4166c46a3..965c38a8a 100644 --- a/doc/clsdk/src/SUMMARY.md +++ b/doc/clsdk/src/SUMMARY.md @@ -21,3 +21,5 @@ - [Block Control](cltester/block/README.md) - [Starting Nodeos](cltester/nodeos/README.md) - [Hostile Takeover](cltester/takeover/README.md) +- [GraphQL](graphql/README.md) + - [Getting Started](graphql/starting/README.md) diff --git a/doc/clsdk/src/graphql/README.md b/doc/clsdk/src/graphql/README.md new file mode 100644 index 000000000..fc0c389fd --- /dev/null +++ b/doc/clsdk/src/graphql/README.md @@ -0,0 +1,3 @@ +# GraphQL + +clsdk comes with the blocks-to-browser (btb) system. btb includes a library that supports running GraphQL queries within WASM. This chapter introduces GraphQL support separate from the rest of the btb system by running GraphQL within contracts. It doesn't use the new action-return-value system introduced with nodeos 2.1. Instead, it uses contract prints for compatibility with nodeos 2.0. diff --git a/doc/clsdk/src/graphql/starting/.vscode/c_cpp_properties.json b/doc/clsdk/src/graphql/starting/.vscode/c_cpp_properties.json new file mode 100644 index 000000000..69f4ade58 --- /dev/null +++ b/doc/clsdk/src/graphql/starting/.vscode/c_cpp_properties.json @@ -0,0 +1,15 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**" + ], + "cStandard": "c11", + "cppStandard": "c++20", + "intelliSenseMode": "linux-clang-x64", + "compileCommands": "${workspaceFolder}/build/compile_commands.json" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/doc/clsdk/src/graphql/starting/.vscode/settings.json b/doc/clsdk/src/graphql/starting/.vscode/settings.json new file mode 100644 index 000000000..63e387e85 --- /dev/null +++ b/doc/clsdk/src/graphql/starting/.vscode/settings.json @@ -0,0 +1,12 @@ +{ + // Stop the buggy CMake vscode extension from clobbering settings + // in the build folder. The extension makes bad assumptions + // about CMAKE_BUILD_TYPE, cross compilers, and other settings and + // is very aggressive at reverting settings that were set at the + // command line (it wipes CMakeCache). + "cmake.buildDirectory": "${workspaceFolder}/vscode-cmake-extension-is-bugged", + + // Don't let the buggy extension stop the debugger from functioning. + // Build from the command-line instead. + "cmake.buildBeforeRun": false +} \ No newline at end of file diff --git a/doc/clsdk/src/graphql/starting/CMakeLists.txt b/doc/clsdk/src/graphql/starting/CMakeLists.txt new file mode 100644 index 000000000..ebf4ca93e --- /dev/null +++ b/doc/clsdk/src/graphql/starting/CMakeLists.txt @@ -0,0 +1,41 @@ +# All cmake projects need these +cmake_minimum_required(VERSION 3.16) +project(example) + +# clsdk requires C++20 +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Libraries for building contracts and tests +find_package(clsdk REQUIRED) + +# Build example.wasm contract +add_executable(example example.cpp example-graphql.cpp) +target_link_libraries(example btb eosio-contract-simple-malloc) + +# Build example-debug.wasm +# This is like example.wasm, but includes debugging information. +add_executable(example-debug example.cpp example-graphql.cpp) +target_link_libraries(example-debug btb-debug eosio-contract-simple-malloc-debug) + +# Generate example.abi +# This is a 2-step process: +# * Build example.abi.wasm. This must link to eosio-contract-abigen. +# * Run the wasm to generate the abi +add_executable(example-abigen example.cpp) +target_link_libraries(example-abigen eosio-contract-abigen) +add_custom_command(TARGET example-abigen POST_BUILD + COMMAND cltester example-abigen.wasm >example.abi +) + +# Builds tests.wasm +# Tests must link to either cltestlib (runs faster) or cltestlib-debug (supports debugging) +add_executable(tests tests.cpp) +target_link_libraries(tests cltestlib-debug) + +# These symlinks help vscode +execute_process(COMMAND ln -sf ${clsdk_DIR} ${CMAKE_CURRENT_BINARY_DIR}/clsdk) +execute_process(COMMAND ln -sf ${WASI_SDK_PREFIX} ${CMAKE_CURRENT_BINARY_DIR}/wasi-sdk) + +# Generate compile_commands.json to aid vscode and other editors +set(CMAKE_EXPORT_COMPILE_COMMANDS on) diff --git a/doc/clsdk/src/graphql/starting/README.md b/doc/clsdk/src/graphql/starting/README.md new file mode 100644 index 000000000..471ee2395 --- /dev/null +++ b/doc/clsdk/src/graphql/starting/README.md @@ -0,0 +1,111 @@ +# GraphQL: Getting Started + +## Contract and Test Modifications + +This example is based on the [cltester Token Example](../../cltester/token/index.html), but has these changes: + +* The contract has two new actions: `graphql` and `graphqlschema`, which are shown below +* `CMakeLists.txt` adds the `btb` and `btb-debug` libraries as dependencies to `example.wasm` and `example-debug.wasm` +* The test case sets up a chain and starts nodeos + +The files: + +* [example.hpp](example.hpp) +* [example.cpp](example.cpp) +* [example-graphql.cpp](example-graphql.cpp) +* [tests.cpp](tests.cpp) +* [CMakeLists.txt](CMakeLists.txt) +* [.vscode/c_cpp_properties.json](.vscode/c_cpp_properties.json) +* [.vscode/settings.json](.vscode/settings.json) + +## Simple GraphQL Query + +`example-graphql.cpp`: +```cpp +{{#include example-graphql.cpp}} +``` + +## Starting the Example + +This builds the example and starts nodeos: + +``` +mkdir build +cd build +cmake `clsdk-cmake-args` .. +make -j $(nproc) +cltester tests.wasm +``` + +## Fetching the Schema + +This uses cleos to fetch the schema. cleos's `-v` option shows print output. + +``` +$ cleos -v push action example graphqlschema '[]' -p alice + +executed transaction: 79a16e17d6bde46a219a9e721ed17d610bbf7c2fa988f7db14e44b7e7fda97ae 96 bytes 185 us +# example <= example::graphqlschema "" +>> type animal { +>> name: String! +>> type: String! +>> owner: String! +>> purchase_price: String! +>> } +>> type Query { +>> contract: String! +>> animal(name: String!): animal +>> } +``` + +## Querying the Contract Name + +This queries the contract name: + +``` +$ cleos -v push action example graphql '["{contract}",""]' -p alice + +executed transaction: 50fa29906ed5b40b3c51dc396f2262c292eda6970813909ff3e06ebf18f618f2 104 bytes 177 us +# example <= example::graphql {"query":"{contract}"} +>> {"data": {"contract":"example"}} +``` + +## Querying an Animal + +This queries a specific animal. + +``` +$ cleos -v push action example graphql '["{animal(name:\"fido\"){name,type,owner,purchase_price}}",""]' -p alice + +executed transaction: 636a96b15cf7c1478992fc8f27716da7fc9c60105144a4c43ecf21035e840454 152 bytes 181 us +# example <= example::graphql {"query":"{animal(name:\"fido\"){name,type,owner,purchase_price}}"} +>> {"data": {"animal":{"name":"fido","type":"dog","owner":"alice","purchase_price":"100.0000 EOS"}}} +``` + +Here's the GraphQL query above: + +``` +{ + animal(name: "fido") { + name + type + owner + purchase_price + } +} +``` + +Here's the formatted output: + +``` +{ + "data": { + "animal": { + "name": "fido", + "type": "dog", + "owner": "alice", + "purchase_price": "100.0000 EOS" + } + } +} +``` diff --git a/doc/clsdk/src/graphql/starting/example-graphql.cpp b/doc/clsdk/src/graphql/starting/example-graphql.cpp new file mode 100644 index 000000000..0aa42d8f3 --- /dev/null +++ b/doc/clsdk/src/graphql/starting/example-graphql.cpp @@ -0,0 +1,42 @@ +#include "example.hpp" + +// GraphQL Support +#include + +// EOSIO_REFLECT2; augments methods with argument names +#include + +// The root of GraphQL queries +struct Query +{ + // Identify the contract + eosio::name contract; + + // Retrieve an animal, if it exists + std::optional animal(eosio::name name) const + { + example::animal_table table{contract, contract.value}; + auto it = table.find(name.value); + if (it != table.end()) + return *it; + else + return std::nullopt; + } +}; +EOSIO_REFLECT2(Query, // + contract, // query a field + method(animal, "name") // query a method; identifies the argument names +) + +// Action: execute a GraphQL query and print the result +void example::example_contract::graphql(const std::string& query) +{ + Query root{get_self()}; + eosio::print(btb::gql_query(root, query, "")); +} + +// Action: print the GraphQL schema +void example::example_contract::graphqlschema() +{ + eosio::print(btb::get_gql_schema()); +} diff --git a/doc/clsdk/src/graphql/starting/example.cpp b/doc/clsdk/src/graphql/starting/example.cpp new file mode 100644 index 000000000..1f4302337 --- /dev/null +++ b/doc/clsdk/src/graphql/starting/example.cpp @@ -0,0 +1,59 @@ +#include "example.hpp" + +#include +#include + +void example::example_contract::notify_transfer(eosio::name from, + eosio::name to, + const eosio::asset& quantity, + std::string memo) +{ + if (from == get_self()) + return; + eosio::check(quantity.symbol == eosio::symbol{"EOS", 4}, + "This contract does not deal with this token"); + add_balance(from, quantity); +} + +void example::example_contract::buydog(eosio::name user, eosio::name dog, const eosio::asset& price) +{ + require_auth(user); + eosio::check(price.symbol == eosio::symbol{"EOS", 4}, + "This contract does not deal with this token"); + eosio::check(price.amount >= 50'0000, "Dogs cost more than that"); + sub_balance(user, price); + animal_table table{get_self(), get_self().value}; + table.emplace(user, [&](auto& record) { + record.name = dog; + record.type = "dog"_n; + record.owner = user; + record.purchase_price = price; + }); +} + +void example::example_contract::add_balance(eosio::name owner, const eosio::asset& quantity) +{ + balance_table table(get_self(), get_self().value); + auto record = table.find(owner.value); + if (record == table.end()) + table.emplace(get_self(), [&](auto& a) { + a.owner = owner; + a.balance = quantity; + }); + else + table.modify(record, eosio::same_payer, [&](auto& a) { a.balance += quantity; }); +} + +void example::example_contract::sub_balance(eosio::name owner, const eosio::asset& quantity) +{ + balance_table table(get_self(), get_self().value); + const auto& record = table.get(owner.value, "user does not have a balance"); + eosio::check(record.balance.amount >= quantity.amount, "not enough funds deposited"); + table.modify(record, owner, [&](auto& a) { a.balance -= quantity; }); +} + +EOSIO_ACTION_DISPATCHER(example::actions) + +EOSIO_ABIGEN(actions(example::actions), + table("balance"_n, example::balance), + table("animal"_n, example::animal)) diff --git a/doc/clsdk/src/graphql/starting/example.hpp b/doc/clsdk/src/graphql/starting/example.hpp new file mode 100644 index 000000000..3fd489054 --- /dev/null +++ b/doc/clsdk/src/graphql/starting/example.hpp @@ -0,0 +1,58 @@ +#include +#include + +namespace example +{ + // Keep track of deposited funds + struct balance + { + eosio::name owner; + eosio::asset balance; + + uint64_t primary_key() const { return owner.value; } + }; + EOSIO_REFLECT(balance, owner, balance) + typedef eosio::multi_index<"balance"_n, balance> balance_table; + + // A purchased animal + struct animal + { + eosio::name name; + eosio::name type; + eosio::name owner; + eosio::asset purchase_price; + + uint64_t primary_key() const { return name.value; } + }; + EOSIO_REFLECT(animal, name, type, owner, purchase_price) + typedef eosio::multi_index<"animal"_n, animal> animal_table; + + struct example_contract : public eosio::contract + { + using eosio::contract::contract; + + void notify_transfer(eosio::name from, + eosio::name to, + const eosio::asset& quantity, + std::string memo); + + void buydog(eosio::name user, eosio::name dog, const eosio::asset& price); + + void add_balance(eosio::name owner, const eosio::asset& quantity); + + void sub_balance(eosio::name owner, const eosio::asset& quantity); + + // Action: execute a GraphQL query and print the result + void graphql(const std::string& query); + + // Action: print the GraphQL schema + void graphqlschema(); + }; + + EOSIO_ACTIONS(example_contract, + "example"_n, + notify("eosio.token"_n, transfer), // Hook up notification + action(buydog, user, dog, price), + action(graphql, query), + action(graphqlschema)) +} // namespace example diff --git a/doc/clsdk/src/graphql/starting/tests.cpp b/doc/clsdk/src/graphql/starting/tests.cpp new file mode 100644 index 000000000..003477c8b --- /dev/null +++ b/doc/clsdk/src/graphql/starting/tests.cpp @@ -0,0 +1,86 @@ +#include +#include // comes bundled with clsdk +#include "example.hpp" + +#define CATCH_CONFIG_MAIN +#include + +using namespace eosio; + +// Set up the token contract +void setup_token(test_chain& t) +{ + t.create_code_account("eosio.token"_n); + t.set_code("eosio.token"_n, CLSDK_CONTRACTS_DIR "token.wasm"); + + // Create and issue tokens. + t.as("eosio.token"_n).act("eosio"_n, s2a("1000000.0000 EOS")); + t.as("eosio.token"_n).act("eosio"_n, s2a("1000000.0000 OTHER")); + t.as("eosio"_n).act("eosio"_n, s2a("1000000.0000 EOS"), ""); + t.as("eosio"_n).act("eosio"_n, s2a("1000000.0000 OTHER"), ""); +} + +// Create and fund user accounts +void fund_users(test_chain& t) +{ + for (auto user : {"alice"_n, "bob"_n, "jane"_n, "joe"_n}) + { + t.create_account(user); + t.as("eosio"_n).act("eosio"_n, user, s2a("10000.0000 EOS"), ""); + t.as("eosio"_n).act("eosio"_n, user, s2a("10000.0000 OTHER"), ""); + } +} + +// Set up the example contract +void setup_example(test_chain& t) +{ + t.create_code_account("example"_n); + t.set_code("example"_n, "example.wasm"); +} + +// Full setup for test chain +void setup(test_chain& t) +{ + setup_token(t); + fund_users(t); + setup_example(t); +} + +TEST_CASE("start nodeos") +{ + // Prepare a chain + test_chain chain; + setup(chain); + + // cltester doesn't need ABIs, but most other tools do + chain.set_abi("eosio.token"_n, CLSDK_CONTRACTS_DIR "token.abi"); + chain.set_abi("example"_n, "example.abi"); + + // Alice buys some dogs + chain.as("alice"_n).act("alice"_n, "example"_n, s2a("300.0000 EOS"), + ""); + chain.as("alice"_n).act("alice"_n, "fido"_n, s2a("100.0000 EOS")); + chain.as("alice"_n).act("alice"_n, "barf"_n, s2a("110.0000 EOS")); + + // Make the above irreversible. This causes the transactions to + // go into the block log. + chain.finish_block(); + chain.finish_block(); + + // Copy blocks.log into a fresh directory for nodeos to use + eosio::execute("rm -rf example_chain"); + eosio::execute("mkdir -p example_chain/blocks"); + eosio::execute("cp " + chain.get_path() + "/blocks/blocks.log example_chain/blocks"); + + // Run nodeos + eosio::execute( + "nodeos -d example_chain " + "--config-dir example_config " + "--plugin eosio::chain_api_plugin " + "--access-control-allow-origin \"*\" " + "--access-control-allow-header \"*\" " + "--http-validate-host 0 " + "--http-server-address 0.0.0.0:8888 " + "--contracts-console " + "-e -p eosio"); +} From 0789f67de5ec93781411ca572b6f5cc14c1562f6 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Mon, 29 Nov 2021 16:15:51 -0500 Subject: [PATCH 04/15] doc graphql --- doc/clsdk/src/graphql/starting/README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/doc/clsdk/src/graphql/starting/README.md b/doc/clsdk/src/graphql/starting/README.md index 471ee2395..380152cbd 100644 --- a/doc/clsdk/src/graphql/starting/README.md +++ b/doc/clsdk/src/graphql/starting/README.md @@ -25,6 +25,17 @@ The files: {{#include example-graphql.cpp}} ``` +## const + +```cpp +std::optional animal(eosio::name name) const +{ + // ... +} +``` + +Since btb's GraphQL system doesn't support mutation, query methods must be marked `const` as above. It ignores non-const methods. + ## Starting the Example This builds the example and starts nodeos: From 8b19f2c32ce007ed0e9df209a0ad97686f0520b5 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Tue, 30 Nov 2021 17:46:16 -0500 Subject: [PATCH 05/15] doc: graphiql --- doc/clsdk/src/SUMMARY.md | 1 + doc/clsdk/src/graphql/graphiql/README.md | 25 + doc/clsdk/src/graphql/graphiql/app.html | 11 + doc/clsdk/src/graphql/graphiql/index.tsx | 117 + doc/clsdk/src/graphql/graphiql/package.json | 29 + doc/clsdk/src/graphql/graphiql/tsconfig.json | 12 + .../src/graphql/graphiql/webpack.config.js | 29 + doc/clsdk/src/graphql/graphiql/yarn.lock | 2540 +++++++++++++++++ 8 files changed, 2764 insertions(+) create mode 100644 doc/clsdk/src/graphql/graphiql/README.md create mode 100644 doc/clsdk/src/graphql/graphiql/app.html create mode 100644 doc/clsdk/src/graphql/graphiql/index.tsx create mode 100644 doc/clsdk/src/graphql/graphiql/package.json create mode 100644 doc/clsdk/src/graphql/graphiql/tsconfig.json create mode 100644 doc/clsdk/src/graphql/graphiql/webpack.config.js create mode 100644 doc/clsdk/src/graphql/graphiql/yarn.lock diff --git a/doc/clsdk/src/SUMMARY.md b/doc/clsdk/src/SUMMARY.md index 965c38a8a..081e21319 100644 --- a/doc/clsdk/src/SUMMARY.md +++ b/doc/clsdk/src/SUMMARY.md @@ -23,3 +23,4 @@ - [Hostile Takeover](cltester/takeover/README.md) - [GraphQL](graphql/README.md) - [Getting Started](graphql/starting/README.md) + - [GraphiQL UI](graphql/graphiql/README.md) diff --git a/doc/clsdk/src/graphql/graphiql/README.md b/doc/clsdk/src/graphql/graphiql/README.md new file mode 100644 index 000000000..223cb68d0 --- /dev/null +++ b/doc/clsdk/src/graphql/graphiql/README.md @@ -0,0 +1,25 @@ +# GraphQL: GraphiQL UI + +cleos isn't very handy for running GraphQL queries. This webapp, based on GraphiQL, provides a friendlier alternative. + +The files: + +* [app.html](app.html) +* [index.tsx](index.tsx) +* [package.json](package.json) +* [tsconfig.json](tsconfig.json) +* [webpack.config.js](webpack.config.js) +* [yarn.lock](yarn.lock) + +## Building and Running + +* Follow the instructions in [GraphQL: Getting Started](../starting/index.html#starting-the-example) to start nodeos +* Run `yarn && yarn build && yarn start` +* Open [http://localhost:3000/](http://localhost:3000/) + +## index.tsx + +`index.tsx`: +```cpp +{{#include index.tsx}} +``` diff --git a/doc/clsdk/src/graphql/graphiql/app.html b/doc/clsdk/src/graphql/graphiql/app.html new file mode 100644 index 000000000..8c8fe578b --- /dev/null +++ b/doc/clsdk/src/graphql/graphiql/app.html @@ -0,0 +1,11 @@ + + + + GraphiQL + + + + + + + \ No newline at end of file diff --git a/doc/clsdk/src/graphql/graphiql/index.tsx b/doc/clsdk/src/graphql/graphiql/index.tsx new file mode 100644 index 000000000..abe4901a1 --- /dev/null +++ b/doc/clsdk/src/graphql/graphiql/index.tsx @@ -0,0 +1,117 @@ +import { JsonRpc } from "eosjs/dist/eosjs-jsonrpc"; +import { Api } from "eosjs/dist/eosjs-api"; +import { JsSignatureProvider } from "eosjs/dist/eosjs-jssig"; +import React from "react"; +import { render } from "react-dom"; +import GraphiQL from "graphiql"; +import { buildSchema, GraphQLSchema } from "graphql"; +import "./node_modules/graphiql/graphiql.min.css"; +global.Buffer = require("buffer/").Buffer; + +// nodeos RPC endpoint +const rpcUrl = + window.location.protocol + "//" + window.location.hostname + ":8888"; + +// This contract runs the graphql queries +const contract = "example"; + +// user which authorizes queries +const user = "eosio"; + +// user's private key +const privateKey = "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"; + +// eosjs +let rpc = new JsonRpc(rpcUrl); +let signatureProvider = new JsSignatureProvider([privateKey]); +let api = new Api({ rpc, signatureProvider }); + +// show status during startup +let statusContent = ""; +function log(msg: string) { + statusContent += msg + "\n"; + render(
{statusContent}
, document.body); +} + +// fetch schema using 'graphqlschema' action +let schema: GraphQLSchema | null = null; +async function fetchSchema() { + const result = (await api.transact( + { + actions: [ + { + authorization: [{ actor: user, permission: "active" }], + account: contract, + name: "graphqlschema", + data: {}, + }, + ], + }, + { useLastIrreversible: true, expireSeconds: 2 } + )) as any; + const sch = result.processed.action_traces[0].console; + log(""); + log(sch); + schema = buildSchema(sch); +} + +// run query using 'graphql' action +async function fetcher({ query }: { query: string }) { + const result = (await api.transact( + { + actions: [ + { + authorization: [{ actor: user, permission: "active" }], + account: contract, + name: "graphql", + data: { query }, + }, + ], + }, + { useLastIrreversible: true, expireSeconds: 2 } + )) as any; + return JSON.parse(result.processed.action_traces[0].console); +} + +// Populate the UI with this example query +const defaultQuery = `# GraphiQL is talking to a contract running in nodeos. +# Press the ▶ button above to run this query. + +{ + contract + animal(name: "fido") { + name + type + owner + purchase_price + } +}`; + +// Query UI +export default function Page() { + return ( +
+ +
+ ); +} + +// Startup +(async () => { + log(`Using RPC: ${rpc.endpoint}`); + log("Fetching schema..."); + try { + await fetchSchema(); + } catch (e) { + console.log(e); + log(e.message); + log("See console for additional details"); + } + render(, document.body); +})(); diff --git a/doc/clsdk/src/graphql/graphiql/package.json b/doc/clsdk/src/graphql/graphiql/package.json new file mode 100644 index 000000000..ee4f67677 --- /dev/null +++ b/doc/clsdk/src/graphql/graphiql/package.json @@ -0,0 +1,29 @@ +{ + "name": "ui", + "version": "0.0.1", + "description": "", + "license": "MIT", + "files": [ + "dist" + ], + "scripts": { + "start": "serve dist", + "build": "yarn run clean && webpack && cp app.html dist/index.html", + "clean": "rm -rf ./dist", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "devDependencies": { + "css-loader": "^6.5.1", + "eosjs": "^22.1.0", + "graphiql": "^1.5.7", + "graphql": "^15.5.1", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "serve": "^13.0.2", + "style-loader": "^3.3.1", + "ts-loader": "^9.2.6", + "typescript": "^4.4.3", + "webpack": "^5.57.1", + "webpack-cli": "^4.8.0" + } +} diff --git a/doc/clsdk/src/graphql/graphiql/tsconfig.json b/doc/clsdk/src/graphql/graphiql/tsconfig.json new file mode 100644 index 000000000..1f313a309 --- /dev/null +++ b/doc/clsdk/src/graphql/graphiql/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "outDir": "./dist/", + "noImplicitAny": true, + "module": "es2020", + "target": "es2020", + "jsx": "react", + "allowJs": true, + "moduleResolution": "node", + "allowSyntheticDefaultImports": true + } +} \ No newline at end of file diff --git a/doc/clsdk/src/graphql/graphiql/webpack.config.js b/doc/clsdk/src/graphql/graphiql/webpack.config.js new file mode 100644 index 000000000..28866365a --- /dev/null +++ b/doc/clsdk/src/graphql/graphiql/webpack.config.js @@ -0,0 +1,29 @@ +const webpack = require('webpack'); + +module.exports = { + mode: 'production', + entry: './index.tsx', + module: { + rules: [ + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + { + test: /\.css$/i, + use: ["style-loader", "css-loader"], + }, + ] + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'], + fallback: { + crypto: false, + buffer: require.resolve('buffer/'), + }, + }, + performance: { + hints: false, + } +}; diff --git a/doc/clsdk/src/graphql/graphiql/yarn.lock b/doc/clsdk/src/graphql/graphiql/yarn.lock new file mode 100644 index 000000000..c1299685a --- /dev/null +++ b/doc/clsdk/src/graphql/graphiql/yarn.lock @@ -0,0 +1,2540 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.0.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431" + integrity sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA== + dependencies: + "@babel/highlight" "^7.16.0" + +"@babel/helper-validator-identifier@^7.15.7": + version "7.15.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" + integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== + +"@babel/highlight@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.0.tgz#6ceb32b2ca4b8f5f361fb7fd821e3fddf4a1725a" + integrity sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g== + dependencies: + "@babel/helper-validator-identifier" "^7.15.7" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@codemirror/highlight@^0.19.0": + version "0.19.6" + resolved "https://registry.yarnpkg.com/@codemirror/highlight/-/highlight-0.19.6.tgz#7f2e066f83f5649e8e0748a3abe0aaeaf64b8ac2" + integrity sha512-+eibu6on9quY8uN3xJ/n3rH+YIDLlpX7YulVmFvqAIz/ukRQ5tWaBmB7fMixHmnmRIRBRZgB8rNtonuMwZSAHQ== + dependencies: + "@codemirror/language" "^0.19.0" + "@codemirror/rangeset" "^0.19.0" + "@codemirror/state" "^0.19.0" + "@codemirror/view" "^0.19.0" + "@lezer/common" "^0.15.0" + style-mod "^4.0.0" + +"@codemirror/language@^0.19.0": + version "0.19.6" + resolved "https://registry.yarnpkg.com/@codemirror/language/-/language-0.19.6.tgz#d43cabe852ab974eed379d14a8ba68b3fb4414b0" + integrity sha512-or5TU/bxhsQdhXT70SK/h9V/gX/rElDEQyG29VbEDnHZ8TaDo3xsX900EYP02/tpIj8sConefmuMQfrePr+OCA== + dependencies: + "@codemirror/state" "^0.19.0" + "@codemirror/text" "^0.19.0" + "@codemirror/view" "^0.19.0" + "@lezer/common" "^0.15.5" + "@lezer/lr" "^0.15.0" + +"@codemirror/rangeset@^0.19.0": + version "0.19.2" + resolved "https://registry.yarnpkg.com/@codemirror/rangeset/-/rangeset-0.19.2.tgz#d7a999e4273c00fecef4aba8535a426073cdcddf" + integrity sha512-5d+X8LtmeZtfFtKrSx57bIHRUpKv2HD0b74clp4fGA7qJLLfYehF6FGkJJxJb8lKsqAga1gdjjWr0jiypmIxoQ== + dependencies: + "@codemirror/state" "^0.19.0" + +"@codemirror/state@^0.19.0", "@codemirror/state@^0.19.3": + version "0.19.6" + resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-0.19.6.tgz#d631f041d39ce41b7891b099fca26cb1fdb9763e" + integrity sha512-sqIQZE9VqwQj7D4c2oz9mfLhlT1ElAzGB5lO1lE33BPyrdNy1cJyCIOecT4cn4VeJOFrnjOeu+IftZ3zqdFETw== + dependencies: + "@codemirror/text" "^0.19.0" + +"@codemirror/stream-parser@^0.19.2": + version "0.19.2" + resolved "https://registry.yarnpkg.com/@codemirror/stream-parser/-/stream-parser-0.19.2.tgz#793428e55aa7b9daa64cb733973e5d5e3d9a2306" + integrity sha512-hBKRQlyu8GUOrY33xZ6/1kAfNZ8ZUm6cX9a7mPx8zAAqnpz/fpksC/qJRrkg1mPMBwxm+JG4fqAwDGJ3gLVniQ== + dependencies: + "@codemirror/highlight" "^0.19.0" + "@codemirror/language" "^0.19.0" + "@codemirror/state" "^0.19.0" + "@codemirror/text" "^0.19.0" + "@lezer/common" "^0.15.0" + "@lezer/lr" "^0.15.0" + +"@codemirror/text@^0.19.0": + version "0.19.5" + resolved "https://registry.yarnpkg.com/@codemirror/text/-/text-0.19.5.tgz#75033af2476214e79eae22b81ada618815441c18" + integrity sha512-Syu5Xc7tZzeUAM/y4fETkT0zgGr48rDG+w4U38bPwSIUr+L9S/7w2wDE1WGNzjaZPz12F6gb1gxWiSTg9ocLow== + +"@codemirror/view@^0.19.0": + version "0.19.23" + resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-0.19.23.tgz#a7481052dec6c13fe30255153dc905a3023a8b94" + integrity sha512-CE6wjyo6gczS9+/PVgJuFA7+Z4IYQoqwZWeDU1epFb+oN83BGyDZqna9ICnkz0geVlKqCUcbGk6PES4Eyt8/oA== + dependencies: + "@codemirror/rangeset" "^0.19.0" + "@codemirror/state" "^0.19.3" + "@codemirror/text" "^0.19.0" + style-mod "^4.0.0" + w3c-keyname "^2.2.4" + +"@discoveryjs/json-ext@^0.5.0": + version "0.5.6" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f" + integrity sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA== + +"@endemolshinegroup/cosmiconfig-typescript-loader@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@endemolshinegroup/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-3.0.2.tgz#eea4635828dde372838b0909693ebd9aafeec22d" + integrity sha512-QRVtqJuS1mcT56oHpVegkKBlgtWjXw/gHNWO3eL9oyB5Sc7HBoc2OLG/nYpVfT/Jejvo3NUrD0Udk7XgoyDKkA== + dependencies: + lodash.get "^4" + make-error "^1" + ts-node "^9" + tslib "^2" + +"@graphiql/toolkit@^0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@graphiql/toolkit/-/toolkit-0.4.2.tgz#34de819add64672f3f7d4830dffb2094fb8d5366" + integrity sha512-14uG67QrONbRrhXwvBJFsMfcQfexmGhj7dgkputesx9xuPUkcCDNmVULnVA8sGYt8P/rSvjkfQYx3rtfW+GhAQ== + dependencies: + "@n1ru4l/push-pull-async-iterable-iterator" "^3.1.0" + meros "^1.1.4" + +"@graphql-tools/batch-execute@^8.3.1": + version "8.3.1" + resolved "https://registry.yarnpkg.com/@graphql-tools/batch-execute/-/batch-execute-8.3.1.tgz#0b74c54db5ac1c5b9a273baefc034c2343ebbb74" + integrity sha512-63kHY8ZdoO5FoeDXYHnAak1R3ysMViMPwWC2XUblFckuVLMUPmB2ONje8rjr2CvzWBHAW8c1Zsex+U3xhKtGIA== + dependencies: + "@graphql-tools/utils" "^8.5.1" + dataloader "2.0.0" + tslib "~2.3.0" + value-or-promise "1.0.11" + +"@graphql-tools/delegate@^8.4.1", "@graphql-tools/delegate@^8.4.2": + version "8.4.2" + resolved "https://registry.yarnpkg.com/@graphql-tools/delegate/-/delegate-8.4.2.tgz#a61d45719855720304e3656800342cfa17d82558" + integrity sha512-CjggOhiL4WtyG2I3kux+1/p8lQxSFHBj0gwa0NxnQ6Vsnpw7Ig5VP1ovPnitFuBv2k4QdC37Nj2xv2n7DRn8fw== + dependencies: + "@graphql-tools/batch-execute" "^8.3.1" + "@graphql-tools/schema" "^8.3.1" + "@graphql-tools/utils" "^8.5.3" + dataloader "2.0.0" + tslib "~2.3.0" + value-or-promise "1.0.11" + +"@graphql-tools/graphql-file-loader@^7.3.2": + version "7.3.3" + resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-file-loader/-/graphql-file-loader-7.3.3.tgz#7cee2f84f08dc13fa756820b510248b857583d36" + integrity sha512-6kUJZiNpYKVhum9E5wfl5PyLLupEDYdH7c8l6oMrk6c7EPEVs6iSUyB7yQoWrtJccJLULBW2CRQ5IHp5JYK0mA== + dependencies: + "@graphql-tools/import" "^6.5.7" + "@graphql-tools/utils" "^8.5.1" + globby "^11.0.3" + tslib "~2.3.0" + unixify "^1.0.0" + +"@graphql-tools/import@^6.5.7": + version "6.6.1" + resolved "https://registry.yarnpkg.com/@graphql-tools/import/-/import-6.6.1.tgz#2a7e1ceda10103ffeb8652a48ddc47150b035485" + integrity sha512-i9WA6k+erJMci822o9w9DoX+uncVBK60LGGYW8mdbhX0l7wEubUpA000thJ1aarCusYh0u+ZT9qX0HyVPXu25Q== + dependencies: + "@graphql-tools/utils" "8.5.3" + resolve-from "5.0.0" + tslib "~2.3.0" + +"@graphql-tools/json-file-loader@^7.3.2": + version "7.3.3" + resolved "https://registry.yarnpkg.com/@graphql-tools/json-file-loader/-/json-file-loader-7.3.3.tgz#45cfde77b9dc4ab6c21575305ae537d2814d237f" + integrity sha512-CN2Qk9rt+Gepa3rb3X/mpxYA5MIYLwZBPj2Njw6lbZ6AaxG+O1ArDCL5ACoiWiBimn1FCOM778uhRM9znd0b3Q== + dependencies: + "@graphql-tools/utils" "^8.5.1" + globby "^11.0.3" + tslib "~2.3.0" + unixify "^1.0.0" + +"@graphql-tools/load@^7.4.1": + version "7.4.1" + resolved "https://registry.yarnpkg.com/@graphql-tools/load/-/load-7.4.1.tgz#aa572fcef11d6028097b6ef39c13fa9d62e5a441" + integrity sha512-UvBodW5hRHpgBUBVz5K5VIhJDOTFIbRRAGD6sQ2l9J5FDKBEs3u/6JjZDzbdL96br94D5cEd2Tk6auaHpTn7mQ== + dependencies: + "@graphql-tools/schema" "8.3.1" + "@graphql-tools/utils" "^8.5.1" + p-limit "3.1.0" + tslib "~2.3.0" + +"@graphql-tools/merge@^8.2.1": + version "8.2.1" + resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-8.2.1.tgz#bf83aa06a0cfc6a839e52a58057a84498d0d51ff" + integrity sha512-Q240kcUszhXiAYudjuJgNuLgy9CryDP3wp83NOZQezfA6h3ByYKU7xI6DiKrdjyVaGpYN3ppUmdj0uf5GaXzMA== + dependencies: + "@graphql-tools/utils" "^8.5.1" + tslib "~2.3.0" + +"@graphql-tools/schema@8.3.1", "@graphql-tools/schema@^8.3.1": + version "8.3.1" + resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-8.3.1.tgz#1ee9da494d2da457643b3c93502b94c3c4b68c74" + integrity sha512-3R0AJFe715p4GwF067G5i0KCr/XIdvSfDLvTLEiTDQ8V/hwbOHEKHKWlEBHGRQwkG5lwFQlW1aOn7VnlPERnWQ== + dependencies: + "@graphql-tools/merge" "^8.2.1" + "@graphql-tools/utils" "^8.5.1" + tslib "~2.3.0" + value-or-promise "1.0.11" + +"@graphql-tools/url-loader@^7.4.2": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@graphql-tools/url-loader/-/url-loader-7.5.3.tgz#a594be40e3bc68d22f76746356e7f0b8117b7137" + integrity sha512-VKMRJ4TOeVIdulkCLGSBUr4stRRwOGcVRXDeoUF+86K32Ufo0H2V0lz7QwS/bCl8GXV19FMgHZCDl4BMJyOXEA== + dependencies: + "@graphql-tools/delegate" "^8.4.1" + "@graphql-tools/utils" "^8.5.1" + "@graphql-tools/wrap" "^8.3.1" + "@n1ru4l/graphql-live-query" "0.9.0" + "@types/websocket" "1.0.4" + "@types/ws" "^8.0.0" + cross-undici-fetch "^0.0.26" + dset "^3.1.0" + extract-files "11.0.0" + graphql-sse "^1.0.1" + graphql-ws "^5.4.1" + isomorphic-ws "4.0.1" + meros "1.1.4" + subscriptions-transport-ws "^0.11.0" + sync-fetch "0.3.1" + tslib "~2.3.0" + valid-url "1.0.9" + value-or-promise "1.0.11" + ws "8.3.0" + +"@graphql-tools/utils@8.5.3", "@graphql-tools/utils@^8.5.1", "@graphql-tools/utils@^8.5.3": + version "8.5.3" + resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-8.5.3.tgz#404062e62cae9453501197039687749c4885356e" + integrity sha512-HDNGWFVa8QQkoQB0H1lftvaO1X5xUaUDk1zr1qDe0xN1NL0E/CrQdJ5UKLqOvH4hkqVUPxQsyOoAZFkaH6rLHg== + dependencies: + tslib "~2.3.0" + +"@graphql-tools/wrap@^8.3.1": + version "8.3.2" + resolved "https://registry.yarnpkg.com/@graphql-tools/wrap/-/wrap-8.3.2.tgz#d3bcecb7529d071e4ecc4dfc75b9566e3da79d4f" + integrity sha512-7DcOBFB+Dd84x9dxSm7qS4iJONMyfLnCJb8A19vGPffpu4SMJ3sFcgwibKFu5l6mMUiigKgXna2RRgWI+02bKQ== + dependencies: + "@graphql-tools/delegate" "^8.4.2" + "@graphql-tools/schema" "^8.3.1" + "@graphql-tools/utils" "^8.5.3" + tslib "~2.3.0" + value-or-promise "1.0.11" + +"@iarna/toml@^2.2.5": + version "2.2.5" + resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.2.5.tgz#b32366c89b43c6f8cefbdefac778b9c828e3ba8c" + integrity sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg== + +"@lezer/common@^0.15.0", "@lezer/common@^0.15.5": + version "0.15.10" + resolved "https://registry.yarnpkg.com/@lezer/common/-/common-0.15.10.tgz#662da668f46244fb20bfaada67b43b3d0463b344" + integrity sha512-vlr+be73zTDoQBIknBVOh/633tmbQcjxUu9PIeVeYESeBK3V6TuBW96RRFg93Y2cyK9lglz241gOgSn452HFvA== + +"@lezer/lr@^0.15.0": + version "0.15.4" + resolved "https://registry.yarnpkg.com/@lezer/lr/-/lr-0.15.4.tgz#634670d7224040fddac1370af01211eecd9ac0a0" + integrity sha512-vwgG80sihEGJn6wJp6VijXrnzVai/KPva/OzYKaWvIx0IiXKjoMQ8UAwcgpSBwfS4Fbz3IKOX/cCNXU3r1FvpQ== + dependencies: + "@lezer/common" "^0.15.0" + +"@n1ru4l/graphql-live-query@0.9.0": + version "0.9.0" + resolved "https://registry.yarnpkg.com/@n1ru4l/graphql-live-query/-/graphql-live-query-0.9.0.tgz#defaebdd31f625bee49e6745934f36312532b2bc" + integrity sha512-BTpWy1e+FxN82RnLz4x1+JcEewVdfmUhV1C6/XYD5AjS7PQp9QFF7K8bCD6gzPTr2l+prvqOyVueQhFJxB1vfg== + +"@n1ru4l/push-pull-async-iterable-iterator@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@n1ru4l/push-pull-async-iterable-iterator/-/push-pull-async-iterable-iterator-3.1.0.tgz#be450c97d1c7cd6af1a992d53232704454345df9" + integrity sha512-K4scWxGhdQM0masHHy4gIQs2iGiLEXCrXttumknyPJqtdl4J179BjpibWSSQ1fxKdCcHgIlCTKXJU6cMM6D6Wg== + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@types/eslint-scope@^3.7.0": + version "3.7.1" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.1.tgz#8dc390a7b4f9dd9f1284629efce982e41612116e" + integrity sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "8.2.0" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.2.0.tgz#afd0519223c29c347087542cbaee2fedc0873b16" + integrity sha512-74hbvsnc+7TEDa1z5YLSe4/q8hGYB3USNvCuzHUJrjPV6hXaq8IXcngCrHkuvFt0+8rFz7xYXrHgNayIX0UZvQ== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*", "@types/estree@^0.0.50": + version "0.0.50" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" + integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== + +"@types/json-schema@*", "@types/json-schema@^7.0.8": + version "7.0.9" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" + integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== + +"@types/node@*": + version "16.11.11" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.11.tgz#6ea7342dfb379ea1210835bada87b3c512120234" + integrity sha512-KB0sixD67CeecHC33MYn+eYARkqTheIRNuu97y2XMjR7Wu3XibO1vaY6VBV6O/a89SPI81cEUIYT87UqUWlZNw== + +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + +"@types/websocket@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.4.tgz#1dc497280d8049a5450854dd698ee7e6ea9e60b8" + integrity sha512-qn1LkcFEKK8RPp459jkjzsfpbsx36BBt3oC3pITYtkoBw/aVX+EZFa5j3ThCRTNpLFvIMr5dSTD4RaMdilIOpA== + dependencies: + "@types/node" "*" + +"@types/ws@^8.0.0": + version "8.2.1" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.2.1.tgz#7bdf6b12869726c9f3cc3c48485efea5d4505274" + integrity sha512-SqQ+LhVZaJi7c7sYVkjWALDigi/Wy7h7Iu72gkQp8Y8OWw/DddEVBrTSKu86pQftV2+Gm8lYM61hadPKqyaIeg== + dependencies: + "@types/node" "*" + +"@webassemblyjs/ast@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" + integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + +"@webassemblyjs/floating-point-hex-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" + integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== + +"@webassemblyjs/helper-api-error@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" + integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== + +"@webassemblyjs/helper-buffer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" + integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== + +"@webassemblyjs/helper-numbers@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" + integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" + integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== + +"@webassemblyjs/helper-wasm-section@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" + integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + +"@webassemblyjs/ieee754@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" + integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" + integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" + integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== + +"@webassemblyjs/wasm-edit@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" + integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/helper-wasm-section" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-opt" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + "@webassemblyjs/wast-printer" "1.11.1" + +"@webassemblyjs/wasm-gen@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" + integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wasm-opt@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" + integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + +"@webassemblyjs/wasm-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" + integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wast-printer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" + integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@xtuc/long" "4.2.2" + +"@webpack-cli/configtest@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.1.0.tgz#8342bef0badfb7dfd3b576f2574ab80c725be043" + integrity sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg== + +"@webpack-cli/info@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.4.0.tgz#b9179c3227ab09cbbb149aa733475fcf99430223" + integrity sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw== + dependencies: + envinfo "^7.7.3" + +"@webpack-cli/serve@^1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.0.tgz#2c275aa05c895eccebbfc34cfb223c6e8bd591a2" + integrity sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA== + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +"@zeit/schemas@2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@zeit/schemas/-/schemas-2.6.0.tgz#004e8e553b4cd53d538bd38eac7bcbf58a867fe3" + integrity sha512-uUrgZ8AxS+Lio0fZKAipJjAh415JyrOZowliZAzmnJSsf7piVL5w+G0+gFJ0KSu3QRhvui/7zuvpLz03YjXAhg== + +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + +accepts@~1.3.5: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +acorn-import-assertions@^1.7.6: + version "1.8.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" + integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== + +acorn@^8.4.1: + version "8.6.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895" + integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw== + +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv@6.12.6, ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-align@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" + integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== + dependencies: + string-width "^4.1.0" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +arch@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" + integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== + +arg@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arg/-/arg-2.0.0.tgz#c06e7ff69ab05b3a4a03ebe0407fac4cba657545" + integrity sha512-XxNTUzKnz1ctK3ZIcI2XUPlD96wbHP2nGqkPKpvk/HNRlPveYrXIVSTk9m3LcqOgDPg3B1nMvdV/K8wZd7PG4w== + +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +backo2@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +bn.js@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" + integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== + +bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +boxen@5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" + integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== + dependencies: + ansi-align "^3.0.0" + camelcase "^6.2.0" + chalk "^4.1.0" + cli-boxes "^2.2.1" + string-width "^4.2.2" + type-fest "^0.20.2" + widest-line "^3.1.0" + wrap-ansi "^7.0.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browserslist@^4.14.5: + version "4.18.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.18.1.tgz#60d3920f25b6860eb917c6c7b185576f4d8b017f" + integrity sha512-8ScCzdpPwR2wQh8IT82CA2VgDwjHyqMovPBZSNH54+tm4Jk2pCuv90gmAdH6J84OCRWi0b4gMe6O6XPXuJnjgQ== + dependencies: + caniuse-lite "^1.0.30001280" + electron-to-chromium "^1.3.896" + escalade "^3.1.1" + node-releases "^2.0.1" + picocolors "^1.0.0" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer@^5.7.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@^6.2.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.1.tgz#250fd350cfd555d0d2160b1d51510eaf8326e86e" + integrity sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA== + +caniuse-lite@^1.0.30001280: + version "1.0.30001283" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001283.tgz#8573685bdae4d733ef18f78d44ba0ca5fe9e896b" + integrity sha512-9RoKo841j1GQFSJz/nCXOj0sD7tHBtlowjYlrqIUS812x9/emfBLBt6IyMz1zIaYc/eRL8Cs6HPUVi2Hzq4sIg== + +chalk@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +cli-boxes@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" + integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== + +clipboardy@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-2.3.0.tgz#3c2903650c68e46a91b388985bc2774287dba290" + integrity sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ== + dependencies: + arch "^2.1.1" + execa "^1.0.0" + is-wsl "^2.1.1" + +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + +codemirror-graphql@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/codemirror-graphql/-/codemirror-graphql-1.2.4.tgz#9bb2e2532500fb2499e5e2a89381f5f9418193b3" + integrity sha512-ZinZ4W3wcnGieeMHfVtKoXBGYDUc3RJgCWc4HcTigw9RbO5hRc9iEHAr9cs7Br1CwXh5oueloNPNdvREYFdB0A== + dependencies: + "@codemirror/stream-parser" "^0.19.2" + graphql-language-service "^3.2.4" + +codemirror@^5.58.2: + version "5.64.0" + resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.64.0.tgz#182eec65b62178e3cd1de8f9d88ab819cfe5f625" + integrity sha512-fqr6CtDQdJ6iNMbD8NX2gH2G876nNDk+TO1rrYkgWnqQdO3O1Xa9tK6q+psqhJJgE5SpbaDcgdfLmukoUVE8pg== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colorette@^2.0.14: + version "2.0.16" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" + integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== + +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^7.0.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +compressible@~2.0.14: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.3.tgz#27e0e176aaf260f7f2c2813c3e440adb9f1993db" + integrity sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.14" + debug "2.6.9" + on-headers "~1.0.1" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +content-disposition@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" + integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= + +copy-to-clipboard@^3.2.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz#115aa1a9998ffab6196f93076ad6da3b913662ae" + integrity sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw== + dependencies: + toggle-selection "^1.0.6" + +cosmiconfig-toml-loader@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig-toml-loader/-/cosmiconfig-toml-loader-1.0.0.tgz#0681383651cceff918177debe9084c0d3769509b" + integrity sha512-H/2gurFWVi7xXvCyvsWRLCMekl4tITJcX0QEsDMpzxtuxDyM59xLatYNg4s/k9AA/HdtCYfj2su8mgA0GSDLDA== + dependencies: + "@iarna/toml" "^2.2.5" + +cosmiconfig@7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" + integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" + +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +cross-spawn@^6.0.0: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +cross-undici-fetch@^0.0.26: + version "0.0.26" + resolved "https://registry.yarnpkg.com/cross-undici-fetch/-/cross-undici-fetch-0.0.26.tgz#29d93d56609f4d2334f9d5333d23ef7a242842a7" + integrity sha512-aMDRrLbWr0TGXfY92stlV+XOGpskeqFmWmrKSWsnc8w6gK5LPE83NBh7O7N6gCb2xjwHcm1Yn2nBXMEVH2RBcA== + dependencies: + abort-controller "^3.0.0" + form-data "^4.0.0" + node-fetch "^2.6.5" + undici "^4.9.3" + +css-loader@^6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.5.1.tgz#0c43d4fbe0d97f699c91e9818cb585759091d1b1" + integrity sha512-gEy2w9AnJNnD9Kuo4XAP9VflW/ujKoS9c/syO+uWMlm5igc7LysKzPXaDoR2vroROkSwsTS2tGr1yGGEbZOYZQ== + dependencies: + icss-utils "^5.1.0" + postcss "^8.2.15" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.0" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.1.0" + semver "^7.3.5" + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +dataloader@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dataloader/-/dataloader-2.0.0.tgz#41eaf123db115987e21ca93c005cd7753c55fe6f" + integrity sha512-YzhyDAwA4TaQIhM5go+vCLmU0UikghC/t9DTQYZR2M/UvZ1MdOhPezSDZcjj9uqQJOMqjLcpWtyW2iNINdlatQ== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +dset@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/dset/-/dset-3.1.1.tgz#07de5af7a8d03eab337ad1a8ba77fe17bba61a8c" + integrity sha512-hYf+jZNNqJBD2GiMYb+5mqOIX4R4RRHXU3qWMWYN+rqcR2/YpRL2bUHr8C8fU+5DNvqYjJ8YvMGSLuVPWU1cNg== + +electron-to-chromium@^1.3.896: + version "1.4.5" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.5.tgz#912e8fd1645edee2f0f212558f40916eb538b1f9" + integrity sha512-YKaB+t8ul5crdh6OeqT2qXdxJGI0fAYb6/X8pDIyye+c3a7ndOCk5gVeKX+ABwivCGNS56vOAif3TN0qJMpEHw== + +elliptic@6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +enhanced-resolve@^5.0.0, enhanced-resolve@^5.8.3: + version "5.8.3" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz#6d552d465cce0423f5b3d718511ea53826a7b2f0" + integrity sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +entities@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" + integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== + +envinfo@^7.7.3: + version "7.8.1" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" + integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== + +eosjs@^22.1.0: + version "22.1.0" + resolved "https://registry.yarnpkg.com/eosjs/-/eosjs-22.1.0.tgz#7ac40e2f1f959fab70539c30ac8ae46c9038aa3c" + integrity sha512-Ka8KO7akC3RxNdSg/3dkGWuUWUQESTzSUzQljBdVP16UG548vmQoBqSGnZdnjlZyfcab8VOu2iEt+JjyfYc5+A== + dependencies: + bn.js "5.2.0" + elliptic "6.5.4" + hash.js "1.1.7" + pako "2.0.3" + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-module-lexer@^0.9.0: + version "0.9.3" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" + integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + +eventemitter3@^3.1.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" + integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +extract-files@11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/extract-files/-/extract-files-11.0.0.tgz#b72d428712f787eef1f5193aff8ab5351ca8469a" + integrity sha512-FuoE1qtbJ4bBVvv94CC7s0oTnKUGvQs+Rjf1L2SJFfS+HTVVjhPFtehPdQ0JiGPqVNfSSZvL5yzHHQq2Z4WNhQ== + +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.1.1: + version "3.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" + integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-url-parser@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/fast-url-parser/-/fast-url-parser-1.1.3.tgz#f4af3ea9f34d8a271cf58ad2b3759f431f0b318d" + integrity sha1-9K8+qfNNiicc9YrSs3WfQx8LMY0= + dependencies: + punycode "^1.3.2" + +fastest-levenshtein@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2" + integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow== + +fastq@^1.6.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + dependencies: + reusify "^1.0.4" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-up@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +glob-parent@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +globby@^11.0.3: + version "11.0.4" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" + integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.0.0" + +graceful-fs@^4.1.2, graceful-fs@^4.2.4: + version "4.2.8" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" + integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== + +graphiql@^1.5.7: + version "1.5.7" + resolved "https://registry.yarnpkg.com/graphiql/-/graphiql-1.5.7.tgz#e37fcbc3997b11eb578303735f2fb7de23d3ba35" + integrity sha512-rKkxQJxpBwJWuQ32orSzFnp/hbJOKBB5Da6leL3NEHN/WnFF8SzKwtfUnx3gM3j4Me7iu32lZ74NzDYGw26DwA== + dependencies: + "@graphiql/toolkit" "^0.4.2" + codemirror "^5.58.2" + codemirror-graphql "^1.2.4" + copy-to-clipboard "^3.2.0" + dset "^3.1.0" + entities "^2.0.0" + escape-html "^1.0.3" + graphql-language-service "^3.2.4" + markdown-it "^12.2.0" + +graphql-config@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/graphql-config/-/graphql-config-4.1.0.tgz#a3b28d3fb537952ebeb69c75e4430605a10695e3" + integrity sha512-Myqay6pmdcmX3KqoH+bMbeKZ1cTODpHS2CxF1ZzNnfTE+YUpGTcp01bOw6LpzamRb0T/WTYtGFbZeXGo9Hab2Q== + dependencies: + "@endemolshinegroup/cosmiconfig-typescript-loader" "3.0.2" + "@graphql-tools/graphql-file-loader" "^7.3.2" + "@graphql-tools/json-file-loader" "^7.3.2" + "@graphql-tools/load" "^7.4.1" + "@graphql-tools/merge" "^8.2.1" + "@graphql-tools/url-loader" "^7.4.2" + "@graphql-tools/utils" "^8.5.1" + cosmiconfig "7.0.1" + cosmiconfig-toml-loader "1.0.0" + minimatch "3.0.4" + string-env-interpolation "1.0.1" + +graphql-language-service-interface@^2.9.4: + version "2.9.4" + resolved "https://registry.yarnpkg.com/graphql-language-service-interface/-/graphql-language-service-interface-2.9.4.tgz#abdadf67cdb24df9c7acf17335caaa853d3728d6" + integrity sha512-AVzes7j0Q5fHfqzZ2JcAUaIGn2PimxwZpPv6ag1xtmGrKl/FNTi8y5Z3QuL/576NvQxaNzVmlUKMzZDIvoFNxg== + dependencies: + graphql-config "^4.1.0" + graphql-language-service-parser "^1.10.3" + graphql-language-service-types "^1.8.6" + graphql-language-service-utils "^2.6.3" + vscode-languageserver-types "^3.15.1" + +graphql-language-service-parser@^1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/graphql-language-service-parser/-/graphql-language-service-parser-1.10.3.tgz#5f17d5b3f42b9916e5fdcc4406d869759abb4189" + integrity sha512-vGHf7g4zxwIt2RxJI0YKkN5Zhjp3s4RmqRij2FS96K08V8lzPvGcaDRcr8Bzoeb20YZPwPAidZjSt/yYqzyX1w== + dependencies: + graphql-language-service-types "^1.8.6" + +graphql-language-service-types@^1.8.6: + version "1.8.6" + resolved "https://registry.yarnpkg.com/graphql-language-service-types/-/graphql-language-service-types-1.8.6.tgz#a95ce09328f50e027e664cdcbe6a24018407b871" + integrity sha512-1xH2kqkgKjvfsc/+fyDnzP21aSSofbVYfzyH8QcNCsxVF0zEvUij+3qyO/dHmQljIyc+Ss62J2udlnZEZM0hcA== + dependencies: + graphql-config "^4.1.0" + +graphql-language-service-utils@^2.6.3: + version "2.6.3" + resolved "https://registry.yarnpkg.com/graphql-language-service-utils/-/graphql-language-service-utils-2.6.3.tgz#be283c2f8cd38e59b3185e7cd04cc40bed0c4d00" + integrity sha512-rc5SToegDZ3VlnC0J7EriWe3G9zxFsPspxNV/rqcMcMq2hON9Q53bxTdg75KTNRUY78h+1ZHsXPEgecQtVk+0w== + dependencies: + graphql-language-service-types "^1.8.6" + nullthrows "^1.0.0" + +graphql-language-service@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/graphql-language-service/-/graphql-language-service-3.2.4.tgz#e507fc984a0b58533ed07174c6193ae34c6b0e03" + integrity sha512-s8WZnfem09gRJm/CmX8laT8O0V7eAcD9DaTZ4/OEAl6wnX4PrYfYC0Y7UxoXaQJDsuFfoQBSH59Kv4Fmf4dgZw== + dependencies: + graphql-language-service-interface "^2.9.4" + graphql-language-service-parser "^1.10.3" + graphql-language-service-types "^1.8.6" + graphql-language-service-utils "^2.6.3" + +graphql-sse@^1.0.1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/graphql-sse/-/graphql-sse-1.0.6.tgz#4f98e0a06f2020542ed054399116108491263224" + integrity sha512-y2mVBN2KwNrzxX2KBncQ6kzc6JWvecxuBernrl0j65hsr6MAS3+Yn8PTFSOgRmtolxugepxveyZVQEuaNEbw3w== + +graphql-ws@^5.4.1: + version "5.5.5" + resolved "https://registry.yarnpkg.com/graphql-ws/-/graphql-ws-5.5.5.tgz#f375486d3f196e2a2527b503644693ae3a8670a9" + integrity sha512-hvyIS71vs4Tu/yUYHPvGXsTgo0t3arU820+lT5VjZS2go0ewp2LqyCgxEN56CzOG7Iys52eRhHBiD1gGRdiQtw== + +graphql@^15.5.1: + version "15.7.2" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.7.2.tgz#85ab0eeb83722977151b3feb4d631b5f2ab287ef" + integrity sha512-AnnKk7hFQFmU/2I9YSQf3xw44ctnSFCfp3zE0N6W174gqe9fWG/2rKaKxROK7CcI3XtERpjEKFqts8o319Kf7A== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== + +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +ignore@^5.1.4: + version "5.1.9" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.9.tgz#9ec1a5cbe8e1446ec60d4420060d43aa6e7382fb" + integrity sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ== + +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-local@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.3.tgz#4d51c2c495ca9393da259ec66b62e022920211e0" + integrity sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +inherits@^2.0.3, inherits@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ini@~1.3.0: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +interpret@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" + integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-core-module@^2.2.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548" + integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw== + dependencies: + has "^1.0.3" + +is-docker@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-wsl@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +isomorphic-ws@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" + integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== + +iterall@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.3.0.tgz#afcb08492e2915cbd8a0884eb93a8c94d0d72fea" + integrity sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg== + +jest-worker@^27.0.6: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.4.2.tgz#0fb123d50955af1a450267787f340a1bf7e12bc4" + integrity sha512-0QMy/zPovLfUPyHuOuuU4E+kGACXXE84nRnq6lBVI9GJg5DCBiA97SATi+ZP8CpiJwEQy1oCPjRBf8AnLjN+Ag== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +linkify-it@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-3.0.3.tgz#a98baf44ce45a550efb4d49c769d07524cc2fa2e" + integrity sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ== + dependencies: + uc.micro "^1.0.1" + +loader-runner@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" + integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash.get@^4: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= + +loose-envify@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +make-error@^1, make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +markdown-it@^12.2.0: + version "12.2.0" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.2.0.tgz#091f720fd5db206f80de7a8d1f1a7035fd0d38db" + integrity sha512-Wjws+uCrVQRqOoJvze4HCqkKl1AsSh95iFAeQDwnyfxM09divCBSXlDR1uTvyUP3Grzpn4Ru8GeCxYPM8vkCQg== + dependencies: + argparse "^2.0.1" + entities "~2.1.0" + linkify-it "^3.0.1" + mdurl "^1.0.1" + uc.micro "^1.0.5" + +mdurl@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +meros@1.1.4, meros@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/meros/-/meros-1.1.4.tgz#c17994d3133db8b23807f62bec7f0cb276cfd948" + integrity sha512-E9ZXfK9iQfG9s73ars9qvvvbSIkJZF5yOo9j4tcwM5tN8mUKfj/EKN5PzOr3ZH0y5wL7dLAHw3RVEfpQV9Q7VQ== + +micromatch@^4.0.0, micromatch@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + dependencies: + braces "^3.0.1" + picomatch "^2.2.3" + +mime-db@1.51.0, "mime-db@>= 1.43.0 < 2": + version "1.51.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" + integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== + +mime-db@~1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" + integrity sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ== + +mime-types@2.1.18: + version "2.1.18" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" + integrity sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ== + dependencies: + mime-db "~1.33.0" + +mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.24: + version "2.1.34" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" + integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== + dependencies: + mime-db "1.51.0" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +minimatch@3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +nanoid@^3.1.30: + version "3.1.30" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362" + integrity sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ== + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +node-fetch@^2.6.1, node-fetch@^2.6.5: + version "2.6.6" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.6.tgz#1751a7c01834e8e1697758732e9efb6eeadfaf89" + integrity sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA== + dependencies: + whatwg-url "^5.0.0" + +node-releases@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" + integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +nullthrows@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1" + integrity sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw== + +object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +on-headers@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-limit@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +pako@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/pako/-/pako-2.0.3.tgz#cdf475e31b678565251406de9e759196a0ea7a43" + integrity sha512-WjR1hOeg+kki3ZIOjaf4b5WVcay1jaliKSYiEaB1XzwhMQZJxRdQRv0V31EKBYlxb4T7SK3hjfc/jxyU64BoSw== + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-json@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-inside@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-to-regexp@2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-2.2.1.tgz#90b617025a16381a879bc82a38d4e8bdeb2bcf45" + integrity sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.2.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" + integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== + +postcss-modules-local-by-default@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" + integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== + dependencies: + icss-utils "^5.0.0" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" + integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== + dependencies: + icss-utils "^5.0.0" + +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: + version "6.0.6" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea" + integrity sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-value-parser@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@^8.2.15: + version "8.4.4" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.4.tgz#d53d4ec6a75fd62557a66bb41978bf47ff0c2869" + integrity sha512-joU6fBsN6EIer28Lj6GDFoC/5yOZzLCfn0zHAn/MYXI7aPt4m4hK5KC5ovEZXy+lnCjmYIbQWngvju2ddyEr8Q== + dependencies: + nanoid "^3.1.30" + picocolors "^1.0.0" + source-map-js "^1.0.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@^1.3.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= + +rc@^1.0.1, rc@^1.1.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +react-dom@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" + integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + scheduler "^0.20.2" + +react@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" + integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +rechoir@^0.7.0: + version "0.7.1" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" + integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg== + dependencies: + resolve "^1.9.0" + +registry-auth-token@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" + integrity sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ== + dependencies: + rc "^1.1.6" + safe-buffer "^5.0.1" + +registry-url@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI= + dependencies: + rc "^1.0.1" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@5.0.0, resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve@^1.9.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +safe-buffer@5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@^5.0.1, safe-buffer@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +scheduler@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" + integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +schema-utils@^3.1.0, schema-utils@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" + integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +semver@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^7.3.4, semver@^7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +serialize-javascript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +serve-handler@6.1.3: + version "6.1.3" + resolved "https://registry.yarnpkg.com/serve-handler/-/serve-handler-6.1.3.tgz#1bf8c5ae138712af55c758477533b9117f6435e8" + integrity sha512-FosMqFBNrLyeiIDvP1zgO6YoTzFYHxLDEIavhlmQ+knB2Z7l1t+kGLHkZIDN7UVWqQAmKI3D20A6F6jo3nDd4w== + dependencies: + bytes "3.0.0" + content-disposition "0.5.2" + fast-url-parser "1.1.3" + mime-types "2.1.18" + minimatch "3.0.4" + path-is-inside "1.0.2" + path-to-regexp "2.2.1" + range-parser "1.2.0" + +serve@^13.0.2: + version "13.0.2" + resolved "https://registry.yarnpkg.com/serve/-/serve-13.0.2.tgz#b19ccb854dfdf3085613cd3a4033c7807aeaf85b" + integrity sha512-71R6fKvNgKrqARAag6lYJNnxDzpH7DCNrMuvPY5PLVaC2PDhJsGTj/34o4o4tPWhTuLgEXqvgnAWbATQ9zGZTQ== + dependencies: + "@zeit/schemas" "2.6.0" + ajv "6.12.6" + arg "2.0.0" + boxen "5.1.2" + chalk "2.4.1" + clipboardy "2.3.0" + compression "1.7.3" + serve-handler "6.1.3" + update-check "1.5.2" + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +signal-exit@^3.0.0, signal-exit@^3.0.3: + version "3.0.6" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" + integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +source-map-js@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.1.tgz#a1741c131e3c77d048252adfa24e23b908670caf" + integrity sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA== + +source-map-support@^0.5.17, source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@~0.7.2: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +string-env-interpolation@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string-env-interpolation/-/string-env-interpolation-1.0.1.tgz#ad4397ae4ac53fe6c91d1402ad6f6a52862c7152" + integrity sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg== + +string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.2: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +style-loader@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575" + integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ== + +style-mod@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/style-mod/-/style-mod-4.0.0.tgz#97e7c2d68b592975f2ca7a63d0dd6fcacfe35a01" + integrity sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw== + +subscriptions-transport-ws@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.11.0.tgz#baf88f050cba51d52afe781de5e81b3c31f89883" + integrity sha512-8D4C6DIH5tGiAIpp5I0wD/xRlNiZAPGHygzCe7VzyzUoxHtawzjNAY9SUTXU05/EY2NMY9/9GF0ycizkXr1CWQ== + dependencies: + backo2 "^1.0.2" + eventemitter3 "^3.1.0" + iterall "^1.2.1" + symbol-observable "^1.0.4" + ws "^5.2.0 || ^6.0.0 || ^7.0.0" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +symbol-observable@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== + +sync-fetch@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/sync-fetch/-/sync-fetch-0.3.1.tgz#62aa82c4b4d43afd6906bfd7b5f92056458509f0" + integrity sha512-xj5qiCDap/03kpci5a+qc5wSJjc8ZSixgG2EUmH1B8Ea2sfWclQA7eH40hiHPCtkCn6MCk4Wb+dqcXdCy2PP3g== + dependencies: + buffer "^5.7.0" + node-fetch "^2.6.1" + +tapable@^2.1.1, tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +terser-webpack-plugin@^5.1.3: + version "5.2.5" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.2.5.tgz#ce65b9880a0c36872555c4874f45bbdb02ee32c9" + integrity sha512-3luOVHku5l0QBeYS8r4CdHYWEGMmIj3H1U64jgkdZzECcSOJAyJ9TjuqcQZvw1Y+4AOBN9SeYJPJmFn2cM4/2g== + dependencies: + jest-worker "^27.0.6" + schema-utils "^3.1.1" + serialize-javascript "^6.0.0" + source-map "^0.6.1" + terser "^5.7.2" + +terser@^5.7.2: + version "5.10.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.10.0.tgz#b86390809c0389105eb0a0b62397563096ddafcc" + integrity sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA== + dependencies: + commander "^2.20.0" + source-map "~0.7.2" + source-map-support "~0.5.20" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toggle-selection@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" + integrity sha1-bkWxJj8gF/oKzH2J14sVuL932jI= + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= + +ts-loader@^9.2.6: + version "9.2.6" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.2.6.tgz#9937c4dd0a1e3dbbb5e433f8102a6601c6615d74" + integrity sha512-QMTC4UFzHmu9wU2VHZEmWWE9cUajjfcdcws+Gh7FhiO+Dy0RnR1bNz0YCHqhI0yRowCE9arVnNxYHqELOy9Hjw== + dependencies: + chalk "^4.1.0" + enhanced-resolve "^5.0.0" + micromatch "^4.0.0" + semver "^7.3.4" + +ts-node@^9: + version "9.1.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.1.1.tgz#51a9a450a3e959401bda5f004a72d54b936d376d" + integrity sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg== + dependencies: + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + source-map-support "^0.5.17" + yn "3.1.1" + +tslib@^2, tslib@~2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" + integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +typescript@^4.4.3: + version "4.5.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.2.tgz#8ac1fba9f52256fdb06fb89e4122fa6a346c2998" + integrity sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw== + +uc.micro@^1.0.1, uc.micro@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" + integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== + +undici@^4.9.3: + version "4.10.3" + resolved "https://registry.yarnpkg.com/undici/-/undici-4.10.3.tgz#7da6155025e9dbd676e3c7b72c32efef1ca3b3f4" + integrity sha512-oMfhoSsFdu7ft+10gBpQ98gfIGT6qovXXRxYPOe07xfUJwpVTcFs0xvuAEpNqtObhf4HQWuMW5kWzaD768YS4Q== + +unixify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unixify/-/unixify-1.0.0.tgz#3a641c8c2ffbce4da683a5c70f03a462940c2090" + integrity sha1-OmQcjC/7zk2mg6XHDwOkYpQMIJA= + dependencies: + normalize-path "^2.1.1" + +update-check@1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/update-check/-/update-check-1.5.2.tgz#2fe09f725c543440b3d7dabe8971f2d5caaedc28" + integrity sha512-1TrmYLuLj/5ZovwUS7fFd1jMH3NnFDN1y1A8dboedIDt7zs/zJMo6TwwlhYKkSeEwzleeiSBV5/3c9ufAQWDaQ== + dependencies: + registry-auth-token "3.3.2" + registry-url "3.1.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +util-deprecate@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +valid-url@1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/valid-url/-/valid-url-1.0.9.tgz#1c14479b40f1397a75782f115e4086447433a200" + integrity sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA= + +value-or-promise@1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/value-or-promise/-/value-or-promise-1.0.11.tgz#3e90299af31dd014fe843fe309cefa7c1d94b140" + integrity sha512-41BrgH+dIbCFXClcSapVs5M6GkENd3gQOJpEfPDNa71LsUGMXDL0jMWpI/Rh7WhX+Aalfz2TTS3Zt5pUsbnhLg== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +vscode-languageserver-types@^3.15.1: + version "3.16.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz#ecf393fc121ec6974b2da3efb3155644c514e247" + integrity sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA== + +w3c-keyname@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/w3c-keyname/-/w3c-keyname-2.2.4.tgz#4ade6916f6290224cdbd1db8ac49eab03d0eef6b" + integrity sha512-tOhfEwEzFLJzf6d1ZPkYfGj+FWhIpBux9ppoP3rlclw3Z0BZv3N7b7030Z1kYth+6rDuAsXUFr+d0VE6Ed1ikw== + +watchpack@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.3.0.tgz#a41bca3da6afaff31e92a433f4c856a0c25ea0c4" + integrity sha512-MnN0Q1OsvB/GGHETrFeZPQaOelWh/7O+EiFlj8sM9GPjtQkis7k01aAxrg/18kTfoIVcLL+haEVFlXDaSRwKRw== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= + +webpack-cli@^4.8.0: + version "4.9.1" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.1.tgz#b64be825e2d1b130f285c314caa3b1ba9a4632b3" + integrity sha512-JYRFVuyFpzDxMDB+v/nanUdQYcZtqFPGzmlW4s+UkPMFhSpfRNmf1z4AwYcHJVdvEFAM7FFCQdNTpsBYhDLusQ== + dependencies: + "@discoveryjs/json-ext" "^0.5.0" + "@webpack-cli/configtest" "^1.1.0" + "@webpack-cli/info" "^1.4.0" + "@webpack-cli/serve" "^1.6.0" + colorette "^2.0.14" + commander "^7.0.0" + execa "^5.0.0" + fastest-levenshtein "^1.0.12" + import-local "^3.0.2" + interpret "^2.2.0" + rechoir "^0.7.0" + webpack-merge "^5.7.3" + +webpack-merge@^5.7.3: + version "5.8.0" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" + integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== + dependencies: + clone-deep "^4.0.1" + wildcard "^2.0.0" + +webpack-sources@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.2.tgz#d88e3741833efec57c4c789b6010db9977545260" + integrity sha512-cp5qdmHnu5T8wRg2G3vZZHoJPN14aqQ89SyQ11NpGH5zEMDCclt49rzo+MaRazk7/UeILhAI+/sEtcM+7Fr0nw== + +webpack@^5.57.1: + version "5.64.4" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.64.4.tgz#e1454b6a13009f57cc2c78e08416cd674622937b" + integrity sha512-LWhqfKjCLoYJLKJY8wk2C3h77i8VyHowG3qYNZiIqD6D0ZS40439S/KVuc/PY48jp2yQmy0mhMknq8cys4jFMw== + dependencies: + "@types/eslint-scope" "^3.7.0" + "@types/estree" "^0.0.50" + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/wasm-edit" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + acorn "^8.4.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.8.3" + es-module-lexer "^0.9.0" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.4" + json-parse-better-errors "^1.0.2" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.3" + watchpack "^2.3.0" + webpack-sources "^3.2.2" + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +widest-line@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" + integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== + dependencies: + string-width "^4.0.0" + +wildcard@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" + integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +ws@8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.3.0.tgz#7185e252c8973a60d57170175ff55fdbd116070d" + integrity sha512-Gs5EZtpqZzLvmIM59w4igITU57lrtYVFneaa434VROv4thzJyV6UjIL3D42lslWlI+D4KzLYnxSwtfuiO79sNw== + +"ws@^5.2.0 || ^6.0.0 || ^7.0.0": + version "7.5.6" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.6.tgz#e59fc509fb15ddfb65487ee9765c5a51dec5fe7b" + integrity sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^1.10.0: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== From 7d9212121ed4488e5c3fdfca47bab13d7aab0a26 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Wed, 1 Dec 2021 14:33:38 -0500 Subject: [PATCH 06/15] doc --- doc/clsdk/src/SUMMARY.md | 1 + doc/clsdk/src/graphql/graphiql/README.md | 2 + doc/clsdk/src/graphql/graphiql/index.tsx | 2 +- doc/clsdk/src/graphql/proxy/README.md | 95 ++++++++++++++++++++++++ 4 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 doc/clsdk/src/graphql/proxy/README.md diff --git a/doc/clsdk/src/SUMMARY.md b/doc/clsdk/src/SUMMARY.md index 081e21319..846670f54 100644 --- a/doc/clsdk/src/SUMMARY.md +++ b/doc/clsdk/src/SUMMARY.md @@ -24,3 +24,4 @@ - [GraphQL](graphql/README.md) - [Getting Started](graphql/starting/README.md) - [GraphiQL UI](graphql/graphiql/README.md) + - [Proxy Objects](graphql/proxy/README.md) diff --git a/doc/clsdk/src/graphql/graphiql/README.md b/doc/clsdk/src/graphql/graphiql/README.md index 223cb68d0..73273434a 100644 --- a/doc/clsdk/src/graphql/graphiql/README.md +++ b/doc/clsdk/src/graphql/graphiql/README.md @@ -17,6 +17,8 @@ The files: * Run `yarn && yarn build && yarn start` * Open [http://localhost:3000/](http://localhost:3000/) +This interface allows you to create queries using code completion then execute them. + ## index.tsx `index.tsx`: diff --git a/doc/clsdk/src/graphql/graphiql/index.tsx b/doc/clsdk/src/graphql/graphiql/index.tsx index abe4901a1..9ff22a9b3 100644 --- a/doc/clsdk/src/graphql/graphiql/index.tsx +++ b/doc/clsdk/src/graphql/graphiql/index.tsx @@ -88,7 +88,7 @@ const defaultQuery = `# GraphiQL is talking to a contract running in nodeos. }`; // Query UI -export default function Page() { +function Page() { return (
+#include +#include "example.hpp" + +// GraphQL proxy for example::animal +struct Animal +{ + const example::animal* obj; + + // These methods have no arguments, so act like fields in GraphQL + auto name() const { return obj->name; } + auto type() const { return obj->type; } + auto owner() const { return obj->owner; } + auto purchasePrice() const { return obj->purchase_price; } + + // This method has an argument, so needs method(...) in the + // EOSIO_REFLECT2 definition below. + auto isA(eosio::name type) const { return type == obj->type; } +}; +EOSIO_REFLECT2(Animal, name, type, owner, purchasePrice, method(isA, "type")) + +struct Query +{ + eosio::name contract; + + // Returns a Proxy object instead of returning the original object + std::optional animal(eosio::name name) const + { + example::animal_table table{contract, contract.value}; + auto it = table.find(name.value); + if (it != table.end()) + return Animal{&*it}; + else + return std::nullopt; + } +}; +EOSIO_REFLECT2(Query, // + contract, // query a field + method(animal, "name") // query a method; identifies the argument names +) + +void example::example_contract::graphql(const std::string& query) +{ + Query root{get_self()}; + eosio::print(btb::gql_query(root, query, "")); +} + +void example::example_contract::graphqlschema() +{ + eosio::print(btb::get_gql_schema()); +} +``` + +## Example Query + +This query: + +``` +{ + animal(name: "fido") { + name + type + owner + purchasePrice + isACat: isA(type: "cat") + isADog: isA(type: "dog") + } +} +``` + +Produces this result: + +```json +{ + "data": { + "animal": { + "name": "fido", + "type": "dog", + "owner": "alice", + "purchasePrice": "100.0000 EOS", + "isACat": false, + "isADog": true + } + } +} +``` From a34da50e160d272729e874764da27a0a1dcbebac Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Wed, 1 Dec 2021 16:43:01 -0500 Subject: [PATCH 07/15] doc --- doc/clsdk/src/SUMMARY.md | 1 + doc/clsdk/src/graphql/graphiql/index.tsx | 2 +- doc/clsdk/src/graphql/linking/README.md | 233 +++++++++++++++++++++++ doc/clsdk/src/graphql/proxy/README.md | 19 +- 4 files changed, 247 insertions(+), 8 deletions(-) create mode 100644 doc/clsdk/src/graphql/linking/README.md diff --git a/doc/clsdk/src/SUMMARY.md b/doc/clsdk/src/SUMMARY.md index 846670f54..979638c7d 100644 --- a/doc/clsdk/src/SUMMARY.md +++ b/doc/clsdk/src/SUMMARY.md @@ -25,3 +25,4 @@ - [Getting Started](graphql/starting/README.md) - [GraphiQL UI](graphql/graphiql/README.md) - [Proxy Objects](graphql/proxy/README.md) + - [Linking Objects](graphql/linking/README.md) diff --git a/doc/clsdk/src/graphql/graphiql/index.tsx b/doc/clsdk/src/graphql/graphiql/index.tsx index 9ff22a9b3..648653bef 100644 --- a/doc/clsdk/src/graphql/graphiql/index.tsx +++ b/doc/clsdk/src/graphql/graphiql/index.tsx @@ -108,10 +108,10 @@ function Page() { log("Fetching schema..."); try { await fetchSchema(); + render(, document.body); } catch (e) { console.log(e); log(e.message); log("See console for additional details"); } - render(, document.body); })(); diff --git a/doc/clsdk/src/graphql/linking/README.md b/doc/clsdk/src/graphql/linking/README.md new file mode 100644 index 000000000..0da98ff55 --- /dev/null +++ b/doc/clsdk/src/graphql/linking/README.md @@ -0,0 +1,233 @@ +# GraphQL: Linking Objects + +Proxy objects can link together to form graphs. + +## Example + +This is a modification of `example-graphql.cpp` from [Getting Started](../starting/index.html). + +```c++ +#include +#include +#include "example.hpp" + +struct User; + +// GraphQL proxy for example::animal +struct Animal +{ + eosio::name contract; + example::animal obj; + + auto name() const { return obj.name; } + auto type() const { return obj.type; } + auto purchasePrice() const { return obj.purchase_price; } + + // Link to a proxy which represents owner + User owner() const; +}; +EOSIO_REFLECT2(Animal, name, type, purchasePrice, owner) + +// GraphQL proxy which represents a user. This proxy may exist even +// if there are no database records for that user. +struct User +{ + eosio::name contract; + eosio::name name; + + // User's remaining balance, if any + std::optional balance() const + { + example::balance_table table{contract, contract.value}; + auto it = table.find(name.value); + if (it != table.end()) + return it->balance; + else + return std::nullopt; + } + + // Link to proxy objects which represent animals owned by user + std::vector animals() const + { + std::vector result; + example::animal_table table{contract, contract.value}; + + // This is an inefficent approach and will time out if there are + // too many animals in the table. We could add a secondary index, + // but that would consume RAM. The blocks-to-browser system + // supports secondary indexes which don't consume on-chain RAM. + for (auto& animal : table) + if (animal.owner == name) + result.push_back(Animal{contract, animal}); + + return result; + } +}; +EOSIO_REFLECT2(User, name, balance, animals) + +User Animal::owner() const +{ + return {contract, obj.owner}; +} + +struct Query +{ + eosio::name contract; + + User user(eosio::name name) const { return {contract, name}; } + + std::optional animal(eosio::name name) const + { + example::animal_table table{contract, contract.value}; + auto it = table.find(name.value); + if (it != table.end()) + return Animal{contract, *it}; + else + return std::nullopt; + } +}; +EOSIO_REFLECT2(Query, contract, method(user, "name"), method(animal, "name")) + +void example::example_contract::graphql(const std::string& query) +{ + Query root{get_self()}; + eosio::print(btb::gql_query(root, query, "")); +} + +void example::example_contract::graphqlschema() +{ + eosio::print(btb::get_gql_schema()); +} +``` + +## Example Queries + +### Owner-to-animal links + +Get information about Alice's and Joe's balances and animals. Joe has never interacted with the contract. + +``` +{ + alice: user(name: "alice") { + name + balance + animals { + name + type + purchasePrice + } + } + joe: user(name: "joe") { + name + balance + animals { + name + type + purchasePrice + } + } +} +``` + +Result: + +```json +{ + "data": { + "alice": { + "name": "alice", + "balance": "90.0000 EOS", + "animals": [ + { + "name": "barf", + "type": "dog", + "purchasePrice": "110.0000 EOS" + }, + { + "name": "fido", + "type": "dog", + "purchasePrice": "100.0000 EOS" + } + ] + }, + "joe": { + "name": "joe", + "balance": null, + "animals": [] + } + } +} +``` + +### Animal-to-owner links + +``` +{ + animal(name: "fido") { + name + type + purchasePrice + owner { + name + balance + } + } +} +``` + +Result: + +```json +{ + "data": { + "animal": { + "name": "fido", + "type": "dog", + "purchasePrice": "100.0000 EOS", + "owner": { + "name": "alice", + "balance": "90.0000 EOS" + } + } + } +} +``` + +### Circular links + +All animals owned by the person who owns fido + +``` +{ + animal(name: "fido") { + owner { + name + animals { + name + } + } + } +} +``` + +Result: + +```json +{ + "data": { + "animal": { + "owner": { + "name": "alice", + "animals": [ + { + "name": "barf" + }, + { + "name": "fido" + } + ] + } + } + } +} +``` diff --git a/doc/clsdk/src/graphql/proxy/README.md b/doc/clsdk/src/graphql/proxy/README.md index d3db3e6aa..4f13b34fd 100644 --- a/doc/clsdk/src/graphql/proxy/README.md +++ b/doc/clsdk/src/graphql/proxy/README.md @@ -14,17 +14,22 @@ This is a modification of `example-graphql.cpp` from [Getting Started](../starti // GraphQL proxy for example::animal struct Animal { - const example::animal* obj; + // The proxy holds a copy of the original database object instead + // of holding a pointer or reference. This is necessary because + // the database object gets destroyed when the table object goes + // out of scope from within Query::animal(). A potential workaround + // is to make the table object a member of the contract object. + example::animal obj; // These methods have no arguments, so act like fields in GraphQL - auto name() const { return obj->name; } - auto type() const { return obj->type; } - auto owner() const { return obj->owner; } - auto purchasePrice() const { return obj->purchase_price; } + auto name() const { return obj.name; } + auto type() const { return obj.type; } + auto owner() const { return obj.owner; } + auto purchasePrice() const { return obj.purchase_price; } // This method has an argument, so needs method(...) in the // EOSIO_REFLECT2 definition below. - auto isA(eosio::name type) const { return type == obj->type; } + auto isA(eosio::name type) const { return type == obj.type; } }; EOSIO_REFLECT2(Animal, name, type, owner, purchasePrice, method(isA, "type")) @@ -38,7 +43,7 @@ struct Query example::animal_table table{contract, contract.value}; auto it = table.find(name.value); if (it != table.end()) - return Animal{&*it}; + return Animal{*it}; else return std::nullopt; } From 2c592a29a84b56a7a82cac69c27ef799e34ebf0a Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Wed, 1 Dec 2021 18:11:12 -0500 Subject: [PATCH 08/15] doc --- doc/clsdk/src/SUMMARY.md | 1 + doc/clsdk/src/graphql/pagination/README.md | 207 +++++++++++++++++++++ doc/clsdk/src/graphql/starting/tests.cpp | 29 ++- 3 files changed, 231 insertions(+), 6 deletions(-) create mode 100644 doc/clsdk/src/graphql/pagination/README.md diff --git a/doc/clsdk/src/SUMMARY.md b/doc/clsdk/src/SUMMARY.md index 979638c7d..045948b65 100644 --- a/doc/clsdk/src/SUMMARY.md +++ b/doc/clsdk/src/SUMMARY.md @@ -26,3 +26,4 @@ - [GraphiQL UI](graphql/graphiql/README.md) - [Proxy Objects](graphql/proxy/README.md) - [Linking Objects](graphql/linking/README.md) + - [Pagination](graphql/pagination/README.md) diff --git a/doc/clsdk/src/graphql/pagination/README.md b/doc/clsdk/src/graphql/pagination/README.md new file mode 100644 index 000000000..711c65088 --- /dev/null +++ b/doc/clsdk/src/graphql/pagination/README.md @@ -0,0 +1,207 @@ +# GraphQL: Pagination + +clsdk's GraphQL library supports most of the [GraphQL Connection Model](https://graphql.org/learn/pagination/#complete-connection-model) for paging through large data sets. + +## Example + +This is a modification of `example-graphql.cpp` from [Getting Started](../starting/index.html). + +```c++ +// Include support for the connection model (pagination) +#include + +#include +#include "example.hpp" + +struct Animal +{ + example::animal obj; + + auto name() const { return obj.name; } + auto type() const { return obj.type; } + auto owner() const { return obj.owner; } + auto purchasePrice() const { return obj.purchase_price; } +}; +EOSIO_REFLECT2(Animal, name, type, owner, purchasePrice) + +// Define the AnimalConnection and AnimalEdge GraphQL types +constexpr const char AnimalConnection_name[] = "AnimalConnection"; +constexpr const char AnimalEdge_name[] = "AnimalEdge"; +using AnimalConnection = + btb::Connection>; + +struct Query +{ + eosio::name contract; + + // Searches for and pages through the animals in the database + // + // The gt, ge, lt, and le arguments support searching for animals with + // names which are greater-than, greater-than-or-equal-to, less-than, + // or less-than-or-equal-to the values provided. If more than 1 of these + // are used, then the result is the intersection of these. + // + // If first is non-null, it limits the result to the first animals found + // which meet the other criteria (gt, ge, lt, le, before, after). + // If last is non-null, it limits the result to the last animals found. + // Using first and last together is allowed, but is not recommended since + // it has an unusual semantic, which matches the GraphQL spec. + // + // If before is non-null, then the result is limited to records before it. + // If after is non-null, then the result is limited to records after it. + // before and after are opaque cursor values. + + AnimalConnection animals(std::optional gt, + std::optional ge, + std::optional lt, + std::optional le, + std::optional first, + std::optional last, + std::optional before, + std::optional after) const + { + example::animal_table table{contract, contract.value}; + + return btb::make_connection( + gt, ge, lt, le, first, last, before, after, + table, // Either a table or a secondary index + [](auto& obj) { + // This is the key used for searching in the table or index + // provided above + return obj.name; + }, + [&](auto& obj) { + // Convert an object found in the table into a proxy + return Animal{obj}; + }, + // Hook up the lower_bound and upper_bound functions. These + // do the actual search. + [](auto& table, auto key) { return table.lower_bound(key.value); }, + [](auto& table, auto key) { return table.upper_bound(key.value); }); + } +}; +EOSIO_REFLECT2(Query, // + method(animals, "gt", "ge", "lt", "le", "first", "last", "before", "after")) + +void example::example_contract::graphql(const std::string& query) +{ + Query root{get_self()}; + eosio::print(btb::gql_query(root, query, "")); +} + +void example::example_contract::graphqlschema() +{ + eosio::print(btb::get_gql_schema()); +} +``` + +## Example Queries + +### Get all animals in the database + +``` +{ + animals { + edges { + node { + name + } + } + } +} +``` + +### Get the first 5 + +``` +{ + animals(first:5) { + edges { + node { + name + } + } + } +} +``` + +### Get the last 5 + +``` +{ + animals(last:5) { + edges { + node { + name + } + } + } +} +``` + +### Get the first 5 starting with dog132 + +``` +{ + animals(first: 5, ge: "dog132") { + edges { + node { + name + } + } + } +} +``` + +### Pagination + +``` +{ + animals(first: 5) { + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } + edges { + node { + name + } + } + } +} +``` + +The result includes this in its output: + +``` +"pageInfo": { + "hasPreviousPage": false, + "hasNextPage": true, + "startCursor": "0000000000B0AE39", + "endCursor": "000000009010184D" +}, +``` + +There are more results (`hasNextPage` is true) and we know where to resume (`endCursor`). To get the next 5: + +``` +{ + animals(first: 5, after: "000000009010184D") { + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } + edges { + node { + name + } + } + } +} +``` diff --git a/doc/clsdk/src/graphql/starting/tests.cpp b/doc/clsdk/src/graphql/starting/tests.cpp index 003477c8b..3007d23b7 100644 --- a/doc/clsdk/src/graphql/starting/tests.cpp +++ b/doc/clsdk/src/graphql/starting/tests.cpp @@ -14,10 +14,10 @@ void setup_token(test_chain& t) t.set_code("eosio.token"_n, CLSDK_CONTRACTS_DIR "token.wasm"); // Create and issue tokens. - t.as("eosio.token"_n).act("eosio"_n, s2a("1000000.0000 EOS")); - t.as("eosio.token"_n).act("eosio"_n, s2a("1000000.0000 OTHER")); - t.as("eosio"_n).act("eosio"_n, s2a("1000000.0000 EOS"), ""); - t.as("eosio"_n).act("eosio"_n, s2a("1000000.0000 OTHER"), ""); + t.as("eosio.token"_n).act("eosio"_n, s2a("10000000.0000 EOS")); + t.as("eosio.token"_n).act("eosio"_n, s2a("10000000.0000 OTHER")); + t.as("eosio"_n).act("eosio"_n, s2a("10000000.0000 EOS"), ""); + t.as("eosio"_n).act("eosio"_n, s2a("10000000.0000 OTHER"), ""); } // Create and fund user accounts @@ -26,8 +26,8 @@ void fund_users(test_chain& t) for (auto user : {"alice"_n, "bob"_n, "jane"_n, "joe"_n}) { t.create_account(user); - t.as("eosio"_n).act("eosio"_n, user, s2a("10000.0000 EOS"), ""); - t.as("eosio"_n).act("eosio"_n, user, s2a("10000.0000 OTHER"), ""); + t.as("eosio"_n).act("eosio"_n, user, s2a("1000000.0000 EOS"), ""); + t.as("eosio"_n).act("eosio"_n, user, s2a("1000000.0000 OTHER"), ""); } } @@ -62,6 +62,23 @@ TEST_CASE("start nodeos") chain.as("alice"_n).act("alice"_n, "fido"_n, s2a("100.0000 EOS")); chain.as("alice"_n).act("alice"_n, "barf"_n, s2a("110.0000 EOS")); + // Jane buys more + chain.as("jane"_n).act("jane"_n, "example"_n, s2a("1000000.0000 EOS"), + ""); + for (auto name : { + "dog111"_n, "dog112"_n, "dog113"_n, "dog114"_n, "dog121"_n, "dog122"_n, "dog123"_n, + "dog124"_n, "dog131"_n, "dog132"_n, "dog133"_n, "dog134"_n, "dog141"_n, "dog142"_n, + "dog143"_n, "dog144"_n, "dog211"_n, "dog212"_n, "dog213"_n, "dog214"_n, "dog221"_n, + "dog222"_n, "dog223"_n, "dog224"_n, "dog231"_n, "dog232"_n, "dog233"_n, "dog234"_n, + "dog241"_n, "dog242"_n, "dog243"_n, "dog244"_n, "dog311"_n, "dog312"_n, "dog313"_n, + "dog314"_n, "dog321"_n, "dog322"_n, "dog323"_n, "dog324"_n, "dog331"_n, "dog332"_n, + "dog333"_n, "dog334"_n, "dog341"_n, "dog342"_n, "dog343"_n, "dog344"_n, "dog411"_n, + "dog412"_n, "dog413"_n, "dog414"_n, "dog421"_n, "dog422"_n, "dog423"_n, "dog424"_n, + "dog431"_n, "dog432"_n, "dog433"_n, "dog434"_n, "dog441"_n, "dog442"_n, "dog443"_n, + "dog444"_n, + }) + chain.as("jane"_n).act("jane"_n, name, s2a("100.0000 EOS")); + // Make the above irreversible. This causes the transactions to // go into the block log. chain.finish_block(); From ebdf51c71e5aebbaca60e73da072101feab14ed5 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Thu, 2 Dec 2021 10:37:08 -0500 Subject: [PATCH 09/15] doc: move graphql --- doc/clsdk/src/SUMMARY.md | 13 +++++++------ doc/clsdk/src/{ => data}/graphql/README.md | 0 doc/clsdk/src/{ => data}/graphql/graphiql/README.md | 0 doc/clsdk/src/{ => data}/graphql/graphiql/app.html | 0 doc/clsdk/src/{ => data}/graphql/graphiql/index.tsx | 0 .../src/{ => data}/graphql/graphiql/package.json | 0 .../src/{ => data}/graphql/graphiql/tsconfig.json | 0 .../{ => data}/graphql/graphiql/webpack.config.js | 0 doc/clsdk/src/{ => data}/graphql/graphiql/yarn.lock | 0 doc/clsdk/src/{ => data}/graphql/linking/README.md | 0 .../src/{ => data}/graphql/pagination/README.md | 0 doc/clsdk/src/{ => data}/graphql/proxy/README.md | 0 .../graphql/starting/.vscode/c_cpp_properties.json | 0 .../graphql/starting/.vscode/settings.json | 0 .../src/{ => data}/graphql/starting/CMakeLists.txt | 0 doc/clsdk/src/{ => data}/graphql/starting/README.md | 2 +- .../{ => data}/graphql/starting/example-graphql.cpp | 0 .../src/{ => data}/graphql/starting/example.cpp | 0 .../src/{ => data}/graphql/starting/example.hpp | 0 doc/clsdk/src/{ => data}/graphql/starting/tests.cpp | 0 20 files changed, 8 insertions(+), 7 deletions(-) rename doc/clsdk/src/{ => data}/graphql/README.md (100%) rename doc/clsdk/src/{ => data}/graphql/graphiql/README.md (100%) rename doc/clsdk/src/{ => data}/graphql/graphiql/app.html (100%) rename doc/clsdk/src/{ => data}/graphql/graphiql/index.tsx (100%) rename doc/clsdk/src/{ => data}/graphql/graphiql/package.json (100%) rename doc/clsdk/src/{ => data}/graphql/graphiql/tsconfig.json (100%) rename doc/clsdk/src/{ => data}/graphql/graphiql/webpack.config.js (100%) rename doc/clsdk/src/{ => data}/graphql/graphiql/yarn.lock (100%) rename doc/clsdk/src/{ => data}/graphql/linking/README.md (100%) rename doc/clsdk/src/{ => data}/graphql/pagination/README.md (100%) rename doc/clsdk/src/{ => data}/graphql/proxy/README.md (100%) rename doc/clsdk/src/{ => data}/graphql/starting/.vscode/c_cpp_properties.json (100%) rename doc/clsdk/src/{ => data}/graphql/starting/.vscode/settings.json (100%) rename doc/clsdk/src/{ => data}/graphql/starting/CMakeLists.txt (100%) rename doc/clsdk/src/{ => data}/graphql/starting/README.md (96%) rename doc/clsdk/src/{ => data}/graphql/starting/example-graphql.cpp (100%) rename doc/clsdk/src/{ => data}/graphql/starting/example.cpp (100%) rename doc/clsdk/src/{ => data}/graphql/starting/example.hpp (100%) rename doc/clsdk/src/{ => data}/graphql/starting/tests.cpp (100%) diff --git a/doc/clsdk/src/SUMMARY.md b/doc/clsdk/src/SUMMARY.md index 045948b65..ebb17703d 100644 --- a/doc/clsdk/src/SUMMARY.md +++ b/doc/clsdk/src/SUMMARY.md @@ -21,9 +21,10 @@ - [Block Control](cltester/block/README.md) - [Starting Nodeos](cltester/nodeos/README.md) - [Hostile Takeover](cltester/takeover/README.md) -- [GraphQL](graphql/README.md) - - [Getting Started](graphql/starting/README.md) - - [GraphiQL UI](graphql/graphiql/README.md) - - [Proxy Objects](graphql/proxy/README.md) - - [Linking Objects](graphql/linking/README.md) - - [Pagination](graphql/pagination/README.md) +- [Data Access]() + - [GraphQL](data/graphql/README.md) + - [Getting Started](data/graphql/starting/README.md) + - [GraphiQL UI](data/graphql/graphiql/README.md) + - [Proxy Objects](data/graphql/proxy/README.md) + - [Linking Objects](data/graphql/linking/README.md) + - [Pagination](data/graphql/pagination/README.md) diff --git a/doc/clsdk/src/graphql/README.md b/doc/clsdk/src/data/graphql/README.md similarity index 100% rename from doc/clsdk/src/graphql/README.md rename to doc/clsdk/src/data/graphql/README.md diff --git a/doc/clsdk/src/graphql/graphiql/README.md b/doc/clsdk/src/data/graphql/graphiql/README.md similarity index 100% rename from doc/clsdk/src/graphql/graphiql/README.md rename to doc/clsdk/src/data/graphql/graphiql/README.md diff --git a/doc/clsdk/src/graphql/graphiql/app.html b/doc/clsdk/src/data/graphql/graphiql/app.html similarity index 100% rename from doc/clsdk/src/graphql/graphiql/app.html rename to doc/clsdk/src/data/graphql/graphiql/app.html diff --git a/doc/clsdk/src/graphql/graphiql/index.tsx b/doc/clsdk/src/data/graphql/graphiql/index.tsx similarity index 100% rename from doc/clsdk/src/graphql/graphiql/index.tsx rename to doc/clsdk/src/data/graphql/graphiql/index.tsx diff --git a/doc/clsdk/src/graphql/graphiql/package.json b/doc/clsdk/src/data/graphql/graphiql/package.json similarity index 100% rename from doc/clsdk/src/graphql/graphiql/package.json rename to doc/clsdk/src/data/graphql/graphiql/package.json diff --git a/doc/clsdk/src/graphql/graphiql/tsconfig.json b/doc/clsdk/src/data/graphql/graphiql/tsconfig.json similarity index 100% rename from doc/clsdk/src/graphql/graphiql/tsconfig.json rename to doc/clsdk/src/data/graphql/graphiql/tsconfig.json diff --git a/doc/clsdk/src/graphql/graphiql/webpack.config.js b/doc/clsdk/src/data/graphql/graphiql/webpack.config.js similarity index 100% rename from doc/clsdk/src/graphql/graphiql/webpack.config.js rename to doc/clsdk/src/data/graphql/graphiql/webpack.config.js diff --git a/doc/clsdk/src/graphql/graphiql/yarn.lock b/doc/clsdk/src/data/graphql/graphiql/yarn.lock similarity index 100% rename from doc/clsdk/src/graphql/graphiql/yarn.lock rename to doc/clsdk/src/data/graphql/graphiql/yarn.lock diff --git a/doc/clsdk/src/graphql/linking/README.md b/doc/clsdk/src/data/graphql/linking/README.md similarity index 100% rename from doc/clsdk/src/graphql/linking/README.md rename to doc/clsdk/src/data/graphql/linking/README.md diff --git a/doc/clsdk/src/graphql/pagination/README.md b/doc/clsdk/src/data/graphql/pagination/README.md similarity index 100% rename from doc/clsdk/src/graphql/pagination/README.md rename to doc/clsdk/src/data/graphql/pagination/README.md diff --git a/doc/clsdk/src/graphql/proxy/README.md b/doc/clsdk/src/data/graphql/proxy/README.md similarity index 100% rename from doc/clsdk/src/graphql/proxy/README.md rename to doc/clsdk/src/data/graphql/proxy/README.md diff --git a/doc/clsdk/src/graphql/starting/.vscode/c_cpp_properties.json b/doc/clsdk/src/data/graphql/starting/.vscode/c_cpp_properties.json similarity index 100% rename from doc/clsdk/src/graphql/starting/.vscode/c_cpp_properties.json rename to doc/clsdk/src/data/graphql/starting/.vscode/c_cpp_properties.json diff --git a/doc/clsdk/src/graphql/starting/.vscode/settings.json b/doc/clsdk/src/data/graphql/starting/.vscode/settings.json similarity index 100% rename from doc/clsdk/src/graphql/starting/.vscode/settings.json rename to doc/clsdk/src/data/graphql/starting/.vscode/settings.json diff --git a/doc/clsdk/src/graphql/starting/CMakeLists.txt b/doc/clsdk/src/data/graphql/starting/CMakeLists.txt similarity index 100% rename from doc/clsdk/src/graphql/starting/CMakeLists.txt rename to doc/clsdk/src/data/graphql/starting/CMakeLists.txt diff --git a/doc/clsdk/src/graphql/starting/README.md b/doc/clsdk/src/data/graphql/starting/README.md similarity index 96% rename from doc/clsdk/src/graphql/starting/README.md rename to doc/clsdk/src/data/graphql/starting/README.md index 380152cbd..ca09af54a 100644 --- a/doc/clsdk/src/graphql/starting/README.md +++ b/doc/clsdk/src/data/graphql/starting/README.md @@ -2,7 +2,7 @@ ## Contract and Test Modifications -This example is based on the [cltester Token Example](../../cltester/token/index.html), but has these changes: +This example is based on the [cltester Token Example](../../../cltester/token/index.html), but has these changes: * The contract has two new actions: `graphql` and `graphqlschema`, which are shown below * `CMakeLists.txt` adds the `btb` and `btb-debug` libraries as dependencies to `example.wasm` and `example-debug.wasm` diff --git a/doc/clsdk/src/graphql/starting/example-graphql.cpp b/doc/clsdk/src/data/graphql/starting/example-graphql.cpp similarity index 100% rename from doc/clsdk/src/graphql/starting/example-graphql.cpp rename to doc/clsdk/src/data/graphql/starting/example-graphql.cpp diff --git a/doc/clsdk/src/graphql/starting/example.cpp b/doc/clsdk/src/data/graphql/starting/example.cpp similarity index 100% rename from doc/clsdk/src/graphql/starting/example.cpp rename to doc/clsdk/src/data/graphql/starting/example.cpp diff --git a/doc/clsdk/src/graphql/starting/example.hpp b/doc/clsdk/src/data/graphql/starting/example.hpp similarity index 100% rename from doc/clsdk/src/graphql/starting/example.hpp rename to doc/clsdk/src/data/graphql/starting/example.hpp diff --git a/doc/clsdk/src/graphql/starting/tests.cpp b/doc/clsdk/src/data/graphql/starting/tests.cpp similarity index 100% rename from doc/clsdk/src/graphql/starting/tests.cpp rename to doc/clsdk/src/data/graphql/starting/tests.cpp From 3483b1d7dcaf64b5f36a174d78e0cb8fdd885c98 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Thu, 2 Dec 2021 16:15:51 -0500 Subject: [PATCH 10/15] fixup after merge --- contracts/eden/src/eden-micro-chain.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/eden/src/eden-micro-chain.cpp b/contracts/eden/src/eden-micro-chain.cpp index 55883e20c..6faa7fb9c 100644 --- a/contracts/eden/src/eden-micro-chain.cpp +++ b/contracts/eden/src/eden-micro-chain.cpp @@ -2335,8 +2335,8 @@ using MemberConnection = constexpr const char SessionConnection_name[] = "SessionConnection"; constexpr const char SessionEdge_name[] = "SessionEdge"; -using SessionConnection = clchain::Connection< - clchain::ConnectionConfig>; +using SessionConnection = + btb::Connection>; constexpr const char ElectionConnection_name[] = "ElectionConnection"; constexpr const char ElectionEdge_name[] = "ElectionEdge"; @@ -2440,7 +2440,7 @@ struct Query std::optional before, std::optional after) const { - return clchain::make_connection( + return btb::make_connection( gt ? std::optional{SessionKey{*gt, public_key_max_r1}} // : std::nullopt, // ge ? std::optional{SessionKey{*ge, public_key_min_k1}} // From dcad2f541277db2f9fd947cdab0478e6197fe980 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Thu, 2 Dec 2021 19:58:24 -0500 Subject: [PATCH 11/15] doc --- doc/clsdk/src/SUMMARY.md | 4 ++ doc/clsdk/src/std/auth1/README.md | 88 +++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 doc/clsdk/src/std/auth1/README.md diff --git a/doc/clsdk/src/SUMMARY.md b/doc/clsdk/src/SUMMARY.md index ebb17703d..14e3a2b24 100644 --- a/doc/clsdk/src/SUMMARY.md +++ b/doc/clsdk/src/SUMMARY.md @@ -21,6 +21,10 @@ - [Block Control](cltester/block/README.md) - [Starting Nodeos](cltester/nodeos/README.md) - [Hostile Takeover](cltester/takeover/README.md) +- [Proposed Standards]() + - [Auth Part 1](std/auth1/README.md) + - [Details]() + - [Using clsdk]() - [Data Access]() - [GraphQL](data/graphql/README.md) - [Getting Started](data/graphql/starting/README.md) diff --git a/doc/clsdk/src/std/auth1/README.md b/doc/clsdk/src/std/auth1/README.md new file mode 100644 index 000000000..af496cc0e --- /dev/null +++ b/doc/clsdk/src/std/auth1/README.md @@ -0,0 +1,88 @@ +# Auth Part 1 + +The native eosio account system is very flexible compared to prior chains, but it does have some limitations: + +- It uses a considerable amount of RAM (~3k minimum) per account, making accounts more costly than they could be. +- It has a strong tie-in (delay) with the deprecated deferred transaction system. +- Accounts are permanent; there is no way to destroy a native account and recover its RAM. +- Any new capabilities require hard-forking changes and tend to worsen the following issue: +- The permission system is difficult to explain to new users. + +It is already possible to define new account systems using non-privileged contracts, but this is rarely done: + +- Contract-based authentication needs either server-pays or contract-pays to function. Server-pays requires deploying specialized infrastructure. Contract-pays doesn't exist yet on public eosio chains. +- There is no existing standard that authenticators and web apps can rely on to authenticate users to contracts. +- There is no existing standard that contracts can rely on to authenticate users to other contracts. +- There is no existing tooling for building contracts which support contract-based authentication. +- There is no existing standard that history services can rely on to interpret activity. + +Contract-pays may be coming; it only needs a system contract change, which is [proposed here](https://github.com/eoscommunity/eosio.contracts/pull/1), plus standards created for it. This leaves the issue of standards for contract-auth, which this chapter starts to address, and tooling, which clsdk addresses. + +## run, run_auth, and verb + +`run` is a proposed standard action that acts as an entry point for executing `verbs` using an extensible authorization system (`run_auth`). It has the following ABI: + +``` +{ + "name": "run", + "fields": [ + { + "name": "auth", + "type": "run_auth" + }, + { + "name": "verbs", + "type": "verb[]" + } + ] +}, +``` + +`run_auth` is a variant containing various options for authenticating users. This standard proposes the following, with more to come in the future: + +``` +"variants": [ + { + "name": "run_auth", + "types": [ + "no_auth", // No auth provided. + "account_auth", // Auth using either a native eosio account, + // or a contract-defined account which is tied to + // a native eosio account. + "signature_auth" // Auth using a contract-defined account which is + // tied to a public key. + ] + } +] +``` + +`verb` is a variant which is specific to the contract. verbs are similar to actions. Here's an example from the Eden contract: + +``` +"variants": [ + { + "name": "verb", + "types": [ + ... + "inductprofil", + "inductvideo", + ... + "electvote", + "electvideo", + ... + ] + }, +] +``` + +clsdk provides a dispatcher which implements the `run` protocol, provides an ABI generator which produces the `verb` variant, and provides definitions of `run_auth` and its related types. clsdk's dispatcher executes all verbs within the context of the original `run` action. It avoids using inline actions since these complicate authentication and increase overhead. + +## Future proposals + +Additional proposals should cover: + +- A standard interface to contract-pays +- A standard interface for contracts to forward authentication information to each other +- A new notification system, since require_recipient does not play well with `run` + +None of these proposals would require hard forks. From 13394d158f2ea8e8e5ee26b45cfeba513b63811a Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Fri, 3 Dec 2021 12:23:08 -0500 Subject: [PATCH 12/15] doc --- doc/clsdk/src/SUMMARY.md | 1 + doc/clsdk/src/std/auth1/README.md | 14 +++++-- doc/clsdk/src/std/cpay/README.md | 70 +++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 doc/clsdk/src/std/cpay/README.md diff --git a/doc/clsdk/src/SUMMARY.md b/doc/clsdk/src/SUMMARY.md index 14e3a2b24..8b2eeef6f 100644 --- a/doc/clsdk/src/SUMMARY.md +++ b/doc/clsdk/src/SUMMARY.md @@ -22,6 +22,7 @@ - [Starting Nodeos](cltester/nodeos/README.md) - [Hostile Takeover](cltester/takeover/README.md) - [Proposed Standards]() + - [Contract Pays](std/cpay/README.md) - [Auth Part 1](std/auth1/README.md) - [Details]() - [Using clsdk]() diff --git a/doc/clsdk/src/std/auth1/README.md b/doc/clsdk/src/std/auth1/README.md index af496cc0e..feef1f07e 100644 --- a/doc/clsdk/src/std/auth1/README.md +++ b/doc/clsdk/src/std/auth1/README.md @@ -16,11 +16,11 @@ It is already possible to define new account systems using non-privileged contra - There is no existing tooling for building contracts which support contract-based authentication. - There is no existing standard that history services can rely on to interpret activity. -Contract-pays may be coming; it only needs a system contract change, which is [proposed here](https://github.com/eoscommunity/eosio.contracts/pull/1), plus standards created for it. This leaves the issue of standards for contract-auth, which this chapter starts to address, and tooling, which clsdk addresses. +Contract-pays may be coming; see [this proposal](../cpay/index.html). This leaves the issue of standards for contract-auth, which this chapter starts to address, and tooling, which clsdk addresses. ## run, run_auth, and verb -`run` is a proposed standard action that acts as an entry point for executing `verbs` using an extensible authorization system (`run_auth`). It has the following ABI: +`run` is a proposed standard action that acts as an entry point for executing `verbs` using an extensible authentication system (`run_auth`). It has the following ABI: ``` { @@ -77,7 +77,7 @@ Contract-pays may be coming; it only needs a system contract change, which is [p clsdk provides a dispatcher which implements the `run` protocol, provides an ABI generator which produces the `verb` variant, and provides definitions of `run_auth` and its related types. clsdk's dispatcher executes all verbs within the context of the original `run` action. It avoids using inline actions since these complicate authentication and increase overhead. -## Future proposals +## Future Proposals Additional proposals should cover: @@ -86,3 +86,11 @@ Additional proposals should cover: - A new notification system, since require_recipient does not play well with `run` None of these proposals would require hard forks. + +## Not Covered + +There is a topic which is application-specific: the creation and management of accounts. Hopefully we'll see several groups experiment with various approaches. Some potential ideas to explore: + +- Pay-to-key: these accounts could come and go as funds enter and exit them +- Real-person accounts, including key recovery using human-to-human verification +- Accounts with time-locked withdrawals diff --git a/doc/clsdk/src/std/cpay/README.md b/doc/clsdk/src/std/cpay/README.md new file mode 100644 index 000000000..fb1b31c94 --- /dev/null +++ b/doc/clsdk/src/std/cpay/README.md @@ -0,0 +1,70 @@ +# Contract Pays + +A system contract change, which is [proposed here](https://github.com/eoscommunity/eosio.contracts/pull/1), can enable contract-pays on eosio chains. This document explains how the PR enables contract-pays and how contract developers may implement it. + +## The Approach + +Early in eosio history, some on the Eosio Developers chat discussed doing the following: + +* Create an account, let's call it `provider`, with a new authority, let's call it `payforit`. +* Create a contract on that account with an action, let's call it `acceptcharge`. This action scans the transaction and aborts if `provider` is unwilling to pay for it. +* Use `linkauth` to enable `provider@payforit` to authorize `provider::acceptcharge`. +* Delegate plenty of CPU and NET to `provider`. +* Publish the private key of `provider@payforit`. + +Usage: + +* Anyone could use `provider@payforit`'s private key to sign a transaction. +* The only thing `provider@payforit` should authorize (see below) is `provider::acceptcharge`. +* If `provider::acceptcharge` is the first action, and that action doesn't abort the transaction, then `provider` will cover NET and CPU costs. + +Attack Vectors: + +* `provider@payforit` can authorize `updateauth`, allowing anyone to replace the published private key with their own, denying access to others. +* `updateauth` also would allow anyone to create a new subauthority under `payforit`, with keys of their choosing. +* `provider@payforit` can authorize `linkauth`, allowing anyone to relink `provider::acceptcharge` to the new subauthority, or to `active` or `owner`. +* `provider@payforit` can authorize `unlinkauth`, allowing anyone to disable `payforit`'s access to `provider::acceptcharge`. +* `provider@payforit` can also authorize `deleteauth`. +* Since `provider@payforit`'s authorization appears within the transaction, an attacker can set `delay` to non-0, consuming `provider`'s RAM to store deferred transactions. + +## Attack Mitigation + +A [system contract update](https://github.com/eoscommunity/eosio.contracts/pull/1) could block `updateauth`, `linkauth`, `unlinkauth`, and `deleteauth`. This covers most of the attack vectors. + +To prevent RAM consumption attacks, `provider` must not pay for deferred transactions. The easiest way to prevent this is for `provider` to have no free RAM. Since `provider::acceptcharge` may need free RAM for tracking purposes, the contract should be on a different account than the resource provider account. + +## Example Code + +```c++ +// This version of eosio::get_action doesn't abort when index is out of range. +std::optional better_get_action(uint32_t type, uint32_t index) +{ + auto size = eosio::internal_use_do_not_use::get_action(type, index, nullptr, 0); + if (size < 0) + return std::nullopt; + std::vector raw(size); + auto size2 = eosio::internal_use_do_not_use::get_action( + type, index, raw.data(), size); + eosio::check(size2 == size, "get_action failed"); + return eosio::unpack(raw.data(), size); +} + +// Examine the transaction to see if we're ok accepting the CPU and NET charges +void the_contract::acceptcharge() +{ + // type 0: context-free action + // type 1: normal action + for (uint32_t type = 0; type < 2; ++type) + { + for (uint32_t index = 0;; ++index) + { + auto action = better_get_action(type, index); + if (!action) + break; + // Simple rule: only allow actions on this contract + eosio::check(action->account == get_self(), + "This transaction has something I won't pay for"); + } + } +} +``` From 40f99a833105c866afadb6b329d4e98ee4d5dce3 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Mon, 6 Dec 2021 10:35:58 -0500 Subject: [PATCH 13/15] fix merge --- contracts/eden/src/eden-micro-chain.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/eden/src/eden-micro-chain.cpp b/contracts/eden/src/eden-micro-chain.cpp index 6fff0dfdd..8f2b49bcc 100644 --- a/contracts/eden/src/eden-micro-chain.cpp +++ b/contracts/eden/src/eden-micro-chain.cpp @@ -767,8 +767,8 @@ EOSIO_REFLECT2(EncryptionKey, account, encryptionKey) constexpr const char EncryptionKeyConnection_name[] = "EncryptionKeyConnection"; constexpr const char EncryptionKeyEdge_name[] = "EncryptionKeyEdge"; -using EncryptionKeyConnection = clchain::Connection< - clchain::ConnectionConfig>; +using EncryptionKeyConnection = btb::Connection< + btb::ConnectionConfig>; EncryptionKey get_encryption_key(eosio::name account) { @@ -2458,7 +2458,7 @@ struct Query std::optional before, std::optional after) const { - return clchain::make_connection( + return btb::make_connection( gt, ge, lt, le, first, last, before, after, // db.encryption_keys.get(), // [](auto& obj) { return obj.account; }, // From 36ee60d1deb2f16c7d52ffadaffda5ecee4fdfde Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Tue, 7 Dec 2021 11:43:10 -0500 Subject: [PATCH 14/15] clsdk: verb support --- contracts/eden/include/eden.hpp | 55 +++--- contracts/eden/include/eden_abi_generator.hpp | 20 --- contracts/eden/include/eden_dispatcher.hpp | 108 ------------ contracts/eden/src/actions/sessions.cpp | 2 +- contracts/eden/src/eden-micro-chain.cpp | 2 +- contracts/eden/src/eden.cpp | 3 +- contracts/eden/tests/include/tester-base.hpp | 2 +- .../contracts/include/eosio/abi_generator.hpp | 19 ++ .../contracts/include/eosio/dispatcher.hpp | 163 ++++++++++++++---- 9 files changed, 183 insertions(+), 191 deletions(-) delete mode 100644 contracts/eden/include/eden_abi_generator.hpp delete mode 100644 contracts/eden/include/eden_dispatcher.hpp diff --git a/contracts/eden/include/eden.hpp b/contracts/eden/include/eden.hpp index 8d5166371..9756c9fb8 100644 --- a/contracts/eden/include/eden.hpp +++ b/contracts/eden/include/eden.hpp @@ -2,7 +2,6 @@ #include #include -#include #include #include #include @@ -225,11 +224,11 @@ namespace eden eosio::ignore>); }; - EDEN_ACTIONS( + EOSIO_ACTIONS( eden, "eden.gm"_n, action(newsession, eden_account, key, expiration, description), - eden_verb(delsession, 0, eden_account, key), + action_verb(delsession, 0, eden_account, key), action(run, auth, verbs), action(withdraw, owner, quantity, ricardian_contract(withdraw_ricardian)), action(donate, owner, quantity), @@ -251,41 +250,41 @@ namespace eden action(addtogenesis, account, expiration), action(gensetexpire, id, new_expiration), action(clearall, ricardian_contract(clearall_ricardian)), - eden_verb(inductinit, - 10, - id, - inviter, - invitee, - witnesses, - ricardian_contract(inductinit_ricardian)), - eden_verb(inductmeetin, 1, account, id, keys, data, old_data), - eden_verb(inductprofil, - 2, - id, - new_member_profile, - ricardian_contract(inductprofil_ricardian)), - eden_verb(inductvideo, 3, account, id, video, ricardian_contract(inductvideo_ricardian)), - eden_verb(inductendors, - 4, - account, - id, - induction_data_hash, - ricardian_contract(inductendors_ricardian)), + action_verb(inductinit, + 10, + id, + inviter, + invitee, + witnesses, + ricardian_contract(inductinit_ricardian)), + action_verb(inductmeetin, 1, account, id, keys, data, old_data), + action_verb(inductprofil, + 2, + id, + new_member_profile, + ricardian_contract(inductprofil_ricardian)), + action_verb(inductvideo, 3, account, id, video, ricardian_contract(inductvideo_ricardian)), + action_verb(inductendors, + 4, + account, + id, + induction_data_hash, + ricardian_contract(inductendors_ricardian)), action(setencpubkey, account, key), action(electsettime, election_time), action(electconfig, day, time, round_duration), - eden_verb(electopt, 5, member, participating), + action_verb(electopt, 5, member, participating), action(electseed, btc_header), - eden_verb(electmeeting, 6, account, round, keys, data, old_data), - eden_verb(electvote, 7, round, voter, candidate), - eden_verb(electvideo, 8, round, voter, video), + action_verb(electmeeting, 6, account, round, keys, data, old_data), + action_verb(electvote, 7, round, voter, candidate), + action_verb(electvideo, 8, round, voter, video), action(electprocess, max_steps), action(bylawspropose, proposer, bylaws), action(bylawsapprove, approver, bylaws_hash), action(bylawsratify, approver, bylaws_hash), action(distribute, max_steps), action(inductdonate, payer, id, quantity, ricardian_contract(inductdonate_ricardian)), - eden_verb(inductcancel, 9, account, id, ricardian_contract(inductcancel_ricardian)), + action_verb(inductcancel, 9, account, id, ricardian_contract(inductcancel_ricardian)), action(inducted, inductee, ricardian_contract(inducted_ricardian)), action(resign, account), action(gc, limit, ricardian_contract(gc_ricardian)), diff --git a/contracts/eden/include/eden_abi_generator.hpp b/contracts/eden/include/eden_abi_generator.hpp deleted file mode 100644 index 91dcdcf5b..000000000 --- a/contracts/eden/include/eden_abi_generator.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#define EOSIO_ABIGEN_ITEMeden_verbs(ns, variant_name, missing_struct_name) \ - ([&] { \ - gen.def.structs.push_back(eosio::struct_def{missing_struct_name}); \ - eosio::variant_def vdef{variant_name}; \ - ns::for_each_verb([&](uint32_t index, const char* name, const auto&) { \ - if (index >= vdef.types.size()) \ - vdef.types.resize(index + 1, missing_struct_name); \ - vdef.types[index] = name; \ - }); \ - auto& variants = gen.def.variants.value; \ - auto it = std::find_if(variants.begin(), variants.end(), \ - [&](auto& d) { return d.name == variant_name; }); \ - if (it != variants.end()) \ - *it = std::move(vdef); \ - else \ - variants.push_back(std::move(vdef)); \ - })(); \ - , 1 diff --git a/contracts/eden/include/eden_dispatcher.hpp b/contracts/eden/include/eden_dispatcher.hpp deleted file mode 100644 index 25bb76215..000000000 --- a/contracts/eden/include/eden_dispatcher.hpp +++ /dev/null @@ -1,108 +0,0 @@ -#pragma once - -#include -#include - -namespace eden -{ - template - void execute_session_action(eosio::name contract, - R (T::*func)(const eosio::not_in_abi& current_session, - Args...), - const eosio::not_in_abi& current_session, - eosio::datastream& ds) - { - std::tuple...> t; - ds >> t; - T inst(contract, contract, ds); - std::apply([&](auto&... args) { (inst.*func)(current_session, std::move(args)...); }, t); - } -} // namespace eden - -#define EOSIO_MATCH_ACTIONeden_verb EOSIO_MATCH_YES -#define EOSIO_EXTRACT_ACTION_NAMEeden_verb(name, index, ...) name -#define EOSIO_EXTRACT_ACTION_ARGSeden_verb(name, index, ...) __VA_ARGS__ - -#define EDEN_MATCH_SESSION_ACTION(x) EOSIO_MATCH(EDEN_MATCH_SESSION_ACTION, x) -#define EDEN_MATCH_SESSION_ACTIONeden_verb EOSIO_MATCH_YES - -#define EDEN_EXTRACT_SESSION_ACTION_INDEX(x) BOOST_PP_CAT(EDEN_EXTRACT_SESSION_ACTION_INDEX, x) -#define EDEN_EXTRACT_SESSION_ACTION_INDEXeden_verb(name, index, ...) index - -#define EDEN_DISPATCH_SESSION_ACTION_INTERNAL_1(r, type, member) \ - case EDEN_EXTRACT_SESSION_ACTION_INDEX(member): \ - ::eden::execute_session_action(contract, &type::EOSIO_EXTRACT_ACTION_NAME(member), \ - current_session, ds); \ - return true; -#define EDEN_DISPATCH_SESSION_ACTION_INTERNAL(r, type, member) \ - BOOST_PP_IIF(EDEN_MATCH_SESSION_ACTION(member), EDEN_DISPATCH_SESSION_ACTION_INTERNAL_1, \ - EOSIO_EMPTY) \ - (r, type, member) -#define EDEN_DISPATCH_SESSION_ACTION(type, MEMBERS) \ - BOOST_PP_SEQ_FOR_EACH(EDEN_DISPATCH_SESSION_ACTION_INTERNAL, type, MEMBERS) - -#define EDEN_GET_SESSION_ACTION_INTERNAL_1(r, type, member) \ - f(EDEN_EXTRACT_SESSION_ACTION_INDEX(member), \ - BOOST_PP_STRINGIZE(EOSIO_EXTRACT_ACTION_NAME(member)), \ - &type::EOSIO_EXTRACT_ACTION_NAME(member)); -#define EDEN_GET_SESSION_ACTION_INTERNAL(r, type, member) \ - BOOST_PP_IIF(EDEN_MATCH_SESSION_ACTION(member), EDEN_GET_SESSION_ACTION_INTERNAL_1, \ - EOSIO_EMPTY) \ - (r, type, member) -#define EDEN_GET_SESSION_ACTION(type, MEMBERS) \ - BOOST_PP_SEQ_FOR_EACH(EDEN_GET_SESSION_ACTION_INTERNAL, type, MEMBERS) - -#define EDEN_NAME_FOR_SESSION_ACTION_INTERNAL_1(r, type, member) \ - case EDEN_EXTRACT_SESSION_ACTION_INDEX(member): \ - return BOOST_PP_CAT(BOOST_PP_STRINGIZE(EOSIO_EXTRACT_ACTION_NAME(member)), _n); -#define EDEN_NAME_FOR_SESSION_ACTION_INTERNAL(r, type, member) \ - BOOST_PP_IIF(EDEN_MATCH_SESSION_ACTION(member), EDEN_NAME_FOR_SESSION_ACTION_INTERNAL_1, \ - EOSIO_EMPTY) \ - (r, type, member) -#define EDEN_NAME_FOR_SESSION_ACTION(type, MEMBERS) \ - BOOST_PP_SEQ_FOR_EACH(EDEN_NAME_FOR_SESSION_ACTION_INTERNAL, type, MEMBERS) - -#define EDEN_INDEX_FOR_SESSION_ACTION_INTERNAL_1(r, type, member) \ - if (name == BOOST_PP_CAT(BOOST_PP_STRINGIZE(EOSIO_EXTRACT_ACTION_NAME(member)), _n)) \ - return EDEN_EXTRACT_SESSION_ACTION_INDEX(member); -#define EDEN_INDEX_FOR_SESSION_ACTION_INTERNAL(r, type, member) \ - BOOST_PP_IIF(EDEN_MATCH_SESSION_ACTION(member), EDEN_INDEX_FOR_SESSION_ACTION_INTERNAL_1, \ - EOSIO_EMPTY) \ - (r, type, member) -#define EDEN_INDEX_FOR_SESSION_ACTION(type, MEMBERS) \ - BOOST_PP_SEQ_FOR_EACH(EDEN_INDEX_FOR_SESSION_ACTION_INTERNAL, type, MEMBERS) - -#define EDEN_ACTIONS(CONTRACT_CLASS, CONTRACT_ACCOUNT, ...) \ - EOSIO_ACTIONS(CONTRACT_CLASS, CONTRACT_ACCOUNT, __VA_ARGS__) \ - namespace actions \ - { \ - inline bool session_dispatch(eosio::name contract, \ - uint32_t index, \ - const eosio::not_in_abi& current_session, \ - eosio::datastream& ds) \ - { \ - switch (index) \ - { \ - EDEN_DISPATCH_SESSION_ACTION(CONTRACT_CLASS, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \ - } \ - return false; \ - } \ - template \ - void for_each_verb(F f) \ - { \ - EDEN_GET_SESSION_ACTION(CONTRACT_CLASS, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \ - } \ - inline eosio::name get_name_for_session_action(uint32_t index) \ - { \ - switch (index) \ - { \ - EDEN_NAME_FOR_SESSION_ACTION(CONTRACT_CLASS, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \ - } \ - return {}; \ - } \ - inline std::optional get_index_for_session_action(eosio::name name) \ - { \ - EDEN_INDEX_FOR_SESSION_ACTION(CONTRACT_CLASS, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \ - return {}; \ - } \ - } diff --git a/contracts/eden/src/actions/sessions.cpp b/contracts/eden/src/actions/sessions.cpp index e338a0685..c1472b03b 100644 --- a/contracts/eden/src/actions/sessions.cpp +++ b/contracts/eden/src/actions/sessions.cpp @@ -217,7 +217,7 @@ namespace eden { eosio::varuint32 index; ds >> index; - eosio::check(actions::session_dispatch(get_self(), index.value, current_session, ds), + eosio::check(actions::dispatch_verb(get_self(), index.value, current_session, ds), "unsupported verb index"); } diff --git a/contracts/eden/src/eden-micro-chain.cpp b/contracts/eden/src/eden-micro-chain.cpp index 8f2b49bcc..7c6fd8321 100644 --- a/contracts/eden/src/eden-micro-chain.cpp +++ b/contracts/eden/src/eden-micro-chain.cpp @@ -2047,7 +2047,7 @@ void run(const action_context& context, eosio::input_stream& s) for (uint32_t i = 0; i < num_verbs.value; ++i) { auto index = eosio::varuint32_from_bin(s); - auto name = eden::actions::get_name_for_session_action(index); + auto name = eden::actions::verb_index_to_name(index); if (!dispatch(name, context, s)) // fatal because this throws off the rest of the stream eosio::check(false, diff --git a/contracts/eden/src/eden.cpp b/contracts/eden/src/eden.cpp index dddaee508..e11c7208a 100644 --- a/contracts/eden/src/eden.cpp +++ b/contracts/eden/src/eden.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -52,7 +51,7 @@ EOSIO_ABIGEN( variant("run_auth", eden::run_auth), variant("verb", eden::verb), actions(eden::actions), - eden_verbs(eden::actions, "verb", "unsupported_verb"), + verbs(eden::actions), table("account"_n, eden::account_variant), table("auction"_n, eden::auction_variant), table("bylaws"_n, eden::bylaws_variant), diff --git a/contracts/eden/tests/include/tester-base.hpp b/contracts/eden/tests/include/tester-base.hpp index 629924fe7..a9fbdf839 100644 --- a/contracts/eden/tests/include/tester-base.hpp +++ b/contracts/eden/tests/include/tester-base.hpp @@ -575,7 +575,7 @@ struct eden_tester template std::vector sact(Ts&&... args) { - auto index = actions::get_index_for_session_action(ActionWrapper::action_name); + auto index = actions::verb_name_to_index(ActionWrapper::action_name); eosio::check(index.has_value(), "action index not found"); auto data = eosio::convert_to_bin(eosio::varuint32(*index)); auto act = ActionWrapper{""_n}.to_action(std::forward(args)...); diff --git a/libraries/eosiolib/contracts/include/eosio/abi_generator.hpp b/libraries/eosiolib/contracts/include/eosio/abi_generator.hpp index 8faddd072..bfdcf4764 100644 --- a/libraries/eosiolib/contracts/include/eosio/abi_generator.hpp +++ b/libraries/eosiolib/contracts/include/eosio/abi_generator.hpp @@ -269,6 +269,25 @@ namespace eosio }); \ , 1 +#define EOSIO_ABIGEN_ITEMverbs(ns) \ + ([&] { \ + gen.def.structs.push_back(eosio::struct_def{"unsupported_verb"}); \ + eosio::variant_def vdef{"verb"}; \ + ns::for_each_verb([&](uint32_t index, const char* name, const auto&) { \ + if (index >= vdef.types.size()) \ + vdef.types.resize(index + 1, "unsupported_verb"); \ + vdef.types[index] = name; \ + }); \ + auto& variants = gen.def.variants.value; \ + auto it = std::find_if(variants.begin(), variants.end(), \ + [&](auto& d) { return d.name == "verb"; }); \ + if (it != variants.end()) \ + *it = std::move(vdef); \ + else \ + variants.push_back(std::move(vdef)); \ + })(); \ + , 1 + #define EOSIO_ABIGEN_ITEMtable(name, type) \ gen.add_table(name); \ , 1 diff --git a/libraries/eosiolib/contracts/include/eosio/dispatcher.hpp b/libraries/eosiolib/contracts/include/eosio/dispatcher.hpp index 1e6ad6444..5e032cc63 100644 --- a/libraries/eosiolib/contracts/include/eosio/dispatcher.hpp +++ b/libraries/eosiolib/contracts/include/eosio/dispatcher.hpp @@ -88,6 +88,18 @@ namespace eosio using args = detail::deduced; }; + template + void execute_verb(eosio::name contract, + R (T::*func)(const Session& current_session, Args...), + const auto& current_session, + eosio::datastream& ds) + { + std::tuple...> t; + ds >> t; + T inst(contract, contract, ds); + std::apply([&](auto&... args) { (inst.*func)(current_session, std::move(args)...); }, t); + } + #define EOSIO_EMPTY(...) #define EOSIO_COMMA_STRINGIZE(arg) , BOOST_PP_STRINGIZE(arg) #define EOSIO_DEFAULT_IF_EMPTY(x, def) BOOST_PP_IIF(BOOST_PP_CHECK_EMPTY(x), def, x) @@ -98,25 +110,32 @@ namespace eosio #define EOSIO_MATCH_YES ~, 1, #define EOSIO_MATCH(base, x) EOSIO_MATCH_CHECK(BOOST_PP_CAT(base, x)) -#define EOSIO_MATCH_ACTION(x) EOSIO_MATCH(EOSIO_MATCH_ACTION, x) -#define EOSIO_MATCH_ACTIONaction EOSIO_MATCH_YES -#define EOSIO_EXTRACT_ACTION_NAME(x) \ - BOOST_PP_IIF(EOSIO_MATCH_ACTION(x), BOOST_PP_CAT(EOSIO_EXTRACT_ACTION_NAME, x), x) -#define EOSIO_EXTRACT_ACTION_NAMEaction(name, ...) name +#define EOSIO_MATCH_ACTION_VERB(x) EOSIO_MATCH(EOSIO_MATCH_ACTION_VERB, x) +#define EOSIO_MATCH_ACTION_VERBaction EOSIO_MATCH_YES +#define EOSIO_MATCH_ACTION_VERBverb EOSIO_MATCH_YES +#define EOSIO_MATCH_ACTION_VERBaction_verb EOSIO_MATCH_YES +#define EOSIO_EXTRACT_ACTION_VERB_NAME(x) \ + BOOST_PP_IIF(EOSIO_MATCH_ACTION_VERB(x), BOOST_PP_CAT(EOSIO_EXTRACT_ACTION_VERB_NAME, x), x) +#define EOSIO_EXTRACT_ACTION_VERB_NAMEaction(name, ...) name +#define EOSIO_EXTRACT_ACTION_VERB_NAMEverb(name, index, ...) name +#define EOSIO_EXTRACT_ACTION_VERB_NAMEaction_verb(name, index, ...) name -#define EOSIO_HAS_ACTION_ARGS(action) \ - BOOST_PP_BITAND(EOSIO_MATCH_ACTION(action), \ - BOOST_PP_COMPL(BOOST_PP_CHECK_EMPTY(EOSIO_EXTRACT_ACTION_ARGS(action)))) -#define EOSIO_EXTRACT_ACTION_ARGS(x) BOOST_PP_CAT(EOSIO_EXTRACT_ACTION_ARGS, x) -#define EOSIO_EXTRACT_ACTION_ARGSaction(name, ...) __VA_ARGS__ +#define EOSIO_HAS_ACTION_VERB_ARGS(action) \ + BOOST_PP_BITAND(EOSIO_MATCH_ACTION_VERB(action), \ + BOOST_PP_COMPL(BOOST_PP_CHECK_EMPTY(EOSIO_EXTRACT_ACTION_VERB_ARGS(action)))) +#define EOSIO_EXTRACT_ACTION_VERB_ARGS(x) BOOST_PP_CAT(EOSIO_EXTRACT_ACTION_VERB_ARGS, x) +#define EOSIO_EXTRACT_ACTION_VERB_ARGSaction(name, ...) __VA_ARGS__ +#define EOSIO_EXTRACT_ACTION_VERB_ARGSverb(name, index, ...) __VA_ARGS__ +#define EOSIO_EXTRACT_ACTION_VERB_ARGSaction_verb(name, index, ...) __VA_ARGS__ #define EOSIO_ACTION_ARG_NAME_STRINGS_1(r, _, i, arg) \ BOOST_PP_IIF(EOSIO_MATCH_RICARDIAN(arg), EOSIO_EMPTY, EOSIO_COMMA_STRINGIZE)(arg) #define EOSIO_ACTION_ARG_NAME_STRINGS_2(action) \ BOOST_PP_SEQ_FOR_EACH_I(EOSIO_ACTION_ARG_NAME_STRINGS_1, _, \ - BOOST_PP_VARIADIC_TO_SEQ(EOSIO_EXTRACT_ACTION_ARGS(action))) -#define EOSIO_ACTION_ARG_NAME_STRINGS(action) \ - BOOST_PP_IIF(EOSIO_HAS_ACTION_ARGS(action), EOSIO_ACTION_ARG_NAME_STRINGS_2, EOSIO_EMPTY)(action) + BOOST_PP_VARIADIC_TO_SEQ(EOSIO_EXTRACT_ACTION_VERB_ARGS(action))) +#define EOSIO_ACTION_ARG_NAME_STRINGS(action) \ + BOOST_PP_IIF(EOSIO_HAS_ACTION_VERB_ARGS(action), EOSIO_ACTION_ARG_NAME_STRINGS_2, EOSIO_EMPTY) \ + (action) #define EOSIO_MATCH_RICARDIAN(action_arg) EOSIO_MATCH(EOSIO_MATCH_RICARDIAN, action_arg) #define EOSIO_MATCH_RICARDIANricardian_contract EOSIO_MATCH_YES @@ -127,9 +146,9 @@ namespace eosio BOOST_PP_IIF(EOSIO_MATCH_RICARDIAN(arg), EOSIO_EXTRACT_RICARDIAN, EOSIO_EMPTY)(arg) #define EOSIO_GET_RICARDIAN_2(action) \ BOOST_PP_SEQ_FOR_EACH_I(EOSIO_GET_RICARDIAN_3, _, \ - BOOST_PP_VARIADIC_TO_SEQ(EOSIO_EXTRACT_ACTION_ARGS(action))) + BOOST_PP_VARIADIC_TO_SEQ(EOSIO_EXTRACT_ACTION_VERB_ARGS(action))) #define EOSIO_GET_RICARDIAN_1(action) \ - BOOST_PP_IIF(EOSIO_HAS_ACTION_ARGS(action), EOSIO_GET_RICARDIAN_2, EOSIO_EMPTY)(action) + BOOST_PP_IIF(EOSIO_HAS_ACTION_VERB_ARGS(action), EOSIO_GET_RICARDIAN_2, EOSIO_EMPTY)(action) #define EOSIO_GET_RICARDIAN(action) EOSIO_DEFAULT_IF_EMPTY(EOSIO_GET_RICARDIAN_1(action), "") #define EOSIO_MATCH_NOTIFY(x) EOSIO_MATCH(EOSIO_MATCH_NOTIFY, x) @@ -139,13 +158,19 @@ namespace eosio #define EOSIO_EXTRACT_NOTIFY_ACTION(x) BOOST_PP_CAT(EOSIO_EXTRACT_NOTIFY_ACTION, x) #define EOSIO_EXTRACT_NOTIFY_ACTIONnotify(code, action) action -#define EOSIO_DISPATCH_ACTION_INTERNAL_1(r, type, member) \ - case eosio::hash_name(BOOST_PP_STRINGIZE(EOSIO_EXTRACT_ACTION_NAME(member))): \ - executed = eosio::execute_action(eosio::name(receiver), eosio::name(code), \ - &type::EOSIO_EXTRACT_ACTION_NAME(member)); \ +// Things which shouldn't be handled by EOSIO_DISPATCH_ACTION +#define EOSIO_MATCH_NOT_DISPATCH_ACTION(x) EOSIO_MATCH(EOSIO_MATCH_NOT_DISPATCH_ACTION, x) +#define EOSIO_MATCH_NOT_DISPATCH_ACTIONnotify EOSIO_MATCH_YES +#define EOSIO_MATCH_NOT_DISPATCH_ACTIONverb EOSIO_MATCH_YES + +#define EOSIO_DISPATCH_ACTION_INTERNAL_1(r, type, member) \ + case eosio::hash_name(BOOST_PP_STRINGIZE(EOSIO_EXTRACT_ACTION_VERB_NAME(member))): \ + executed = eosio::execute_action(eosio::name(receiver), eosio::name(code), \ + &type::EOSIO_EXTRACT_ACTION_VERB_NAME(member)); \ break; -#define EOSIO_DISPATCH_ACTION_INTERNAL(r, type, member) \ - BOOST_PP_IIF(EOSIO_MATCH_NOTIFY(member), EOSIO_EMPTY, EOSIO_DISPATCH_ACTION_INTERNAL_1) \ +#define EOSIO_DISPATCH_ACTION_INTERNAL(r, type, member) \ + BOOST_PP_IIF(EOSIO_MATCH_NOT_DISPATCH_ACTION(member), EOSIO_EMPTY, \ + EOSIO_DISPATCH_ACTION_INTERNAL_1) \ (r, type, member) #define EOSIO_DISPATCH_ACTION(type, MEMBERS) \ BOOST_PP_SEQ_FOR_EACH(EOSIO_DISPATCH_ACTION_INTERNAL, type, MEMBERS) @@ -166,23 +191,68 @@ namespace eosio #define EOSIO_DISPATCH_NOTIFY(type, MEMBERS) \ BOOST_PP_SEQ_FOR_EACH(EOSIO_DISPATCH_NOTIFY_INTERNAL, type, MEMBERS) -#define EOSIO_ACTION_WRAPPER_DECL_1(r, data, action) \ - using EOSIO_EXTRACT_ACTION_NAME(action) = eosio::action_wrapper; +#define EOSIO_ACTION_WRAPPER_DECL_1(r, data, action) \ + using EOSIO_EXTRACT_ACTION_VERB_NAME(action) = eosio::action_wrapper< \ + BOOST_PP_CAT(BOOST_PP_STRINGIZE(EOSIO_EXTRACT_ACTION_VERB_NAME(action)), _h), \ + &contract_class::EOSIO_EXTRACT_ACTION_VERB_NAME(action), contract_account>; #define EOSIO_ACTION_WRAPPER_DECL_0(r, data, action) #define EOSIO_ACTION_WRAPPER_DECL(r, data, action) \ BOOST_PP_CAT(EOSIO_ACTION_WRAPPER_DECL_, BOOST_PP_COMPL(EOSIO_MATCH_NOTIFY(action))) \ (r, data, action) -#define EOSIO_REFLECT_ACTION_1(r, data, action) \ - f(BOOST_PP_CAT( \ - BOOST_PP_STRINGIZE(EOSIO_EXTRACT_ACTION_NAME(action)), _h), \ - eosio::action_type_wrapper<&contract_class::EOSIO_EXTRACT_ACTION_NAME(action)>{}, \ - EOSIO_GET_RICARDIAN(action) EOSIO_ACTION_ARG_NAME_STRINGS(action)); +#define EOSIO_REFLECT_ACTION_1(r, data, action) \ + f(BOOST_PP_CAT(BOOST_PP_STRINGIZE(EOSIO_EXTRACT_ACTION_VERB_NAME(action)), _h), \ + eosio::action_type_wrapper<&contract_class::EOSIO_EXTRACT_ACTION_VERB_NAME(action)>{}, \ + EOSIO_GET_RICARDIAN(action) EOSIO_ACTION_ARG_NAME_STRINGS(action)); #define EOSIO_REFLECT_ACTION(r, data, action) \ BOOST_PP_IIF(EOSIO_MATCH_NOTIFY(action), EOSIO_EMPTY, EOSIO_REFLECT_ACTION_1)(r, data, action) +#define EOSIO_MATCH_VERB(x) EOSIO_MATCH(EOSIO_MATCH_VERB, x) +#define EOSIO_MATCH_VERBverb EOSIO_MATCH_YES +#define EOSIO_MATCH_VERBaction_verb EOSIO_MATCH_YES + +#define EOSIO_EXTRACT_VERB_INDEX(x) BOOST_PP_CAT(EOSIO_EXTRACT_VERB_INDEX, x) +#define EOSIO_EXTRACT_VERB_INDEXverb(name, index, ...) index +#define EOSIO_EXTRACT_VERB_INDEXaction_verb(name, index, ...) index + +#define EOSIO_DISPATCH_VERB_INTERNAL_1(r, type, member) \ + case EOSIO_EXTRACT_VERB_INDEX(member): \ + ::eosio::execute_verb(contract, &type::EOSIO_EXTRACT_ACTION_VERB_NAME(member), \ + current_session, ds); \ + return true; +#define EOSIO_DISPATCH_VERB_INTERNAL(r, type, member) \ + BOOST_PP_IIF(EOSIO_MATCH_VERB(member), EOSIO_DISPATCH_VERB_INTERNAL_1, EOSIO_EMPTY) \ + (r, type, member) +#define EOSIO_DISPATCH_VERB(type, MEMBERS) \ + BOOST_PP_SEQ_FOR_EACH(EOSIO_DISPATCH_VERB_INTERNAL, type, MEMBERS) + +#define EOSIO_FOR_EACH_VERB_INTERNAL_1(r, type, member) \ + f(EOSIO_EXTRACT_VERB_INDEX(member), BOOST_PP_STRINGIZE(EOSIO_EXTRACT_ACTION_VERB_NAME(member)), \ + &type::EOSIO_EXTRACT_ACTION_VERB_NAME(member)); +#define EOSIO_FOR_EACH_VERB_INTERNAL(r, type, member) \ + BOOST_PP_IIF(EOSIO_MATCH_VERB(member), EOSIO_FOR_EACH_VERB_INTERNAL_1, EOSIO_EMPTY) \ + (r, type, member) +#define EOSIO_FOR_EACH_VERB(type, MEMBERS) \ + BOOST_PP_SEQ_FOR_EACH(EOSIO_FOR_EACH_VERB_INTERNAL, type, MEMBERS) + +#define EOSIO_VERB_INDEX_TO_NAME_INTERNAL_1(r, type, member) \ + case EOSIO_EXTRACT_VERB_INDEX(member): \ + return BOOST_PP_CAT(BOOST_PP_STRINGIZE(EOSIO_EXTRACT_ACTION_VERB_NAME(member)), _n); +#define EOSIO_VERB_INDEX_TO_NAME_INTERNAL(r, type, member) \ + BOOST_PP_IIF(EOSIO_MATCH_VERB(member), EOSIO_VERB_INDEX_TO_NAME_INTERNAL_1, EOSIO_EMPTY) \ + (r, type, member) +#define EOSIO_VERB_INDEX_TO_NAME(type, MEMBERS) \ + BOOST_PP_SEQ_FOR_EACH(EOSIO_VERB_INDEX_TO_NAME_INTERNAL, type, MEMBERS) + +#define EOSIO_VERB_NAME_TO_INDEX_INTERNAL_1(r, type, member) \ + if (name == BOOST_PP_CAT(BOOST_PP_STRINGIZE(EOSIO_EXTRACT_ACTION_VERB_NAME(member)), _n)) \ + return EOSIO_EXTRACT_VERB_INDEX(member); +#define EOSIO_VERB_NAME_TO_INDEX_INTERNAL(r, type, member) \ + BOOST_PP_IIF(EOSIO_MATCH_VERB(member), EOSIO_VERB_NAME_TO_INDEX_INTERNAL_1, EOSIO_EMPTY) \ + (r, type, member) +#define EOSIO_VERB_NAME_TO_INDEX(type, MEMBERS) \ + BOOST_PP_SEQ_FOR_EACH(EOSIO_VERB_NAME_TO_INDEX_INTERNAL, type, MEMBERS) + #define EOSIO_ACTIONS(CONTRACT_CLASS, CONTRACT_ACCOUNT, ...) \ namespace actions \ { \ @@ -214,6 +284,39 @@ namespace eosio } \ EOSIO_DISPATCH_NOTIFY(CONTRACT_CLASS, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \ } \ + } \ + \ + inline bool dispatch_verb(eosio::name contract, \ + uint32_t index, \ + const auto& current_session, \ + eosio::datastream& ds) \ + { \ + switch (index) \ + { \ + EOSIO_DISPATCH_VERB(CONTRACT_CLASS, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \ + } \ + return false; \ + } \ + \ + template \ + void for_each_verb(F f) \ + { \ + EOSIO_FOR_EACH_VERB(CONTRACT_CLASS, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \ + } \ + \ + inline eosio::name verb_index_to_name(uint32_t index) \ + { \ + switch (index) \ + { \ + EOSIO_VERB_INDEX_TO_NAME(CONTRACT_CLASS, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \ + } \ + return {}; \ + } \ + \ + inline std::optional verb_name_to_index(eosio::name name) \ + { \ + EOSIO_VERB_NAME_TO_INDEX(CONTRACT_CLASS, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \ + return {}; \ } \ } From 8d738ca546fa34717d7dc068b2a447fb67a24fbe Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Wed, 8 Dec 2021 20:18:58 -0500 Subject: [PATCH 15/15] clsdk: contract auth --- contracts/eden/include/eden.hpp | 2 +- contracts/eden/include/sessions.hpp | 53 +------- contracts/eden/src/actions/sessions.cpp | 57 ++++----- contracts/eden/src/eden-micro-chain.cpp | 2 +- contracts/eden/src/eden.cpp | 2 +- contracts/eden/tests/include/tester-base.hpp | 2 +- .../contracts/include/eosio/contract_auth.hpp | 119 ++++++++++++++++++ 7 files changed, 148 insertions(+), 89 deletions(-) create mode 100644 libraries/eosiolib/contracts/include/eosio/contract_auth.hpp diff --git a/contracts/eden/include/eden.hpp b/contracts/eden/include/eden.hpp index 9756c9fb8..87da66626 100644 --- a/contracts/eden/include/eden.hpp +++ b/contracts/eden/include/eden.hpp @@ -87,7 +87,7 @@ namespace eden eosio::name eden_account, const eosio::public_key& key); - void run(eosio::ignore auth, eosio::ignore> verbs); + void run(eosio::ignore auth, eosio::ignore> verbs); void withdraw(eosio::name owner, const eosio::asset& quantity); diff --git a/contracts/eden/include/sessions.hpp b/contracts/eden/include/sessions.hpp index 91a8aa962..03da478fb 100644 --- a/contracts/eden/include/sessions.hpp +++ b/contracts/eden/include/sessions.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -46,58 +47,6 @@ namespace eden void clearall_sessions(eosio::name contract); void remove_sessions(eosio::name contract, eosio::name eden_account); - // No authorization provided - struct no_auth - { - }; - EOSIO_REFLECT(no_auth) - - // Case 1: eosio account. run() does a require_auth(eosio_account). - // * contract: "" - // * contract_account: "" - // * eosio_account: the account - // - // Case 2: contract-defined account. run() does a require_auth(eosio_account), verifies - // that eosio_account is associated with contract_account, verifies the recovered - // public key is registered for the account, and checks the sequence number. run() - // may delegate everything except the require_auth to another contract. - // * contract: the contract defining the account space - // * contract_account: the account - // * eosio_account: eosio account associated with contract_account. - // - // The Eden contract only supports Case 2 and requires contract == the Eden contract. - struct account_auth - { - eosio::name contract; - eosio::name contract_account; - eosio::name eosio_account; - }; - EOSIO_REFLECT(account_auth, contract, contract_account, eosio_account) - - // * signature: covers sha256(contract, account, sequence, verbs) - // * contract: the contract defining the account space, or "" if an eosio account - // * account: the contract account or eosio account - // * sequence: replay prevention - // - // The Eden contract requires contract == the Eden contract. - struct signature_auth - { - eosio::signature signature; - eosio::name contract; - eosio::name account; - eosio::varuint32 sequence; - }; - EOSIO_REFLECT(signature_auth, signature, contract, account, sequence) - - using run_auth = std::variant; - - enum class run_auth_type - { - no_auth, - account_auth, - signature_auth - }; - struct session_info { std::optional authorized_eden_account; diff --git a/contracts/eden/src/actions/sessions.cpp b/contracts/eden/src/actions/sessions.cpp index c1472b03b..c4ba51d2c 100644 --- a/contracts/eden/src/actions/sessions.cpp +++ b/contracts/eden/src/actions/sessions.cpp @@ -134,70 +134,61 @@ namespace eden table.erase(sc); } // eden::delsession - void eden::run(eosio::ignore auth, eosio::ignore> verbs) + void eden::run(eosio::ignore auth, eosio::ignore> verbs) { auto& ds = get_datastream(); eosio::name eden_account; - eosio::varuint32 auth_type; - ds >> auth_type; - if (auth_type.value == (int)run_auth_type::no_auth) + auto a = eosio::recover_auth(ds); + if (a.type == eosio::run_auth_type::no_auth) { } - else if (auth_type.value == (int)run_auth_type::account_auth) + else if (a.type == eosio::run_auth_type::account_auth) { - account_auth a; - ds >> a; eosio::check(a.contract == get_self(), "unsupported contract for auth"); eosio::check(a.contract_account == a.eosio_account, "account recovery not yet implemented"); - eosio::require_auth(a.eosio_account); eden_account = a.contract_account; } - else if (auth_type.value == (int)run_auth_type::signature_auth) + else if (a.type == eosio::run_auth_type::signature_auth) { - eosio::signature signature; - eosio::name contract; - eosio::varuint32 sequence; - ds >> signature; - auto digest = eosio::sha256(ds.pos(), ds.remaining()); - auto recovered = eosio::recover_key(digest, signature); - ds >> contract; - ds >> eden_account; - ds >> sequence; - eosio::check(contract == get_self(), "unsupported contract for auth"); + eosio::check(a.contract == get_self(), "unsupported contract for auth"); + eden_account = a.contract_account; sessions_table_type table(get_self(), default_scope); auto sc = table.find(eden_account.value); if (sc == table.end()) - eosio::check(false, "Recovered session key " + public_key_to_string(recovered) + + eosio::check(false, "Recovered session key " + public_key_to_string(a.recovered_key) + " is either expired or not found"); table.modify(sc, get_self(), [&](auto& sc) { expire(get_self(), sc); set_expiration(sc); auto& sessions = sc.sessions(); - auto session = std::find_if(sessions.begin(), sessions.end(), - [&](auto& session) { return session.key == recovered; }); + auto session = std::find_if(sessions.begin(), sessions.end(), [&](auto& session) { + return session.key == a.recovered_key; + }); if (session == sessions.end()) - eosio::check(false, "Recovered session key " + public_key_to_string(recovered) + + eosio::check(false, "Recovered session key " + + public_key_to_string(a.recovered_key) + " is either expired or not found"); auto& sequences = session->sequences; if (sequences.begin() != sequences.end()) { - if (sequence.value < *sequences.begin() && sequences.size() >= 20) + if (a.sequence.value < *sequences.begin() && sequences.size() >= 20) eosio::check(false, - "received duplicate sequence " + std::to_string(sequence.value)); - else if (sequence.value > sequences.end()[-1].value + 10) + "received duplicate sequence " + std::to_string(a.sequence.value)); + else if (a.sequence.value > sequences.end()[-1].value + 10) eosio::check(false, - "sequence " + std::to_string(sequence.value) + " skips too many"); + "sequence " + std::to_string(a.sequence.value) + " skips too many"); } - else if (sequence.value > 10) + else if (a.sequence.value > 10) + eosio::check(false, + "sequence " + std::to_string(a.sequence.value) + " skips too many"); + auto it = std::lower_bound(sequences.begin(), sequences.end(), a.sequence); + if (it != sequences.end() && *it == a.sequence) eosio::check(false, - "sequence " + std::to_string(sequence.value) + " skips too many"); - auto it = std::lower_bound(sequences.begin(), sequences.end(), sequence); - if (it != sequences.end() && *it == sequence) - eosio::check(false, "received duplicate sequence " + std::to_string(sequence.value)); - sequences.insert(it, sequence); + "received duplicate sequence " + std::to_string(a.sequence.value)); + sequences.insert(it, a.sequence); if (sequences.size() > 20) sequences.erase(sequences.begin()); }); diff --git a/contracts/eden/src/eden-micro-chain.cpp b/contracts/eden/src/eden-micro-chain.cpp index 7c6fd8321..880201115 100644 --- a/contracts/eden/src/eden-micro-chain.cpp +++ b/contracts/eden/src/eden-micro-chain.cpp @@ -2040,7 +2040,7 @@ bool dispatch(eosio::name action_name, const action_context& context, eosio::inp void run(const action_context& context, eosio::input_stream& s) { - eden::run_auth auth; + eosio::run_auth auth; eosio::varuint32 num_verbs; from_bin(auth, s); from_bin(num_verbs, s); diff --git a/contracts/eden/src/eden.cpp b/contracts/eden/src/eden.cpp index e11c7208a..379883e1e 100644 --- a/contracts/eden/src/eden.cpp +++ b/contracts/eden/src/eden.cpp @@ -48,7 +48,7 @@ EOSIO_ABIGEN( "FLOAT_VEC", "DOUBLE_VEC", "STRING_VEC"), - variant("run_auth", eden::run_auth), + variant("run_auth", eosio::run_auth), variant("verb", eden::verb), actions(eden::actions), verbs(eden::actions), diff --git a/contracts/eden/tests/include/tester-base.hpp b/contracts/eden/tests/include/tester-base.hpp index a9fbdf839..18122766f 100644 --- a/contracts/eden/tests/include/tester-base.hpp +++ b/contracts/eden/tests/include/tester-base.hpp @@ -548,7 +548,7 @@ struct eden_tester auto digest = eosio::sha256(data.data(), data.size()); auto signature = eosio::sign(key, digest); auto sig_bin = eosio::convert_to_bin(signature); - data.insert(data.begin(), (uint8_t)eden::run_auth_type::signature_auth); + data.insert(data.begin(), (uint8_t)eosio::run_auth_type::signature_auth); data.insert(data.begin() + 1, sig_bin.begin(), sig_bin.end()); eosio::action act; diff --git a/libraries/eosiolib/contracts/include/eosio/contract_auth.hpp b/libraries/eosiolib/contracts/include/eosio/contract_auth.hpp new file mode 100644 index 000000000..636b8d4b3 --- /dev/null +++ b/libraries/eosiolib/contracts/include/eosio/contract_auth.hpp @@ -0,0 +1,119 @@ +#pragma once + +#include +#include +#include + +namespace eosio +{ + // No authorization provided + struct no_auth + { + }; + EOSIO_REFLECT(no_auth) + + // Case 1: eosio account. run() does a require_auth(eosio_account). + // * contract: "" + // * contract_account: "" + // * eosio_account: the account + // + // Case 2: contract-defined account. run() does a require_auth(eosio_account), verifies + // that eosio_account is associated with contract_account, verifies the recovered + // public key is registered for the account, and checks the sequence number. run() + // may delegate everything except the require_auth to another contract. + // * contract: the contract defining the account space + // * contract_account: the account + // * eosio_account: eosio account associated with contract_account. + struct account_auth + { + eosio::name contract; + eosio::name contract_account; + eosio::name eosio_account; + }; + EOSIO_REFLECT(account_auth, contract, contract_account, eosio_account) + + // * signature: covers sha256(contract, account, sequence, verbs) + // * contract: the contract defining the account space, or "" if an eosio account + // * account: the contract account or eosio account + // * sequence: replay prevention + struct signature_auth + { + eosio::signature signature; + eosio::name contract; + eosio::name account; + eosio::varuint32 sequence; + }; + EOSIO_REFLECT(signature_auth, signature, contract, account, sequence) + + using run_auth = std::variant; + + enum class run_auth_type + { + no_auth, + account_auth, + signature_auth + }; + + // * contract: the contract defining the account space, or "" + // * contract_account: the contract account, or "" + // * eosio_account: eosio account, or "" + // * recovered_key: public key recovered from signature_auth + // * sequence: replay prevention + struct recovered_auth + { + run_auth_type type = {run_auth_type::no_auth}; + eosio::name contract = {}; + eosio::name contract_account = {}; + eosio::name eosio_account = {}; + eosio::public_key recovered_key = {}; + eosio::varuint32 sequence = {}; + }; + + // Recover authentication from the datastream. ds must have this format: + // run_auth, std::vector<*> + // + // * If run_auth is no_auth, then all fields of recovered_auth are default (empty) + // * If run_auth is account_auth, then recover_auth() runs require_auth(eosio_account) and + // copies the fields of account_auth. + // * If run_auth is signature_auth, then recover_auth() recovers the public key from + // signature and copies the remaining fields from signature_auth. + inline recovered_auth recover_auth(datastream& ds) + { + recovered_auth result; + eosio::varuint32 t; + ds >> t; + result.type = (run_auth_type)t.value; + if (t.value == (int)run_auth_type::no_auth) + { + } + else if (t.value == (int)run_auth_type::account_auth) + { + eosio::account_auth a; + ds >> a; + eosio::require_auth(a.eosio_account); + result.contract = a.contract; + result.contract_account = a.contract_account; + result.eosio_account = a.eosio_account; + } + else if (t.value == (int)run_auth_type::signature_auth) + { + eosio::signature signature; + eosio::name account; + ds >> signature; + auto digest = eosio::sha256(ds.pos(), ds.remaining()); + result.recovered_key = eosio::recover_key(digest, signature); + ds >> result.contract; + ds >> account; + ds >> result.sequence; + if (result.contract.value) + result.contract_account = account; + else + result.eosio_account = account; + } + else + { + eosio::check(false, "unsupported auth type"); + } + return result; + } +} // namespace eosio