cjoudrey / graphql-schema-linter

Validate GraphQL schema definitions against a set of rules

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Custom rules are not working

scherroman opened this issue · comments

I'm trying to write my own custom rule to enforce that field names are strictly camel cased, with no successive uppercase allowed, so a field named pathName would be allowed, but pathNAME would throw an error.

However, when I run graphql-schema-linter with the custom rule passed in via --custom-rule-paths, it always succeeds regardless of whether the rule is violated in my graphql. It doesn't seem to be executing the rule at all as no console.log statements are printed, and no errors are raised even if the first and only thing i do in my rule is immediately throw an error or context.reportError.

The command I run is

graphql-schema-linter 'source/**/*.graphql' --custom-rule-paths 'source/validation/rules/fieldsAreStrictlyCamelCased.js'

and the result I see, regardless of whether my graphql violates the custom rule is:

✔ 0 errors detected

My custom rule is pretty much copy pasted from the old fields-are-camel-cased
rule before it was changed to allow successive uppercase. I only changed the imports / exports to use use commonjs instead of es6 modules since es6 modules would need translation with babel:

const camelCase = require('lodash.camelcase')
const { ValidationError } = require('../validationError')

function FieldsAreStrictlyCamelCased(context) {
    return {
        FieldDefinition(node, key, parent, path, ancestors) {
            const fieldName = node.name.value
            const camelCased = camelCase(fieldName)
            if (camelCased !== fieldName) {
                const parentName = ancestors[ancestors.length - 1].name.value
                context.reportError(
                    new ValidationError(
                        'fields-are-strictly-camel-cased',
                        `The field \`${parentName}.${fieldName}\` is not camel cased.`,
                        [node]
                    )
                )
            }
        }
    }
}

module.exports = { FieldsAreStrictlyCamelCased }

I've also tried a default export as well with no success:

module.exports = FieldsAreStrictlyCamelCased

The only errors thrown are if an error occurs outside my rule definition like an import error, or if I provide a non-existant path to --custom-rule-paths:

✖ Error on custom-rule-paths: There was an issue loading the specified custom rules: 'Cannot find module '../validation_error''
✖ Error on custom-rule-paths: There was an issue loading the specified custom rules: 'Cannot find module ...fieldsAreStrictlyCamelCasedxxx.js''

Is there something I'm missing?

Hey @scherroman,

I did some quick testing and it seems like the problem is that you're missing --rules FieldsAreStrictlyCamelCased when calling graphql-schema-linter.

It feels a bit weird because you'd have to specify the list of all rules you'd want to enable (including default rules provided by the library).

I forget if this was intentional or if it's a bug.

In other words, I wonder if the right default behaviour in this case is to automatically enable the rules that are included in custom rules rather than force the user to specify them and lose the default rules.

@cjoudrey thank you! It works perfectly once I specify to use FieldsAreStrictlyCamelCased in my rules. I already specify the exact rules i want to use in my package.json, so it's no issue now that I understand how it works.

Based on the custom rules documentation in the readme, I was expecting the custom rules picked up by --custom-rule-paths to be included automatically as rules, but I see now that the custom rule paths are just meant to gather custom rules, and once gathered, those rules become available to use in --rules. I have some similar confusion when attempting to use schemaPaths in my package.json so I can just run graphql-schema-linter with no inputs, which results in No valid schema input. I think some clarification in the readme could prevent future confusion.

Based on the custom rules documentation in the readme, I was expecting the custom rules picked up by --custom-rule-paths to be included automatically as rules

I think this should be the default behaviour. This is likely a bug caused by a missing test. 😄 I'll look into fixing it.

I have some similar confusion when attempting to use schemaPaths in my package.json so I can just run graphql-schema-linter with no inputs, which results in No valid schema input. I think some clarification in the readme could prevent future confusion.

That was also the intended behaviour.

Sorry that you hit these two bugs. My guess is that these two features aren't widely used which is this is just surfacing now.

I'll investigate both of these behaviours to see what's going on.

re: schemaPaths, it seems to be working for me locally:

$ ls
dummy.graphql	package.json
$ cat package.json
{
  "name": "test",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "graphql-schema-linter": {
    "schemaPaths": ["dummy.graphql"]
  }
}
$ graphql-schema-linter
/private/tmp/test/dummy.graphql
1:1 The object type `Query` is missing a description.            types-have-descriptions
1:1 A `PageInfo` object type is required as per the Relay spec.  relay-page-info-spec
2:3 The field `Query.a` is missing a description.                fields-have-descriptions

✖ 3 errors detected
$ graphql-schema-linter --version
0.2.4

That's strange, for me both graphql-schema-linter 'source/**/*.graphql' and graphql-schema-linter 'source/graphql/models/color/color.graphql' work from the command line, but running just graphql-schema-linter with any of the 3 configuration file types and schemaPaths results in No valid schema input. Both rules and customRulePaths work from the configuration files however. Changing the order of the arguments or only providing schemaPaths doesn't seem to have an effect.

My package.json:

{
    "name": "grapi-api",
    "version": "0.0.0",
    "description": "A GraphQL API",
    "scripts": {
        "lint": "eslint '{source,tests}/**/*.js' && graphql-schema-linter 'source/**/*.graphql'",
    },
    "graphql-schema-linter": {
        "schemaPaths": [
            "source/**/*.graphql"
        ],
        "rules": [
            "types-are-capitalized",
            "fields-are-camel-cased",
            "input-object-values-are-camel-cased",
            "enum-values-all-caps",
            "defined-types-are-used",
            "deprecations-have-a-reason",
            "FieldsAreStrictlyCamelCased"
        ],
        "customRulePaths": [
            "source/validation/rules/fieldsAreStrictlyCamelCased.js"
        ]
    }
}

My .graphql-schema-linterrc:

{
    "schemaPaths": ["source/**/*.graphql"],
    "rules": [        
        "types-are-capitalized",
        "fields-are-camel-cased",
        "input-object-values-are-camel-cased",
        "enum-values-all-caps",
        "defined-types-are-used",
        "deprecations-have-a-reason",
        "FieldsAreStrictlyCamelCased"
    ],
    "customRulePaths": ["source/validation/rules/fieldsAreStrictlyCamelCased.js"]
}

My graphql-schema-linter.config.js:

module.exports = {
    schemaPaths: ["source/**/*.graphql"],
    rules: [
        "types-are-capitalized",
        "fields-are-camel-cased",
        "input-object-values-are-camel-cased",
        "enum-values-all-caps",
        "defined-types-are-used",
        "deprecations-have-a-reason",
        "FieldsAreStrictlyCamelCased"
    ],
    customRulePaths: ["source/validation/rules/fieldsAreStrictlyCamelCased.js"]
}

Damn, support for schemaPaths in package.json was added in v0.2.3 and I was working out of v0.2.1! I updated to the most recent version and there's no more issues here.

Thanks for the help @cjoudrey

Damn, support for schemaPaths in package.json was added in v0.2.3 and I was working out of v0.2.1! I updated to the most recent version and there's no more issues here.

Thanks for the help @cjoudrey

😂 Yay! 🎉 Happy that there is no weird bug happening on your machine.