skir-cc-gen 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/CMakeLists.txt +38 -19
- package/client/skir.cc +57 -0
- package/client/skir.h +176 -147
- package/client/skir.testing.h +2 -3
- package/dist/enum_variant.js +1 -1
- package/dist/enum_variant.js.map +1 -1
- package/package.json +2 -2
- package/src/enum_variant.ts +1 -1
package/client/CMakeLists.txt
CHANGED
|
@@ -13,11 +13,23 @@ if(NOT TARGET absl::base)
|
|
|
13
13
|
find_package(absl REQUIRED)
|
|
14
14
|
endif()
|
|
15
15
|
|
|
16
|
-
# GoogleTest -
|
|
17
|
-
if(NOT
|
|
18
|
-
|
|
16
|
+
# GoogleTest - optional, only needed for testing library
|
|
17
|
+
if(NOT DEFINED SKIR_ENABLE_TESTING)
|
|
18
|
+
# Default: enable testing if GTest is available
|
|
19
|
+
if(TARGET GTest::gtest)
|
|
20
|
+
set(SKIR_ENABLE_TESTING ON)
|
|
21
|
+
else()
|
|
22
|
+
find_package(GTest QUIET)
|
|
23
|
+
if(GTest_FOUND)
|
|
24
|
+
set(SKIR_ENABLE_TESTING ON)
|
|
25
|
+
else()
|
|
26
|
+
set(SKIR_ENABLE_TESTING OFF)
|
|
27
|
+
endif()
|
|
28
|
+
endif()
|
|
19
29
|
endif()
|
|
20
30
|
|
|
31
|
+
message(STATUS "Skir testing library: ${SKIR_ENABLE_TESTING}")
|
|
32
|
+
|
|
21
33
|
# ============================================================================
|
|
22
34
|
# Main skir library
|
|
23
35
|
# ============================================================================
|
|
@@ -48,24 +60,31 @@ target_link_libraries(skir PUBLIC
|
|
|
48
60
|
|
|
49
61
|
# ============================================================================
|
|
50
62
|
# Testing library (interface library with header-only implementation)
|
|
63
|
+
# Only built if GTest is available
|
|
51
64
|
# ============================================================================
|
|
52
65
|
|
|
53
|
-
|
|
66
|
+
if(SKIR_ENABLE_TESTING)
|
|
67
|
+
add_library(skir_testing INTERFACE)
|
|
54
68
|
|
|
55
|
-
target_sources(skir_testing INTERFACE
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
)
|
|
69
|
+
target_sources(skir_testing INTERFACE
|
|
70
|
+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/skir.testing.h>
|
|
71
|
+
$<INSTALL_INTERFACE:include/skir.testing.h>
|
|
72
|
+
)
|
|
59
73
|
|
|
60
|
-
target_include_directories(skir_testing INTERFACE
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
)
|
|
74
|
+
target_include_directories(skir_testing INTERFACE
|
|
75
|
+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
|
76
|
+
$<INSTALL_INTERFACE:include>
|
|
77
|
+
)
|
|
64
78
|
|
|
65
|
-
target_link_libraries(skir_testing INTERFACE
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
)
|
|
79
|
+
target_link_libraries(skir_testing INTERFACE
|
|
80
|
+
skir
|
|
81
|
+
absl::base
|
|
82
|
+
absl::die_if_null
|
|
83
|
+
GTest::gtest
|
|
84
|
+
GTest::gmock
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
message(STATUS "Skir testing library target created")
|
|
88
|
+
else()
|
|
89
|
+
message(STATUS "Skir testing library disabled (GTest not available)")
|
|
90
|
+
endif()
|
package/client/skir.cc
CHANGED
|
@@ -996,6 +996,63 @@ void ParseFieldOrVariant(JsonTokenizer& tokenizer, FieldOrVariant& out) {
|
|
|
996
996
|
}
|
|
997
997
|
} // namespace
|
|
998
998
|
|
|
999
|
+
skir::service::RawResponse MakeOkJsonResponse(std::string data) {
|
|
1000
|
+
return {
|
|
1001
|
+
.data = std::move(data),
|
|
1002
|
+
.status_code = 200,
|
|
1003
|
+
.content_type = "application/json",
|
|
1004
|
+
};
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
skir::service::RawResponse MakeOkHtmlResponse(std::string data) {
|
|
1008
|
+
return {
|
|
1009
|
+
.data = std::move(data),
|
|
1010
|
+
.status_code = 200,
|
|
1011
|
+
.content_type = "text/html; charset=utf-8",
|
|
1012
|
+
};
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
std::string GetStudioHtml(absl::string_view studio_app_js_url) {
|
|
1016
|
+
const std::string escaped_url =
|
|
1017
|
+
absl::StrReplaceAll(studio_app_js_url, {{"&", "&"},
|
|
1018
|
+
{"<", "<"},
|
|
1019
|
+
{">", ">"},
|
|
1020
|
+
{"\"", """},
|
|
1021
|
+
{"'", "'"}});
|
|
1022
|
+
return absl::StrCat(R"html(<!DOCTYPE html>
|
|
1023
|
+
|
|
1024
|
+
<html>
|
|
1025
|
+
<head>
|
|
1026
|
+
<meta charset="utf-8" />
|
|
1027
|
+
<title>Skir Studio</title>
|
|
1028
|
+
<script src=")html",
|
|
1029
|
+
escaped_url,
|
|
1030
|
+
R"html("></script>
|
|
1031
|
+
</head>
|
|
1032
|
+
<body style="margin: 0; padding: 0;">
|
|
1033
|
+
<skir-studio-app></skir-studio-app>
|
|
1034
|
+
</body>
|
|
1035
|
+
</html>
|
|
1036
|
+
)html");
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
skir::service::RawResponse MakeBadRequestResponse(std::string data) {
|
|
1040
|
+
return {
|
|
1041
|
+
.data = std::move(data),
|
|
1042
|
+
.status_code = 400,
|
|
1043
|
+
.content_type = "text/plain; charset=utf-8",
|
|
1044
|
+
};
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
skir::service::RawResponse MakeServerErrorResponse(std::string data,
|
|
1048
|
+
int status_code) {
|
|
1049
|
+
return {
|
|
1050
|
+
.data = std::move(data),
|
|
1051
|
+
.status_code = status_code,
|
|
1052
|
+
.content_type = "text/plain; charset=utf-8",
|
|
1053
|
+
};
|
|
1054
|
+
}
|
|
1055
|
+
|
|
999
1056
|
JsonTokenType JsonTokenizer::Next() {
|
|
1000
1057
|
if (!state_.status.ok()) return JsonTokenType::kError;
|
|
1001
1058
|
return state_.token_type = NextImpl(state_);
|
package/client/skir.h
CHANGED
|
@@ -882,64 +882,120 @@ struct enum_wrapper_variant {
|
|
|
882
882
|
|
|
883
883
|
namespace service {
|
|
884
884
|
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
885
|
+
// HTTP status codes for errors.
|
|
886
|
+
enum class HttpErrorCode {
|
|
887
|
+
k400_BadRequest = 400,
|
|
888
|
+
k401_Unauthorized = 401,
|
|
889
|
+
k402_PaymentRequired = 402,
|
|
890
|
+
k403_Forbidden = 403,
|
|
891
|
+
k404_NotFound = 404,
|
|
892
|
+
k405_MethodNotAllowed = 405,
|
|
893
|
+
k406_NotAcceptable = 406,
|
|
894
|
+
k407_ProxyAuthenticationRequired = 407,
|
|
895
|
+
k408_RequestTimeout = 408,
|
|
896
|
+
k409_Conflict = 409,
|
|
897
|
+
k410_Gone = 410,
|
|
898
|
+
k411_LengthRequired = 411,
|
|
899
|
+
k412_PreconditionFailed = 412,
|
|
900
|
+
k413_ContentTooLarge = 413,
|
|
901
|
+
k414_UriTooLong = 414,
|
|
902
|
+
k415_UnsupportedMediaType = 415,
|
|
903
|
+
k416_RangeNotSatisfiable = 416,
|
|
904
|
+
k417_ExpectationFailed = 417,
|
|
905
|
+
k418_ImATeapot = 418,
|
|
906
|
+
k421_MisdirectedRequest = 421,
|
|
907
|
+
k422_UnprocessableContent = 422,
|
|
908
|
+
k423_Locked = 423,
|
|
909
|
+
k424_FailedDependency = 424,
|
|
910
|
+
k425_TooEarly = 425,
|
|
911
|
+
k426_UpgradeRequired = 426,
|
|
912
|
+
k428_PreconditionRequired = 428,
|
|
913
|
+
k429_TooManyRequests = 429,
|
|
914
|
+
k431_RequestHeaderFieldsTooLarge = 431,
|
|
915
|
+
k451_UnavailableForLegalReasons = 451,
|
|
916
|
+
k500_InternalServerError = 500,
|
|
917
|
+
k501_NotImplemented = 501,
|
|
918
|
+
k502_BadGateway = 502,
|
|
919
|
+
k503_ServiceUnavailable = 503,
|
|
920
|
+
k504_GatewayTimeout = 504,
|
|
921
|
+
k505_HttpVersionNotSupported = 505,
|
|
922
|
+
k506_VariantAlsoNegotiates = 506,
|
|
923
|
+
k507_InsufficientStorage = 507,
|
|
924
|
+
k508_LoopDetected = 508,
|
|
925
|
+
k510_NotExtended = 510,
|
|
926
|
+
k511_NetworkAuthenticationRequired = 511,
|
|
927
|
+
};
|
|
928
|
+
|
|
929
|
+
// Represents an error with a specific HTTP status code.
|
|
930
|
+
// Use this as a return type from service methods when you want to control the
|
|
931
|
+
// HTTP error code sent to clients. For generic errors where the default 500
|
|
932
|
+
// status code is acceptable, use absl::Status instead.
|
|
933
|
+
struct Error {
|
|
934
|
+
HttpErrorCode code = HttpErrorCode::k500_InternalServerError;
|
|
935
|
+
std::string message;
|
|
936
|
+
};
|
|
937
|
+
|
|
938
|
+
// Represents either a successful Response or an Error with a specific HTTP
|
|
939
|
+
// status code. Use this as the return type for service methods when you need
|
|
940
|
+
// fine-grained control over HTTP error codes. For simple error handling where
|
|
941
|
+
// generic HTTP status codes are sufficient, use absl::StatusOr<Response>
|
|
942
|
+
// instead.
|
|
943
|
+
template <typename Response>
|
|
944
|
+
class ErrorOr {
|
|
945
|
+
public:
|
|
946
|
+
ErrorOr() = default;
|
|
947
|
+
ErrorOr(const ErrorOr&) = default;
|
|
948
|
+
ErrorOr(ErrorOr&&) = default;
|
|
903
949
|
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
return 200;
|
|
909
|
-
case ResponseType::kBadRequest:
|
|
910
|
-
return 400;
|
|
911
|
-
case ResponseType::kServerError:
|
|
912
|
-
return 500;
|
|
913
|
-
}
|
|
950
|
+
ErrorOr(Response response) : variant_(std::move(response)) {}
|
|
951
|
+
ErrorOr(Error error) : variant_(std::move(error)) {}
|
|
952
|
+
ErrorOr(absl::StatusOr<Response> response_or_error) {
|
|
953
|
+
(*this) = std::move(response_or_error);
|
|
914
954
|
}
|
|
915
955
|
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
956
|
+
ErrorOr& operator=(const ErrorOr&) = default;
|
|
957
|
+
ErrorOr& operator=(ErrorOr&&) = default;
|
|
958
|
+
|
|
959
|
+
ErrorOr& operator=(Response response) {
|
|
960
|
+
variant_ = std::move(response);
|
|
961
|
+
return *this;
|
|
962
|
+
}
|
|
963
|
+
ErrorOr& operator=(Error error) {
|
|
964
|
+
variant_ = std::move(error);
|
|
965
|
+
return *this;
|
|
966
|
+
}
|
|
967
|
+
ErrorOr& operator=(absl::StatusOr<Response> response_or_error) {
|
|
968
|
+
if (response_or_error.ok()) {
|
|
969
|
+
variant_ = *std::move(response_or_error);
|
|
970
|
+
} else {
|
|
971
|
+
variant_ = Error{
|
|
972
|
+
HttpErrorCode::k500_InternalServerError,
|
|
973
|
+
absl::StrCat("server error: ", response_or_error.status().message())};
|
|
931
974
|
}
|
|
975
|
+
return *this;
|
|
932
976
|
}
|
|
933
977
|
|
|
978
|
+
bool ok() const { return std::holds_alternative<Response>(variant_); }
|
|
979
|
+
|
|
980
|
+
const std::variant<Response, Error>& variant() const { return variant_; }
|
|
981
|
+
std::variant<Response, Error>& variant() { return variant_; }
|
|
982
|
+
|
|
983
|
+
private:
|
|
984
|
+
using variant_type = std::variant<Response, Error>;
|
|
985
|
+
variant_type variant_;
|
|
986
|
+
};
|
|
987
|
+
|
|
988
|
+
// Raw response returned by the server.
|
|
989
|
+
struct RawResponse {
|
|
990
|
+
std::string data;
|
|
991
|
+
int status_code{};
|
|
992
|
+
std::string content_type;
|
|
993
|
+
|
|
934
994
|
absl::StatusOr<std::string> AsStatus() && {
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
case ResponseType::kOkHtml:
|
|
938
|
-
return std::move(data);
|
|
939
|
-
case ResponseType::kBadRequest:
|
|
940
|
-
case ResponseType::kServerError:
|
|
941
|
-
return absl::UnknownError(std::move(data));
|
|
995
|
+
if (status_code >= 200 && status_code < 300) {
|
|
996
|
+
return std::move(data);
|
|
942
997
|
}
|
|
998
|
+
return absl::UnknownError(std::move(data));
|
|
943
999
|
}
|
|
944
1000
|
};
|
|
945
1001
|
|
|
@@ -975,14 +1031,22 @@ class HttpHeaders {
|
|
|
975
1031
|
absl::flat_hash_map<std::string, std::vector<std::string>> map_;
|
|
976
1032
|
};
|
|
977
1033
|
|
|
1034
|
+
// Options for handling service requests.
|
|
1035
|
+
struct ServiceOptions {
|
|
1036
|
+
UnrecognizedValuesPolicy unrecognized_values =
|
|
1037
|
+
UnrecognizedValuesPolicy::kDrop;
|
|
1038
|
+
std::string studio_app_js_url =
|
|
1039
|
+
"https://cdn.jsdelivr.net/npm/skir-studio/dist/skir-studio-standalone.js";
|
|
1040
|
+
};
|
|
1041
|
+
|
|
978
1042
|
// Sends RPCs to a skir service.
|
|
979
1043
|
class Client {
|
|
980
1044
|
public:
|
|
981
1045
|
virtual ~Client() = default;
|
|
982
1046
|
|
|
983
1047
|
virtual absl::StatusOr<std::string> operator()(
|
|
984
|
-
absl::string_view request_data,
|
|
985
|
-
HttpHeaders&
|
|
1048
|
+
absl::string_view request_data,
|
|
1049
|
+
const HttpHeaders& request_headers) const = 0;
|
|
986
1050
|
};
|
|
987
1051
|
|
|
988
1052
|
} // namespace service
|
|
@@ -990,6 +1054,12 @@ class Client {
|
|
|
990
1054
|
|
|
991
1055
|
namespace skir_internal {
|
|
992
1056
|
|
|
1057
|
+
skir::service::RawResponse MakeOkJsonResponse(std::string data);
|
|
1058
|
+
skir::service::RawResponse MakeOkHtmlResponse(std::string data);
|
|
1059
|
+
skir::service::RawResponse MakeBadRequestResponse(std::string data);
|
|
1060
|
+
skir::service::RawResponse MakeServerErrorResponse(std::string data,
|
|
1061
|
+
int status_code);
|
|
1062
|
+
|
|
993
1063
|
template <typename T>
|
|
994
1064
|
T& get(T& input) {
|
|
995
1065
|
return input;
|
|
@@ -2593,33 +2663,19 @@ struct MethodListAdapter {
|
|
|
2593
2663
|
inline MethodDescriptorAdapter GetAdapter(skir_type<MethodDescriptor>);
|
|
2594
2664
|
inline MethodListAdapter GetAdapter(skir_type<MethodList>);
|
|
2595
2665
|
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
<
|
|
2599
|
-
<head>
|
|
2600
|
-
<meta charset="utf-8" />
|
|
2601
|
-
<title>RESTudio</title>
|
|
2602
|
-
<script src="https://cdn.jsdelivr.net/npm/restudio/dist/restudio-standalone.js"></script>
|
|
2603
|
-
</head>
|
|
2604
|
-
<body style="margin: 0; padding: 0;">
|
|
2605
|
-
<restudio-app></restudio-app>
|
|
2606
|
-
</body>
|
|
2607
|
-
</html>
|
|
2608
|
-
)html";
|
|
2609
|
-
|
|
2610
|
-
template <typename ServiceImpl, typename RequestMeta, typename ResponseMeta>
|
|
2666
|
+
std::string GetStudioHtml(absl::string_view studio_app_js_url);
|
|
2667
|
+
|
|
2668
|
+
template <typename ServiceImpl, typename RequestMeta>
|
|
2611
2669
|
class HandleRequestOp {
|
|
2612
2670
|
public:
|
|
2613
2671
|
HandleRequestOp(ServiceImpl* absl_nonnull service_impl,
|
|
2614
2672
|
absl::string_view request_body,
|
|
2615
|
-
skir::
|
|
2616
|
-
const RequestMeta* absl_nonnull request_meta
|
|
2617
|
-
ResponseMeta* absl_nonnull response_meta)
|
|
2673
|
+
const skir::service::ServiceOptions* absl_nonnull options,
|
|
2674
|
+
const RequestMeta* absl_nonnull request_meta)
|
|
2618
2675
|
: service_impl_(*service_impl),
|
|
2619
2676
|
request_body_(request_body),
|
|
2620
|
-
|
|
2621
|
-
request_meta_(*request_meta)
|
|
2622
|
-
response_meta_(*response_meta) {}
|
|
2677
|
+
options_(*options),
|
|
2678
|
+
request_meta_(*request_meta) {}
|
|
2623
2679
|
|
|
2624
2680
|
skir::service::RawResponse Run() {
|
|
2625
2681
|
if (request_body_ == "" || request_body_ == "list") {
|
|
@@ -2631,20 +2687,16 @@ class HandleRequestOp {
|
|
|
2631
2687
|
typename ServiceImpl::methods());
|
|
2632
2688
|
ReadableJson json;
|
|
2633
2689
|
MethodListAdapter::Append(method_list, json);
|
|
2634
|
-
return
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
} else if (request_body_ == "debug" || request_body_ == "restudio") {
|
|
2639
|
-
return {std::string(kRestudioHtml), skir::service::ResponseType::kOkHtml};
|
|
2690
|
+
return skir_internal::MakeOkJsonResponse(json.out);
|
|
2691
|
+
} else if (request_body_ == "studio") {
|
|
2692
|
+
return skir_internal::MakeOkHtmlResponse(
|
|
2693
|
+
GetStudioHtml(options_.studio_app_js_url));
|
|
2640
2694
|
}
|
|
2641
2695
|
|
|
2642
2696
|
if (const absl::Status status = request_body_parsed_.Parse(request_body_);
|
|
2643
2697
|
!status.ok()) {
|
|
2644
|
-
return
|
|
2645
|
-
absl::StrCat("bad request: ", status.message())
|
|
2646
|
-
skir::service::ResponseType::kBadRequest,
|
|
2647
|
-
};
|
|
2698
|
+
return skir_internal::MakeBadRequestResponse(
|
|
2699
|
+
absl::StrCat("bad request: ", status.message()));
|
|
2648
2700
|
}
|
|
2649
2701
|
|
|
2650
2702
|
std::apply(
|
|
@@ -2655,19 +2707,16 @@ class HandleRequestOp {
|
|
|
2655
2707
|
if (raw_response_.has_value()) {
|
|
2656
2708
|
return std::move(*raw_response_);
|
|
2657
2709
|
}
|
|
2658
|
-
return
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
"; number: ", request_body_parsed_.method_number.value_or(-1)),
|
|
2662
|
-
skir::service::ResponseType::kBadRequest};
|
|
2710
|
+
return skir_internal::MakeBadRequestResponse(absl::StrCat(
|
|
2711
|
+
"bad request: method not found: ", request_body_parsed_.method_name,
|
|
2712
|
+
"; number: ", request_body_parsed_.method_number.value_or(-1)));
|
|
2663
2713
|
}
|
|
2664
2714
|
|
|
2665
2715
|
private:
|
|
2666
2716
|
ServiceImpl& service_impl_;
|
|
2667
2717
|
const absl::string_view request_body_;
|
|
2668
|
-
const skir::
|
|
2718
|
+
const skir::service::ServiceOptions& options_;
|
|
2669
2719
|
const RequestMeta& request_meta_;
|
|
2670
|
-
ResponseMeta& response_meta_;
|
|
2671
2720
|
|
|
2672
2721
|
RequestBody request_body_parsed_;
|
|
2673
2722
|
|
|
@@ -2689,29 +2738,28 @@ class HandleRequestOp {
|
|
|
2689
2738
|
// an error in this case.
|
|
2690
2739
|
return;
|
|
2691
2740
|
}
|
|
2692
|
-
raw_response_.emplace();
|
|
2693
2741
|
absl::StatusOr<RequestType> request = skir::Parse<RequestType>(
|
|
2694
|
-
request_body_parsed_.request_data,
|
|
2742
|
+
request_body_parsed_.request_data, options_.unrecognized_values);
|
|
2695
2743
|
if (!request.ok()) {
|
|
2696
|
-
raw_response_
|
|
2697
|
-
absl::StrCat("bad request: ", request.status().message());
|
|
2698
|
-
raw_response_->type = skir::service::ResponseType::kBadRequest;
|
|
2744
|
+
raw_response_ = skir_internal::MakeBadRequestResponse(
|
|
2745
|
+
absl::StrCat("bad request: ", request.status().message()));
|
|
2699
2746
|
return;
|
|
2700
2747
|
}
|
|
2701
|
-
|
|
2702
|
-
method, std::move(*request), request_meta_
|
|
2703
|
-
if (!
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2748
|
+
skir::service::ErrorOr<ResponseType> response_or_error =
|
|
2749
|
+
service_impl_(method, std::move(*request), request_meta_);
|
|
2750
|
+
if (!response_or_error.ok()) {
|
|
2751
|
+
auto& error = std::get<skir::service::Error>(response_or_error.variant());
|
|
2752
|
+
raw_response_ = skir_internal::MakeServerErrorResponse(
|
|
2753
|
+
std::move(error.message), int(error.code));
|
|
2707
2754
|
return;
|
|
2708
2755
|
}
|
|
2756
|
+
const auto& response = std::get<ResponseType>(response_or_error.variant());
|
|
2709
2757
|
if (request_body_parsed_.readable) {
|
|
2710
|
-
raw_response_
|
|
2711
|
-
|
|
2758
|
+
raw_response_ =
|
|
2759
|
+
skir_internal::MakeOkJsonResponse(skir::ToReadableJson(response));
|
|
2712
2760
|
} else {
|
|
2713
|
-
raw_response_
|
|
2714
|
-
|
|
2761
|
+
raw_response_ =
|
|
2762
|
+
skir_internal::MakeOkJsonResponse(skir::ToDenseJson(response));
|
|
2715
2763
|
}
|
|
2716
2764
|
}
|
|
2717
2765
|
};
|
|
@@ -2724,8 +2772,7 @@ class HttplibClient : public skir::service::Client {
|
|
|
2724
2772
|
|
|
2725
2773
|
absl::StatusOr<std::string> operator()(
|
|
2726
2774
|
absl::string_view request_data,
|
|
2727
|
-
const skir::service::HttpHeaders& request_headers
|
|
2728
|
-
skir::service::HttpHeaders& response_headers) const {
|
|
2775
|
+
const skir::service::HttpHeaders& request_headers) const {
|
|
2729
2776
|
auto headers =
|
|
2730
2777
|
decltype(std::declval<HttplibClientPtr>()->Get("")->headers)();
|
|
2731
2778
|
SkirToHttplibHeaders(request_headers, headers);
|
|
@@ -2733,7 +2780,6 @@ class HttplibClient : public skir::service::Client {
|
|
|
2733
2780
|
client_->Post(query_path_, headers, request_data.data(),
|
|
2734
2781
|
request_data.length(), "text/plain; charset=utf-8");
|
|
2735
2782
|
if (result) {
|
|
2736
|
-
response_headers = HttplibToSkirHeaders(result->headers);
|
|
2737
2783
|
const int status_code = result->status;
|
|
2738
2784
|
if (200 <= status_code && status_code <= 299) {
|
|
2739
2785
|
// OK status.
|
|
@@ -2751,7 +2797,6 @@ class HttplibClient : public skir::service::Client {
|
|
|
2751
2797
|
}
|
|
2752
2798
|
} else {
|
|
2753
2799
|
// HTTP error.
|
|
2754
|
-
response_headers = {};
|
|
2755
2800
|
std::stringstream ss;
|
|
2756
2801
|
ss << "HTTP error: " << result.error();
|
|
2757
2802
|
return {absl::UnknownError(ss.str())};
|
|
@@ -2775,11 +2820,15 @@ namespace service {
|
|
|
2775
2820
|
// 1. It must have a public `methods` type alias which resolves to a tuple of
|
|
2776
2821
|
// // method types.
|
|
2777
2822
|
// 2. For each method, it must have a member function with this signature:
|
|
2823
|
+
//
|
|
2778
2824
|
// absl::StatusOr<typename Method::response_type> operator()(
|
|
2779
2825
|
// Method method,
|
|
2780
2826
|
// typename Method::request_type request,
|
|
2781
|
-
// const HttpHeaders& request_headers
|
|
2782
|
-
//
|
|
2827
|
+
// const HttpHeaders& request_headers);
|
|
2828
|
+
//
|
|
2829
|
+
// Or, if you want to specify a specific HTTP status code other than 500
|
|
2830
|
+
// in case of an error, use ErrorOr<typename Method::response_type>
|
|
2831
|
+
// instead of absl::StatusOr<typename Method::response_type>.
|
|
2783
2832
|
//
|
|
2784
2833
|
// For example:
|
|
2785
2834
|
//
|
|
@@ -2792,16 +2841,14 @@ namespace service {
|
|
|
2792
2841
|
// absl::StatusOr<skirout_methods::ListUsersResponse> operator()(
|
|
2793
2842
|
// skirout_methods::ListUsers,
|
|
2794
2843
|
// skirout_methods::ListUsersRequest request,
|
|
2795
|
-
// const HttpHeaders& request_headers
|
|
2796
|
-
// HttpHeaders& response_headers) const {
|
|
2844
|
+
// const HttpHeaders& request_headers) const {
|
|
2797
2845
|
// ...
|
|
2798
2846
|
// }
|
|
2799
2847
|
//
|
|
2800
2848
|
// absl::StatusOr<skirout_methods::GetUserResponse> operator()(
|
|
2801
2849
|
// skirout_methods::GetUser,
|
|
2802
2850
|
// skirout_methods::GetUserRequest request,
|
|
2803
|
-
// const HttpHeaders& request_headers
|
|
2804
|
-
// HttpHeaders& response_headers) const {
|
|
2851
|
+
// const HttpHeaders& request_headers) const {
|
|
2805
2852
|
// ...
|
|
2806
2853
|
// }
|
|
2807
2854
|
// };
|
|
@@ -2815,20 +2862,14 @@ namespace service {
|
|
|
2815
2862
|
// If the request is a GET request, pass in the decoded query string as the
|
|
2816
2863
|
// request's body. The query string is the part of the URL after '?', and it can
|
|
2817
2864
|
// be decoded with DecodeUrlQueryString.
|
|
2818
|
-
//
|
|
2819
|
-
// Pass in UnrecognizedValuesPolicy::kKeep if the request is guaranteed to come
|
|
2820
|
-
// from a trusted user.
|
|
2821
2865
|
template <typename ServiceImpl>
|
|
2822
2866
|
RawResponse HandleRequest(ServiceImpl& service_impl,
|
|
2823
2867
|
absl::string_view request_body,
|
|
2824
2868
|
const HttpHeaders& request_headers,
|
|
2825
|
-
|
|
2826
|
-
UnrecognizedValuesPolicy unrecognized_values =
|
|
2827
|
-
UnrecognizedValuesPolicy::kDrop) {
|
|
2869
|
+
const ServiceOptions& options = {}) {
|
|
2828
2870
|
skir_internal::assert_unique_method_numbers<typename ServiceImpl::methods>();
|
|
2829
|
-
return skir_internal::HandleRequestOp(&service_impl, request_body,
|
|
2830
|
-
|
|
2831
|
-
&response_headers)
|
|
2871
|
+
return skir_internal::HandleRequestOp(&service_impl, request_body, &options,
|
|
2872
|
+
&request_headers)
|
|
2832
2873
|
.Run();
|
|
2833
2874
|
}
|
|
2834
2875
|
|
|
@@ -2844,21 +2885,16 @@ absl::StatusOr<std::string> DecodeUrlQueryString(
|
|
|
2844
2885
|
//
|
|
2845
2886
|
// ServiceImpl must satisfy the requirements outlined in the documentation for
|
|
2846
2887
|
// HandleRequest.
|
|
2847
|
-
//
|
|
2848
|
-
// Pass in UnrecognizedValuesPolicy::kKeep if the request is guaranteed to come
|
|
2849
|
-
// from a trusted user.
|
|
2850
2888
|
template <typename HttplibServer, typename ServiceImpl>
|
|
2851
|
-
void InstallServiceOnHttplibServer(
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
UnrecognizedValuesPolicy::kDrop) {
|
|
2889
|
+
void InstallServiceOnHttplibServer(HttplibServer& server,
|
|
2890
|
+
absl::string_view query_path,
|
|
2891
|
+
std::shared_ptr<ServiceImpl> service_impl,
|
|
2892
|
+
const ServiceOptions& options = {}) {
|
|
2856
2893
|
ABSL_CHECK_NE(service_impl, nullptr);
|
|
2857
2894
|
const typename HttplibServer::Handler handler = //
|
|
2858
|
-
[service_impl,
|
|
2895
|
+
[service_impl, options](const auto& req, auto& resp) {
|
|
2859
2896
|
const HttpHeaders request_headers =
|
|
2860
2897
|
skir_internal::HttplibToSkirHeaders(req.headers);
|
|
2861
|
-
HttpHeaders response_headers;
|
|
2862
2898
|
absl::string_view request_body;
|
|
2863
2899
|
std::string decoded_query_string;
|
|
2864
2900
|
if (!req.body.empty()) {
|
|
@@ -2874,14 +2910,12 @@ void InstallServiceOnHttplibServer(
|
|
|
2874
2910
|
DecodeUrlQueryString(query_string).value_or("");
|
|
2875
2911
|
request_body = decoded_query_string;
|
|
2876
2912
|
}
|
|
2877
|
-
RawResponse raw_response =
|
|
2878
|
-
|
|
2879
|
-
response_headers, unrecognized_values);
|
|
2880
|
-
skir_internal::SkirToHttplibHeaders(response_headers, resp.headers);
|
|
2913
|
+
RawResponse raw_response = HandleRequest(*service_impl, request_body,
|
|
2914
|
+
request_headers, options);
|
|
2881
2915
|
|
|
2882
2916
|
resp.set_content(std::move(raw_response.data),
|
|
2883
|
-
std::string(raw_response.content_type
|
|
2884
|
-
resp.status = raw_response.status_code
|
|
2917
|
+
std::string(raw_response.content_type));
|
|
2918
|
+
resp.status = raw_response.status_code;
|
|
2885
2919
|
};
|
|
2886
2920
|
server.Get(std::string(query_path), handler);
|
|
2887
2921
|
server.Post(std::string(query_path), handler);
|
|
@@ -2894,16 +2928,11 @@ template <typename Method>
|
|
|
2894
2928
|
absl::StatusOr<typename Method::response_type> InvokeRemote(
|
|
2895
2929
|
const Client& client, Method method,
|
|
2896
2930
|
const typename Method::request_type& request,
|
|
2897
|
-
const HttpHeaders& request_headers = {}
|
|
2898
|
-
HttpHeaders* absl_nonnull response_headers = nullptr) {
|
|
2931
|
+
const HttpHeaders& request_headers = {}) {
|
|
2899
2932
|
const std::string request_data = absl::StrCat(
|
|
2900
2933
|
Method::kMethodName, ":", Method::kNumber, "::", ToDenseJson(request));
|
|
2901
|
-
HttpHeaders response_headers_tmp;
|
|
2902
2934
|
absl::StatusOr<std::string> response_data =
|
|
2903
|
-
client(request_data, request_headers
|
|
2904
|
-
if (response_headers != nullptr) {
|
|
2905
|
-
*response_headers = std::move(response_headers_tmp);
|
|
2906
|
-
}
|
|
2935
|
+
client(request_data, request_headers);
|
|
2907
2936
|
if (!response_data.ok()) {
|
|
2908
2937
|
return std::move(response_data).status();
|
|
2909
2938
|
}
|
package/client/skir.testing.h
CHANGED
|
@@ -252,10 +252,9 @@ class ClientForTesting : public ::skir::service::Client {
|
|
|
252
252
|
|
|
253
253
|
absl::StatusOr<std::string> operator()(
|
|
254
254
|
absl::string_view request_data,
|
|
255
|
-
const skir::service::HttpHeaders& request_headers
|
|
256
|
-
skir::service::HttpHeaders& response_headers) const override {
|
|
255
|
+
const skir::service::HttpHeaders& request_headers) const override {
|
|
257
256
|
return ::skir::service::HandleRequest(api_impl_, request_data,
|
|
258
|
-
request_headers
|
|
257
|
+
request_headers)
|
|
259
258
|
.AsStatus();
|
|
260
259
|
}
|
|
261
260
|
|
package/dist/enum_variant.js
CHANGED
package/dist/enum_variant.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enum_variant.js","sourceRoot":"","sources":["../src/enum_variant.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,WAAW,EAAE,MAAM,eAAe,CAAC;AA+BtE,MAAM,UAAU,eAAe,CAC7B,QAA0B,EAC1B,WAAwB;IAExB,MAAM,MAAM,GAAyB,EAAE,CAAC;IACxC,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAClC,KAAK,MAAM,SAAS,IAAI,QAAQ,EAAE,CAAC;QACjC,IAAI,UAA8B,CAAC;QACnC,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC;YACnB,UAAU,GAAG,kBAAkB,CAAC,SAAS,EAAE,SAAS,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QACzE,CAAC;aAAM,CAAC;YACN,UAAU,GAAG,mBAAmB,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC;QACvE,CAAC;QACD,UAAU,CAAC,aAAa,GAAG,SAAS,CAAC,MAAM,CAAC;QAC5C,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,kBAAkB;IACzB,OAAO;QACL,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"enum_variant.js","sourceRoot":"","sources":["../src/enum_variant.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skir-cc-gen",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"repository": {
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"mocha": "^11.7.5",
|
|
54
54
|
"prettier": "^3.2.4",
|
|
55
55
|
"prettier-plugin-organize-imports": "^4.2.0",
|
|
56
|
-
"skir": "^1.0.
|
|
56
|
+
"skir": "^1.0.11",
|
|
57
57
|
"ts-node": "^10.9.2",
|
|
58
58
|
"tsx": "^4.21.0",
|
|
59
59
|
"typescript": "^5.2.2",
|