profusion / apollo-validation-directives Goto Github PK
View Code? Open in Web Editor NEWGraphQL directives to implement field validations in Apollo Server
GraphQL directives to implement field validations in Apollo Server
StringLength directive adds validationError
with could not convert value to string
message when field is empty on a nullable field.
I saw that you have added a fix (which is not yet released) to a similar issue to other directives, but @stringLength
also have this problem.
It doesn't work after migrating to apollo server v3, no errors is thrown, but no directives actually produce errors in info.validationErrors
Currently, when @hasPermissions
is used on a INPUT_FIELD_DEFINITION
, if the field have a default value, it checks for the permissions even if no value(or the default value) was sent in the request.
e.g.:
for the following schema:
input InputType {
field1: String = "123" @hasPermissions(permissions: ["allowed"])
field2: Boolean @hasPermissions(permissions: ["allowed"])
}
Query {
someQuery(input: InputType!): Boolean!
}
Using the following query:
query myQuery($input: InputType!) {
someQuery(input: $input)
}
When the user doesn't have the necessary permissions, it results in an error due the @hasPermissions
on field1
when the following variables are used:
{
input: {}
}
Whereas it allows the following variables:
{
input: {
field1: null
}
}
If the user doesn't have permissions to send the field, only the default value should be allowed (not even null should be allowed if null is not the default value)
When a nullable argument is not valid, it is transformed into null
in resolver.
# schema
type Mutation {
chooseSmallString(value: String @stringLength(max: 5)): String
}
# query
mutation {
chooseSmallString(value: "dddddddsdjnasdjnasjdnddd")
}
# result
{
"data": {
"chooseSmallString": null
}
}
I would have expected the resolver to not have been called and a validation error to have been returned to the user.
Indeed, standard GraphQL argument validations throws an error when an argument does not match the expected type:
# schema
type Mutation {
choosString(value: String): String
}
# query
mutation {
chooseString(value: true)
}
# result
{
"error": {
"errors": [
{
"message": "Expected type String, found true.",
"locations": [
{
"line": 2,
"column": 23
}
],
"extensions": {
"code": "GRAPHQL_VALIDATION_FAILED",
"exception": {
"stacktrace": [
"GraphQLError: Expected type String, found true.",
"...."
]
}
}
}
]
}
}
When i try to use this package with apollo-server-lambda
i get an error:
ModuleNotFoundError: Module not found: Error: Can't resolve 'apollo-server' in '.../node_modules/@profusion/apollo-validation-directives/build/lib'
no idea what is the difference in API between them and if it's even possible to use it with apollo-server-lambda
(I havesn't seen any working examples so far), but it would be really nice thing
type Mutation {
createBook(book: BookInput): Book!
}
input BookInput {
title: String! @stringLength(max: 5)
description: String
}
mutation {
createBook(book: {
title: "ddd"
}) {
title,
}
}
The createBook
resolver receives a validationErrors
on description
input field: TypeError: String cannot represent value: undefined
whereas it was not provided.
See this sandbox for reproduction.
trying to run the Value validation example.
I'm being returned this issue by typescript :
error TS2322: Type 'typeof ConcreteValidateDirectiveVisitor' is not assignable to type 'typeof SchemaDirectiveVisitor'.
Types of property 'visitSchemaDirectives' are incompatible.
Type '(schema: GraphQLSchema, directiveVisitors: { [directiveName: string]: typeof SchemaDirectiveVisitor; }, context?: { [key: string]: any; } | undefined) => { [directiveName: string]: SchemaDirectiveVisitor[]; }' is not assignable to type '(schema: GraphQLSchema, directiveVisitors: Record<string, typeof SchemaDirectiveVisitor>, context?: Record<string, any> | undefined, pathToDirectivesInExtensions?: string[] | undefined) => Record<...>'.
Types of parameters 'directiveVisitors' and 'directiveVisitors' are incompatible.
Type 'Record<string, typeof SchemaDirectiveVisitor>' is not assignable to type '{ [directiveName: string]: typeof SchemaDirectiveVisitor; }'.
Index signatures are incompatible.
Type 'typeof import("node_modules/@graphql-tools/utils/SchemaDirectiveVisitor").SchemaDirectiveVisitor' is not assignable to type 'typeof import("node_modules/apollo-server-core/node_modules/graphql-tools/dist/schemaVisitor").SchemaDirectiveVisitor'.
The types returned by 'getDirectiveDeclaration(...)' are incompatible between these types.
Type 'GraphQLDirective | null | undefined' is not assignable to type 'GraphQLDirective'.
Type 'undefined' is not assignable to type 'GraphQLDirective'.
adding // @ts-ignore
before schemaDirectives: { range },
is silencing the issue
What is the license of this package?
Thanks!
Hi Y’all,
First of all, thank you for creating the directive helpers! They’ve helped save a lot of time and unnecessary issues!
I have a use case where i would like to see which field is causing validation error, right now we only get the field value or the higher level argument name but not the actual field name.
This happens with input validation, for read validation I see the field name in the path portion of error string.
Is there any way I can get the field name?
Example:
Type exampleinputType {
Id: string @stringlength(min: 4)
Name: string @stringlength(max: 253)
}
Mutation m {
UpdateExample( exampleInput: {
Id :1
Name: “example”
}) {}
}
The path error portion shows only updateExample and doesn’t show the actual field(id) which is erroring.
Thanks for the help!
Could you please give an example how to use it with apollo-federation?
Today it's published as @profusion/apollo-validation-directives
:)
For some reason, I'm getting a stack overflow when calling ValidateDirectiveVisitor.addValidationResolversToSchema()
:
2020-08-27T17:32:09.449Z [error]: uncaughtException: Maximum call stack size exceeded
RangeError: Maximum call stack size exceeded
at Object.get [as GraphQLNonNull] (C:\Code\project\node_modules\graphql\type\index.js:296:20)
at Object.get [as GraphQLNonNull] (C:\Code\project\node_modules\graphql\index.js:87:18)
at checkMustValidateInput (C:\Code\project\node_modules\@profusion\apollo-validation-directives\build\lib\ValidateDirectiveVisitor.js:74:40)
at checkMustValidateInput (C:\Code\project\node_modules\@profusion\apollo-validation-directives\build\lib\ValidateDirectiveVisitor.js:78:16)
at checkMustValidateInputField (C:\Code\project\node_modules\@profusion\apollo-validation-directives\build\lib\ValidateDirectiveVisitor.js:70:12)
at Array.some (<anonymous>)
at checkMustValidateInput (C:\Code\project\node_modules\@profusion\apollo-validation-directives\build\lib\ValidateDirectiveVisitor.js:84:53)
at checkMustValidateInput (C:\Code\project\node_modules\@profusion\apollo-validation-directives\build\lib\ValidateDirectiveVisitor.js:78:16)
at checkMustValidateInputField (C:\Code\project\node_modules\@profusion\apollo-validation-directives\build\lib\ValidateDirectiveVisitor.js:70:12)
at Array.some (<anonymous>)
at checkMustValidateInput (C:\Code\project\node_modules\@profusion\apollo-validation-directives\build\lib\ValidateDirectiveVisitor.js:84:53)
at checkMustValidateInput (C:\Code\project\node_modules\@profusion\apollo-validation-directives\build\lib\ValidateDirectiveVisitor.js:78:16)
at checkMustValidateInputField (C:\Code\project\node_modules\@profusion\apollo-validation-directives\build\lib\ValidateDirectiveVisitor.js:70:12)
at Array.some (<anonymous>)
at checkMustValidateInput (C:\Code\project\node_modules\@profusion\apollo-validation-directives\build\lib\ValidateDirectiveVisitor.js:84:53)
at checkMustValidateInput (C:\Code\project\node_modules\@profusion\apollo-validation-directives\build\lib\ValidateDirectiveVisitor.js:78:16)
We need to make this lib compatible with apollo 4. For that, we need to update the apollo dependency as well as the gql dependency. Unfortunately, gql lib changed a lot since our last update, so we will have to reimplement the visitor algorithm.
We must know how to implement the visitor to implement directives.
In this issue we must have a small report explaining:
Timebox: 4 days
Check if the directives work as is in the Apollo Gateway, blocking invalid requests (including permissions) at the gateway before sending them to the federated micro services.
Hey 👋 thanks for the great library.
I'd like to get apollo-validation-directives working with graphql-tools mocking lib .
I thought I'd be able to call addValidationResolversToSchema
after adding mocks to the schema and therefore have both real validationResolvers with mock application resolvers. But it doesn't appear to work.
Is there a way to achieve this?
I've created a minimal reproduction to illustrate the use case: https://github.com/hobochild/-apollo-validation-directives-repro
Thanks again
It is not possible to use partial update with the validation directives.
The directives add field: null
even if the input did not contain the (not required) field. This can cause unwanted overwrites on fields.
schema:
type Profile {
name: String @stringLength(max: 120)
avatarUrl: String @pattern(regexp: ...)
}
user input:
"name": "John Doe"
the resolver gets after validation:
"name": "Jonh Doe",
"avatarUrl": null
This module requires apollo-server but apparently doesn't declare as a dependency that it requires it. I have a fully functional Apollo app that directly has apollo-server-koa
and apollo-server-core
as dependencies, but not apollo-server
. When I try to load this module, it fails:
const {
ValidateDirectiveVisitor,
stringLength,
range,
pattern,
listLength
} = require('@profusion/apollo-validation-directives')
2020-08-24T19:35:05.612Z [error]: uncaughtException: Cannot find module 'apollo-server'
Require stack:
- C:\Code\ncp\study-design-service\node_modules\@profusion\apollo-validation-directives\build\lib\EasyDirectiveVisitor.js
- C:\Code\ncp\study-design-service\node_modules\@profusion\apollo-validation-directives\build\lib\index.js
- C:\Code\ncp\study-design-service\src\graphql\schema\index.js
- C:\Code\ncp\study-design-service\src\graphql\index.js
- C:\Code\ncp\study-design-service\src\server.js
- C:\Code\ncp\study-design-service\index.js
Error: Cannot find module 'apollo-server'
Require stack:
- C:\Code\ncp\study-design-service\node_modules\@profusion\apollo-validation-directives\build\lib\EasyDirectiveVisitor.js
- C:\Code\ncp\study-design-service\node_modules\@profusion\apollo-validation-directives\build\lib\index.js
- C:\Code\ncp\study-design-service\src\graphql\schema\index.js
- C:\Code\ncp\study-design-service\src\graphql\index.js
- C:\Code\ncp\study-design-service\src\server.js
- C:\Code\ncp\study-design-service\index.js
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:965:15)
at Function.Module._load (internal/modules/cjs/loader.js:841:27)
at Module.require (internal/modules/cjs/loader.js:1025:19)
at require (internal/modules/cjs/helpers.js:72:18)
at Object.<anonymous> (C:\Code\ncp\study-design-service\node_modules\@profusion\apollo-validation-directives\build\lib\EasyDirectiveVisitor.js:15:25)
at Module._compile (internal/modules/cjs/loader.js:1137:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)
at Module.load (internal/modules/cjs/loader.js:985:32)
at Function.Module._load (internal/modules/cjs/loader.js:878:14)
at Module.require (internal/modules/cjs/loader.js:1025:19)
at require (internal/modules/cjs/helpers.js:72:18)
at Object.<anonymous> (C:\Code\ncp\study-design-service\node_modules\@profusion\apollo-validation-directives\build\lib\index.js:4:30)
at Module._compile (internal/modules/cjs/loader.js:1137:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)
at Module.load (internal/modules/cjs/loader.js:985:32)
at Function.Module._load (internal/modules/cjs/loader.js:878:14) metadata: {
"error": {
"code": "MODULE_NOT_FOUND",
"requireStack": [
"C:\\Code\\ncp\\study-design-service\\node_modules\\@profusion\\apollo-validation-directives\\build\\lib\\EasyDirectiveVisitor.js",
"C:\\Code\\ncp\\study-design-service\\node_modules\\@profusion\\apollo-validation-directives\\build\\lib\\index.js",
"C:\\Code\\ncp\\study-design-service\\src\\graphql\\schema\\index.js",
"C:\\Code\\ncp\\study-design-service\\src\\graphql\\index.js",
"C:\\Code\\ncp\\study-design-service\\src\\server.js",
"C:\\Code\\ncp\\study-design-service\\index.js"
]
}
FilterMissingPermissions
, and functions like debugFilterMissingPermissions
and prodFilterMissingPermissions
for building custom features. Re-enabling these imports would be helpful, providing useful functions to be used in projects.The extra argument validationErrors
is visible in the produced schema while, apriori, the client does not need to know it exists.
Wouldn't be better injected in the info
argument of resolver?
createUser(_, args, ctxt, info) {
if(info.validationErrors && info.validationErrors.length) {
// guess i should throw
}
}
Hello there !
How can We show a custom message for example :
type Mutation { DoThing(input : some!) : Boolean } puery input some{ subSome: String! @stringLength(min: 0, max: 10,) }
if I use DoThing(input:{subSome:"0123456789A"})
it returns default message : "String Length is More than 10"
I want to change it to "subSome is too long"
how can I do this ?!
Hi,
First of all, thank you for this great library, really convenient !
This issue has already been raised and closed (#21) but I have found (I think) where its origin is.
I have the following input field:
input A {
B: [C]
D: String!
E: ID
F: [A] # this line creates the error
G: JSON
H: [Int]
}
In ValidateDirectiveVisitor
inside the checkMustValidateInput
function when I add a log here:
if (finalType instanceof graphql_1.GraphQLInputObjectType) {
console.log({type, finalType});
return Object.values(finalType.getFields()).some(checkMustValidateInputField);
}
I get { type: A, finalType: A }
several times until the crash.
I don't know whether the schema itself is a bit sketchy this way or if the library could handle that case itself to prevent that error from happening 🤔
What do you think ?
Thanks !
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.