UNPKG

fastify

Version:

Fast and low overhead web framework, for Node.js

165 lines (142 loc) 5.86 kB
'use strict' const { buildSchemas } = require('./schemas') const SerializerSelector = require('@fastify/fast-json-stringify-compiler') const ValidatorSelector = require('@fastify/ajv-compiler') /** * Called at every fastify context that is being created. * @param {object} parentSchemaCtrl: the SchemaController instance of the Fastify parent context * @param {object} opts: the `schemaController` server option. It can be undefined when a parentSchemaCtrl is set * @return {object}:a new SchemaController */ function buildSchemaController (parentSchemaCtrl, opts) { if (parentSchemaCtrl) { return new SchemaController(parentSchemaCtrl, opts) } const compilersFactory = Object.assign({ buildValidator: null, buildSerializer: null }, opts?.compilersFactory) if (!compilersFactory.buildValidator) { compilersFactory.buildValidator = ValidatorSelector() } if (!compilersFactory.buildSerializer) { compilersFactory.buildSerializer = SerializerSelector() } const option = { bucket: (opts && opts.bucket) || buildSchemas, compilersFactory, isCustomValidatorCompiler: typeof opts?.compilersFactory?.buildValidator === 'function', isCustomSerializerCompiler: typeof opts?.compilersFactory?.buildValidator === 'function' } return new SchemaController(undefined, option) } class SchemaController { constructor (parent, options) { this.opts = options || parent?.opts this.addedSchemas = false this.compilersFactory = this.opts.compilersFactory if (parent) { this.schemaBucket = this.opts.bucket(parent.getSchemas()) this.validatorCompiler = parent.getValidatorCompiler() this.serializerCompiler = parent.getSerializerCompiler() this.isCustomValidatorCompiler = parent.isCustomValidatorCompiler this.isCustomSerializerCompiler = parent.isCustomSerializerCompiler this.parent = parent } else { this.schemaBucket = this.opts.bucket() this.isCustomValidatorCompiler = this.opts.isCustomValidatorCompiler || false this.isCustomSerializerCompiler = this.opts.isCustomSerializerCompiler || false } } // Bucket interface add (schema) { this.addedSchemas = true return this.schemaBucket.add(schema) } getSchema (schemaId) { return this.schemaBucket.getSchema(schemaId) } getSchemas () { return this.schemaBucket.getSchemas() } setValidatorCompiler (validatorCompiler) { // Set up as if the fixed validator compiler had been provided // by a custom 'options.compilersFactory.buildValidator' that // always returns the same compiler object. This is required because: // // - setValidatorCompiler must immediately install a compiler to preserve // legacy behavior // - setupValidator will recreate compilers from builders in some // circumstances, so we have to install this adapter to make it // behave the same if the legacy API is used // // The cloning of the compilersFactory object is necessary because // we are aliasing the parent compilersFactory if none was provided // to us (see constructor.) this.compilersFactory = Object.assign( {}, this.compilersFactory, { buildValidator: () => validatorCompiler }) this.validatorCompiler = validatorCompiler this.isCustomValidatorCompiler = true } setSerializerCompiler (serializerCompiler) { // Set up as if the fixed serializer compiler had been provided // by a custom 'options.compilersFactory.buildSerializer' that // always returns the same compiler object. This is required because: // // - setSerializerCompiler must immediately install a compiler to preserve // legacy behavior // - setupSerializer will recreate compilers from builders in some // circumstances, so we have to install this adapter to make it // behave the same if the legacy API is used // // The cloning of the compilersFactory object is necessary because // we are aliasing the parent compilersFactory if none was provided // to us (see constructor.) this.compilersFactory = Object.assign( {}, this.compilersFactory, { buildSerializer: () => serializerCompiler }) this.serializerCompiler = serializerCompiler this.isCustomSerializerCompiler = true } getValidatorCompiler () { return this.validatorCompiler || (this.parent && this.parent.getValidatorCompiler()) } getSerializerCompiler () { return this.serializerCompiler || (this.parent && this.parent.getSerializerCompiler()) } getSerializerBuilder () { return this.compilersFactory.buildSerializer || (this.parent && this.parent.getSerializerBuilder()) } getValidatorBuilder () { return this.compilersFactory.buildValidator || (this.parent && this.parent.getValidatorBuilder()) } /** * This method will be called when a validator must be setup. * Do not setup the compiler more than once * @param {object} serverOptions the fastify server options */ setupValidator (serverOptions) { const isReady = this.validatorCompiler !== undefined && !this.addedSchemas if (isReady) { return } this.validatorCompiler = this.getValidatorBuilder()(this.schemaBucket.getSchemas(), serverOptions.ajv) } /** * This method will be called when a serializer must be setup. * Do not setup the compiler more than once * @param {object} serverOptions the fastify server options */ setupSerializer (serverOptions) { const isReady = this.serializerCompiler !== undefined && !this.addedSchemas if (isReady) { return } this.serializerCompiler = this.getSerializerBuilder()(this.schemaBucket.getSchemas(), serverOptions.serializerOpts) } } SchemaController.buildSchemaController = buildSchemaController module.exports = SchemaController