UNPKG

graphql-validate-directive

Version:
139 lines 4.87 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.GraphQLValidateDirective = void 0; const utils_1 = require("@graphql-tools/utils"); const ajv_1 = __importDefault(require("ajv")); const graphql_1 = require("graphql"); const pick_1 = __importDefault(require("lodash/pick")); const constants_1 = require("./constants"); class GraphQLValidateDirective { schema; directiveName; ajv; constructor(schema, directiveName = constants_1.DefaultValidateDirectiveName, ajv = new ajv_1.default()) { this.schema = schema; this.directiveName = directiveName; this.ajv = ajv; } getScalerTypeSchema(type, opt) { if (type === graphql_1.GraphQLInt) { return { type: 'integer', ...(0, pick_1.default)(opt, constants_1.KeywordsForNumber), }; } if (type === graphql_1.GraphQLFloat) { return { type: 'number', ...(0, pick_1.default)(opt, constants_1.KeywordsForNumber), }; } if (type === graphql_1.GraphQLString) { return { type: 'string', ...(0, pick_1.default)(opt, constants_1.KeywordsForString), }; } return {}; } getListTypeSchema(type, opt) { return { type: 'array', ...(0, pick_1.default)(opt, constants_1.KeywordsForArray), items: this.getInputTypeSchema(type.ofType, opt), }; } getInputTypeSchema(type, opt) { if ((0, graphql_1.isScalarType)(type) && opt) { return this.getScalerTypeSchema(type, opt); } if ((0, graphql_1.isListType)(type) && opt) { return this.getListTypeSchema(type, opt); } if ((0, graphql_1.isNonNullType)(type)) { return this.getInputTypeSchema(type.ofType, opt); } if ((0, graphql_1.isInputObjectType)(type)) { return { $ref: this.getInputTypeRefName(type.name), }; } return {}; } getInputTypeRefName(name) { return `#/definitions/customInputType${name}`; } getTypeSchema(type) { if (!(0, graphql_1.isInputObjectType)(type)) return; const fields = type.getFields(); const properties = {}; const jsonSchema = { type: 'object', properties, additionalProperties: true, }; for (const [name, field] of Object.entries(fields)) { const directive = (0, utils_1.getDirective)(this.schema, field, this.directiveName); properties[name] = this.getInputTypeSchema(field.type, directive?.[0]); } return jsonSchema; } registerTypeSchemas(typeMap) { for (const [name, type] of Object.entries(typeMap)) { const jsonSchema = this.getTypeSchema(type); if (!jsonSchema) continue; this.ajv.addSchema(jsonSchema, this.getInputTypeRefName(name)); } } getArgsSchema(args) { const properties = {}; const jsonSchema = { $async: true, type: 'object', properties, additionalProperties: true, }; for (const arg of args) { const directive = (0, utils_1.getDirective)(this.schema, arg, this.directiveName); properties[arg.name] = this.getInputTypeSchema(arg.type, directive?.[0]); } return jsonSchema; } createValidator(args) { const schema = this.getArgsSchema(args); return this.ajv.compile(schema); } composeResolverForField(field) { if (field.args.length === 0) return; const validate = this.createValidator(field.args); const originalResolve = field.resolve; field.resolve = async function resolverWithValidator(...args) { await validate(args[1]); return originalResolve?.apply(this, args); }; } composeResolver(type) { if (!type) return; const fields = type.getFields(); for (const [, field] of Object.entries(fields)) { this.composeResolverForField(field); } } transformSchema() { const typeMap = this.schema.getTypeMap(); this.registerTypeSchemas(typeMap); const objectTypes = Object.values(typeMap).filter(graphql_1.isObjectType); for (const objectType of objectTypes) { this.composeResolver(objectType); } } } exports.GraphQLValidateDirective = GraphQLValidateDirective; //# sourceMappingURL=GraphQLValidateDirective.js.map