UNPKG

graphql-shield-generator

Version:
163 lines 6.73 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getOutputPath = exports.getTypeResolverMap = exports.constructShield = void 0; const tslib_1 = require("tslib"); const schema_1 = require("@graphql-tools/schema"); const utils_1 = require("@graphql-tools/utils"); const graphql_1 = require("graphql"); const path_1 = tslib_1.__importDefault(require("path")); const process_1 = require("process"); const constructShield = ({ typeResolverMap, options }) => { let rootItems = ''; // Sort types by priority if groupbyobjects is enabled const typeEntries = Object.entries(typeResolverMap); const sortedTypes = options.groupbyobjects ? typeEntries.sort(([typeA], [typeB]) => { const priority = { Query: 1, Mutation: 2, Subscription: 3 }; const priorityA = priority[typeA] || 99; const priorityB = priority[typeB] || 99; if (priorityA !== priorityB) return priorityA - priorityB; return typeA.localeCompare(typeB); }) : typeEntries; for (const [type, resolverNames] of sortedTypes) { if (type.length > 0) { const sortedResolvers = resolverNames.sort().map((resolverName) => { var _a; return `'${resolverName}': ${(_a = options.customrule) !== null && _a !== void 0 ? _a : 'allow'}`; }); const subscriptionLinesWrapped = `${type}: ${wrapWithObject({ shieldItemLines: sortedResolvers, options, })},`; rootItems += subscriptionLinesWrapped; } } if (rootItems.length === 0) return ''; let shieldText = getImports('graphql-shield', options); shieldText += '\n\n'; shieldText += wrapWithExport({ shieldObjectText: wrapWithGraphqlShieldCall({ shieldObjectTextWrapped: wrapWithObject({ shieldItemLines: rootItems, options }), }, options), options, }); return shieldText; }; exports.constructShield = constructShield; const getTypeResolverMap = async (schema) => { var _a; if (!(schema instanceof graphql_1.GraphQLSchema)) { schema = await (0, schema_1.makeExecutableSchema)({ typeDefs: schema.typeDefs, resolvers: schema.resolvers }); } const typeResolverMap = {}; const rootTypeMap = (0, utils_1.getRootTypeMap)(schema); for (const [, rootType] of rootTypeMap.entries()) { const typeName = rootType.name; const fields = rootType.getFields(); for (const [resolverName] of Object.entries(fields)) { if (!typeResolverMap[typeName]) { typeResolverMap[typeName] = []; } if (typeName === 'Query') { typeResolverMap[typeName].push(resolverName); } else if (typeName === 'Mutation') { typeResolverMap[typeName].push(resolverName); } else if (typeName === 'Subscription') { typeResolverMap[typeName].push(resolverName); } } } const typeMap = schema.getTypeMap(); for (const typeName in typeMap) { const type = typeMap[typeName]; if (((_a = type.astNode) === null || _a === void 0 ? void 0 : _a.kind) === 'ObjectTypeDefinition' && !['Query', 'Mutation', 'Subscription'].includes(type.name)) { const foundType = schema.getType(type.name); //@ts-ignore const fields = foundType === null || foundType === void 0 ? void 0 : foundType.toConfig().fields; Object.keys(fields).forEach((fieldName) => { const field = fields[fieldName]; const resolver = field.resolve; if (resolver) { if (!typeResolverMap[type.name]) { typeResolverMap[type.name] = []; } typeResolverMap[type.name].push(fieldName); } }); } } return typeResolverMap; }; exports.getTypeResolverMap = getTypeResolverMap; const getOutputPath = (options) => { var _a, _b; const ext = `.${(_a = options.extension) !== null && _a !== void 0 ? _a : 'js'}`; const dirPath = options.outputDir ? path_1.default.resolve((0, process_1.cwd)(), options.outputDir) : path_1.default.join((0, process_1.cwd)()); const filePath = path_1.default.format({ dir: dirPath, name: (_b = options.fileName) !== null && _b !== void 0 ? _b : 'shield', ext: ext, }); return filePath; }; exports.getOutputPath = getOutputPath; const wrapWithObject = ({ shieldItemLines, options }) => { let wrapped = '{'; wrapped += '\n'; if (Array.isArray(shieldItemLines)) { const fallbackRule = options === null || options === void 0 ? void 0 : options.fallbackRule; const fallbackLine = fallbackRule ? ` '*': ${fallbackRule},\n` : ''; wrapped += fallbackLine + ' ' + shieldItemLines.join(',\n '); } else { wrapped += ' ' + shieldItemLines; } wrapped += '\n'; wrapped += '}'; return wrapped; }; const getImports = (type, options) => { const needsDeny = options.fallbackRule === 'deny'; const needsAllow = !options.customrule || options.fallbackRule === 'allow'; const imports = ['shield']; if (needsAllow) imports.push('allow'); if (needsDeny) imports.push('deny'); switch (options.moduleSystem) { case 'ES modules': let result = `import { ${imports.join(', ')} } from '${type}';\n`; if (options.customrule) { result += `import { ${options.customrule} } from '${options.customrulepath}';\n`; } return result; case 'CommonJS': default: let resultCommon = `const { ${imports.join(', ')} } = require('${type}');\n`; if (options.customrule) { resultCommon += `const { ${options.customrule} } = require('${options.customrulepath}');\n`; } return resultCommon; } }; const wrapWithExport = ({ shieldObjectText, options }) => { switch (options.moduleSystem) { case 'ES modules': return ` export const permissions = ${shieldObjectText};`; case 'CommonJS': default: return ` module.exports.permissions = ${shieldObjectText};`; } }; const wrapWithGraphqlShieldCall = ({ shieldObjectTextWrapped }, options) => { var _a; let wrapped = 'shield('; wrapped += '\n'; wrapped += ' ' + shieldObjectTextWrapped; wrapped += `\n, ${(_a = options.shieldoptions) !== null && _a !== void 0 ? _a : ''}`; wrapped += ')'; return wrapped; }; //# sourceMappingURL=helpers.js.map