Receiving error: Class Action is missing in schema: actions.actions - nearprotocol

I'm trying to broadcast transaction having following actions:
actions: [
transactions.createAccount(),
transactions.transfer(new BN(swapParams.value.toFixed())),
transactions.deployContract(new Uint8Array(bytecode)),
transactions.functionCall(
ABI.init.method,
{
secretHash: Buffer.from(swapParams.secretHash, 'hex').toString('base64'),
expiration: `${toNearTimestampFormat(swapParams.expiration)}`,
buyer: swapParams.recipientAddress
},
new BN(ABI.init.gas),
new BN(0)
)
]
But when I invoke
const tx = await from.signAndSendTransaction(addressToString(options.to), options.actions)
I receive following callstack:
Any idea what might be the reason?
I'm using:
near-js-api: 0.39.0

According to the documentation, source code, and defined types signAndSendTransaction should take a single argument (an object with receiverId and actions fields):
const tx = await from.signAndSendTransaction({
receiverId: addressToString(options.to),
actions: options.actions
})
Was there an example/doc that mislead you, so you arrived with this function call interface? We should fix that.

Related

Apollo client ignoring argument for GQL REST query

I have a query that is defined like this:
export const getProjectCosts = gql`
query GetProjectCosts($projectId: Int) {
ProjectCostList #rest(type: "ProjectCostList", path: "ProjectCosts/{args.projectId}") {
id
projectId
cost
description
costType
budgetYear
createdByUser
createdDate
}
}
`;
export const useGetProjectCostsListQuery = (baseOptions?: QueryHookOptions<ProjectCostList>) => {
const options = { ...baseOptions };
return useQuery<ProjectCostList>(getProjectCosts, options);
};
I call it like this:
const {
loading: projectCostLoading,
error: projectCostError,
data: projectCostData,
} = useGetProjectCostsListQuery({
variables: {
projectId: args.defaultValues.id,
},
});
I have verified in the debugger that the argument is sent correctly.
However, in the browser I see a warning:
Warning: RestLink caught an error while unpacking ProjectCosts/{args.projectId}|args.projectId This tends to happen if you forgot to pass a parameter needed for creating an #rest(path, or if RestLink was configured to deeply unpack a path parameter that wasn't provided. This message will only log once per detected instance. Trouble-shooting hint: check #rest(path: and the variables provided to this query.
(anonymous) # restLink.ts:567
And a request is sent to api/ProjectCosts/ instead of api/ProjectCosts/1234, which not surprisingly fails with a HTTP 404 error.
Is this a bug or am I doing something wrong?
I found this issue on Github, which looks very similar to what I'm experiencing.
We're using a custom .NET backend.
If it's a bug, is there a workaround?
The problem was that the parameter has to be declared twice.
This is the solution:
export const getProjectCosts = gql`
query GetProjectCosts($projectId: Int!) {
ProjectCostList(projectId: $projectId) #rest(type: "ProjectCostList", path: "ProjectCosts/{args.projectId}") {

500 error when caching AWS Lambda Authenticator response

I'm using serverless stack, now attempting to add a Lambda Custom Authenticator to validate authorization tokens with Auth0 and add custom data to my request context when the authentication passes.
Everything works mostly fine at this point, except for when I cache the Authenticator response for the same token.
I'm using a 5-second cache for development. The first request with a valid token goes through as it should. The next requests in the 5-second window fail with a mysterious 500 error without ever reaching my code.
Authorizer configuration
// MyStack.ts
const authorizer = new sst.Function(this, "AuthorizerFunction", {
handler: "src/services/Auth/handler.handler",
});
const api = new sst.Api(this, "MarketplaceApi", {
defaultAuthorizationType: sst.ApiAuthorizationType.CUSTOM,
defaultAuthorizer: new HttpLambdaAuthorizer("Authorizer", authorizer, {
authorizerName: "LambdaAuthorizer",
resultsCacheTtl: Duration.seconds(5), // <-- this is the cache config
}),
routes: {
"ANY /{proxy+}": "APIGateway.handler",
},
});
Authorizer handler
const handler = async (event: APIGatewayAuthorizerEvent): Promise<APIGatewayAuthorizerResult> => {
// Authenticates with Auth0 and serializes context data I wanna
// forward to the underlying service
const authentication = await authenticate(event);
const context = packAuthorizerContext(authentication.value);
const result: APIGatewayAuthorizerResult = {
principalId: authentication.value?.id || "unknown",
policyDocument: buildPolicy(authentication.isSuccess ? "Allow" : "Deny", event.methodArn),
context, // context has the following shape:
// {
// info: {
// id: string,
// marketplaceId: string,
// roles: string,
// permissions: string
// }
// }
};
return result;
};
CloudWatch logs
☝️ Every uncached request succeeds, with status code 200, an integration ID and everything, as it's supposed to. Every other request during the 5-second cache fails with 500 error code and no integration ID, meaning it doesn't reach my code.
Any tips?
Update
I just found this in an api-gateway.d.ts #types file (attention to the comments, please):
// Poorly documented, but API Gateway will just fail internally if
// the context type does not match this.
// Note that although non-string types will be accepted, they will be
// coerced to strings on the other side.
export interface APIGatewayAuthorizerResultContext {
[name: string]: string | number | boolean | null | undefined;
}
And I did have this problem before I could get the Authorizer to work in the first place. I had my roles and permissions properties as string arrays, and I had to transform them to plain strings. Then it worked.
Lo and behold, I just ran a test right now, removing the context information I was returning for successfully validated tokens and now the cache is working 😔 every request succeeds, but I do need my context information...
Maybe there's a max length for the context object? Please let me know of any restrictions on the context object. As the #types file states, that thing is poorly documented. This is the docs I know about.
The issue is that none of the context object values may contain "special" characters.
Your context object must be something like:
"context": {
"someString": "value",
"someNumber": 1,
"someBool": true
},
You cannot set a JSON object or array as a valid value of any key in the context map. The only valid value types are string, number and boolean.
In my case, though, I needed to send a string array.
I tried to get around the type restriction by JSON-serializing the array, which produced "[\"valueA\",\"valueB\"]" and, for some reason, AWS didn't like it.
TL;DR
What solved my problem was using myArray.join(",") instead of JSON.stringify(myArray)

GraphQL Nexus Schema (nexusjs) doesn't compile with scalar types

I am trying to follow the documentation on the Nexus-Schema (nexusjs) website for adding scalar types to my GraphQL application.
I have tried adding many of the different implementations to my src/types/Types.ts file using the samples provided in the documentation and the interactive examples. My attempts include:
Without a 3rd party libraries:
const DateScalar = scalarType({
name: 'Date',
asNexusMethod: 'date',
description: 'Date custom scalar type',
parseValue(value) {
return new Date(value)
},
serialize(value) {
return value.getTime()
},
parseLiteral(ast) {
if (ast.kind === Kind.INT) {
return new Date(ast.value)
}
return null
},
})
With graphql-iso-date 3rd party library:
import { GraphQLDate } from 'graphql-iso-date'
export const DateTime = GraphQLDate
With graphql-scalars 3rd party library (as shown in the ghost example):
export const GQLDate = decorateType(GraphQLDate, {
rootTyping: 'Date',
asNexusMethod: 'date',
})
I am using this new scalar type in an object definition like the following:
const SomeObject = objectType({
name: 'SomeObject',
definition(t) {
t.date('createdAt') // t.date() is supposed to be available because of `asNexusMethod`
},
})
In all cases, these types are exported from the types file and imported into the makeSchema's types property.
import * as types from './types/Types'
console.log("Found types", types)
export const apollo = new ApolloServer({
schema: makeSchema({
types,
...
context:()=>(
...
})
})
The console.log statement above does show that consts declared in the types file are in scope:
Found types {
GQLDate: Date,
...
}
If I run the app in development mode, everything boots up and runs fine.
ts-node-dev --transpile-only ./src/app.ts
However, I encounter errors whenever I try to compile the app to deploy to a server
ts-node ./src/app.ts && tsc
Note: This error occurs occurs running just ts-node ./src/app.ts before it gets to tsc
The errors that shown during the build process are the following:
/Users/user/checkouts/project/node_modules/ts-node/src/index.ts:500
return new TSError(diagnosticText, diagnosticCodes)
^
TSError: ⨯ Unable to compile TypeScript:
src/types/SomeObject.ts:11:7 - error TS2339: Property 'date' does not exist on type 'ObjectDefinitionBlock<"SomeObject">'.
11 t.date('createdAt')
Does anyone have any ideas on either:
a) How can I work around this error? While long-term solutions are ideal, temporary solutions would also be appreciated.
b) Any steps I could follow to debug this error? Or ideas on how get additional information to assist with debugging?
Any assistance would be very much welcomed. Thanks!
The issue seems to be resolved when --transpile-only flag is added to the nexus:reflect command.
This means the reflection command gets updated to:
ts-node --transpile-only ./src/app.ts
and the build comand gets updated to:
env-cmd -f ./config/.env ts-node --transpile-only ./src/app.ts --nexusTypegen && tsc
A github issue has also been created which can be reviewed here: https://github.com/graphql-nexus/schema/issues/690

MS Teams bot - create conversation in newly created Group returns 405 BadArgument

I'm trying to create new convesation for just created channel using Nodejs + botframework v4.9.2.
I've
created new Channel using POST https://graph.microsoft.com/beta/teams/${teamId}/channels
new tab using POST https://graph.microsoft.com/beta/teams/${req.teamId}/channels/${req.channelId}/tabs
I can see new channel and tab in Teams UI
trying to create new conversation via Conversations.createConversation from bot sdk, it's basically calling POST https://directline.botframework.com/v3/conversations with passing new channel id and getting 405 BadArgument This channel does not support this operation
I'm running bot locally and proxying via ngrok.
Also I can access GET /v3/conversations.
Updated code
Get Team Memebers GET ${graphUrl}/groups/${teamId}/members
Create new Channel
const createChannelRequest: IGraphCreateChannelBody = {
"#odata.type": "#Microsoft.Teams.Core.channel",
displayName: channelName,
description: `This channel is for incident id : ${incidentId}`,
members: membersIds.map(memberId => (
{
"#odata.type": "#microsoft.graph.aadUserConversationMember",
"user#odata.bind": `https://graph.microsoft.com/beta/users('${memberId}')`,
roles: ["owner"]
}
))
};
return await graphClient.createChannel(teamId, createChannelRequest);
createChannel is basically POST ${graphUrl}/teams/${teamId}/channels
Create new Tab POST ${graphUrl}/teams/${req.teamId}/channels/${req.channelId}/tabs where channelId is createChannelResponse.id
Create new conversation
const client = new BotConnector.ConnectorClient(credentials, {baseUri: serviceUrl});
const {bot} = TurnContext.getConversationReference(activity);
const createConversationResponse = await client.conversations.createConversation({
bot,
activity: incidentActivity,
members: teamMembers.value.map(member => ({
id: member.id,
name: member.displayName
})),
channelData: {
channel: {
id: newIncidentChannelId
},
tenant: {
id: tenantId
}
},
isGroup: true
});
where createConversation fails with 405
[Posting a complete answer, based on the comments above]
There's no need (and it won't work), in the context of Teams, to use createConversation, because the conversation is created the moment the Team/Channel/Group chat itself is created (createConversation exists for other Bot Framework scenarios, and is not applicable for Teams). As a result SendToConversation is the correct operation to use.
As to how to use SendToConversation, there are certain important variables you need to have already your side, and the most common time to get these is when your bot is added to the channel/chat/whatever in the first place. You can read more about that here, but more generally, this is considered something called "proactive" messaging, in Teams, and it's worth reading up on that topic more. Please see here and here as good starting points.

