UNPKG

@apollo/federation-internals

Version:
299 lines 14.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.printDirectiveDefinition = exports.printTypeDefinitionAndExtensions = exports.printType = exports.printSchema = exports.shallowOrderPrintedDefinitions = exports.orderPrintedDefinitions = exports.defaultPrintOptions = void 0; const utils_1 = require("./utils"); const values_1 = require("./values"); exports.defaultPrintOptions = { indentString: " ", definitionsOrder: ['schema', 'directives', 'types'], rootTypesOrder: ['query', 'mutation', 'subscription'], mergeTypesAndExtensions: false, showAllBuiltIns: false, noDescriptions: false, typeFilter: () => true, fieldFilter: () => true, directiveApplicationFilter: () => true, }; function orderPrintedDefinitions(options) { return { ...options, typeCompareFn: (t1, t2) => t1.name.localeCompare(t2.name), implementedInterfaceCompareFn: (t1, t2) => t1.interface.name.localeCompare(t2.interface.name), fieldCompareFn: (t1, t2) => t1.name.localeCompare(t2.name), unionMemberCompareFn: (t1, t2) => t1.type.name.localeCompare(t2.type.name), enumValueCompareFn: (t1, t2) => t1.name.localeCompare(t2.name), inputObjectFieldCompareFn: (t1, t2) => t1.name.localeCompare(t2.name), directiveCompareFn: (t1, t2) => t1.name.localeCompare(t2.name), }; } exports.orderPrintedDefinitions = orderPrintedDefinitions; function shallowOrderPrintedDefinitions(options) { return { ...options, typeCompareFn: (t1, t2) => t1.name.localeCompare(t2.name), directiveCompareFn: (t1, t2) => t1.name.localeCompare(t2.name), }; } exports.shallowOrderPrintedDefinitions = shallowOrderPrintedDefinitions; function isDefinitionOrderValid(options) { return options.definitionsOrder.length === 3 && options.definitionsOrder.indexOf('schema') >= 0 && options.definitionsOrder.indexOf('types') >= 0 && options.definitionsOrder.indexOf('directives') >= 0; } function validateOptions(options) { if (!isDefinitionOrderValid(options)) { throw new Error(`'definitionsOrder' should be a 3-element array containing 'schema', 'types' and 'directives' in the desired order (got: [${options.definitionsOrder.join(', ')}])`); } } function printSchema(schema, options = exports.defaultPrintOptions) { validateOptions(options); let directives = options.showAllBuiltIns ? schema.allDirectives() : schema.directives(); if (options.directiveDefinitionFilter) { directives = directives.filter(options.directiveDefinitionFilter); } if (options.directiveCompareFn) { directives = directives.concat().sort(options.directiveCompareFn); } let types = options.showAllBuiltIns ? schema.allTypes() : schema.types(); if (options.typeFilter) { types = types.filter(options.typeFilter); } if (options.typeCompareFn) { types = types.concat().sort(options.typeCompareFn); } const definitions = new Array(3); definitions[options.definitionsOrder.indexOf('schema')] = printSchemaDefinitionAndExtensions(schema.schemaDefinition, options); definitions[options.definitionsOrder.indexOf('directives')] = directives.map(directive => printDirectiveDefinition(directive, options)); definitions[options.definitionsOrder.indexOf('types')] = types.flatMap(type => printTypeDefinitionAndExtensions(type, options)); return definitions.flat().join('\n\n'); } exports.printSchema = printSchema; function definitionAndExtensions(element, options) { return options.mergeTypesAndExtensions ? [undefined] : [null, ...element.extensions()]; } function printSchemaDefinitionAndExtensions(schemaDefinition, options) { return printDefinitionAndExtensions(schemaDefinition, options, printSchemaDefinitionOrExtension); } function printDefinitionAndExtensions(t, options, printer) { return definitionAndExtensions(t, options) .map(ext => printer(t, options, ext)) .filter(v => v !== undefined); } function printIsExtension(extension) { return extension ? 'extend ' : ''; } function forExtension(ts, extension) { if (extension === undefined) { return ts; } return ts.filter(r => { var _a; return ((_a = r.ofExtension()) !== null && _a !== void 0 ? _a : null) === extension; }); } function orderRoots(roots, options) { return roots.concat().sort((r1, r2) => options.rootTypesOrder.indexOf(r1.rootKind) - options.rootTypesOrder.indexOf(r2.rootKind)); } function appliedDirectives(element, options, extension) { let directives = forExtension(element.appliedDirectives, extension); if (options.directiveApplicationFilter) { directives = directives.filter(options.directiveApplicationFilter); } return directives; } function printSchemaDefinitionOrExtension(schemaDefinition, options, extension) { const roots = forExtension(schemaDefinition.roots(), extension); const directives = appliedDirectives(schemaDefinition, options, extension); if (!roots.length && !directives.length) { return undefined; } if (!extension && !directives.length && isSchemaOfCommonNames(schemaDefinition)) { return undefined; } const rootEntries = orderRoots(roots, options).map((rootType) => `${options.indentString}${rootType.rootKind}: ${rootType.type}`); return printDescription(schemaDefinition, options, extension) + printIsExtension(extension) + 'schema' + printAppliedDirectives(directives, options, true, rootEntries.length !== 0) + (directives.length === 0 ? ' ' : '') + (rootEntries.length === 0 ? '' : '{\n' + rootEntries.join('\n') + '\n}'); } function isSchemaOfCommonNames(schema) { return !schema.description && schema.roots().every(r => r.isDefaultRootName()); } function printType(type, options = exports.defaultPrintOptions) { const definitionAndExtensions = printTypeDefinitionAndExtensions(type, options); (0, utils_1.assert)(definitionAndExtensions.length == 1, `Type ${type} is built from more than 1 definition or extension`); return definitionAndExtensions[0]; } exports.printType = printType; function printTypeDefinitionAndExtensions(type, options = exports.defaultPrintOptions) { switch (type.kind) { case 'ScalarType': return printDefinitionAndExtensions(type, options, printScalarDefinitionOrExtension); case 'ObjectType': return printDefinitionAndExtensions(type, options, (t, options, ext) => printFieldBasedTypeDefinitionOrExtension('type', t, options, ext)); case 'InterfaceType': return printDefinitionAndExtensions(type, options, (t, options, ext) => printFieldBasedTypeDefinitionOrExtension('interface', t, options, ext)); case 'UnionType': return printDefinitionAndExtensions(type, options, printUnionDefinitionOrExtension); case 'EnumType': return printDefinitionAndExtensions(type, options, printEnumDefinitionOrExtension); case 'InputObjectType': return printDefinitionAndExtensions(type, options, printInputDefinitionOrExtension); } } exports.printTypeDefinitionAndExtensions = printTypeDefinitionAndExtensions; function printDirectiveDefinition(directive, options = exports.defaultPrintOptions) { const locations = directive.locations.join(' | '); return `${printDescription(directive, options, null)}directive ${directive}${printArgs(directive.arguments(), options)}${directive.repeatable ? ' repeatable' : ''} on ${locations}`; } exports.printDirectiveDefinition = printDirectiveDefinition; function printAppliedDirectives(appliedDirectives, options, onNewLines = false, endWithNewLine = onNewLines) { if (appliedDirectives.length == 0) { return ""; } const joinStr = onNewLines ? '\n' + options.indentString : ' '; const directives = appliedDirectives.map(d => d.toString()).join(joinStr); return onNewLines ? '\n' + options.indentString + directives + (endWithNewLine ? '\n' : '') : ' ' + directives; } function printDescription(element, options, extension, indentation = '', firstInBlock = true) { if (extension || element.description === undefined || options.noDescriptions) { return ''; } const preferMultipleLines = element.description.length > 70; const blockString = printBlockString(element.description, '', preferMultipleLines); const prefix = indentation && !firstInBlock ? '\n' + indentation : indentation; return prefix + blockString.replace(/\n/g, '\n' + indentation) + '\n'; } function printScalarDefinitionOrExtension(type, options, extension) { const directives = appliedDirectives(type, options, extension); if (extension && !directives.length) { return undefined; } return `${printDescription(type, options, extension)}${printIsExtension(extension)}scalar ${type.name}${printAppliedDirectives(directives, options, true, false)}`; } function printImplementedInterfaces(implementations) { return implementations.length ? ' implements ' + implementations.map(i => i.interface.name).join(' & ') : ''; } function printFieldBasedTypeDefinitionOrExtension(kind, type, options, extension) { const directives = appliedDirectives(type, options, extension); let interfaces = forExtension(type.interfaceImplementations(), extension); let fields = forExtension(type.fields(), extension); if (options.fieldFilter) { fields = fields.filter(options.fieldFilter); } if (!directives.length && !interfaces.length && !fields.length && (extension || !type.preserveEmptyDefinition)) { return undefined; } if (options.implementedInterfaceCompareFn) { interfaces = interfaces.concat().sort(options.implementedInterfaceCompareFn); } if (options.fieldCompareFn) { fields = fields.concat().sort(options.fieldCompareFn); } return printDescription(type, options, extension) + printIsExtension(extension) + kind + ' ' + type + printImplementedInterfaces(interfaces) + printAppliedDirectives(directives, options, true, fields.length > 0) + (directives.length === 0 && fields.length > 0 ? ' ' : '') + printFields(fields, options); } function printUnionDefinitionOrExtension(type, options, extension) { const directives = appliedDirectives(type, options, extension); let members = forExtension(type.members(), extension); if (!directives.length && !members.length && (extension || !type.preserveEmptyDefinition)) { return undefined; } if (options.unionMemberCompareFn) { members = members.concat().sort(options.unionMemberCompareFn); } const possibleTypes = members.length ? ' = ' + members.map(m => m.type).join(' | ') : ''; return printDescription(type, options, extension) + printIsExtension(extension) + 'union ' + type + printAppliedDirectives(directives, options, true, members.length > 0) + possibleTypes; } function printEnumDefinitionOrExtension(type, options, extension) { const directives = appliedDirectives(type, options, extension); let values = forExtension(type.values, extension); if (!directives.length && !values.length && (extension || !type.preserveEmptyDefinition)) { return undefined; } if (options.enumValueCompareFn) { values = values.concat().sort(options.enumValueCompareFn); } const vals = values.map((v, i) => printDescription(v, options, extension, options.indentString, !i) + options.indentString + v + printAppliedDirectives(v.appliedDirectives, options)); return printDescription(type, options, extension) + printIsExtension(extension) + 'enum ' + type + printAppliedDirectives(directives, options, true, vals.length > 0) + (directives.length === 0 && vals.length > 0 ? ' ' : '') + printBlock(vals); } function printInputDefinitionOrExtension(type, options, extension) { const directives = appliedDirectives(type, options, extension); let fields = forExtension(type.fields(), extension); if (!directives.length && !fields.length && (extension || !type.preserveEmptyDefinition)) { return undefined; } if (options.inputObjectFieldCompareFn) { fields = fields.concat().sort(options.inputObjectFieldCompareFn); } return printDescription(type, options, extension) + printIsExtension(extension) + 'input ' + type + printAppliedDirectives(directives, options, true, fields.length > 0) + (directives.length === 0 && fields.length > 0 ? ' ' : '') + printFields(fields, options); } function printFields(fields, options) { return printBlock(fields.map((f, i) => printDescription(f, options, undefined, options.indentString, !i) + options.indentString + printField(f, options) + printAppliedDirectives(appliedDirectives(f, options), options))); } function printField(field, options) { const args = field.kind == 'FieldDefinition' ? printArgs(field.arguments(), options, options.indentString) : ''; const defaultValue = field.kind === 'InputFieldDefinition' && field.defaultValue !== undefined ? ' = ' + (0, values_1.valueToString)(field.defaultValue, field.type) : ''; return `${field.name}${args}: ${field.type}${defaultValue}`; } function printArgs(args, options, indentation = '') { if (args.length === 0) { return ''; } if (args.every(arg => !arg.description)) { return '(' + args.map(arg => printArg(arg, options)).join(', ') + ')'; } const formattedArgs = args .map((arg, i) => printDescription(arg, options, null, ' ' + indentation, !i) + ' ' + indentation + printArg(arg, options)) .join('\n'); return `(\n${formattedArgs}\n${indentation})`; } function printArg(arg, options) { return `${arg}${printAppliedDirectives(appliedDirectives(arg, options), options)}`; } function printBlock(items) { return items.length !== 0 ? '{\n' + items.join('\n') + '\n}' : ''; } function printBlockString(value, indentation = '', preferMultipleLines = false) { const isSingleLine = value.indexOf('\n') === -1; const hasLeadingSpace = value[0] === ' ' || value[0] === '\t'; const hasTrailingQuote = value[value.length - 1] === '"'; const hasTrailingSlash = value[value.length - 1] === '\\'; const printAsMultipleLines = !isSingleLine || hasTrailingQuote || hasTrailingSlash || preferMultipleLines; let result = ''; if (printAsMultipleLines && !(isSingleLine && hasLeadingSpace)) { result += '\n' + indentation; } result += indentation ? value.replace(/\n/g, '\n' + indentation) : value; if (printAsMultipleLines) { result += '\n'; } return '"""' + result.replace(/"""/g, '\\"""') + '"""'; } //# sourceMappingURL=print.js.map