UNPKG

@eddeee888/gcg-typescript-resolver-files

Version:

This [GraphQL Code Generator](https://www.the-guild.dev/graphql/codegen) plugin creates resolvers given GraphQL schema.

213 lines 11.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.preset = exports.presetName = void 0; const tslib_1 = require("tslib"); const path = tslib_1.__importStar(require("path")); const addPlugin = tslib_1.__importStar(require("@graphql-codegen/add")); const schemaAstPlugin = tslib_1.__importStar(require("@graphql-codegen/schema-ast")); const typeScriptPlugin = tslib_1.__importStar(require("@graphql-codegen/typescript")); const typescript_resolvers_1 = require("@graphql-codegen/typescript-resolvers"); const plugin_helpers_1 = require("@graphql-codegen/plugin-helpers"); const ts_morph_1 = require("ts-morph"); const gcg_server_config_1 = require("@eddeee888/gcg-server-config"); const parseSources_1 = require("./parseSources"); const parseGraphQLSchema_1 = require("./parseGraphQLSchema"); const generateResolverFiles_1 = require("./generateResolverFiles"); const generateTypeDefsFiles_1 = require("./generateTypeDefsFiles"); const getGraphQLObjectTypeResolversToGenerate_1 = require("./getGraphQLObjectTypeResolversToGenerate"); const addVirtualTypesFileToTsMorphProject_1 = require("./addVirtualTypesFileToTsMorphProject"); const parseTypeMappers_1 = require("./parseTypeMappers"); const validatePresetConfig_1 = require("./validatePresetConfig"); const validateAndMergeParsedConfigs_1 = require("./validateAndMergeParsedConfigs"); const normalizeAddConfigPath_1 = require("./normalizeAddConfigPath"); const utils_1 = require("./utils"); exports.presetName = '@eddeee888/gcg-typescript-resolver-files'; exports.preset = { buildGeneratesSection: (_a) => tslib_1.__awaiter(void 0, [_a], void 0, function* ({ schema, schemaAst, presetConfig: rawPresetConfig, baseOutputDir, profiler = (0, plugin_helpers_1.createNoopProfiler)(), }) { if (!schemaAst) { throw new Error('Missing schemaAst'); } const sources = schemaAst.extensions.extendedSources; if (!Array.isArray(sources) || sources.length === 0) { throw new Error('Empty Sources. Make sure schema files are parsed correctly.'); } const { add, resolverTypesPath: relativeResolverTypesPathFromBaseOutputDir, resolverRelativeTargetDir, mappersRelativeTargetDir: typeMappersRelativeTargetDir, mappersFileExtension: typeMappersFileExtension, mappersSuffix: typeMappersSuffix, resolverMainFile, resolverMainFileMode, resolverGeneration, typeDefsFilePath, typeDefsFileMode, mergeSchema, moduleNamingMode, scalarsModule, scalarsOverrides, mode, whitelistedModules, blacklistedModules, externalResolvers, typesPluginsConfig, tsMorphProjectOptions, fixObjectTypeResolvers, emitLegacyCommonJSImports, } = (0, validatePresetConfig_1.validatePresetConfig)(rawPresetConfig); const resolverTypesPath = path.posix.join(baseOutputDir, relativeResolverTypesPathFromBaseOutputDir); const normalizedAdd = (0, normalizeAddConfigPath_1.normalizeAddConfigPath)({ add, baseOutputDir }); const { sourceMap } = (0, parseSources_1.parseSources)({ sources, baseOutputDir, moduleNamingMode, }); const tsMorphProject = yield profiler.run(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () { return new ts_morph_1.Project(tsMorphProjectOptions); }), createProfilerRunName('Initialising ts-morph project')); const typeMappersMap = yield profiler.run(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () { return (0, parseTypeMappers_1.parseTypeMappers)({ sourceMap, resolverTypesPath, typeMappersRelativeTargetDir, typeMappersFileExtension, typeMappersSuffix, tsMorphProject, emitLegacyCommonJSImports, }); }), createProfilerRunName('parseTypeMappers')); const generatesSection = []; const parsedGraphQLSchemaMeta = yield profiler.run(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () { return (0, parseGraphQLSchema_1.parseGraphQLSchema)({ schemaAst, sourceMap, resolverTypesPath, scalarsModule, scalarsOverrides, typeMappersMap, mode, baseOutputDir, resolverRelativeTargetDir, whitelistedModules, blacklistedModules, }); }), createProfilerRunName('parseGraphQLSchema')); const mergedConfig = (0, validateAndMergeParsedConfigs_1.validateAndMergeParsedConfigs)({ unmanagedNonScalarResolvers: externalResolvers, parsedGraphQLSchemaMeta, }); // typescript and typescript-resolvers plugins config const resolverTypesConfig = (0, gcg_server_config_1.defineConfig)(Object.assign(Object.assign({ optionalResolveType: true, resolversNonOptionalTypename: { unionMember: true, interfaceImplementingType: true, }, namingConvention: 'keep', emitLegacyCommonJSImports, generateInternalResolversIfNeeded: { __resolveReference: true, } }, typesPluginsConfig), { scalars: mergedConfig.scalarTypes, mappers: Object.assign(Object.assign({}, mergedConfig.typeMappers), typesPluginsConfig.mappers) })); // typesSourceFile is the virtual `types.generated.ts` // This is useful when we need to do static analysis as most types come from this file // e.g. comparing mappers field type vs schema object field type const { typesSourceFile, meta: generatedTypesFileMeta } = yield profiler.run(() => (0, addVirtualTypesFileToTsMorphProject_1.addVirtualTypesFileToTsMorphProject)({ tsMorphProject, schemaAst, resolverTypesConfig, resolverTypesPath, addConfig: normalizedAdd === null || normalizedAdd === void 0 ? void 0 : normalizedAdd[resolverTypesPath], }), createProfilerRunName('addVirtualTypesFileToTsMorphProject')); const graphQLObjectTypeResolversToGenerate = yield profiler.run(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () { return fixObjectTypeResolvers.object === 'smart' ? (0, getGraphQLObjectTypeResolversToGenerate_1.getGraphQLObjectTypeResolversToGenerate)({ tsMorphProject, typesSourceFile, userDefinedSchemaObjectTypeMap: mergedConfig.userDefinedSchemaTypeMap.object, typeMappersMap, generatedTypesFileMeta, }) : {}; }), createProfilerRunName('getGraphQLObjectTypeResolversToGenerate')); const resolverTypesFilePlugins = [ { typescript: {} }, { ['typescript-resolvers']: {} }, ]; if (normalizedAdd === null || normalizedAdd === void 0 ? void 0 : normalizedAdd[resolverTypesPath]) { resolverTypesFilePlugins.push({ add: normalizedAdd[resolverTypesPath], }); } const resolverTypesFile = { filename: resolverTypesPath, pluginMap: { typescript: typeScriptPlugin, 'typescript-resolvers': { plugin: typescript_resolvers_1.plugin }, add: addPlugin, }, plugins: resolverTypesFilePlugins, config: resolverTypesConfig, schema, documents: [], }; generatesSection.push(resolverTypesFile); // typeDefs if (typeDefsFilePath) { const typeDefsFiles = yield profiler.run(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () { return (0, generateTypeDefsFiles_1.generateTypeDefsFiles)({ baseOutputDir, typeDefsFilePath, typeDefsFileMode, sourceMap, whitelistedModules, blacklistedModules, }); }), createProfilerRunName('generateTypeDefsFiles')); Object.entries(typeDefsFiles).forEach(([filename, meta]) => { const typeDefsFile = { filename: filename, pluginMap: { add: addPlugin }, plugins: [{ add: { content: meta.content } }], config: {}, schema, documents: [], }; generatesSection.push(typeDefsFile); }); } // merge schema if (mergeSchema) { generatesSection.push({ filename: path.posix.join(baseOutputDir, mergeSchema.path), pluginMap: { ['schema-ast']: schemaAstPlugin }, plugins: [{ ['schema-ast']: {} }], schema, documents: [], config: mergeSchema.config, }); } // resolver files const result = { files: {}, externalImports: {}, }; yield profiler.run(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () { return (0, generateResolverFiles_1.generateResolverFiles)({ config: { baseOutputDir, resolverTypesPath, resolverRelativeTargetDir, resolverMainFile, resolverMainFileMode, resolverGeneration, typeMappersMap, parsedGraphQLSchemaMeta, graphQLObjectTypeResolversToGenerate, tsMorph: { project: tsMorphProject, typesSourceFile, }, fixObjectTypeResolvers, unmanagedResolvers: Object.assign({}, mergedConfig.unmanagedResolvers), emitLegacyCommonJSImports, generatedTypesFileMeta, }, result, }); }), createProfilerRunName('generateResolverFiles')); const resultFilesArray = Object.entries(result.files); const resolverFilesGenerateOptions = resultFilesArray .filter(([_, file]) => { // Only generate files that are: // 1. `virtual` - because file doesn't exist yet // 2. on `filesystem` and with `contentUpdated` - because file content has been updated, so we want to apply the changes return (file.filesystem.type === 'virtual' || (file.filesystem.type === 'filesystem' && file.filesystem.contentUpdated === true)); }) .map(([filename, { content }]) => { return { filename, pluginMap: { add: addPlugin }, plugins: [{ add: { content } }], config: {}, schema, documents: [], }; }); utils_1.logger.debug(`Applying changes to ${resolverFilesGenerateOptions.length}/${resultFilesArray.length} files. (${resultFilesArray.length - resolverFilesGenerateOptions.length} skipped files because they are already on filesystem and are not updated)`); return [...resolverFilesGenerateOptions, ...generatesSection]; }), }; const createProfilerRunName = (traceName) => `[${exports.presetName}]: ${traceName}`; //# sourceMappingURL=preset.js.map