I am trying grand-stack-starter from neo4j and getting the below error with API module after I do all the graphql schema part. it complains that directive 'relation' and 'cypher'are unknown.
I reinstalled neo4j-graphql-js but didnt solve the problem.
Below is the error message
grand-stack-starter-api#0.0.1 start C:\Users\grand-stack-starter-master\api
nodemon --exec babel-node src/index.js
[nodemon] 1.18.9
[nodemon] to restart at any time, enter rs
[nodemon] watching: .
[nodemon] starting babel-node src/index.js
C:\Users\grand-stack-starter-master\api\node_modules\graphql\validation\validate.js:89
throw new Error(errors.map(function (error) {
^
Error: Unknown directive "relation".
Unknown directive "relation".
Unknown directive "cypher".
Unknown directive "cypher".
Unknown directive "relation".
Unknown directive "relation".
Unknown directive "relation".
Unknown directive "relation".
Unknown directive "relation".
Unknown directive "cypher".
at assertValidSDL (C:\Users\N19683\grand-stack-starter-master\api\node_modules\graphql\validation\validate.js:89:11)
at Object.buildASTSchema (C:\Users\N19683\grand-stack-starter-master\api\node_modules\graphql\utilities\buildASTSchema.js:67:34)
at Object.buildSchemaFromTypeDefinitions (C:\Users\N19683\grand-stack-starter-master\api\node_modules\graphql-tools\src\generate\buildSchemaFromTypeDefinitions.ts:43:32)
at makeExecutableSchema (C:\Users\N19683\grand-stack-starter-master\api\node_modules\graphql-tools\src\makeExecutableSchema.ts:52:16)
at Object.<anonymous> (C:/Users/N19683/grand-stack-starter-master/api/src/index.js:18:16)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at loader (C:\Users\N19683\grand-stack-starter-master\api\node_modules\babel-register\lib\node.js:144:5)
at Object.require.extensions.(anonymous function) [as .js] (C:\Users\N19683\grand-stack-starter-master\api\node_modules\babel-register\lib\node.js:154:7)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
**
Below is the graphql-schema.js
import { neo4jgraphql } from "neo4j-graphql-js";
export const typeDefs = `
type User {
id: ID!
name: String
friends: [User] #relation(name: "FRIENDS", direction: "BOTH")
reviews: [Review] #relation(name: "WROTE", direction: "OUT")
avgStars: Float
#cypher(
statement: "MATCH (this)-[:WROTE]->(r:Review) RETURN toFloat(avg(r.stars))"
)
numReviews: Int
#cypher(statement: "MATCH (this)-[:WROTE]->(r:Review) RETURN COUNT(r)")
}
type Business {
id: ID!
name: String
address: String
city: String
state: String
reviews: [Review] #relation(name: "REVIEWS", direction: "IN")
categories: [Category] #relation(name: "IN_CATEGORY", direction: "OUT")
}
type Review {
id: ID!
stars: Int
text: String
date: Date
business: Business #relation(name: "REVIEWS", direction: "OUT")
user: User #relation(name: "WROTE", direction: "IN")
}
type Category {
name: ID!
businesses: [Business] #relation(name: "IN_CATEGORY", direction: "IN")
}
type Query {
usersBySubstring(substring: String): [User]
#cypher(
statement: "MATCH (u:User) WHERE u.name CONTAINS $substring RETURN u"
)
}
`
export const resolvers = {
Query: {
Users: neo4jgraphql,
Business: neo4jgraphql,
Category: neo4jgraphql,
Review: neo4jgraphql
}
};
index.js
import { typeDefs, resolvers } from "./graphql-schema";
import { ApolloServer, gql, makeExecutableSchema } from "apollo-server";
import { v1 as neo4j } from "neo4j-driver";
import { augmentSchema } from "neo4j-graphql-js";
import dotenv from "dotenv";
// set environment variables from ../.env
dotenv.config();
const schema = makeExecutableSchema({
typeDefs,
resolvers
});
const augmentedSchema = augmentSchema(schema);
const driver = neo4j.driver(
process.env.NEO4J_URI || "bolt://localhost:7689",
neo4j.auth.basic(
process.env.NEO4J_USER || "neo4j",
process.env.NEO4J_PASSWORD || "letmein"
)
);
const server = new ApolloServer({
context: { driver },
schema: augmentedSchema
});
server.listen(process.env.GRAPHQL_LISTEN_PORT, "0.0.0.0").then(({ url }) => {
console.log(`GraphQL API ready at ${url}`);
});
Can anyone please help to fix the issue! Thanks in advance
As noted in the docs
NOTE: Only use augmentSchema if you are working with an existing GraphQLSchema object. In most cases you should use makeAugmentedSchema which can construct the GraphQLSchema object from type definitions.
The error is occurring because you're attempting to use makeExecutableSchema to create your schema. The #relation and #cypher directives are used exclusively by neo4j-graphql. Since they're not actually defined as part of your schema, building your schema with makeExecutableSchema will result in an error just like using any other undefined directive.
You should just use makeAugmentedSchema instead:
const schema = makeAugmentedSchema({
typeDefs,
resolvers,
})
const driver = /* ... */
const server = new ApolloServer({
context: { driver },
schema,
})
Related
I am adding next-auth with google provider to my next.js project in developement mode, but I am geeting this error on the browser URL : http://localhost:3000/api/auth/signin?error=OAuthCallback
and Try signing in with a different account message on the screen.
and
after signing in with signIn('google') everytime the following error appears in my terminal in vscode:
[next-auth][warn][NEXTAUTH_URL]
https://next-auth.js.org/warnings#nextauth_url
data unauthenticated
[next-auth][error][OAUTH_CALLBACK_ERROR]
https://next-auth.js.org/errors#oauth_callback_error JWT expired, now 1675094480, exp 1675094221 {
error: RPError: JWT expired, now 1675094480, exp 1675094221
at Client.validateJWT (D:\React_prj\ChatApp\frontend\node_modules\openid-client\lib\client.js:956:15)
at Client.validateIdToken (D:\React_prj\ChatApp\frontend\node_modules\openid-client\lib\client.js:745:60)
at Client.callback (D:\React_prj\ChatApp\frontend\node_modules\openid-client\lib\client.js:488:18)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async oAuthCallback (D:\React_prj\ChatApp\frontend\node_modules\next-auth\core\lib\oauth\callback.js:129:16)
at async Object.callback (D:\React_prj\ChatApp\frontend\node_modules\next-auth\core\routes\callback.js:52:11)
at async AuthHandler (D:\React_prj\ChatApp\frontend\node_modules\next-auth\core\index.js:201:28)
at async NextAuthHandler (D:\React_prj\ChatApp\frontend\node_modules\next-auth\next\index.js:24:19)
at async D:\React_prj\ChatApp\frontend\node_modules\next-auth\next\index.js:60:32
at async Object.apiResolver (D:\React_prj\ChatApp\frontend\node_modules\next\dist\server\api-utils\node.js:372:9) at async DevServer.runApi (D:\React_prj\ChatApp\frontend\node_modules\next\dist\server\next-server.js:488:9)
at async Object.fn (D:\React_prj\ChatApp\frontend\node_modules\next\dist\server\next-server.js:751:37)
at async Router.execute (D:\React_prj\ChatApp\frontend\node_modules\next\dist\server\router.js:253:36)
at async DevServer.run (D:\React_prj\ChatApp\frontend\node_modules\next\dist\server\base-server.js:384:29)
at async DevServer.run (D:\React_prj\ChatApp\frontend\node_modules\next\dist\server\dev\next-dev-server.js:743:20)
at async DevServer.handleRequest (D:\React_prj\ChatApp\frontend\node_modules\next\dist\server\base-server.js:322:20) {
name: 'OAuthCallbackError',
code: undefined
},
providerId: 'google',
message: 'JWT expired, now 1675094480, exp 1675094221'
}
everytime on the browser I see the following image (Try signing in with a different account.)even trying with another account I get this image in the browser
enter image description here
also, I use prisma as the adapter as well
the following are my codes:
[...nextauth].ts
import NextAuth from 'next-auth';
import GoogleProvider from 'next-auth/providers/google';
import { PrismaAdapter } from '#next-auth/prisma-adapter';
import prisma from '../../../lib/prismadb';
export default NextAuth({
adapter: PrismaAdapter(prisma),
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID as string,
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
}),
],
});
prismadb.ts
import { PrismaClient } from '#prisma/client';
declare global {
var prisma: PrismaClient | undefined;
}
const client = globalThis.prisma || new PrismaClient();
if (process.env.NODE_ENV !== 'production') globalThis.prisma = client;
export default client;
schema.prisma
datasource db {
provider = "mongodb"
url = env("MONGODB_URI")
}
generator client {
provider = "prisma-client-js"
}
model Account {
id String #id #default(auto()) #map("_id") #db.ObjectId
userId String
type String
provider String
providerAccountId String
refresh_token String? #db.String
access_token String? #db.String
expires_at Int?
token_type String?
scope String?
id_token String? #db.String
session_state String?
user User #relation(fields: [userId], references: [id], onDelete: Cascade)
##unique([provider, providerAccountId])
}
model Session {
id String #id #default(auto()) #map("_id") #db.ObjectId
sessionToken String #unique
userId String
expires DateTime
user User #relation(fields: [userId], references: [id], onDelete: Cascade)
}
model User {
id String #id #default(auto()) #map("_id") #db.ObjectId
name String?
email String? #unique
emailVerified DateTime?
image String?
accounts Account[]
sessions Session[]
}
model VerificationToken {
id String #id #default(auto()) #map("_id") #db.ObjectId
identifier String
token String #unique
expires DateTime
##unique([identifier, token])
}
and .env.local
GOOGLE_CLIENT_ID=46255473************od0rt849b.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=GOCSPX-*************I7SNBuJ6
MONGODB_URI =mongodb://localhost/chatapp
I tried many othersolution provided on the google and other providers but I cannot fix this issue.
please help
thx
I tried to login with next-auth with google as the provider and prisma as the adapter, but I get callback error
B"H
I've seen this question and I want to do the same thing with the GraphQL driver for Neo4j. I think the answer lies somewhere in combining AND and OR operators found here, of some sort, but not sure how.
To illustrate the question, say I have this type:
type Comment {
id: ID #id
timeAdded: DateTime! #timestamp(
operations: [CREATE]
)
writer: User! #relationship(
type: "WRITTEN_BY",
direction: IN
)
content: String
}
type User {
id: ID #id
name: String
commentsWritten: [Comment!]! #relationship(
type: "WRITTEN_BY",
direction: OUT
)
}
type Mutation {
addComment(authorID: String)
}
and this resolver to add a new comment (where "Comment" is a reference to the OGM model of the Comment type):
addComment: async (
src,
args,
ctx
) => {
var authorID = args/*edit*/.authorID //let's say this is passed
//from request headers / JWT token or something
var adCom = await Comment.create({
input: [
{
content: args.content,
writer: {
connect: {
where: {
node: {
users: {
id: authorID
}
}
}
}
}
}
]
})
return adCom;
}
So it attempts to connect to that user with that ID. but if there is no user with that ID, I don't want to create anything [not only do I not want to connect it].
I could run another query to find a User with that ID, and test if it went through, but was wondering if it's possible to do everything in one call
Why am I getting the following error when trying to create a metadata account using createCreateMetadataAccountV2Instruction from the #metaplex-foundation/mpl-token-metadata library?
SendTransactionError: failed to send transaction: Transaction simulation failed: Error processing Instruction 0: Program failed to complete
at Connection.sendEncodedTransaction (C:\xampp\htdocs\sol-tools\node_modules\#solana\web3.js\src\connection.ts:4464:13)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async Connection.sendRawTransaction (C:\xampp\htdocs\sol-tools\node_modules\#solana\web3.js\src\connection.ts:4423:20)
at async Connection.sendTransaction (C:\xampp\htdocs\sol-tools\node_modules\#solana\web3.js\src\connection.ts:4411:12)
at async sendAndConfirmTransaction (C:\xampp\htdocs\sol-tools\node_modules\#solana\web3.js\src\util\send-and-confirm-transaction.ts:31:21)
at async addMetadataToToken (C:\xampp\htdocs\sol-tools\src\lib\metadata.ts:86:16)
at async Command.<anonymous> (C:\xampp\htdocs\sol-tools\src\cli.ts:48:7) {
logs: [
'Program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s invoke [1]',
'Program log: Instruction: Create Metadata Accounts v2',
"Program log: panicked at 'range end index 36 out of range for slice of length 0', program/src/utils.rs:231:27",
'Program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s consumed 6223 of 1400000 compute units',
'Program failed to complete: BPF program panicked',
'Program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s failed: Program failed to complete'
]
}
Here's my code:
import {
createCreateMetadataAccountV2Instruction,
PROGRAM_ID,
} from '#metaplex-foundation/mpl-token-metadata'
import {
Connection,
Keypair,
PublicKey,
sendAndConfirmTransaction,
Transaction,
} from '#solana/web3.js'
export const addMetadataToToken = async (
connection: Connection,
tokenMint: PublicKey,
tokenOwner: Keypair,
name: string,
symbol: string,
arweaveLink: string
) => {
const seed1 = Buffer.from('metadata', 'utf8')
const seed2 = PROGRAM_ID.toBuffer()
const seed3 = tokenMint.toBuffer()
const [metadataPDA, _bump] = PublicKey.findProgramAddressSync(
[seed1, seed2, seed3],
PROGRAM_ID
)
const accounts = {
metadata: metadataPDA,
mint: tokenMint,
mintAuthority: tokenOwner.publicKey,
payer: tokenOwner.publicKey,
updateAuthority: tokenOwner.publicKey,
}
const dataV2 = {
name,
symbol,
uri: arweaveLink,
// we don't need these
sellerFeeBasisPoints: 0,
creators: null,
collection: null,
uses: null,
}
const args = {
createMetadataAccountArgsV2: {
data: dataV2,
isMutable: true,
},
}
const ix = createCreateMetadataAccountV2Instruction(accounts, args)
const tx = new Transaction()
tx.add(ix)
const txid = await sendAndConfirmTransaction(connection, tx, [tokenOwner])
console.log(txid)
}
Turns out I was on trying to create metadata for a token on devnet, but was using a mainnet-beta rpc endpoint for the Connection class. Thus the token I was trying to create metadata for didn't exist.
This is a really Common Error Message that occurs when there is some issue with what you are passing to the program. So make sure everything that you are input to the program is correct. In 90% of the cases, it gets resolved when checking the inputs correctly.
I got the demo example from grand-stack and was able to start up graphql, start up the Neo4J sandbox and populate the test database using
npm run seedDb
However, when I try to write my own data entries to populate into a neo4j database, I cannot get the relation between nodes to work at all. The error message is the most non-useful message (and I believe it is from the apollo client, and is a status code 400 error). I simplified the code to the most simplest case to make it work, and it still does not. Here is the schema.graphql file:
type Patient {
id: ID!
name: String
reviews: [Review] #relation(name:"WROTE", direction:"OUT")
}
type Review {
id: ID!
stars: Int
text: String
date: Date
user: Patient #relation(name: "WROTE", direction: "IN")
}
and here is the seed-mutation.js file:
export default /* GraphQL */ `
mutation {
p1: CreatePatient(
id: "p1",
name: "John Doe 1"
) {
id
name
}
r1: CreateReview(id: "r1", stars: 4, text: "Great IPA selection!", date: { formatted: "2016-01-03"}) {
id
}
ar1: AddUserReviews(from: { id: "p1"}, to: { id: "r1" }) { from {id}}
}
`;
When I do "npm run seedDb", this yields the error message:
{ Error: Network error: Response not successful: Received status code 400
at new ApolloError (/Users/xxxx/Downloads/grand-stack-starter-master/api/node_modules/apollo-client/bundle.esm.js:60:28)
at Object.error (/Users/xxxx/Downloads/grand-stack-starter-master/api/node_modules/apollo-client/bundle.esm.js:1032:48)
at notifySubscription (/Users/xxxx/Downloads/grand-stack-starter-master/api/node_modules/zen-observable/lib/Observable.js:134:18)
at onNotify (/Users/xxxx/Downloads/grand-stack-starter-master/api/node_modules/zen-observable/lib/Observable.js:165:3)
at SubscriptionObserver.error (/Users/xxxx/Downloads/grand-stack-starter-master/api/node_modules/zen-observable/lib/Observable.js:224:7)
at /Users/xxxx/Downloads/grand-stack-starter-master/api/node_modules/apollo-link-http/src/httpLink.ts:184:20
at <anonymous>
at process._tickDomainCallback (internal/process/next_tick.js:228:7)
graphQLErrors: [],
networkError:
{ ServerError: Response not successful: Received status code 400
at Object.exports.throwServerError (/Users/xxxx/Downloads/grand-stack-starter-master/api/node_modules/apollo-link-http-common/src/index.ts:114:17)
at /Users/xxxx/Downloads/grand-stack-starter-master/api/node_modules/apollo-link-http-common/src/index.ts:145:11
at <anonymous>
at process._tickDomainCallback (internal/process/next_tick.js:228:7)
name: 'ServerError',
response:
Response {
size: 0,
timeout: 0,
[Symbol(Body internals)]: [Object],
[Symbol(Response internals)]: [Object] },
statusCode: 400,
result: { errors: [Array] } },
message: 'Network error: Response not successful: Received status code 400',
extraInfo: undefined }
I started with multiple complex codes and this is pretty much the most stripped down version. When I run the seedDB command after the seed-mutation.js file was modified to:
export default /* GraphQL */ `
mutation {
p1: CreatePatient(
id: "p1",
name: "John Doe 1"
) {
id
name
}
r1: CreateReview(id: "r1", stars: 4, text: "Great IPA selection!", date: { formatted: "2016-01-03"}) {
id
}
}
`;
the database gets populated, however the two nodes are not connected to each other, as expected (basically, this is the code with the AddUserReviews removed). How do I build the relation between the nodes through using graphql and seedDb? What am I missing?
You can use GraphQL Playground to inspect the GraphQL API (in the "Docs" tab):
to ensure the mutations you are calling have the correct name and arguments. From inspecting the schema, it looks like instead of AddUserReviews, you want AddPatientReviews?
I'm getting a connection related error when defining a static query that filters an embedded document field.
I've tried to separate the embedded document in a separate schema file but didn't resolve the issue. Any ideas?
Error follows:
C:\development_GIT\myproject\app\models\mymodel.js:40
this.find({ text.lang_code: langCode }).sort('text.name').exec(callback);
^
Error: Trying to open unclosed connection.
at NativeConnection.Connection.open (C:\development_GIT\myproject\node_
modules\mongoose\lib\connection.js:205:15)
at Mongoose.connect (C:\development_GIT\myproject\node_modules\mongoose
\lib\index.js:156:15)
at Object.<anonymous> (C:\development_GIT\myproject\server.js:13:10)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at repl:1:1
The error is launched when using the filter { text.lang_code: langCode }
option in the following model. If I don't use the embedded document and try to filter for exampe { _id: langCode } it does not throw errors.
//MyModel.js located at ./app/models
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var MyModelSchema = new Schema({
name: { type: String, trim: true },
text: [{ name: String, lang_code: String }]
});
MyModelSchema .static({
findByLangCode : function(langCode, callback) {
this.find({ text.lang_code: langCode }).sort('text.name').exec(callback);
}
});
mongoose.model('MyModel', CategorySchema);
The first lines of my main file server.js are:
//server.js
var express = require('express');
var env = process.env.NODE_ENV || 'development';
var config = require('./config/config')[env];
var mongoose = require('mongoose');
var fs = require('fs');
require('express-namespace');
mongoose.connect(config.db);
// Bootstrap models
fs.readdirSync(__dirname + '/app/models').forEach(function (file) {
if (~file.indexOf('.js')) require(__dirname + '/app/models/' + file)
});
Solution was building the query in a different way. It seems that subdocuments can not be used inside find().
Before: (not working)
this.find({ text.lang_code: langCode }).sort('text.name').exec(callback);
After (working)
this.find().where('text.lang_code').equals(langCode).sort('text.name').exec(callback);
Im using this all the time and it works fine for me.
this.find({ 'text.lang_code': langCode }).sort('text.name').exec(callback);
MongoDb can only handle one lvl of objects, but if you give it a string like you are doing in the .where function, mongodb will do magic and match it to subdocuments :)