Says Jasmine spy is not being called, but I can see that its being called

I can't figure out why Jasmine is claiming that the function I'm spying on isn't being called, especially since it is logging in buildLinksObj when called through and not calling when I remove .and.callThrough() I feel like I've written similar code a bunch of times before without any problem. I'm using Jasmine 2.9
The error message I'm getting is:
1) addToLinks should call buildLinksObj if its given an object with children
it should add the personalized links to PageApp.meta.analytics.links
Expected spy buildLinksObj to have been called.
at UserContext.<anonymous> (http://localhost:9877webpack:///tests/specs/common/FetchPersonalContent.spec.js:854:0 <- tests/app-mcom.js:104553:48)
Here's the except of my code:
FetchPersonalContent.js
const buildLinksObj = (responseObj = {}, targetObj, PageApp) => {
console.log('it logs in buildLinksObj') // This is logging!
}
const addToLinks = (responseArr, personalizedLinks) => {
responseArr.forEach((media) => {
const type = media.type;
const typeObj = media[type];
buildLinksObj(typeObj, personalizedLinks, PageApp);
if (typeObj && typeObj.children) {
console.log('has children!')
console.log('typeObj.children is: ', typeObj.children);
typeObj.children.forEach((child) => {
console.log('has a child')
buildLinksObj(child, personalizedLinks, PageApp);
console.log('buildLinksObj was definitely called. what the heck?')
});
}
});
}
export {buildLinksObj, addToLinks, FetchPersonalContent as default,
};
FetchPersonalContent.spec.js
import * as FetchPersonalContent from '../../../src/FetchPersonalContent'; // my path is definitely correct
describe('it should add the personalized links to PageApp.meta.analytics.links', () => {
it('addToLinks should call buildLinksObj if its given an object with children ', () => {
spyOn(FetchPersonalContent, 'buildLinksObj').and.callThrough();
FetchPersonalContent.addToLinks([{
"personalId": 30718,
"type": "carousel",
"carousel": {}
}], {});
expect(FetchPersonalContent.buildLinksObj).toHaveBeenCalled();
});
});
I'd really appreciate any help!
I have a feeling FetchPersonalContent.buildLinksObj in the spec file is not pointing to the same instance as buildLinksObj in the FetchPersonalContent.js file.
Why is export {FetchPersonalContent as default} required? I am assuming you have shared the complete content of FetchPersonalContent.js in your question.
Possible solutions:
You can try removing FetchPersonalContent from the export statement.
Or
Instead of
export {buildLinksObj, addToLinks, FetchPersonalContent as default,
};
You can directly export the constants in FetchPersonalContent.js file.

Resources