Closed mac2000 closed 3 years ago
Hey @mac2000, thanks for opening this issue.
Sorry for the late reply.
At this time this is not possible, however, have you considered using --stdin
instead of using a tempfile?
I'm not familiar with apollo client:download-schema
but if it has a way to output to stdout, you could pipe it to graphql-schema-linter --stdin
.
Hm, nope, apollo tools does output info messages so passing /dev/stdout as a target does not solve the issue
But indeed it will work with any other tool that is able to retrieve schema from endpoint, my personal wish to have less tools around this one, so can use simple command in CI process
After a while, it seems that this one is not required anymore. In the end, we start to configure linter more and more and even create a bunch of our custom rules. As a result, we just created a dedicated repository that holds all rules and configurations and serves as a kind of wrapper around the original linter which allows us not only to download schema from URL but much more
Here is a pseudo-code to give an idea for anyone interested:
cli.js
#!/usr/bin/env node
const retrieve = require('./utils/retrieve')
const lint = require('./utils/lint')
retrieve(process.argv[2])
.then(lint)
.then(print)
.then(process.exit)
Where:
retrieve
is a function that accepts URL or path and with help of graphql-tools tries to load the schemalint
wrapper around linter (see below)lint.js
this one is blind copypasta from linter with few hardcoded configurations nothing fancy
const path = require('path')
const retrieve = require('./retrieve')
const { loadSchema } = require('graphql-schema-linter/lib/schema')
const { Configuration } = require('graphql-schema-linter/lib/configuration')
const { validateSchemaDefinition } = require('graphql-schema-linter/lib/validator')
const options = require('../graphql-schema-linter.config')
options.customRulePaths = options.customRulePaths.map(p => path.join(__dirname, '../', p))
const lint = async pathOrUrl => {
if (!pathOrUrl) {
return {
pathOrUrl: pathOrUrl,
code: 2,
message: 'Schema missing. Pass it as first argument. it should be path to a graphql file or url to graphql endpoint',
issues: [],
errors: [],
}
}
const schemaPath = await retrieve(pathOrUrl)
const schema = await loadSchema({ schemaPaths: [schemaPath] })
if (schema === null) {
return {
pathOrUrl: pathOrUrl,
code: 2,
message: 'No valid schema input.',
issues: [],
errors: [],
}
}
const configuration = new Configuration(schema, options)
const issues = configuration.validate()
if (issues.some(({ type }) => type === 'error')) {
return {
pathOrUrl: pathOrUrl,
code: 2,
message: 'There were issues with linter configuration.',
issues: issues,
errors: [],
}
}
const rules = configuration.getRules()
const errors = validateSchemaDefinition(schema, rules, configuration)
return {
pathOrUrl: pathOrUrl,
code: errors.length ? 1 : 0,
message: errors.length ? `${errors.length} errors detected` : 'Schema is valid.',
issues: issues.map(({ type, field, message }) => ({ type, field, message })),
errors: errors.map(({ ruleName, message }) => ({ rule: ruleName, message })),
}
}
module.exports = lint
So now we have everything in one place as a npm package which is used to lint all our service
@cjoudrey thank you for awesome library!
In case the project uses code first approach (e.g. there is no schema file) there is no way to lint it, will be so much easier if we could do something like
npx graphql-schema-linter http://localhost:4000
Workaround: at moment we can do something like: