UNPKG

graphqldoc

Version:
289 lines (288 loc) 12 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const path_1 = require("path"); const wrap = require("word-wrap"); const utility_1 = require("../../lib/utility"); const MAX_CODE_LEN = 80; // const MAX_COMMENT_LEN = 80; class SchemaPlugin extends utility_1.Plugin { getHeaders() { return [ '<link href="https://fonts.googleapis.com/css?family=Ubuntu+Mono:400,700" rel="stylesheet">', '<link type="text/css" rel="stylesheet" href="./assets/code.css" />', '<script src="./assets/line-link.js"></script>' ]; } getAssets() { return [ path_1.resolve(__dirname, 'assets/code.css'), path_1.resolve(__dirname, 'assets/line-link.js') ]; } getDocuments(buildForType) { this.html = new utility_1.HTML(); const code = this.code(buildForType); if (code) return [ new utility_1.DocumentSection('GraphQL Schema definition', this.html.code(code)) ]; return []; } code(buildForType) { if (!buildForType) return this.schema(this.document); const directive = this.document .directives .find((directive) => directive.name === buildForType); if (directive) return this.directive(directive); const type = this.document .types .find((type) => type.name === buildForType); if (type) { switch (type.kind) { case utility_1.SCALAR: return this.scalar(type); case utility_1.OBJECT: return this.object(type); case utility_1.INTERFACE: return this.interfaces(type); case utility_1.UNION: return this.union(type); case utility_1.ENUM: return this.enum(type); case utility_1.INPUT_OBJECT: return this.inputObject(type); } } throw new TypeError('Unexpected type: ' + buildForType); } argument(arg) { return this.html.property(arg.name) + ': ' + this.html.useIdentifier(arg.type, this.url(arg.type)) // + ' ' + this.deprecated(arg); ; } argumentLength(arg) { return arg.name.length + 1 + this.html.useIdentifierLength(arg.type); } arguments(fieldOrDirectives) { if (fieldOrDirectives.args.length === 0) { return ''; } return '(' + fieldOrDirectives.args .map((arg) => this.argument(arg)) .join(', ') + ')'; } argumentsLength(fieldOrDirectives) { if (fieldOrDirectives.args.length === 0) { return 0; } return fieldOrDirectives.args.reduce((sum, arg) => sum + this.argumentLength(arg), 2); } argumentsMultiline(fieldOrDirectives) { if (fieldOrDirectives.args.length === 0) { return []; } const maxIndex = fieldOrDirectives.args.length - 1; return fieldOrDirectives.args .map((arg, index) => { return index < maxIndex ? this.argument(arg) + ',' : this.argument(arg); }); } argumentDescription(arg) { const desc = !arg.description ? '[' + this.html.highlight('Not documented') + ']' : arg.description; return this.description(this.html.highlight(arg.name) + ': ' + desc); } argumentsDescription(fieldOrDirectives) { const argsWithDescriptions = fieldOrDirectives.args.filter(arg => arg.description); if (argsWithDescriptions.length === 0) { return []; } const reduceArguments = (descriptions, arg) => descriptions.concat(this.argumentDescription(arg)); return argsWithDescriptions .reduce(reduceArguments, [this.html.comment('Arguments')]); } deprecated(fieldOrEnumVal) { if (!fieldOrEnumVal.isDeprecated) return ''; if (!fieldOrEnumVal.deprecationReason) { return this.html.keyword('@deprecated'); } return this.html.keyword('@deprecated') + '( reason: ' + this.html.value('"' + fieldOrEnumVal.deprecationReason + '" ') + ' )'; } deprecatedLength(fieldOrEnumVal) { if (!fieldOrEnumVal.isDeprecated) return 0; if (!fieldOrEnumVal.deprecationReason) { return '@deprecated'.length; } return '@deprecated( reason: "'.length + fieldOrEnumVal.deprecationReason.length + '" )'.length; } description(description) { if (description) return wrap(description, { width: MAX_CODE_LEN }) .split('\n') .map(l => this.html.comment(l)); return []; } directive(directive) { return this.html.line(this.html.keyword('directive') + ' ' + this.html.keyword('@' + directive.name) + this.arguments(directive) + ' on ' + directive.locations.map(location => this.html.keyword(location)).join(' | ')); } enum(type) { const reduceEnumValues = (lines, enumValue) => lines .concat([''], this.description(enumValue.description), [this.html.property(enumValue.name) + this.deprecated(enumValue)]); return this.html.line(this.html.keyword('enum') + ' ' + this.html.identifier(type) + ' {') + type.enumValues .reduce(reduceEnumValues, []) .map(line => this.html.line(this.html.tab(line))) .join('') + this.html.line('}'); } field(field) { const fieldDescription = this.description(field.description); const argumentsDescription = this.argumentsDescription(field); if (fieldDescription.length > 0 && argumentsDescription.length) fieldDescription.push(this.html.comment('')); const fieldDefinition = field.args.length > 0 && this.fieldLength(field) > MAX_CODE_LEN ? // Multiline definition: // fieldName( // argumentName: ArgumentType, \n ... // ): ReturnType [@deprecated...] [ this.html.property(field.name) + '(', ...this.argumentsMultiline(field).map(l => this.html.tab(l)), '): ' + this.html.useIdentifier(field.type, this.url(field.type)) + ' ' + this.deprecated(field) ] : // Single line // fieldName(argumentName: ArgumentType): ReturnType [@deprecated...] [ this.html.property(field.name) + this.arguments(field) + ': ' + this.html.useIdentifier(field.type, this.url(field.type)) + ' ' + this.deprecated(field) ]; return [] .concat(fieldDescription) .concat(argumentsDescription) .concat(fieldDefinition) .map(line => this.html.line(this.html.tab(line))) .join(''); } fieldLength(field) { return field.name.length + this.argumentsLength(field) + ': '.length + this.html.useIdentifierLength(field) + ' '.length + this.deprecatedLength(field); } fields(type) { let fields = ''; fields += this.html.line(); for (let i = 0; i < type.fields.length; i++) { fields += this.field(type.fields[i]); fields += this.html.line(); } return fields; } inputObject(type) { return this.html.line(this.html.keyword('input') + ' ' + this.html.identifier(type) + ' {') + this.inputValues(type.inputFields) + this.html.line('}'); } inputValues(inputValues) { return inputValues .map(inputValue => this.html.line(this.html.tab(this.inputValue(inputValue)))) .join(''); } inputValue(arg) { const argDescription = this.description(arg.description); return [] .concat(argDescription) .concat([ this.html.property(arg.name) + ': ' + this.html.useIdentifier(arg.type, this.url(arg.type)) // + ' ' + this.deprecated(arg) ]) .map(line => this.html.line(this.html.tab(line))) .join(''); } interfaces(type) { return this.html.line(this.html.keyword('interface') + ' ' + this.html.identifier(type) + ' {') + this.fields(type) + this.html.line('}'); } object(type) { const interfaces = type.interfaces .map(i => this.html.useIdentifier(i, this.url(i))) .join(', '); const implement = interfaces.length === 0 ? '' : ' ' + this.html.keyword('implements') + ' ' + interfaces; return this.html.line(this.html.keyword('type') + ' ' + this.html.identifier(type) + implement + ' {') + this.fields(type) + this.html.line('}'); } scalar(type) { return this.html.line(this.html.keyword('scalar') + ' ' + this.html.identifier(type)); } schema(schema) { let definition = this.html.line(this.html.keyword('schema') + ' {'); if (schema.queryType) definition += this.html.line() + this.description(schema.queryType.description) .map(line => this.html.line(this.html.tab(line))) .join('') + this.html.line(this.html.tab(this.html.property('query') + ': ' + this.html.useIdentifier(schema.queryType, this.url(schema.queryType)))); if (schema.mutationType) definition += this.html.line() + this.description(schema.mutationType.description) .map(line => this.html.line(this.html.tab(line))) .join('') + this.html.line(this.html.tab(this.html.property('mutation') + ': ' + this.html.useIdentifier(schema.mutationType, this.url(schema.mutationType)))); if (schema.subscriptionType) definition += this.html.line() + this.description(schema.subscriptionType.description) .map(line => this.html.line(this.html.tab(line))) .join('') + this.html.line(this.html.tab(this.html.property('subscription') + ': ' + this.html.useIdentifier(schema.subscriptionType, this.url(schema.subscriptionType)))); definition += this.html.line('}'); return definition; /* .concat( schema.directives .map((directive) => { return this.html.line(this.html.comment('DIRECTIVE')) + this.description(directive.description) .map(line => this.html.line(line)) .join('') + this.code(directive.name); }), schema.types .sort((a: SchemaType, b: SchemaType) => { return order[a.kind].localeCompare(order[b.kind]); }) .map((type) => { return this.html.line(this.html.comment(type.kind)) + this.description(type.description) .map(line => this.html.line(line)) .join('') + this.code(type.name); }))*/ /* return [this.schemaDefinition(schema)] .concat( directives.map(directive => this.directive(directive)), types.map((type) => this.type(type) as string) ) .join('\n\n') + '\n';*/ } union(type) { return this.html.line(this.html.keyword('union') + ' ' + this.html.identifier(type) + ' = ' + type.possibleTypes .map(type => this.html.useIdentifier(type, this.url(type))) .join(' | ')); } } exports.default = SchemaPlugin;