UNPKG

@graphql-codegen/graphql-modules-preset

Version:

GraphQL Code Generator preset for modularized schema

203 lines (202 loc) • 6.89 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.collectUsedTypes = collectUsedTypes; exports.resolveTypeNode = resolveTypeNode; exports.isGraphQLPrimitive = isGraphQLPrimitive; exports.unique = unique; exports.withQuotes = withQuotes; exports.indent = indent; exports.buildBlock = buildBlock; exports.groupSourcesByModule = groupSourcesByModule; exports.stripFilename = stripFilename; exports.normalize = normalize; exports.pushUnique = pushUnique; exports.concatByKey = concatByKey; exports.uniqueByKey = uniqueByKey; exports.createObject = createObject; const tslib_1 = require("tslib"); const graphql_1 = require("graphql"); const parse_filepath_1 = tslib_1.__importDefault(require("parse-filepath")); const sep = '/'; /** * Searches every node to collect used types */ function collectUsedTypes(doc) { const used = []; for (const node of doc.definitions) { findRelated(node); } function markAsUsed(type) { pushUnique(used, type); } function findRelated(node) { if (node.kind === graphql_1.Kind.OBJECT_TYPE_DEFINITION || node.kind === graphql_1.Kind.OBJECT_TYPE_EXTENSION) { // Object markAsUsed(node.name.value); if (node.fields) { for (const n of node.fields) { findRelated(n); } } if (node.interfaces) { for (const n of node.interfaces) { findRelated(n); } } } else if (node.kind === graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION || node.kind === graphql_1.Kind.INPUT_OBJECT_TYPE_EXTENSION) { // Input markAsUsed(node.name.value); if (node.fields) { for (const n of node.fields) { findRelated(n); } } } else if (node.kind === graphql_1.Kind.INTERFACE_TYPE_DEFINITION || node.kind === graphql_1.Kind.INTERFACE_TYPE_EXTENSION) { // Interface markAsUsed(node.name.value); if (node.fields) { for (const n of node.fields) { findRelated(n); } } if (node.interfaces) { for (const n of node.interfaces) { findRelated(n); } } } else if (node.kind === graphql_1.Kind.UNION_TYPE_DEFINITION || node.kind === graphql_1.Kind.UNION_TYPE_EXTENSION) { // Union markAsUsed(node.name.value); if (node.types) { for (const n of node.types) { findRelated(n); } } } else if (node.kind === graphql_1.Kind.ENUM_TYPE_DEFINITION || node.kind === graphql_1.Kind.ENUM_TYPE_EXTENSION) { // Enum markAsUsed(node.name.value); } else if (node.kind === graphql_1.Kind.SCALAR_TYPE_DEFINITION || node.kind === graphql_1.Kind.SCALAR_TYPE_EXTENSION) { // Scalar if (!isGraphQLPrimitive(node.name.value)) { markAsUsed(node.name.value); } } else if (node.kind === graphql_1.Kind.INPUT_VALUE_DEFINITION) { // Argument findRelated(resolveTypeNode(node.type)); } else if (node.kind === graphql_1.Kind.FIELD_DEFINITION) { // Field findRelated(resolveTypeNode(node.type)); if (node.arguments) { for (const n of node.arguments) { findRelated(n); } } } else if (node.kind === graphql_1.Kind.NAMED_TYPE && // Named type !isGraphQLPrimitive(node.name.value)) { markAsUsed(node.name.value); } } return used; } function resolveTypeNode(node) { if (node.kind === graphql_1.Kind.LIST_TYPE) { return resolveTypeNode(node.type); } if (node.kind === graphql_1.Kind.NON_NULL_TYPE) { return resolveTypeNode(node.type); } return node; } function isGraphQLPrimitive(name) { return ['String', 'Boolean', 'ID', 'Float', 'Int'].includes(name); } function unique(val, i, all) { return i === all.indexOf(val); } function withQuotes(val) { return `'${val}'`; } function indent(size) { const space = new Array(size).fill(' ').join(''); function indentInner(val) { return val .split('\n') .map(line => `${space}${line}`) .join('\n'); } return indentInner; } function buildBlock({ name, lines }) { if (!lines.length) { return ''; } return [`${name} {`, ...lines.map(indent(2)), '};'].join('\n'); } const getRelativePath = function (filepath, basePath) { const normalizedFilepath = normalize(filepath); const normalizedBasePath = ensureStartsWithSeparator(normalize(ensureEndsWithSeparator(basePath))); const [, relativePath] = normalizedFilepath.split(normalizedBasePath); return relativePath; }; function groupSourcesByModule(sources, basePath) { const grouped = {}; for (const source of sources) { const relativePath = getRelativePath(source.location, basePath); if (relativePath) { // PERF: we could guess the module by matching source.location with a list of already resolved paths const mod = extractModuleDirectory(source.location, basePath); grouped[mod] ||= []; grouped[mod].push(source); } } return grouped; } function extractModuleDirectory(filepath, basePath) { const relativePath = getRelativePath(filepath, basePath); const [moduleDirectory] = relativePath.split(sep); return moduleDirectory; } function stripFilename(path) { const parsedPath = (0, parse_filepath_1.default)(path); return normalize(parsedPath.dir); } function normalize(path) { return path.replace(/\\/g, '/'); } function ensureEndsWithSeparator(path) { return path.endsWith(sep) ? path : path + sep; } function ensureStartsWithSeparator(path) { return path.startsWith('.') ? path.replace(/^(..\/)|(.\/)/, '/') : path.startsWith('/') ? path : '/' + path; } /** * Pushes an item to a list only if the list doesn't include the item */ function pushUnique(list, item) { if (!list.includes(item)) { list.push(item); } } function concatByKey(left, right, key) { // Remove duplicate, if an element is in right & left, it will be only once in the returned array. return [...new Set([...left[key], ...right[key]])]; } function uniqueByKey(left, right, key) { return left[key].filter(item => !right[key].includes(item)); } function createObject(keys, valueFn) { const obj = {}; for (const key of keys) { obj[key] = valueFn(key); } return obj; }