Loopback project broken after upgrade - loopbackjs

After creating a model with the command "lb4 model", it asked me to update the dependencies, after installing when compiling it throws this error, how can I fix it?
> adselfservice#1.0.0 build C:\Users\PC\WebstormProjects\adselfservice-node-backend
> lb-tsc
src/__tests__/acceptance/test-helper.ts:57:38 - error TS2345: Argument of type 'AdSelfServiceApplication' is not assignable to parameter of type 'RestApplicationLike'.
Property 'restServer' is missing in type 'AdSelfServiceApplication' but required in type 'RestApplicationLike'.
57 const client = createRestAppClient(app);
~~~
node_modules/#loopback/testlab/dist/client.d.ts:20:5
20 restServer: RestServerLike;
~~~~~~~~~~
'restServer' is declared here.
src/application.ts:20:32 - error TS2345: Argument of type 'typeof RestApplication' is not assignable to parameter of type 'Constructor<{ readonly options: ApplicationConfig; re
adonly state: string; controller: <T>(controllerCtor: Constructor<T>, nameOrOptions?: string | BindingFromClassOptions | undefined) => Binding<...>; ... 53 more ...; listenerCo
unt: (type: string | symbol) => number; }>'.
Construct signature return types 'RestApplication' and '{ readonly options: ApplicationConfig; readonly state: string; controller: <T>(controllerCtor: Constructor<T>, nameOrO
ptions?: string | BindingFromClassOptions | undefined) => Binding<...>; ... 53 more ...; listenerCount: (type: string | symbol) => number; }' are incompatible.
The types returned by 'controller(...)' are incompatible between these types.
Type 'import("C:/Users/PC/WebstormProjects/adselfservice-node-backend/node_modules/#loopback/rest-explorer/node_modules/#loopback/context/dist/binding").Binding<T>' is no
t assignable to type 'import("C:/Users/PC/WebstormProjects/adselfservice-node-backend/node_modules/#loopback/context/dist/binding").Binding<T>'.
Types have separate declarations of a private property '_scope'.
20 ServiceMixin(RepositoryMixin(RestApplication)),
~~~~~~~~~~~~~~~

Related

Rust struct to lambda_http

