UNPKG

@graphql-codegen/near-operation-file-preset

Version:

GraphQL Code Generator preset for generating operation code near the operation file

143 lines (142 loc) 7.13 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.preset = exports.resolveDocumentImports = void 0; const tslib_1 = require("tslib"); const path_1 = require("path"); const graphql_1 = require("graphql"); const add_1 = tslib_1.__importDefault(require("@graphql-codegen/add")); const visitor_plugin_common_1 = require("@graphql-codegen/visitor-plugin-common"); const resolve_document_imports_js_1 = require("./resolve-document-imports.js"); Object.defineProperty(exports, "resolveDocumentImports", { enumerable: true, get: function () { return resolve_document_imports_js_1.resolveDocumentImports; } }); const utils_js_1 = require("./utils.js"); exports.preset = { buildGeneratesSection: options => { var _a; const schemaObject = options.schemaAst ? options.schemaAst : (0, graphql_1.buildASTSchema)(options.schema, options.config); const baseDir = options.presetConfig.cwd || process.cwd(); const fileName = options.presetConfig.fileName || ''; const extension = options.presetConfig.extension || '.generated.ts'; const folder = options.presetConfig.folder || ''; const importTypesNamespace = options.presetConfig.importTypesNamespace || 'Types'; const importAllFragmentsFrom = options.presetConfig.importAllFragmentsFrom || null; const { baseTypesPath } = options.presetConfig; if (!baseTypesPath) { throw new Error(`Preset "near-operation-file" requires you to specify "baseTypesPath" configuration and point it to your base types file (generated by "typescript" plugin)!`); } const shouldAbsolute = !baseTypesPath.startsWith('~'); const pluginMap = { ...options.pluginMap, add: add_1.default, }; const sources = (0, resolve_document_imports_js_1.resolveDocumentImports)(options, schemaObject, { baseDir, generateFilePath(location) { const newFilePath = (0, utils_js_1.defineFilepathSubfolder)(location, folder); return (0, utils_js_1.appendFileNameToFilePath)(newFilePath, fileName, extension); }, schemaTypesSource: { path: shouldAbsolute ? (0, path_1.join)(options.baseOutputDir, baseTypesPath) : baseTypesPath, namespace: importTypesNamespace, }, typesImport: (_a = options.config.useTypeImports) !== null && _a !== void 0 ? _a : false, }, (0, visitor_plugin_common_1.getConfigValue)(options.config.dedupeFragments, false)); const filePathsMap = new Map(); for (const source of sources) { let record = filePathsMap.get(source.filename); if (record === undefined) { record = { importStatements: new Set(), documents: [], externalFragments: [], fragmentImports: [], }; filePathsMap.set(source.filename, record); } for (const importStatement of source.importStatements) { record.importStatements.add(importStatement); } record.documents.push(...source.documents); record.externalFragments.push(...source.externalFragments); record.fragmentImports.push(...source.fragmentImports); } const artifacts = []; for (const [filename, record] of filePathsMap.entries()) { let fragmentImportsArr = record.fragmentImports; if (importAllFragmentsFrom) { fragmentImportsArr = record.fragmentImports.map(t => { const newImportSource = typeof importAllFragmentsFrom === 'string' ? { ...t.importSource, path: importAllFragmentsFrom } : importAllFragmentsFrom(t.importSource, filename); return { ...t, importSource: newImportSource || t.importSource, }; }); } // Merge multiple fragment imports from the same file const fragmentImportsByImportSource = {}; fragmentImportsArr.forEach(fi => { if (!fragmentImportsByImportSource[fi.importSource.path]) { fragmentImportsByImportSource[fi.importSource.path] = fi; } else { const mergedIdentifiersByName = {}; fragmentImportsByImportSource[fi.importSource.path].importSource.identifiers.forEach(identifier => { mergedIdentifiersByName[identifier.name] = identifier; }); fi.importSource.identifiers.forEach(identifier => { mergedIdentifiersByName[identifier.name] = identifier; }); fragmentImportsByImportSource[fi.importSource.path].importSource.identifiers = Object.values(mergedIdentifiersByName); } }); fragmentImportsArr = Object.values(fragmentImportsByImportSource); const plugins = [ // TODO/NOTE I made globalNamespace include schema types - is that correct? ...(options.config.globalNamespace ? [] : Array.from(record.importStatements).map(importStatement => ({ add: { content: importStatement }, }))), ...options.plugins, ]; const config = { ...options.config, // This is set here in order to make sure the fragment spreads sub types // are exported from operations file exportFragmentSpreadSubTypes: true, namespacedImportName: importTypesNamespace, externalFragments: record.externalFragments, fragmentImports: fragmentImportsArr, }; const document = { kind: graphql_1.Kind.DOCUMENT, definitions: [] }; const combinedSource = { rawSDL: '', document, location: record.documents[0].location, }; for (const source of record.documents) { combinedSource.rawSDL += source.rawSDL; combinedSource.document.definitions.push(...source.document.definitions); } artifacts.push({ ...options, filename, documents: [combinedSource], plugins, pluginMap, config, schema: options.schema, schemaAst: schemaObject, skipDocumentsValidation: typeof options.config.skipDocumentsValidation === 'undefined' ? { skipDuplicateValidation: true } : options.config.skipDocumentsValidation, }); } return artifacts; }, }; exports.default = exports.preset;