UNPKG

@graphql-hive/cli

Version:

A CLI util to manage and control your GraphQL Hive

234 lines • 9.61 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const fs_1 = require("fs"); const graphql_1 = require("graphql"); const utils_1 = require("@graphql-tools/utils"); const core_1 = require("@oclif/core"); const base_command_1 = tslib_1.__importDefault(require("../../base-command")); const config_1 = require("../../helpers/config"); const git_1 = require("../../helpers/git"); const schema_1 = require("../../helpers/schema"); const validation_1 = require("../../helpers/validation"); class SchemaPublish extends base_command_1.default { resolveMetadata(metadata) { if (!metadata) { return; } try { JSON.parse(metadata); // If we are able to parse it, it means it's a valid JSON, let's use it as-is return metadata; } catch (e) { // If we can't parse it, we can try to load it from FS const exists = (0, fs_1.existsSync)(metadata); if (!exists) { throw new Error(`Failed to load metadata from "${metadata}": Please specify a path to an existing file, or a string with valid JSON.`); } try { const fileContent = (0, fs_1.readFileSync)(metadata, 'utf-8'); JSON.parse(fileContent); return fileContent; } catch (e) { throw new Error(`Failed to load metadata from file "${metadata}": Please make sure the file is readable and contains a valid JSON`); } } } async run() { var _a; try { const { flags, args } = await this.parse(SchemaPublish); await this.require(flags); const registry = this.ensure({ key: 'registry', args: flags, defaultValue: config_1.graphqlEndpoint, env: 'HIVE_REGISTRY', }); const service = this.maybe('service', flags); const url = this.maybe('url', flags); const file = args.file; const token = this.ensure({ key: 'token', args: flags, env: 'HIVE_TOKEN', }); const force = this.maybe('force', flags); const experimental_acceptBreakingChanges = this.maybe('experimental_acceptBreakingChanges', flags); const metadata = this.resolveMetadata(this.maybe('metadata', flags)); const usesGitHubApp = this.maybe('github', flags) === true; let commit = flags.commit; let author = flags.author; if (!commit || !author) { const git = await (0, git_1.gitInfo)(() => { this.warn(`No git information found. Couldn't resolve author and commit.`); }); if (!commit) { commit = git.commit; } if (!author) { author = git.author; } } if (!author) { throw new core_1.Errors.CLIError(`Missing "author"`); } if (!commit) { throw new core_1.Errors.CLIError(`Missing "commit"`); } let sdl; try { const rawSdl = await (0, schema_1.loadSchema)(file); (0, validation_1.invariant)(typeof rawSdl === 'string' && rawSdl.length > 0, 'Schema seems empty'); const transformedSDL = (0, graphql_1.print)((0, utils_1.transformCommentsToDescriptions)(rawSdl)); sdl = (0, schema_1.minifySchema)(transformedSDL); } catch (err) { if (err instanceof graphql_1.GraphQLError) { const location = (_a = err.locations) === null || _a === void 0 ? void 0 : _a[0]; const locationString = location ? ` at line ${location.line}, column ${location.column}` : ''; throw new Error(`The SDL is not valid${locationString}:\n ${err.message}`); } throw err; } const result = await this.registryApi(registry, token).schemaPublish({ input: { service, url, author, commit, sdl, force, experimental_acceptBreakingChanges: experimental_acceptBreakingChanges === true, metadata, github: usesGitHubApp, }, usesGitHubApp, }); if (result.schemaPublish.__typename === 'SchemaPublishSuccess') { const changes = result.schemaPublish.changes; if (result.schemaPublish.initial) { this.success('Published initial schema.'); } else if (result.schemaPublish.successMessage) { this.success(result.schemaPublish.successMessage); } else if (changes && changes.total === 0) { this.success('No changes. Skipping.'); } else { if (changes) { schema_1.renderChanges.call(this, changes); } this.success('Schema published'); } if (result.schemaPublish.linkToWebsite) { this.info(`Available at ${result.schemaPublish.linkToWebsite}`); } } else if (result.schemaPublish.__typename === 'SchemaPublishMissingServiceError') { this.fail(`${result.schemaPublish.missingServiceError} Please use the '--service <name>' parameter.`); this.exit(1); } else if (result.schemaPublish.__typename === 'SchemaPublishMissingUrlError') { this.fail(`${result.schemaPublish.missingUrlError} Please use the '--url <url>' parameter.`); this.exit(1); } else if (result.schemaPublish.__typename === 'SchemaPublishError') { const changes = result.schemaPublish.changes; const errors = result.schemaPublish.errors; schema_1.renderErrors.call(this, errors); if (changes && changes.total) { this.log(''); schema_1.renderChanges.call(this, changes); } this.log(''); if (!force) { this.fail('Failed to publish schema'); this.exit(1); } else { this.success('Schema published (forced)'); } if (result.schemaPublish.linkToWebsite) { this.info(`Available at ${result.schemaPublish.linkToWebsite}`); } } else if (result.schemaPublish.__typename === 'GitHubSchemaPublishSuccess') { this.success(result.schemaPublish.message); } else { this.error('message' in result.schemaPublish ? result.schemaPublish.message : 'Unknown error'); } } catch (error) { if (error instanceof core_1.Errors.ExitError) { throw error; } else { this.fail('Failed to publish schema'); this.handleFetchError(error); } } } } SchemaPublish.description = 'publishes schema'; SchemaPublish.flags = { service: core_1.Flags.string({ description: 'service name (only for distributed schemas)', }), url: core_1.Flags.string({ description: 'service url (only for distributed schemas)', }), metadata: core_1.Flags.string({ description: 'additional metadata to attach to the GraphQL schema. This can be a string with a valid JSON, or a path to a file containing a valid JSON', }), registry: core_1.Flags.string({ description: 'registry address', }), token: core_1.Flags.string({ description: 'api token', }), author: core_1.Flags.string({ description: 'author of the change', }), commit: core_1.Flags.string({ description: 'associated commit sha', }), github: core_1.Flags.boolean({ description: 'Connect with GitHub Application', default: false, }), force: core_1.Flags.boolean({ description: 'force publish even on breaking changes', default: false, deprecated: { message: '--force is enabled by default for newly created projects', }, }), experimental_acceptBreakingChanges: core_1.Flags.boolean({ description: '(experimental) accept breaking changes and mark schema as valid (only if composable)', deprecated: { message: '--experimental_acceptBreakingChanges is enabled by default for newly created projects', }, }), require: core_1.Flags.string({ description: 'Loads specific require.extensions before running the codegen and reading the configuration', default: [], multiple: true, }), }; SchemaPublish.args = [ { name: 'file', required: true, description: 'Path to the schema file(s)', hidden: false, }, ]; exports.default = SchemaPublish; //# sourceMappingURL=publish.js.map