Skip to content

Commit

Permalink
fix: updates to (wip)
Browse files Browse the repository at this point in the history
fix: new gen

fix: enums

wip

feat: generate kotlin

fix: make ios work
  • Loading branch information
gtokman committed Aug 30, 2024
1 parent c96843b commit a4714d6
Show file tree
Hide file tree
Showing 51 changed files with 2,625 additions and 1,468 deletions.
2 changes: 1 addition & 1 deletion packages/npm/send/example/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ PLATFORMS

DEPENDENCIES
activesupport (>= 6.1.7.5, != 7.1.0)
cocoapods (>= 1.13, != 1.15.1, != 1.15.0)
cocoapods (>= 1.15.2)

RUBY VERSION
ruby 2.7.5p203
Expand Down
4 changes: 2 additions & 2 deletions packages/npm/send/example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ PODS:
- hermes-engine (0.75.2):
- hermes-engine/Pre-built (= 0.75.2)
- hermes-engine/Pre-built (0.75.2)
- NitroModules (0.5.0):
- NitroModules (0.6.0):
- DoubleConversion
- glog
- hermes-engine
Expand Down Expand Up @@ -1754,7 +1754,7 @@ SPEC CHECKSUMS:
fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120
glog: 69ef571f3de08433d766d614c73a9838a06bf7eb
hermes-engine: 3b6e0717ca847e2fc90a201e59db36caf04dee88
NitroModules: bf2e284e950d5c173f785f3c76a84439dbc35432
NitroModules: b404fe4ebf47e0b057c526959b5e200256000f09
RCT-Folly: 4464f4d875961fce86008d45f4ecf6cef6de0740
RCTDeprecation: 34cbf122b623037ea9facad2e92e53434c5c7422
RCTRequired: 24c446d7bcd0f517d516b6265d8df04dc3eb1219
Expand Down
2 changes: 1 addition & 1 deletion packages/npm/send/example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"dependencies": {
"react": "18.3.1",
"react-native": "0.75.2",
"react-native-nitro-modules": "^0.5.0"
"react-native-nitro-modules": "^0.6.0"
},
"devDependencies": {
"@babel/core": "^7.20.0",
Expand Down
51 changes: 27 additions & 24 deletions packages/npm/send/ios/Send.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ extension SendError: Error {}
extension Request {
var url: Result<URL, SendError> {
guard var urlComponents = URLComponents(string: baseURL) else {
return .failure(SendError(code: .invalid_request_base_url, message: "Your base URL is not valid."))
return .failure(SendError(code: .invalidRequestBaseUrl, message: "Your base URL is not valid."))
}
urlComponents.path = path

Expand All @@ -24,15 +24,15 @@ extension Request {
}

guard let url = urlComponents.url else {
return .failure(SendError(code: .invalid_request_path_or_query_parameters, message: "Your path or query parameters is not valid."))
return .failure(SendError(code: .invalidRequestPathOrQueryParameters, message: "Your path or query parameters is not valid."))
}
return .success(url)
}

var urlRequest: Result<URLRequest, SendError> {
return url.flatMap { url in
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = method
urlRequest.httpMethod = method.stringValue

for (key, value) in header.parameters {
urlRequest.setValue(value, forHTTPHeaderField: key)
Expand All @@ -42,12 +42,12 @@ extension Request {
let contentTypeHeader = header.parameters.first(where: { $0.key.caseInsensitiveCompare("Content-Type") == .orderedSame })?.value
if bodyIsUTF8(contentTypeHeader: contentTypeHeader, utf8ContentTypes: utf8ContentTypes) {
guard let utf8Body = body.data(using: .utf8) else {
return .failure(SendError(code: .non_utf8_request_body, message: "Your request headers specify a Content-Type included in `utf8ContentTypes`, but your request body is not a UTF8-encoded string."))
return .failure(SendError(code: .nonUtf8RequestBody, message: "Your request headers specify a Content-Type included in `utf8ContentTypes`, but your request body is not a UTF8-encoded string."))
}
urlRequest.httpBody = utf8Body
} else {
guard let base64Body = Data(base64Encoded: body) else {
return .failure(SendError(code: .non_base64_request_body, message: "Your request headers specify a Content-Type NOT included in `utf8ContentTypes`, but your request body is not a base64-encoded string."))
return .failure(SendError(code: .nonUtf8RequestBody, message: "Your request headers specify a Content-Type NOT included in `utf8ContentTypes`, but your request body is not a base64-encoded string."))
}
urlRequest.httpBody = base64Body
}
Expand All @@ -60,30 +60,30 @@ extension Request {
extension Response {
init(request: Request, data: Data, httpURLResponse: HTTPURLResponse) throws {
guard let headerParameters = httpURLResponse.allHeaderFields as? [String: String] else {
throw SendError(code: .invalid_response_header_parameters, message: "The response headers were not valid.")
throw SendError(code: .invalidResponseHeaderParameters, message: "The response headers were not valid.")
}
let body: String?
let statusCode = Double(httpURLResponse.statusCode)
let header = Parameters(parameters: headerParameters)
if (data.isEmpty) {
body = nil
self.init(statusCode: statusCode, header: header, body: nil)
} else {
let bodyIsUTF8 = bodyIsUTF8(
contentTypeHeader: httpURLResponse.value(forHTTPHeaderField: "Content-Type"),
utf8ContentTypes: request.utf8ContentTypes
)
if (bodyIsUTF8) {
guard let utf8Body = String(data: data, encoding: .utf8) else {
throw SendError(code: .non_utf8_response_body, message: "The response headers specify a Content-Type included in `utf8ContentTypes`, but the response body was not UTF8-encoded.")
throw SendError(code: .nonUtf8ResponseBody, message: "The response headers specify a Content-Type included in `utf8ContentTypes`, but the response body was not UTF8-encoded.")
}
body = utf8Body
self.init(statusCode: statusCode, header: header, body: utf8Body)
} else {
body = data.base64EncodedString()
self.init(
statusCode: statusCode,
header: header,
body: data.base64EncodedString()
)
}
}
self.init(
statusCode: Double(httpURLResponse.statusCode),
header: Parameters(parameters: headerParameters),
body: body
)
}
}

Expand All @@ -101,19 +101,22 @@ final class Send: HybridSendSpec {
return getSizeOf(self)
}

static let session = URLSession(
lazy var session = URLSession(
configuration: .default,
delegate: IgnoreRedirectsDelegate(),
delegateQueue: nil
)

func send(request: Request) -> NitroModules.Promise<SendResult> {
return Promise.async {
func send(request: Request) throws -> Promise<SendResult> {
return Promise.async { [weak self] in
guard let self else {
return .init(response: nil, error: nil)
}
do {
let urlRequest = try request.urlRequest.get()
let (data, urlResponse) = try await Self.session.data(for: urlRequest)
let (data, urlResponse) = try await self.session.data(for: urlRequest)
guard let httpURLResponse = urlResponse as? HTTPURLResponse else {
let sendError = SendError(code: .response_invalid, message: "Your request received a response, but it couldn't be processed. Please verify the configuration of your server.")
let sendError = SendError(code: .responseInvalid, message: "Your request received a response, but it couldn't be processed. Please verify the configuration of your server.")
return SendResult(response: nil, error: sendError)
}
let response = try Response(
Expand Down Expand Up @@ -143,7 +146,7 @@ final class Send: HybridSendSpec {
.unsupportedURL,
.userAuthenticationRequired,
.userCancelledAuthentication:
let sendError = SendError(code: .request_invalid, message: urlError.localizedDescription)
let sendError = SendError(code: .requestInvalid, message: urlError.localizedDescription)
return SendResult(response: nil, error: sendError)
case .callIsActive,
.internationalRoamingOff,
Expand All @@ -157,7 +160,7 @@ final class Send: HybridSendSpec {
.secureConnectionFailed,
.timedOut,
.appTransportSecurityRequiresSecureConnection:
let sendError = SendError(code: .no_response, message: urlError.localizedDescription)
let sendError = SendError(code: .noResponse, message: urlError.localizedDescription)
return SendResult(response: nil, error: sendError)
case .backgroundSessionInUseByAnotherProcess,
.backgroundSessionRequiresSharedContainer,
Expand All @@ -177,7 +180,7 @@ final class Send: HybridSendSpec {
.httpTooManyRedirects,
.redirectToNonExistentLocation,
.zeroByteResource:
let sendError = SendError(code: .response_invalid, message: urlError.localizedDescription)
let sendError = SendError(code: .responseInvalid, message: urlError.localizedDescription)
return SendResult(response: nil, error: sendError)
default:
// NOTE: The only other documented case is `unknown`, but code is not an enum so a default case is required regardless
Expand Down
86 changes: 86 additions & 0 deletions packages/npm/send/nitrogen/generated/android/c++/JCode.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
///
/// JCode.hpp
/// Fri Aug 30 2024
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
/// https://github.com/mrousavy/nitro
/// Copyright © 2024 Marc Rousavy @ Margelo
///

#pragma once

#include <fbjni/fbjni.h>
#include "Code.hpp"

namespace margelo::nitro::send {

using namespace facebook;

/**
* The C++ JNI bridge between the C++ enum "Code" and the the Kotlin enum "Code".
*/
struct JCode final: public jni::JavaClass<JCode> {
public:
static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/candlefinance_send/Code;";

public:
/**
* Convert this Java/Kotlin-based enum to the C++ enum Code.
*/
[[maybe_unused]]
Code toCpp() const {
static const auto clazz = javaClassStatic();
static const auto fieldOrdinal = clazz->getField<int>("ordinal");
int ordinal = this->getFieldValue(fieldOrdinal);
return static_cast<Code>(ordinal);
}

public:
/**
* Create a Java/Kotlin-based enum with the given C++ enum's value.
*/
[[maybe_unused]]
static jni::alias_ref<JCode> fromCpp(Code value) {
static const auto clazz = javaClassStatic();
static const auto fieldRESPONSE_INVALID = clazz->getStaticField<JCode>("RESPONSE_INVALID");
static const auto fieldREQUEST_INVALID = clazz->getStaticField<JCode>("REQUEST_INVALID");
static const auto fieldNETWORK_ERROR = clazz->getStaticField<JCode>("NETWORK_ERROR");
static const auto fieldNO_RESPONSE = clazz->getStaticField<JCode>("NO_RESPONSE");
static const auto fieldNON_UTF8_RESPONSE_BODY = clazz->getStaticField<JCode>("NON_UTF8_RESPONSE_BODY");
static const auto fieldNON_UTF8_REQUEST_BODY = clazz->getStaticField<JCode>("NON_UTF8_REQUEST_BODY");
static const auto fieldINVALID_REQUEST_PATH_OR_QUERY_PARAMETERS = clazz->getStaticField<JCode>("INVALID_REQUEST_PATH_OR_QUERY_PARAMETERS");
static const auto fieldINVALID_REQUEST_BASE_URL = clazz->getStaticField<JCode>("INVALID_REQUEST_BASE_URL");
static const auto fieldNON_BASE64_REQUEST_BODY = clazz->getStaticField<JCode>("NON_BASE64_REQUEST_BODY");
static const auto fieldINVALID_RESPONSE_HEADER_PARAMETERS = clazz->getStaticField<JCode>("INVALID_RESPONSE_HEADER_PARAMETERS");
static const auto fieldUNEXPECTED = clazz->getStaticField<JCode>("UNEXPECTED");

switch (value) {
case Code::RESPONSE_INVALID:
return clazz->getStaticFieldValue(fieldRESPONSE_INVALID);
case Code::REQUEST_INVALID:
return clazz->getStaticFieldValue(fieldREQUEST_INVALID);
case Code::NETWORK_ERROR:
return clazz->getStaticFieldValue(fieldNETWORK_ERROR);
case Code::NO_RESPONSE:
return clazz->getStaticFieldValue(fieldNO_RESPONSE);
case Code::NON_UTF8_RESPONSE_BODY:
return clazz->getStaticFieldValue(fieldNON_UTF8_RESPONSE_BODY);
case Code::NON_UTF8_REQUEST_BODY:
return clazz->getStaticFieldValue(fieldNON_UTF8_REQUEST_BODY);
case Code::INVALID_REQUEST_PATH_OR_QUERY_PARAMETERS:
return clazz->getStaticFieldValue(fieldINVALID_REQUEST_PATH_OR_QUERY_PARAMETERS);
case Code::INVALID_REQUEST_BASE_URL:
return clazz->getStaticFieldValue(fieldINVALID_REQUEST_BASE_URL);
case Code::NON_BASE64_REQUEST_BODY:
return clazz->getStaticFieldValue(fieldNON_BASE64_REQUEST_BODY);
case Code::INVALID_RESPONSE_HEADER_PARAMETERS:
return clazz->getStaticFieldValue(fieldINVALID_RESPONSE_HEADER_PARAMETERS);
case Code::UNEXPECTED:
return clazz->getStaticFieldValue(fieldUNEXPECTED);
default:
std::string stringValue = std::to_string(static_cast<int>(value));
throw std::runtime_error("Invalid enum value (" + stringValue + "!");
}
}
};

} // namespace margelo::nitro::send
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
///
/// JHybridSendSpec.cpp
/// Fri Aug 30 2024
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
/// https://github.com/mrousavy/nitro
/// Copyright © 2024 Marc Rousavy @ Margelo
///

#include "JHybridSendSpec.hpp"

// Forward declaration of `SendResult` to properly resolve imports.
namespace margelo::nitro::send { struct SendResult; }
// Forward declaration of `Response` to properly resolve imports.
namespace margelo::nitro::send { struct Response; }
// Forward declaration of `Parameters` to properly resolve imports.
namespace margelo::nitro::send { struct Parameters; }
// Forward declaration of `SendError` to properly resolve imports.
namespace margelo::nitro::send { struct SendError; }
// Forward declaration of `Code` to properly resolve imports.
namespace margelo::nitro::send { enum class Code; }
// Forward declaration of `Request` to properly resolve imports.
namespace margelo::nitro::send { struct Request; }
// Forward declaration of `Method` to properly resolve imports.
namespace margelo::nitro::send { enum class Method; }

#include <future>
#include "SendResult.hpp"
#include <NitroModules/JPromise.hpp>
#include "JSendResult.hpp"
#include <optional>
#include "Response.hpp"
#include "JResponse.hpp"
#include "Parameters.hpp"
#include "JParameters.hpp"
#include <unordered_map>
#include <string>
#include "SendError.hpp"
#include "JSendError.hpp"
#include "Code.hpp"
#include "JCode.hpp"
#include "Request.hpp"
#include "JRequest.hpp"
#include "Method.hpp"
#include "JMethod.hpp"
#include <vector>

namespace margelo::nitro::send {

jni::local_ref<JHybridSendSpec::jhybriddata> JHybridSendSpec::initHybrid(jni::alias_ref<jhybridobject> jThis) {
return makeCxxInstance(jThis);
}

void JHybridSendSpec::registerNatives() {
registerHybrid({
makeNativeMethod("initHybrid", JHybridSendSpec::initHybrid),
});
}

size_t JHybridSendSpec::getExternalMemorySize() noexcept {
static const auto method = _javaPart->getClass()->getMethod<jlong()>("getMemorySize");
return method(_javaPart);
}

// Properties


// Methods
std::future<SendResult> JHybridSendSpec::send(const Request& request) {
static const auto method = _javaPart->getClass()->getMethod<jni::alias_ref<JPromise::javaobject>(jni::alias_ref<JRequest> /* request */)>("send");
auto result = method(_javaPart, JRequest::fromCpp(request));
return [&]() {
auto promise = std::make_shared<std::promise<SendResult>>();
result->cthis()->addOnResolvedListener([=](const jni::global_ref<jni::JObject>& boxedResult) {
auto result = jni::static_ref_cast<JSendResult>(boxedResult);
promise->set_value(result->toCpp());
});
result->cthis()->addOnRejectedListener([=](const jni::global_ref<jni::JString>& message) {
std::runtime_error error(message->toStdString());
promise->set_exception(std::make_exception_ptr(error));
});
return promise->get_future();
}();
}

} // namespace margelo::nitro::send
Loading

0 comments on commit a4714d6

Please sign in to comment.