Giter Club home page Giter Club logo

validation's People

Contributors

anthonyroach avatar bilalshareef avatar dependabot[bot] avatar fdawgs avatar jonnydgreen avatar lity avatar mcollina avatar sameer-coder avatar simoneb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

validation's Issues

Mercurius-codegen throw error: error TS2304: Cannot find name '_Service'.

I am using @mercuriusjs/federation and mercurius-codegen to build a subgraph. I follow implementation directed by the doc. But always get the following errors

src/__generated-types__.ts:209:33 - error TS2304: Cannot find name '_Service'.

209   _Service: ResolverTypeWrapper<_Service>;
                                    ~~~~~~~~

src/__generated-types__.ts:223:13 - error TS2304: Cannot find name '_Service'.

223   _Service: _Service;
                ~~~~~~~~

src/__generated-types__.ts:277:19 - error TS2304: Cannot find name 'Query_entitiesArgs'.

277     RequireFields<Query_entitiesArgs, "representations">
                      ~~~~~~~~~~~~~~~~~~

src/__generated-types__.ts:356:52 - error TS2304: Cannot find name '_Service'.

356     sdl?: LoaderResolver<Maybe<Scalars["String"]>, _Service, {}, TContext>;

In my code typescript is not angry anywhere.
Here is my server.ts file

import Fastify, { FastifyRequest, FastifyReply } from "fastify";
import mercurius from "mercurius";
import mercuriusCodegen from "mercurius-codegen";
import { buildFederationSchema } from "@mercuriusjs/federation";
//
import { userTypeDefs } from "./user/user.schema";
import { userResolvers } from "./user/user.resolvers";

//###########################################################################

const app = Fastify();

const PORT = 4001;

const buildContext = async (req: FastifyRequest, _reply: FastifyReply) => {
  return {
    authorization: req.headers.authorization,
  };
};

type PromiseType<T> = T extends PromiseLike<infer U> ? U : T;

declare module "mercurius" {
  interface MercuriusContext
    extends PromiseType<ReturnType<typeof buildContext>> {}
}

app.register(mercurius, {
  schema: buildFederationSchema(userTypeDefs, {
    isGateway: false,
  }),
  resolvers: userResolvers,
  context: buildContext,
});

mercuriusCodegen(app, {
  // Commonly relative to your root package.json
  targetPath: "./src/__generated-types__.ts",
  // operationsGlob: "./src/graphql/operations/*.gql",
  // codegenConfig: {
  //   loadersCustomParentTypes: {
  //     Human: "never",
  //   },
  // },
}).catch(console.error);

// Start server
app.get("/", async function (req, reply) {
  const query = "{ _service { sdl } }";
  return app.graphql(query);
});

app.listen({ port: PORT });

I don't know what is going wrong there. I cannot modify generated-types.ts file since it is generated automatically when I start the server.

Validation stop working if extendSchema is called.

As title, if I use extendSchema after registering mercurius-validation, it no longer works.

${mercuriusValidation.graphQLTypeDefs}


type Query {
  foo(page: Pagination!): Int!
}

input Pagination {
  skip: Int @constraint(minimum: 0)
  take: Int @constraint(minimum: 1)
}
await fastify.register(mercurius, {
    schema,
    resolvers,
    path: "/graphql",
    graphiql: false
  });
await fastify.register(mercuriusValidation);

// From another plugin
fastify.graphql.extendSchema(schema);

Array or null validation error

UPD. Found a workaround by setting directiveValidation: false, in my case it doesn't matter as I don't use directive mercurius validation.

For gql type CreateInput args nums and description are optional, so we can pass { nums: null, description: null } in CreateInput:

input CreateInput {
    description: String
    nums: [Int!]
}

Validation:

  CreateInput : {
    nums: {
      type: 'array',
      nullable: true,
      maxItems: 10,
      uniqueItems: true,
      items: { type: 'integer', minimum: 0, maximum: 9 },
    },
   description: { type: 'string', maxLength: 1000 }
  },

