@graphql-inspector/validate-command
Advanced tools
Comparing version 0.0.0-canary.8127707 to 0.0.0-canary.02a53c5
207
index.cjs.js
'use strict'; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
const tslib = require('tslib'); | ||
@@ -7,5 +9,75 @@ const commands = require('@graphql-inspector/commands'); | ||
const core = require('@graphql-inspector/core'); | ||
const path = require('path'); | ||
const fs = require('fs'); | ||
const graphql = require('graphql'); | ||
function handler({ schema, documents, strictFragments, maxDepth, apollo, keepClientFields, failOnDeprecated, filter, onlyErrors, relativePaths, output, silent, }) { | ||
let invalidDocuments = core.validate(schema, documents.map((doc) => new graphql.Source(graphql.print(doc.document), doc.location)), { | ||
strictFragments, | ||
maxDepth, | ||
apollo, | ||
keepClientFields, | ||
}); | ||
if (filter) { | ||
invalidDocuments = invalidDocuments.filter((doc) => filter.some((filepath) => doc.source.name.includes(filepath))); | ||
} | ||
if (!invalidDocuments.length) { | ||
logger.Logger.success('All documents are valid'); | ||
} | ||
else { | ||
if (failOnDeprecated) { | ||
invalidDocuments = moveDeprecatedToErrors(invalidDocuments); | ||
} | ||
if (relativePaths) { | ||
invalidDocuments = useRelativePaths(invalidDocuments); | ||
} | ||
const errorsCount = countErrors(invalidDocuments); | ||
const deprecated = countDeprecated(invalidDocuments); | ||
const shouldFailProcess = errorsCount > 0; | ||
if (errorsCount) { | ||
if (!silent) { | ||
logger.Logger.log(`\nDetected ${errorsCount} invalid document${errorsCount > 1 ? 's' : ''}:\n`); | ||
} | ||
printInvalidDocuments(invalidDocuments, 'errors', true, silent); | ||
} | ||
else { | ||
logger.Logger.success('All documents are valid'); | ||
} | ||
if (deprecated && !onlyErrors) { | ||
if (!silent) { | ||
logger.Logger.info(`\nDetected ${deprecated} document${deprecated > 1 ? 's' : ''} with deprecated fields:\n`); | ||
} | ||
printInvalidDocuments(invalidDocuments, 'deprecated', false, silent); | ||
} | ||
if (output) { | ||
fs.writeFileSync(output, JSON.stringify({ | ||
status: !shouldFailProcess, | ||
documents: invalidDocuments, | ||
}, null, 2), { | ||
encoding: 'utf-8', | ||
}); | ||
} | ||
if (shouldFailProcess) { | ||
process.exit(1); | ||
} | ||
} | ||
} | ||
function moveDeprecatedToErrors(docs) { | ||
return docs.map((doc) => { | ||
var _a, _b; | ||
return ({ | ||
source: doc.source, | ||
errors: [...((_a = doc.errors) !== null && _a !== void 0 ? _a : []), ...((_b = doc.deprecated) !== null && _b !== void 0 ? _b : [])], | ||
deprecated: [], | ||
}); | ||
}); | ||
} | ||
function useRelativePaths(docs) { | ||
return docs.map((doc) => { | ||
doc.source.name = path.relative(process.cwd(), doc.source.name); | ||
return doc; | ||
}); | ||
} | ||
const index = commands.createCommand((api) => { | ||
const { loaders } = api; | ||
return { | ||
@@ -22,3 +94,3 @@ command: 'validate <documents> <schema>', | ||
.positional('documents', { | ||
describe: 'Point to docuents', | ||
describe: 'Point to documents', | ||
type: 'string', | ||
@@ -28,4 +100,4 @@ demandOption: true, | ||
.options({ | ||
d: { | ||
alias: 'deprecated', | ||
deprecated: { | ||
alias: 'd', | ||
describe: 'Fail on deprecated usage', | ||
@@ -54,55 +126,64 @@ type: 'boolean', | ||
}, | ||
filter: { | ||
describe: 'Show results only from a list of files (or file)', | ||
array: true, | ||
type: 'string', | ||
}, | ||
onlyErrors: { | ||
describe: 'Show only errors', | ||
type: 'boolean', | ||
default: false, | ||
}, | ||
relativePaths: { | ||
describe: 'Show relative paths', | ||
type: 'boolean', | ||
default: false, | ||
}, | ||
silent: { | ||
describe: 'Do not print results', | ||
type: 'boolean', | ||
default: false, | ||
}, | ||
output: { | ||
describe: 'Output JSON file', | ||
type: 'string', | ||
}, | ||
}); | ||
}, | ||
handler(args) { | ||
var _a; | ||
return tslib.__awaiter(this, void 0, void 0, function* () { | ||
const { loaders, intercept } = api; | ||
if (intercept) { | ||
intercept(args); | ||
} | ||
const { headers, token } = commands.parseGlobalArgs(args); | ||
const apollo = args.apollo || false; | ||
const aws = args.aws || false; | ||
const apolloFederation = args.federation || false; | ||
const method = ((_a = args.method) === null || _a === void 0 ? void 0 : _a.toUpperCase()) || 'POST'; | ||
const maxDepth = args.maxDepth || undefined; | ||
const strictFragments = !args.noStrictFragments; | ||
const keepClientFields = args.keepClientFields || false; | ||
const failOnDeprecated = args.deprecated; | ||
const output = args.output; | ||
const silent = args.silent || false; | ||
const relativePaths = args.relativePaths || false; | ||
const onlyErrors = args.onlyErrors || false; | ||
const schema = yield loaders.loadSchema(args.schema, { | ||
headers, | ||
token, | ||
}); | ||
method, | ||
}, apolloFederation, aws); | ||
const documents = yield loaders.loadDocuments(args.documents); | ||
const invalidDocuments = core.validate(schema, documents.map((doc) => new graphql.Source(graphql.print(doc.document), doc.location)), { | ||
strictFragments: !args.noStrictFragments, | ||
maxDepth: args.maxDepth || undefined, | ||
apollo: args.apollo || false, | ||
keepClientFields: args.keepClientFields || false, | ||
return handler({ | ||
schema, | ||
documents, | ||
apollo, | ||
maxDepth, | ||
strictFragments, | ||
keepClientFields, | ||
failOnDeprecated, | ||
filter: args.filter, | ||
silent, | ||
output, | ||
relativePaths, | ||
onlyErrors, | ||
}); | ||
if (!invalidDocuments.length) { | ||
logger.Logger.success('All documents are valid'); | ||
} | ||
else { | ||
const errorsCount = countErrors(invalidDocuments); | ||
const deprecated = countDeprecated(invalidDocuments); | ||
if (errorsCount) { | ||
logger.Logger.log(`\nDetected ${errorsCount} invalid document${errorsCount > 1 ? 's' : ''}:\n`); | ||
invalidDocuments.forEach((doc) => { | ||
if (doc.errors.length) { | ||
renderInvalidDocument(doc).forEach((line) => { | ||
logger.Logger.log(line); | ||
}); | ||
} | ||
}); | ||
} | ||
else if (!args.deprecated) { | ||
logger.Logger.success('All documents are valid'); | ||
} | ||
if (deprecated) { | ||
logger.Logger.info(`\nDetected ${deprecated} document${deprecated > 1 ? 's' : ''} with deprecated fields:\n`); | ||
invalidDocuments.forEach((doc) => { | ||
if (doc.deprecated.length) { | ||
renderDeprecatedUsageInDocument(doc, args.deprecated).forEach((line) => { | ||
logger.Logger.log(line); | ||
}); | ||
} | ||
}); | ||
} | ||
if (errorsCount || (deprecated && args.deprecated)) { | ||
process.exit(1); | ||
} | ||
} | ||
}); | ||
@@ -125,21 +206,22 @@ }, | ||
} | ||
function renderInvalidDocument(invalidDoc) { | ||
const errors = invalidDoc.errors | ||
.map((e) => ` - ${logger.bolderize(e.message)}`) | ||
.join('\n'); | ||
return [ | ||
logger.chalk.redBright('error'), | ||
`in ${invalidDoc.source.name}:\n\n`, | ||
errors, | ||
'\n\n', | ||
]; | ||
function printInvalidDocuments(invalidDocuments, listKey, isError = false, silent = false) { | ||
if (silent) { | ||
return; | ||
} | ||
invalidDocuments.forEach((doc) => { | ||
if (doc.errors.length) { | ||
renderErrors(doc.source.name, doc[listKey], isError).forEach((line) => { | ||
logger.Logger.log(line); | ||
}); | ||
} | ||
}); | ||
} | ||
function renderDeprecatedUsageInDocument(invalidDoc, isCritical = false) { | ||
const deprecated = invalidDoc.deprecated | ||
function renderErrors(sourceName, errors, isError = false) { | ||
const errorsAsString = errors | ||
.map((e) => ` - ${logger.bolderize(e.message)}`) | ||
.join('\n'); | ||
return [ | ||
isCritical ? logger.chalk.redBright('error') : logger.chalk.yellowBright('warn'), | ||
`in ${invalidDoc.source.name}:\n\n`, | ||
deprecated, | ||
isError ? logger.chalk.redBright('error') : logger.chalk.yellowBright('warn'), | ||
`in ${sourceName}:\n\n`, | ||
errorsAsString, | ||
'\n\n', | ||
@@ -149,3 +231,4 @@ ]; | ||
module.exports = index; | ||
exports.default = index; | ||
exports.handler = handler; | ||
//# sourceMappingURL=index.cjs.js.map |
@@ -1,11 +0,33 @@ | ||
import { GlobalArgs } from '@graphql-inspector/commands'; | ||
declare const _default: import("../../commands/src").CommandFactory<{}, { | ||
import { GlobalArgs, CommandFactory } from '@graphql-inspector/commands'; | ||
import { Source as DocumentSource } from '@graphql-tools/utils'; | ||
import { GraphQLSchema } from 'graphql'; | ||
export { CommandFactory }; | ||
export declare function handler({ schema, documents, strictFragments, maxDepth, apollo, keepClientFields, failOnDeprecated, filter, onlyErrors, relativePaths, output, silent, }: { | ||
schema: GraphQLSchema; | ||
documents: DocumentSource[]; | ||
failOnDeprecated: boolean; | ||
strictFragments: boolean; | ||
apollo: boolean; | ||
keepClientFields: boolean; | ||
maxDepth?: number; | ||
filter?: string[]; | ||
onlyErrors?: boolean; | ||
relativePaths?: boolean; | ||
output?: string; | ||
silent?: boolean; | ||
}): void; | ||
declare const _default: CommandFactory<{}, { | ||
schema: string; | ||
documents: string; | ||
deprecated?: boolean | undefined; | ||
deprecated: boolean; | ||
noStrictFragments: boolean; | ||
apollo?: boolean | undefined; | ||
keepClientFields?: boolean | undefined; | ||
apollo: boolean; | ||
keepClientFields: boolean; | ||
maxDepth?: number | undefined; | ||
filter?: string[] | undefined; | ||
onlyErrors?: boolean | undefined; | ||
relativePaths?: boolean | undefined; | ||
output?: string | undefined; | ||
silent?: boolean | undefined; | ||
} & GlobalArgs>; | ||
export default _default; |
203
index.esm.js
@@ -5,5 +5,75 @@ import { __awaiter } from 'tslib'; | ||
import { validate } from '@graphql-inspector/core'; | ||
import { relative } from 'path'; | ||
import { writeFileSync } from 'fs'; | ||
import { Source, print } from 'graphql'; | ||
function handler({ schema, documents, strictFragments, maxDepth, apollo, keepClientFields, failOnDeprecated, filter, onlyErrors, relativePaths, output, silent, }) { | ||
let invalidDocuments = validate(schema, documents.map((doc) => new Source(print(doc.document), doc.location)), { | ||
strictFragments, | ||
maxDepth, | ||
apollo, | ||
keepClientFields, | ||
}); | ||
if (filter) { | ||
invalidDocuments = invalidDocuments.filter((doc) => filter.some((filepath) => doc.source.name.includes(filepath))); | ||
} | ||
if (!invalidDocuments.length) { | ||
Logger.success('All documents are valid'); | ||
} | ||
else { | ||
if (failOnDeprecated) { | ||
invalidDocuments = moveDeprecatedToErrors(invalidDocuments); | ||
} | ||
if (relativePaths) { | ||
invalidDocuments = useRelativePaths(invalidDocuments); | ||
} | ||
const errorsCount = countErrors(invalidDocuments); | ||
const deprecated = countDeprecated(invalidDocuments); | ||
const shouldFailProcess = errorsCount > 0; | ||
if (errorsCount) { | ||
if (!silent) { | ||
Logger.log(`\nDetected ${errorsCount} invalid document${errorsCount > 1 ? 's' : ''}:\n`); | ||
} | ||
printInvalidDocuments(invalidDocuments, 'errors', true, silent); | ||
} | ||
else { | ||
Logger.success('All documents are valid'); | ||
} | ||
if (deprecated && !onlyErrors) { | ||
if (!silent) { | ||
Logger.info(`\nDetected ${deprecated} document${deprecated > 1 ? 's' : ''} with deprecated fields:\n`); | ||
} | ||
printInvalidDocuments(invalidDocuments, 'deprecated', false, silent); | ||
} | ||
if (output) { | ||
writeFileSync(output, JSON.stringify({ | ||
status: !shouldFailProcess, | ||
documents: invalidDocuments, | ||
}, null, 2), { | ||
encoding: 'utf-8', | ||
}); | ||
} | ||
if (shouldFailProcess) { | ||
process.exit(1); | ||
} | ||
} | ||
} | ||
function moveDeprecatedToErrors(docs) { | ||
return docs.map((doc) => { | ||
var _a, _b; | ||
return ({ | ||
source: doc.source, | ||
errors: [...((_a = doc.errors) !== null && _a !== void 0 ? _a : []), ...((_b = doc.deprecated) !== null && _b !== void 0 ? _b : [])], | ||
deprecated: [], | ||
}); | ||
}); | ||
} | ||
function useRelativePaths(docs) { | ||
return docs.map((doc) => { | ||
doc.source.name = relative(process.cwd(), doc.source.name); | ||
return doc; | ||
}); | ||
} | ||
const index = createCommand((api) => { | ||
const { loaders } = api; | ||
return { | ||
@@ -20,3 +90,3 @@ command: 'validate <documents> <schema>', | ||
.positional('documents', { | ||
describe: 'Point to docuents', | ||
describe: 'Point to documents', | ||
type: 'string', | ||
@@ -26,4 +96,4 @@ demandOption: true, | ||
.options({ | ||
d: { | ||
alias: 'deprecated', | ||
deprecated: { | ||
alias: 'd', | ||
describe: 'Fail on deprecated usage', | ||
@@ -52,55 +122,64 @@ type: 'boolean', | ||
}, | ||
filter: { | ||
describe: 'Show results only from a list of files (or file)', | ||
array: true, | ||
type: 'string', | ||
}, | ||
onlyErrors: { | ||
describe: 'Show only errors', | ||
type: 'boolean', | ||
default: false, | ||
}, | ||
relativePaths: { | ||
describe: 'Show relative paths', | ||
type: 'boolean', | ||
default: false, | ||
}, | ||
silent: { | ||
describe: 'Do not print results', | ||
type: 'boolean', | ||
default: false, | ||
}, | ||
output: { | ||
describe: 'Output JSON file', | ||
type: 'string', | ||
}, | ||
}); | ||
}, | ||
handler(args) { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const { loaders, intercept } = api; | ||
if (intercept) { | ||
intercept(args); | ||
} | ||
const { headers, token } = parseGlobalArgs(args); | ||
const apollo = args.apollo || false; | ||
const aws = args.aws || false; | ||
const apolloFederation = args.federation || false; | ||
const method = ((_a = args.method) === null || _a === void 0 ? void 0 : _a.toUpperCase()) || 'POST'; | ||
const maxDepth = args.maxDepth || undefined; | ||
const strictFragments = !args.noStrictFragments; | ||
const keepClientFields = args.keepClientFields || false; | ||
const failOnDeprecated = args.deprecated; | ||
const output = args.output; | ||
const silent = args.silent || false; | ||
const relativePaths = args.relativePaths || false; | ||
const onlyErrors = args.onlyErrors || false; | ||
const schema = yield loaders.loadSchema(args.schema, { | ||
headers, | ||
token, | ||
}); | ||
method, | ||
}, apolloFederation, aws); | ||
const documents = yield loaders.loadDocuments(args.documents); | ||
const invalidDocuments = validate(schema, documents.map((doc) => new Source(print(doc.document), doc.location)), { | ||
strictFragments: !args.noStrictFragments, | ||
maxDepth: args.maxDepth || undefined, | ||
apollo: args.apollo || false, | ||
keepClientFields: args.keepClientFields || false, | ||
return handler({ | ||
schema, | ||
documents, | ||
apollo, | ||
maxDepth, | ||
strictFragments, | ||
keepClientFields, | ||
failOnDeprecated, | ||
filter: args.filter, | ||
silent, | ||
output, | ||
relativePaths, | ||
onlyErrors, | ||
}); | ||
if (!invalidDocuments.length) { | ||
Logger.success('All documents are valid'); | ||
} | ||
else { | ||
const errorsCount = countErrors(invalidDocuments); | ||
const deprecated = countDeprecated(invalidDocuments); | ||
if (errorsCount) { | ||
Logger.log(`\nDetected ${errorsCount} invalid document${errorsCount > 1 ? 's' : ''}:\n`); | ||
invalidDocuments.forEach((doc) => { | ||
if (doc.errors.length) { | ||
renderInvalidDocument(doc).forEach((line) => { | ||
Logger.log(line); | ||
}); | ||
} | ||
}); | ||
} | ||
else if (!args.deprecated) { | ||
Logger.success('All documents are valid'); | ||
} | ||
if (deprecated) { | ||
Logger.info(`\nDetected ${deprecated} document${deprecated > 1 ? 's' : ''} with deprecated fields:\n`); | ||
invalidDocuments.forEach((doc) => { | ||
if (doc.deprecated.length) { | ||
renderDeprecatedUsageInDocument(doc, args.deprecated).forEach((line) => { | ||
Logger.log(line); | ||
}); | ||
} | ||
}); | ||
} | ||
if (errorsCount || (deprecated && args.deprecated)) { | ||
process.exit(1); | ||
} | ||
} | ||
}); | ||
@@ -123,21 +202,22 @@ }, | ||
} | ||
function renderInvalidDocument(invalidDoc) { | ||
const errors = invalidDoc.errors | ||
.map((e) => ` - ${bolderize(e.message)}`) | ||
.join('\n'); | ||
return [ | ||
chalk.redBright('error'), | ||
`in ${invalidDoc.source.name}:\n\n`, | ||
errors, | ||
'\n\n', | ||
]; | ||
function printInvalidDocuments(invalidDocuments, listKey, isError = false, silent = false) { | ||
if (silent) { | ||
return; | ||
} | ||
invalidDocuments.forEach((doc) => { | ||
if (doc.errors.length) { | ||
renderErrors(doc.source.name, doc[listKey], isError).forEach((line) => { | ||
Logger.log(line); | ||
}); | ||
} | ||
}); | ||
} | ||
function renderDeprecatedUsageInDocument(invalidDoc, isCritical = false) { | ||
const deprecated = invalidDoc.deprecated | ||
function renderErrors(sourceName, errors, isError = false) { | ||
const errorsAsString = errors | ||
.map((e) => ` - ${bolderize(e.message)}`) | ||
.join('\n'); | ||
return [ | ||
isCritical ? chalk.redBright('error') : chalk.yellowBright('warn'), | ||
`in ${invalidDoc.source.name}:\n\n`, | ||
deprecated, | ||
isError ? chalk.redBright('error') : chalk.yellowBright('warn'), | ||
`in ${sourceName}:\n\n`, | ||
errorsAsString, | ||
'\n\n', | ||
@@ -148,2 +228,3 @@ ]; | ||
export default index; | ||
export { handler }; | ||
//# sourceMappingURL=index.esm.js.map |
{ | ||
"name": "@graphql-inspector/validate-command", | ||
"version": "0.0.0-canary.8127707", | ||
"version": "0.0.0-canary.02a53c5", | ||
"description": "Validate Documents in GraphQL Inspector", | ||
@@ -10,5 +10,5 @@ "sideEffects": false, | ||
"dependencies": { | ||
"@graphql-inspector/commands": "0.0.0-canary.8127707", | ||
"@graphql-inspector/core": "0.0.0-canary.8127707", | ||
"@graphql-inspector/logger": "0.0.0-canary.8127707", | ||
"@graphql-inspector/commands": "0.0.0-canary.02a53c5", | ||
"@graphql-inspector/core": "0.0.0-canary.02a53c5", | ||
"@graphql-inspector/logger": "0.0.0-canary.02a53c5", | ||
"tslib": "^2.0.0" | ||
@@ -15,0 +15,0 @@ }, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
50657
479
2
1
116
+ Added@graphql-inspector/commands@0.0.0-canary.02a53c5(transitive)
+ Added@graphql-inspector/config@0.0.0-canary.02a53c5(transitive)
+ Added@graphql-inspector/core@0.0.0-canary.02a53c5(transitive)
+ Added@graphql-inspector/loaders@0.0.0-canary.02a53c5(transitive)
+ Added@graphql-inspector/logger@0.0.0-canary.02a53c5(transitive)
+ Addedchalk@4.1.1(transitive)
+ Addedci-info@3.9.0(transitive)
+ Addedcliui@7.0.4(transitive)
+ Addeddependency-graph@0.11.0(transitive)
+ Addedescalade@3.2.0(transitive)
+ Addedis-unicode-supported@0.1.0(transitive)
+ Addedlog-symbols@4.1.0(transitive)
+ Addedobject-inspect@1.10.3(transitive)
+ Addedstd-env@2.3.0(transitive)
+ Addedwrap-ansi@7.0.0(transitive)
+ Addedy18n@5.0.8(transitive)
+ Addedyargs@17.0.1(transitive)
+ Addedyargs-parser@20.2.9(transitive)
- Removed@graphql-inspector/commands@0.0.0-canary.8127707(transitive)
- Removed@graphql-inspector/config@0.0.0-canary.8127707(transitive)
- Removed@graphql-inspector/core@0.0.0-canary.8127707(transitive)
- Removed@graphql-inspector/loaders@0.0.0-canary.8127707(transitive)
- Removed@graphql-inspector/logger@0.0.0-canary.8127707(transitive)
- Removed@graphql-tools/utils@6.2.4(transitive)
- Removedcamel-case@4.1.1(transitive)
- Removedcamelcase@5.3.1(transitive)
- Removedchalk@4.0.0(transitive)
- Removedci-info@1.6.0(transitive)
- Removedcliui@6.0.0(transitive)
- Removeddecamelize@1.2.0(transitive)
- Removeddependency-graph@0.9.0(transitive)
- Removedfind-up@4.1.0(transitive)
- Removedlocate-path@5.0.0(transitive)
- Removedlog-symbols@4.0.0(transitive)
- Removedp-limit@2.3.0(transitive)
- Removedp-locate@4.1.0(transitive)
- Removedp-try@2.2.0(transitive)
- Removedpath-exists@4.0.0(transitive)
- Removedrequire-main-filename@2.0.0(transitive)
- Removedset-blocking@2.0.0(transitive)
- Removedstd-env@2.2.1(transitive)
- Removedtslib@1.14.1(transitive)
- Removedwhich-module@2.0.1(transitive)
- Removedwrap-ansi@6.2.0(transitive)
- Removedy18n@4.0.3(transitive)
- Removedyargs@15.3.1(transitive)
- Removedyargs-parser@18.1.3(transitive)