I'm trying to use lambda_http but having an issue with it.
Basically, I'm trying to create a service_fn by passing a Service trait implemented object to it for a structure that holds state. But it seems to be tripping on std::marker::Send
struct Handler {
db: aws_sdk_dynamodb::Client,
s3: aws_sdk_s3::Client,
}
impl Handler {
..some_stuff..
}
pub trait Service {
fn route<T>(&self, data: T) -> serde_json::Value;
}
impl Service for Handler {
fn route<Request>(&self, req: Request) -> serde_json::Value {
json!({ "error": "Route not found" })
}
}
pub async fn run(service: Arc<impl Service>) -> Result<(), Error> {
let func = service_fn(|req| lambda_handler(req, service.clone()));
lambda_http::run(func).await?;
Ok(())
}
pub(crate) async fn lambda_handler(
evt: Request,
svc: Arc<impl Service>,
) -> Result<impl IntoResponse, Error> {
let reply = svc.route(evt);
let response = LambdaResponse::builder().(..some_stuff..).body(reply.to_string()).unwrap();
Ok(response)
}
For some reason this doesnt quite work and its tied to synchronization but not sure how to fix it.
Compiling runtime v0.1.0 (/home/xyz/Documents/lservice/runtime)
warning: unused import: `serde_json::json`
--> runtime/src/lib.rs:12:5
|
12 | use serde_json::json;
| ^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
error: future cannot be sent between threads safely
--> runtime/src/lib.rs:21:22
|
21 | lambda_http::run(func).await?;
| ^^^^ future returned by `lambda_handler` is not `Send`
|
note: captured value is not `Send`
--> runtime/src/lib.rs:29:5
|
29 | svc: Arc<impl Service>,
| ^^^ has type `Arc<impl Service>` which is not `Send`
note: required by a bound in `lambda_http::run`
--> /home/xyz/.cargo/registry/src/github.com-1ecc6299db9ec823/lambda_http-0.7.1/src/lib.rs:185:16
|
185 | S::Future: Send + 'a,
| ^^^^ required by this bound in `lambda_http::run`
help: consider further restricting this bound
|
19 | pub async fn run(service: Arc<impl Service + std::marker::Sync>) -> Result<(), Error> {
| +++++++++++++++++++
error: future cannot be sent between threads safely
--> runtime/src/lib.rs:21:22
|
21 | lambda_http::run(func).await?;
| ^^^^ future returned by `lambda_handler` is not `Send`
|
note: captured value is not `Send`
--> runtime/src/lib.rs:29:5
|
29 | svc: Arc<impl Service>,
| ^^^ has type `Arc<impl Service>` which is not `Send`
note: required by a bound in `lambda_http::run`
--> /home/xyz/.cargo/registry/src/github.com-1ecc6299db9ec823/lambda_http-0.7.1/src/lib.rs:185:16
|
185 | S::Future: Send + 'a,
| ^^^^ required by this bound in `lambda_http::run`
help: consider further restricting this bound
|
19 | pub async fn run(service: Arc<impl Service + std::marker::Send>) -> Result<(), Error> {
| +++++++++++++++++++
warning: `runtime` (lib) generated 1 warning
error: could not compile `runtime` due to 2 previous errors; 1 warning emitted
This does however work if I just pass dynamodb.clone() to it directly rather than nested inside the Handler struct so I know it probably needs me to implement Send on Handler, but not sure if I'm on the right track here so need a little help on the way forward.
<# UPDATE #>
One thing that made this eventually work, was by just protecting the Handler with a Arc<Mutex>. Since it was complaining about a value not being able to pass between threads safely, I just locked it before sending it. Though I can't shake the feeling that this is a sledgehammer approach, especially given if I use lambda_runtime::run (instead of lambda_http::run) this seems to work with just a simple Arc::clone().
<# UPDATE 2 #>
A suggestion by #Mikdore to also implement Sync as a supertrait did the trick. Now it doesnt need any external locks and just works as is.
You don't have to implement Send. And you almost always probably shouldn't. If all members of your struct are Send, rust will implement it for you automatically. The compiler tells you what the problem is:
help: consider further restricting this bound
|
19 | pub async fn run(service: Arc<impl Service + std::marker::Send>) -> Result<(), Error> {
| +++++++++++++++++++
Any arbitrary type could in theory implement Service. Not all of those types are Send. You can, as the compiler tells you, restrict your function to take Arc<impl Service + Send>. However, perhaps more sensibly, you can also make Service a supertrait of Send, by doing:
trait Service: Send {
//...
}
This way, every type implementing Service is required to implement Send, and you can use impl Service in async contexts.

AWS lambda rust - how to make a function to return outer closure?

I am using rust-aws-lambda project. My use case is with Lambda as an API Gateway Proxy. Additionally I am using closures as explained in this example, as I want to use shared resources such as clients and secret value (retrieved from AWS Secrets Manager) in my lambda code.
The issue I am struggling with for long time is how I can abstract the closures into another helper function. I want the function to return the outer closure in this case, for example. I have tryd but I cannot get Rust compiler to let me do this.
The both closures are within main function. Per the listed example, my inner closure is defined something like this:
let handler_func_closure = move |event: ApiProxyRequest| async move {
...
Ok::<_, Error>(success_resp)
};
These are my relevant imports in the code:
use lambda_http::{service_fn, Body, Error, IntoResponse, Request as ApiProxyRequest, RequestExt};
use lambda_http::tower::util::ServiceFn;
I have below closure which I have defined in async main function in main.rs, which is working for me so far.
let outer_closure = move |event: ApiProxyRequest| async move {
match handler_func_closure(event).await {
Ok(s) => Ok(s.into_response()),
Err(e) => Ok(http::Response::builder()
.header(http::header::CONTENT_TYPE, "application/json")
.status(400)
.body(
serde_json::to_string(&json!({"error": &err.to_string()}))
.expect("unable to serialize serde_json::Value")
.into(),
)
.expect("unable to build http::Response")),
}
};
Where into_response() is satisfied by a struct implementing from trait IntoResponse.
So basically what I'm trying to do is make a function to return closure that can be passed in to service_fn. Below is my attempt so far - but it's not satisfy Rust compiler currently.
pub fn get_service_fn<T, T2, F, F2, I: IntoResponse>(handler_func_closure: T) -> ServiceFn<T2>
where T: Fn(http::Request<Body>) -> F + Send + Sync,
T2: Fn(lambda_http::Request) -> F2,
F2: Future<Output=crate::Result<http::Response<Body>>>,
F: Future<Output=crate::Result<I>> + Send {
let outer_closure = move |event: ApiProxyRequest| async move {
match handler_func_closure(event).await {
Ok(s) => Ok(s.into_response()),
Err(e) => failure(Box::new(e), None),
}
};
service_fn(outer_closure)
};
I have seen other question asked on how can function return closure, but I cannot seem to get it to work in this case. I am curious to know if anyone able to get this to work where an outer closure returned by a function can be passed in to service_fn.
I feel like I've spent countless hours in trying to figure this out, but I've been unable to make it work. I'm not entirely sure whether this is possible in Rust to be honest, but I'd be curious if anyone has an idea how to approach this.
Edit: This is the compiler error I'm getting in case it's helpful:
error[E0308]: mismatched types
--> src/bin/my_lambda/main.rs:197:16
|
185 | pub fn get_service_fn<T, T2, F, F2, I: IntoResponse>(handler_func_closure: T) -> ServiceFn<T2>
| -- this type parameter
...
190 | let outer_closure = move |event: ApiProxyRequest| async move {
| __________________________-________________________________________-
| | _________________________|
| ||
191 | || match handler_func_closure(event).await {
192 | || Ok(s) => Ok(s.into_response()),
193 | || Err(e) => failure(Box::new(e), None),
194 | || }
195 | || };
| || -
| ||_____|
| |______the found closure
| the found `async` block
196 |
197 | service_fn(outer_closure)
| ^^^^^^^^^^^^^ expected type parameter `T2`, found closure
|
::: /Users/rnag/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/future/mod.rs:61:43
|
61 | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
| ------------------------------- the found opaque type
|
= note: expected type parameter `T2`
found closure `[closure#src/bin/my_lambda/main.rs:190:25: 195:6]`
= help: every closure has a distinct type and so could not always match the caller-chosen type of parameter `T2`

Problems using `u8` in Substrate and ink

I am trying to add a simple u8 to my Substrate Runtime Module:
decl_storage! {
trait Store for Module<T: Trait> as TemplateModule {
MyByte: u8;
}
}
However, I get a compiler error that it does not implement Parity Codec's Encode or Decode:
error[E0277]: the trait bound `u8: _IMPL_DECODE_FOR_Event::_parity_codec::Encode` is not satisfied
--> /Users/shawntabrizi/Documents/GitHub/substrate-package/substrate-node-template/runtime/src/template.rs:23:1
|
23 | / decl_storage! {
24 | | trait Store for Module<T: Trait> as TemplateModule {
25 | | MyByte: u8;
26 | | }
27 | | }
| |_^ the trait `_IMPL_DECODE_FOR_Event::_parity_codec::Encode` is not implemented for `u8`
A similar problem occurs when I try to store a u8 in a Substrate Smart Contract using ink!:
contract! {
struct MyContract {
value: storage::Value<u8>,
}
...
}
Error:
error[E0277]: the trait bound `u8: parity_codec::codec::Encode` is not satisfied
--> src/lib.rs:26:1
|
26 | / contract! {
27 | | struct MyContract {
28 | | value: storage::Value<u8>,
29 | | }
... |
49 | | }
50 | | }
| |_^ the trait `parity_codec::codec::Encode` is not implemented for `u8`
Why is that, and what can I do to resolve the issue?
Today, the parity_codec does not support Encoding of u8 due to avoid a type collision, since Vec<u8> is a special case from Vec<T>.
See: https://github.com/paritytech/parity-codec/issues/47
gavofyork:
Because it would otherwise make the two encodings: Vec<u8> and Vec<T: Codec> clash.
It is possible this could be fixed in the future with additional Rust features, but for now, you will need to store your single bytes as [u8; 1] and work with that type.
Substrate Runtime Module
One hacky solution for a Substrate Runtime Module looks something like this:
use support::{decl_module, decl_storage, decl_event, StorageValue, dispatch::Result};
use system::ensure_signed;
pub trait Trait: system::Trait {
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
}
type U8 = [u8; 1];
decl_storage! {
trait Store for Module<T: Trait> as TemplateModule {
MyByte get(my_byte): U8;
}
}
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
fn deposit_event<T>() = default;
pub fn set_my_byte(origin, input: U8) -> Result {
let who = ensure_signed(origin)?;
<MyByte<T>>::put(input);
Self::deposit_event(RawEvent::MyByteStored(input, who));
Ok(())
}
pub fn add_to_byte(origin, input: U8) -> Result {
let who = ensure_signed(origin)?;
let my_byte = Self::my_byte()[0];
let my_new_byte = my_byte.checked_add(input[0]).ok_or("Overflow")?;
<MyByte<T>>::put([my_new_byte]);
Self::deposit_event(RawEvent::MyByteStored([my_new_byte], who));
Ok(())
}
}
}
decl_event!(
pub enum Event<T> where AccountId = <T as system::Trait>::AccountId {
MyByteStored(U8, AccountId),
}
);
Where we assign a new type type U8 = [u8; 1];. The choice of our new type name is important since it will trick the Polkadot UI to treat this value simply as a u8 for any input/output fields it generates. If you try to use a custom type like type Byte = [u8; 1], the UI will ask you to import the definition of that custom type. If you try to use [u8; 1] directly, the Polkadot UI will not know how to render the input/output of that value.
Furthermore, as of the time of writing this post, the decl_event! macro has an issue depositing a [u8; 1] directly due to pattern matching.
Note that you will need to treat this type like an array when you use it. add_to_byte() shows an example of that. So ultimately, you need to extract the first item of the array to extract the byte, and you need to wrap your byte in an array to set a U8:
let my_byte = Self::my_byte()[0];
...
<MyByte<T>>::put([my_new_byte]);
Other solutions may involve using other types which are natively supported like Vec<u8> or u16, and doing the appropriate checks on your runtime that this is treated like a single u8, but the UI will not know better.
Substrate Smart Contracts
I have not found a great solution for ink! yet, but you should be able to use [u8; 1] directly in all of your code. Again, you will need to treat it like an array for getters and setters. But when generating the ABI you will need to manually change the instances of [u8; 1] to u8 to trick the UI to do what you want.

Is it possible to create a polymorphic variant type dynamically using modules?

I'm trying to organzine and reuse my reasonML code. I have model module types that look like the following:
module Diet = {
type schemaType = [`DietSchema];
type idType = [`DietId(UUID.t)];
let schema = `DietSchema;
type idAsType('a) = [> | idType] as 'a;
};
module Ingredient = {
type schemaType = [`IngredientSchema];
type idType = [`IngredientId(UUID.t)];
let schema = `IngredientSchema;
type idAsType('a) = [> | idType] as 'a;
};
module Restriction = {
type schemaType = [`RestrictionSchema];
type idType = [`RestrictionId(UUID.t)];
let schema = `RestrictionSchema;
type idAsType('a) = [> | idType] as 'a;
};
And I would like to generate a types and functions from the idTypes and schemaTypes.
examples are:
type modelIdType = [
| Diet.idType
| Restriction.idType
| Ingredient.idType
];
type schemaType = [
| Diet.schemaType
| Restriction.schemaType
| Ingredient.schemaType
];
let modelIdToIdFunction = (recordIdType): (schemaType, UUID.t) =>
switch (recordIdType) {
| `DietId(uuid) => (Diet.schema, uuid)
| `RestrictionId(uuid) => (Restriction.schema, uuid)
| `IngredientId(uuid) => (Ingredient.schema, uuid)
};
So I'm attempting to construct a module using a functor passing each of the schemas through
module Diet : SchemaType = {
/* ... */
};
module type SchemaType {
type schemaType;
type idType;
let schema: [> schemaType];
type idAsType('a) = [> | idType] as 'a;
};
module ProcessSchema = (
Schema : SchemaType,
PrevFullSchema : FullSchema
) : (FullSchema) => {
type id = [> Schema.idType' | PrevFullSchema.id'('a)] as 'a;
/* type id = [PrevFullSchema.openId(PrevFullSchema.id) | Schema.idType]; */
/* type schema = [PrevFullSchema.schema | Schema.schema]; */
/* type openSchema = [PrevFullSchema.schema | Schema.schema]; */
};
The code above didn't work. I'm having trouble adding module types to the model modules at the top. I also attempted through a SchemaType module type but kept hitting The type idType is not a polymorphic variant type, When I wanted each model to have distinct polymorphic variable types.
So overall, I want to know if it is possible to create a polymorphic variant type that can be created or extended using modules and functors?
If not is it possible to construct polymorphic variant types using a "list of modules"?
Thanks
Someone asked a similar question back in 2002. According to one of the OCaml language developers, it's not possible to dynamically extend polymorphic variant types like that: https://caml-list.inria.narkive.com/VVwLM96e/module-types-and-polymorphic-variants . The relevant bit:
The functor definition is refused because
"The type M.t is not a polymorphic variant type"
Is there a workaround?
Not that I know. Polymorphic variant extension only works for known
closed variant types, otherwise it would not be sound.
The rest of the post has a suggestion which boils down to capturing the new variant types inside different tags, but again that wouldn't work for your use case of dynamically 'adding together' types using a functor.
For the types you can use an extensible variant type. But for the modelIdToIdFunction function given a list of modules I think you can only search through the list, which won't scale.
You should extend the uuid with an ID for each module so you can create a lookup table from module_id to the module from the list for fast access.

How to write reasonml binding for a union type

I am trying to write bindings for https://github.com/oblador/react-native-keychain/blob/master/typings/react-native-keychain.d.ts#L76
getGenericPassword returns false if an error, else an object (credentials). I am not sure this union type can be represented in reason, but a better API would be the result an option (option(credentials)). But, how can I convert Promise<boolean | credentials> -> Js.Promise.t(option(credentials)) in the binding file. Below is a template.
Thanks for your help.
[#bs.deriving abstract]
type credentials = {
service: string,
username: string,
password: string,
};
/* TODO convert the actual return value
Js.Promise.t(option(credentials)) to more reason type
Js.Promise.t(option(credentials)) */
[#bs.module "react-native-keychain"] [#bs.scope "default"]
external getGenericPassword: unit => Js.Promise.t(option(credentials)) = "";
You can use Js.Types.classify to get the runtime type of a value.
type maybeCredentials;
[#bs.module "react-native-keychain"] [#bs.scope "default"]
external getGenericPassword: unit => Js.Promise.t(maybeCredentials) = "";
let getGenericPassword: unit => Js.Promise.t(option(credentials)) =
() =>
Js.Promise.(
getGenericPassword()
|> then_(maybeCredentials =>
switch (Js.Types.classify(maybeCredentials)) {
| JSObject(obj) => resolve(Some(obj |> Obj.magic))
| _ => resolve(None)
}
)
);
Here maybeCredentials is defined and used as an intermediate type.
We then define a function with the same name as the binding, which will "shadow" the name and prevent the binding from being used directly in favour of our "override". However, within the override we're still able to use the binding.
We then call Js.Types.classify to get the runtime type of the returned value. If it is an object we use Obj.magic to cast the abstract obj_type to our credentials type (inferred from the return type of the function), and wrap it in an option. For any other type we return None.
By the way, this kind of "type" is called an untagged union. I've written down a few examples using different strategies for dealing with these, as both a producer and a consumer, in bucklescript-cookbook.