@graphql-hive/cli
Version:
A CLI util to manage and control your GraphQL Hive
274 lines • 9.74 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const core_1 = require("@oclif/core");
const base_command_1 = tslib_1.__importDefault(require("../../base-command"));
const gql_1 = require("../../gql");
const config_1 = require("../../helpers/config");
const git_1 = require("../../helpers/git");
const schema_1 = require("../../helpers/schema");
const schemaCheckMutation = (0, gql_1.graphql)(/* GraphQL */ `
mutation schemaCheck($input: SchemaCheckInput!, $usesGitHubApp: Boolean!) {
schemaCheck(input: $input) {
__typename
... on SchemaCheckSuccess @skip(if: $usesGitHubApp) {
valid
initial
warnings {
nodes {
message
source
line
column
}
total
}
changes {
nodes {
message(withSafeBasedOnUsageNote: false)
criticality
isSafeBasedOnUsage
approval {
approvedBy {
id
displayName
}
}
}
total
...RenderChanges_schemaChanges
}
schemaCheck {
webUrl
}
}
... on SchemaCheckError @skip(if: $usesGitHubApp) {
valid
changes {
nodes {
message(withSafeBasedOnUsageNote: false)
criticality
isSafeBasedOnUsage
}
total
...RenderChanges_schemaChanges
}
warnings {
nodes {
message
source
line
column
}
total
}
errors {
nodes {
message
}
total
}
schemaCheck {
webUrl
}
}
... on GitHubSchemaCheckSuccess @include(if: $usesGitHubApp) {
message
}
... on GitHubSchemaCheckError @include(if: $usesGitHubApp) {
message
}
}
}
`);
class SchemaCheck extends base_command_1.default {
async run() {
var _a, _b, _c;
try {
const { flags, args } = await this.parse(SchemaCheck);
await this.require(flags);
const service = flags.service;
const forceSafe = flags.forceSafe;
const usesGitHubApp = flags.github === true;
const endpoint = this.ensure({
key: 'registry.endpoint',
args: flags,
legacyFlagName: 'registry',
defaultValue: config_1.graphqlEndpoint,
env: 'HIVE_REGISTRY',
});
const file = args.file;
const accessToken = this.ensure({
key: 'registry.accessToken',
args: flags,
legacyFlagName: 'token',
env: 'HIVE_TOKEN',
});
const sdl = await (0, schema_1.loadSchema)('introspection', file);
const git = await (0, git_1.gitInfo)(() => {
// noop
});
const commit = flags.commit || (git === null || git === void 0 ? void 0 : git.commit);
const author = flags.author || (git === null || git === void 0 ? void 0 : git.author);
if (typeof sdl !== 'string' || sdl.length === 0) {
throw new core_1.Errors.CLIError('Schema seems empty');
}
let github = null;
if (usesGitHubApp) {
if (!commit) {
throw new core_1.Errors.CLIError(`Couldn't resolve commit sha required for GitHub Application`);
}
if (!git.repository) {
throw new core_1.Errors.CLIError(`Couldn't resolve git repository required for GitHub Application`);
}
if (!git.pullRequestNumber) {
this.warn("Could not resolve pull request number. Are you running this command on a 'pull_request' event?\n" +
'See https://the-guild.dev/graphql/hive/docs/other-integrations/ci-cd#github-workflow-for-ci');
}
github = {
commit: commit,
repository: git.repository,
pullRequestNumber: git.pullRequestNumber,
};
}
const result = await this.registryApi(endpoint, accessToken).request({
operation: schemaCheckMutation,
variables: {
input: {
service,
sdl: (0, schema_1.minifySchema)(sdl),
github,
meta: !!commit && !!author
? {
commit,
author,
}
: null,
contextId: (_a = flags.contextId) !== null && _a !== void 0 ? _a : undefined,
},
usesGitHubApp,
},
});
if (result.schemaCheck.__typename === 'SchemaCheckSuccess') {
const changes = result.schemaCheck.changes;
if (result.schemaCheck.initial) {
this.success('Schema registry is empty, nothing to compare your schema with.');
}
else if (!(changes === null || changes === void 0 ? void 0 : changes.total)) {
this.success('No changes');
}
else {
schema_1.renderChanges.call(this, changes);
this.log('');
}
const warnings = result.schemaCheck.warnings;
if (warnings === null || warnings === void 0 ? void 0 : warnings.total) {
schema_1.renderWarnings.call(this, warnings);
this.log('');
}
if ((_b = result.schemaCheck.schemaCheck) === null || _b === void 0 ? void 0 : _b.webUrl) {
this.log(`View full report:\n${result.schemaCheck.schemaCheck.webUrl}`);
}
}
else if (result.schemaCheck.__typename === 'SchemaCheckError') {
const changes = result.schemaCheck.changes;
const errors = result.schemaCheck.errors;
const warnings = result.schemaCheck.warnings;
schema_1.renderErrors.call(this, errors);
if (warnings === null || warnings === void 0 ? void 0 : warnings.total) {
schema_1.renderWarnings.call(this, warnings);
this.log('');
}
if (changes && changes.total) {
this.log('');
schema_1.renderChanges.call(this, changes);
}
if ((_c = result.schemaCheck.schemaCheck) === null || _c === void 0 ? void 0 : _c.webUrl) {
this.log('');
this.log(`View full report:\n${result.schemaCheck.schemaCheck.webUrl}`);
}
this.log('');
if (forceSafe) {
this.success('Breaking changes were expected (forced)');
}
else {
this.exit(1);
}
}
else if (result.schemaCheck.__typename === 'GitHubSchemaCheckSuccess') {
this.success(result.schemaCheck.message);
}
else {
this.error(result.schemaCheck.message);
}
}
catch (error) {
if (error instanceof core_1.Errors.ExitError) {
throw error;
}
else {
this.fail('Failed to check schema');
this.handleFetchError(error);
}
}
}
}
SchemaCheck.description = 'checks schema';
SchemaCheck.flags = {
service: core_1.Flags.string({
description: 'service name (only for distributed schemas)',
}),
'registry.endpoint': core_1.Flags.string({
description: 'registry endpoint',
}),
/** @deprecated */
registry: core_1.Flags.string({
description: 'registry address',
deprecated: {
message: 'use --registry.endpoint instead',
version: '0.21.0',
},
}),
'registry.accessToken': core_1.Flags.string({
description: 'registry access token',
}),
/** @deprecated */
token: core_1.Flags.string({
description: 'api token',
deprecated: {
message: 'use --registry.accessToken instead',
version: '0.21.0',
},
}),
forceSafe: core_1.Flags.boolean({
description: 'mark the check as safe, breaking changes are expected',
}),
github: core_1.Flags.boolean({
description: 'Connect with GitHub Application',
default: false,
}),
require: core_1.Flags.string({
description: 'Loads specific require.extensions before running the codegen and reading the configuration',
default: [],
multiple: true,
}),
author: core_1.Flags.string({
description: 'Author of the change',
}),
commit: core_1.Flags.string({
description: 'Associated commit sha',
}),
contextId: core_1.Flags.string({
description: 'Context ID for grouping the schema check.',
}),
};
SchemaCheck.args = {
file: core_1.Args.string({
name: 'file',
required: true,
description: 'Path to the schema file(s)',
hidden: false,
}),
};
exports.default = SchemaCheck;
//# sourceMappingURL=check.js.map