UNPKG

@graphql-codegen/graphql-modules-preset

Version:

GraphQL Code Generator preset for modularized schema

114 lines (113 loc) 5.84 kB
import { join, relative, resolve } from 'path'; import { BaseVisitor, getConfigValue } from '@graphql-codegen/visitor-plugin-common'; import { concatAST, isScalarType } from 'graphql'; import { buildModule } from './builder.js'; import { groupSourcesByModule, isGraphQLPrimitive, normalize, stripFilename } from './utils.js'; export const preset = { buildGeneratesSection: options => { var _a; const { baseOutputDir } = options; const { baseTypesPath, encapsulateModuleTypes } = options.presetConfig; const useGraphQLModules = getConfigValue(options === null || options === void 0 ? void 0 : options.presetConfig.useGraphQLModules, true); const requireRootResolvers = getConfigValue(options === null || options === void 0 ? void 0 : options.presetConfig.requireRootResolvers, false); const useTypeImports = getConfigValue(options === null || options === void 0 ? void 0 : options.config.useTypeImports, false) || false; const cwd = resolve(options.presetConfig.cwd || process.cwd()); const importTypesNamespace = options.presetConfig.importTypesNamespace || 'Types'; if (!baseTypesPath) { throw new Error(`Preset "graphql-modules" requires you to specify "baseTypesPath" configuration and point it to your base types file (generated by "typescript" plugin)!`); } if (!((_a = options.schemaAst) === null || _a === void 0 ? void 0 : _a.extensions.sources)) { throw new Error(`Preset "graphql-modules" requires to use GraphQL SDL`); } const extensions = options.schemaAst.extensions; const sourcesByModuleMap = groupSourcesByModule(extensions.extendedSources, baseOutputDir); const modules = Object.keys(sourcesByModuleMap); const baseVisitor = new BaseVisitor(options.config, {}); // One file with an output from all plugins const baseOutput = { filename: resolve(cwd, baseOutputDir, baseTypesPath), schema: options.schema, documents: options.documents, plugins: [ ...options.plugins, { 'modules-exported-scalars': {}, }, ], pluginMap: { ...options.pluginMap, 'modules-exported-scalars': { plugin: schema => { const typeMap = schema.getTypeMap(); return Object.keys(typeMap) .map(t => { if (t && typeMap[t] && isScalarType(typeMap[t]) && !isGraphQLPrimitive(t)) { const convertedName = baseVisitor.convertName(t); return `export type ${convertedName} = Scalars["${t}"];`; } return null; }) .filter(Boolean) .join('\n'); }, }, }, config: { ...options.config, enumsAsTypes: true, }, schemaAst: options.schemaAst, }; const baseTypesFilename = baseTypesPath.replace(/\.(js|ts|d.ts)$/, ''); const baseTypesDir = stripFilename(baseOutput.filename); // One file per each module const outputs = modules.map(moduleName => { const filename = resolve(cwd, baseOutputDir, moduleName, options.presetConfig.filename); const dirpath = stripFilename(filename); const relativePath = relative(dirpath, baseTypesDir); const importPath = options.presetConfig.importBaseTypesFrom || normalize(join(relativePath, baseTypesFilename)); const sources = sourcesByModuleMap[moduleName]; const moduleDocument = concatAST(sources.map(source => source.document)); const shouldDeclare = filename.endsWith('.d.ts'); return { filename, schema: options.schema, documents: [], plugins: [ ...options.plugins.filter(p => typeof p === 'object' && Boolean(p.add)), { 'graphql-modules-plugin': {}, }, ], pluginMap: { ...options.pluginMap, 'graphql-modules-plugin': { plugin: schema => { var _a, _b, _c; return buildModule(moduleName, moduleDocument, { importNamespace: importTypesNamespace, importPath, encapsulate: encapsulateModuleTypes || 'namespace', requireRootResolvers, shouldDeclare, schema, baseVisitor, useGraphQLModules, rootTypes: [ (_a = schema.getQueryType()) === null || _a === void 0 ? void 0 : _a.name, (_b = schema.getMutationType()) === null || _b === void 0 ? void 0 : _b.name, (_c = schema.getSubscriptionType()) === null || _c === void 0 ? void 0 : _c.name, ].filter(Boolean), useTypeImports, }); }, }, }, config: options.config, schemaAst: options.schemaAst, }; }); return [baseOutput].concat(outputs); }, }; export default preset;