For some reason I get error when { nums: null } is passed as argument while { description: null } or { nums: [] } works:

      "message": "Failed Validation on arguments for field 'Mutation.smthCreate'",
      "stack":
          ValidationError: Failed Validation on arguments for field 'Mutation.smthCreate'
              at node_modules\.pnpm\[email protected]\node_modules\mercurius-validation\lib\validators\validator.js:32:15
              at executeField (node_modules\.pnpm\[email protected]\node_modules\graphql\execution\execute.js:481:20)
              at node_modules\.pnpm\[email protected]\node_modules\graphql\execution\execute.js:377:22
              at promiseReduce (node_modules\.pnpm\[email protected]\node_modules\graphql\jsutils\promiseReduce.js:23:9)
              at executeFieldsSerially (node_modules\.pnpm\[email protected]\node_modules\graphql\execution\execute.js:373:43)
              at executeOperation (node_modules\.pnpm\[email protected]\node_modules\graphql\execution\execute.js:347:14)
              at execute (node_modules\.pnpm\[email protected]\node_modules\graphql\execution\execute.js:136:20)
              at Object.fastifyGraphQl [as graphql] (node_modules\.pnpm\[email protected][email protected]\node_modules\mercurius\index.js:654:29)
              at _Reply.graphql (node_modules\.pnpm\[email protected][email protected]\node_modules\mercurius\index.js:340:16)
              at executeQuery (node_modules\.pnpm\[email protected][email protected]\node_modules\mercurius\lib\routes.js:224:18)
      "path": [
        "smthCreate"
      ],
      "locations": [
        {
          "line": 3,
          "column": 3
        }
      ],
      "extensions": {
        "name": "ValidationError",
        "details": [
          {
            "instancePath": "/input/nums",
            "schemaPath": "https://mercurius.dev/validation/CreateInput/properties/nums/type",
            "keyword": "type",
            "params": {
              "type": "array"
            },
            "message": "must be array",
            "schema": "array",
            "parentSchema": {
              "type": "array",
              "maxItems": 10,
              "uniqueItems": true,
              "items": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9
              },
              "$id": "https://mercurius.dev/validation/CreateInput/nums"
            },
            "data": null
          }
        ]
      }
    }

Basic implementation

Hey! Opening up an issue here to discuss a basic initial implementation of the plugin off the back of: mercurius-js/mercurius#509

Current state of play:

@mcollina when you discussed with @simone-sanfratello about writing a validation plugin, did you talk about any alternative approaches that could be worth looking at?

Customizable inferJSONSchemaType

Make it able to add custom scalar inferring types, so far it only support 3 types

GraphQLString <=> { type: 'string' }
GraphQLInt <=> { type: 'integer' }
GraphQLFloat <=> { type: 'number' }

Validation failures from constraints result in a 500 status code rather than a 400 status code

Validation errors mean the client sent something invalid, so they should result in a 400 status code but instead they result in a 500 status code.

Library versions:

  • mercurius 10.0.0
  • fastify 4.1.0
  • mercurius-validation 2.0.2

Example:

HTTP/1.1 500 Internal Server Error
cache-control: no-cache
content-type: application/json; charset=utf-8
content-length: 605
Date: Wed, 29 Jun 2022 19:36:33 GMT
Connection: close

{
  "errors": [
    {
      "message": "Failed Validation on arguments for field 'Query.uploadFile'",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "uploadFile"
      ],
      "extensions": {
        "name": "ValidationError",
        "code": "MER_VALIDATION_ERR_FAILED_VALIDATION",
        "details": [
          {
            "instancePath": "/key/name",
            "schemaPath": "https://mercurius.dev/validation/FileKey/properties/name/pattern",
            "keyword": "pattern",
            "params": {
              "pattern": "^[^/]+$"
            },
            "message": "must match pattern \"^[^/]+$\"",
            "schema": "^[^/]+$",
            "parentSchema": {
              "pattern": "^[^/]+$",
              "type": "string",
              "$id": "https://mercurius.dev/validation/FileKey/name"
            },
            "data": "foo/icon.png"
          }
        ]
      }
    }
  ],
  "data": null
}

mercurius-validation doesn't support nullable type correctly

According to GraphQL spec optional input values (that is, the one without exclamation mark) can receive a null value that is different than not providing any input (see http://spec.graphql.org/October2021/#sec-Null-Value).

Mercurius supports this behaviour and will correctly transform any null value input to null.
mercurius-validation instead transforms the null value into an empty string.
This is because:

  • mercurius-validation validates all inputs, inferring the type from their scalar type in the GraphQL schema even if no directive or schema is explicitly added
  • ajv is created with the coerceType set to true

The problem is mercurius-validation is inferring the wrong type and not taking nullable types into consideration.

The inferJSONSchemaType functionion (https://github.com/mercurius-js/validation/blob/main/lib/utils.js#L38-L49) should return different json schema types based on whether the original GraphQL type was nullable or not.
I.e. { type: 'string' } for String! and { type: ['string', 'null'] } for String.
This issue may be caused by getTypeInfo (https://github.com/mercurius-js/validation/blob/main/lib/utils.js#L51-L54) which removes the nullable information from the type.

Code to reproduce the issue: https://gist.github.com/paolochiodi/93a75b1b1cd551a745b6d8d77f83e1a4
Expected behaviour: no failure
Current behaviour: returns error due to assertion failing.
Removing Mercurius-validation by commenting out line https://gist.github.com/paolochiodi/93a75b1b1cd551a745b6d8d77f83e1a4#file-index-js-L29 will make the code run

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.