/
home
/
infinitibizsol
/
testingcrm.infinitibizsol.com
/
node_modules
/
fastify
/
File Upload :
llllll
Current File: /home/infinitibizsol/testingcrm.infinitibizsol.com/node_modules/fastify/fastify.js
'use strict' const VERSION = '3.29.5' const Avvio = require('avvio') const http = require('http') const querystring = require('querystring') let lightMyRequest const { kAvvioBoot, kChildren, kBodyLimit, kRoutePrefix, kLogLevel, kLogSerializers, kHooks, kSchemaController, kRequestAcceptVersion, kReplySerializerDefault, kContentTypeParser, kReply, kRequest, kFourOhFour, kState, kOptions, kPluginNameChain, kSchemaErrorFormatter, kErrorHandler, kKeepAliveConnections, kFourOhFourContext } = require('./lib/symbols.js') const { createServer } = require('./lib/server') const Reply = require('./lib/reply') const Request = require('./lib/request') const supportedMethods = ['DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT', 'OPTIONS'] const decorator = require('./lib/decorate') const ContentTypeParser = require('./lib/contentTypeParser') const SchemaController = require('./lib/schema-controller') const { Hooks, hookRunnerApplication, supportedHooks } = require('./lib/hooks') const { createLogger } = require('./lib/logger') const pluginUtils = require('./lib/pluginUtils') const reqIdGenFactory = require('./lib/reqIdGenFactory') const { buildRouting, validateBodyLimitOption } = require('./lib/route') const build404 = require('./lib/fourOhFour') const getSecuredInitialConfig = require('./lib/initialConfigValidation') const override = require('./lib/pluginOverride') const warning = require('./lib/warnings') const noopSet = require('./lib/noop-set') const { defaultInitOptions } = getSecuredInitialConfig const { FST_ERR_BAD_URL, FST_ERR_MISSING_MIDDLEWARE } = require('./lib/errors') const onBadUrlContext = { config: { }, onSend: [], onError: [], [kFourOhFourContext]: null } function defaultBuildPrettyMeta (route) { // return a shallow copy of route's sanitized context const cleanKeys = {} const allowedProps = ['errorHandler', 'logLevel', 'logSerializers'] allowedProps.concat(supportedHooks).forEach(k => { cleanKeys[k] = route.store[k] }) return Object.assign({}, cleanKeys) } function defaultErrorHandler (error, request, reply) { if (reply.statusCode < 500) { reply.log.info( { res: reply, err: error }, error && error.message ) } else { reply.log.error( { req: request, res: reply, err: error }, error && error.message ) } reply.send(error) } function fastify (options) { // Options validations options = options || {} if (typeof options !== 'object') { throw new TypeError('Options must be an object') } if (options.querystringParser && typeof options.querystringParser !== 'function') { throw new Error(`querystringParser option should be a function, instead got '${typeof options.querystringParser}'`) } if (options.schemaController && options.schemaController.bucket && typeof options.schemaController.bucket !== 'function') { throw new Error(`schemaController.bucket option should be a function, instead got '${typeof options.schemaController.bucket}'`) } validateBodyLimitOption(options.bodyLimit) const requestIdHeader = options.requestIdHeader || defaultInitOptions.requestIdHeader const querystringParser = options.querystringParser || querystring.parse const genReqId = options.genReqId || reqIdGenFactory() const requestIdLogLabel = options.requestIdLogLabel || 'reqId' const bodyLimit = options.bodyLimit || defaultInitOptions.bodyLimit const disableRequestLogging = options.disableRequestLogging || false const exposeHeadRoutes = options.exposeHeadRoutes != null ? options.exposeHeadRoutes : false const ajvOptions = Object.assign({ customOptions: {}, plugins: [] }, options.ajv) const frameworkErrors = options.frameworkErrors // Ajv options if (!ajvOptions.customOptions || Object.prototype.toString.call(ajvOptions.customOptions) !== '[object Object]') { throw new Error(`ajv.customOptions option should be an object, instead got '${typeof ajvOptions.customOptions}'`) } if (!ajvOptions.plugins || !Array.isArray(ajvOptions.plugins)) { throw new Error(`ajv.plugins option should be an array, instead got '${typeof ajvOptions.plugins}'`) } // Instance Fastify components const { logger, hasLogger } = createLogger(options) // Update the options with the fixed values options.connectionTimeout = options.connectionTimeout || defaultInitOptions.connectionTimeout options.keepAliveTimeout = options.keepAliveTimeout || defaultInitOptions.keepAliveTimeout options.forceCloseConnections = typeof options.forceCloseConnections === 'boolean' ? options.forceCloseConnections : defaultInitOptions.forceCloseConnections options.maxRequestsPerSocket = options.maxRequestsPerSocket || defaultInitOptions.maxRequestsPerSocket options.requestTimeout = options.requestTimeout || defaultInitOptions.requestTimeout options.logger = logger options.genReqId = genReqId options.requestIdHeader = requestIdHeader options.querystringParser = querystringParser options.requestIdLogLabel = requestIdLogLabel options.disableRequestLogging = disableRequestLogging options.ajv = ajvOptions options.clientErrorHandler = options.clientErrorHandler || defaultClientErrorHandler options.exposeHeadRoutes = exposeHeadRoutes const initialConfig = getSecuredInitialConfig(options) const keepAliveConnections = options.forceCloseConnections === true ? new Set() : noopSet() let constraints = options.constraints if (options.versioning) { warning.emit('FSTDEP009') constraints = { ...constraints, version: { name: 'version', mustMatchWhenDerived: true, storage: options.versioning.storage, deriveConstraint: options.versioning.deriveVersion, validate (value) { if (typeof value !== 'string') { throw new Error('Version constraint should be a string.') } } } } } // Default router const router = buildRouting({ config: { defaultRoute, onBadUrl, constraints, ignoreTrailingSlash: options.ignoreTrailingSlash || defaultInitOptions.ignoreTrailingSlash, maxParamLength: options.maxParamLength || defaultInitOptions.maxParamLength, caseSensitive: options.caseSensitive, buildPrettyMeta: defaultBuildPrettyMeta }, keepAliveConnections }) // 404 router, used for handling encapsulated 404 handlers const fourOhFour = build404(options) // HTTP server and its handler const httpHandler = wrapRouting(router.routing, options) // we need to set this before calling createServer options.http2SessionTimeout = initialConfig.http2SessionTimeout const { server, listen } = createServer(options, httpHandler) const setupResponseListeners = Reply.setupResponseListeners const schemaController = SchemaController.buildSchemaController(null, options.schemaController) // Public API const fastify = { // Fastify internals [kState]: { listening: false, closing: false, started: false }, [kKeepAliveConnections]: keepAliveConnections, [kOptions]: options, [kChildren]: [], [kBodyLimit]: bodyLimit, [kRoutePrefix]: '', [kLogLevel]: '', [kLogSerializers]: null, [kHooks]: new Hooks(), [kSchemaController]: schemaController, [kSchemaErrorFormatter]: null, [kErrorHandler]: defaultErrorHandler, [kReplySerializerDefault]: null, [kContentTypeParser]: new ContentTypeParser( bodyLimit, (options.onProtoPoisoning || defaultInitOptions.onProtoPoisoning), (options.onConstructorPoisoning || defaultInitOptions.onConstructorPoisoning) ), [kReply]: Reply.buildReply(Reply), [kRequest]: Request.buildRequest(Request, options.trustProxy), [kFourOhFour]: fourOhFour, [pluginUtils.registeredPlugins]: [], [kPluginNameChain]: [], [kAvvioBoot]: null, // routing method routing: httpHandler, getDefaultRoute: router.getDefaultRoute.bind(router), setDefaultRoute: router.setDefaultRoute.bind(router), // routes shorthand methods delete: function _delete (url, opts, handler) { return router.prepareRoute.call(this, 'DELETE', url, opts, handler) }, get: function _get (url, opts, handler) { return router.prepareRoute.call(this, 'GET', url, opts, handler) }, head: function _head (url, opts, handler) { return router.prepareRoute.call(this, 'HEAD', url, opts, handler) }, patch: function _patch (url, opts, handler) { return router.prepareRoute.call(this, 'PATCH', url, opts, handler) }, post: function _post (url, opts, handler) { return router.prepareRoute.call(this, 'POST', url, opts, handler) }, put: function _put (url, opts, handler) { return router.prepareRoute.call(this, 'PUT', url, opts, handler) }, options: function _options (url, opts, handler) { return router.prepareRoute.call(this, 'OPTIONS', url, opts, handler) }, all: function _all (url, opts, handler) { return router.prepareRoute.call(this, supportedMethods, url, opts, handler) }, // extended route route: function _route (opts) { // we need the fastify object that we are producing so we apply a lazy loading of the function, // otherwise we should bind it after the declaration return router.route.call(this, opts) }, // expose logger instance log: logger, // hooks addHook, // schemas addSchema, getSchema: schemaController.getSchema.bind(schemaController), getSchemas: schemaController.getSchemas.bind(schemaController), setValidatorCompiler, setSerializerCompiler, setSchemaController, setReplySerializer, setSchemaErrorFormatter, // custom parsers addContentTypeParser: ContentTypeParser.helpers.addContentTypeParser, hasContentTypeParser: ContentTypeParser.helpers.hasContentTypeParser, getDefaultJsonParser: ContentTypeParser.defaultParsers.getDefaultJsonParser, defaultTextParser: ContentTypeParser.defaultParsers.defaultTextParser, removeContentTypeParser: ContentTypeParser.helpers.removeContentTypeParser, removeAllContentTypeParsers: ContentTypeParser.helpers.removeAllContentTypeParsers, // Fastify architecture methods (initialized by Avvio) register: null, after: null, ready: null, onClose: null, close: null, printPlugins: null, // http server listen, server, // extend fastify objects decorate: decorator.add, hasDecorator: decorator.exist, decorateReply: decorator.decorateReply, decorateRequest: decorator.decorateRequest, hasRequestDecorator: decorator.existRequest, hasReplyDecorator: decorator.existReply, // fake http injection inject, // pretty print of the registered routes printRoutes, // custom error handling setNotFoundHandler, setErrorHandler, // Set fastify initial configuration options read-only object initialConfig } fastify[kReply].prototype.server = fastify fastify[kRequest].prototype.server = fastify Object.defineProperties(fastify, { pluginName: { get () { if (this[kPluginNameChain].length > 1) { return this[kPluginNameChain].join(' -> ') } return this[kPluginNameChain][0] } }, prefix: { get () { return this[kRoutePrefix] } }, validatorCompiler: { get () { return this[kSchemaController].getValidatorCompiler() } }, serializerCompiler: { get () { return this[kSchemaController].getSerializerCompiler() } }, version: { get () { return VERSION } }, errorHandler: { get () { return this[kErrorHandler] } } }) // We are adding `use` to the fastify prototype so the user // can still access it (and get the expected error), but `decorate` // will not detect it, and allow the user to override it. Object.setPrototypeOf(fastify, { use }) if (options.schemaErrorFormatter) { validateSchemaErrorFormatter(options.schemaErrorFormatter) fastify[kSchemaErrorFormatter] = options.schemaErrorFormatter.bind(fastify) } // Install and configure Avvio // Avvio will update the following Fastify methods: // - register // - after // - ready // - onClose // - close const avvio = Avvio(fastify, { autostart: false, timeout: Number(options.pluginTimeout) || defaultInitOptions.pluginTimeout, expose: { use: 'register' } }) // Override to allow the plugin encapsulation avvio.override = override avvio.on('start', () => (fastify[kState].started = true)) fastify[kAvvioBoot] = fastify.ready // the avvio ready function fastify.ready = ready // overwrite the avvio ready function fastify.printPlugins = avvio.prettyPrint.bind(avvio) // cache the closing value, since we are checking it in an hot path avvio.once('preReady', () => { fastify.onClose((instance, done) => { fastify[kState].closing = true router.closeRoutes() if (fastify[kState].listening) { // No new TCP connections are accepted instance.server.close(done) for (const conn of fastify[kKeepAliveConnections]) { // We must invoke the destroy method instead of merely unreffing // the sockets. If we only unref, then the callback passed to // `fastify.close` will never be invoked; nor will any of the // registered `onClose` hooks. conn.destroy() fastify[kKeepAliveConnections].delete(conn) } } else { done(null) } }) }) // Set the default 404 handler fastify.setNotFoundHandler() fourOhFour.arrange404(fastify) router.setup(options, { avvio, fourOhFour, logger, hasLogger, setupResponseListeners, throwIfAlreadyStarted }) // Delay configuring clientError handler so that it can access fastify state. server.on('clientError', options.clientErrorHandler.bind(fastify)) try { const dc = require('diagnostics_channel') const initChannel = dc.channel('fastify.initialization') if (initChannel.hasSubscribers) { initChannel.publish({ fastify }) } } catch (e) { // This only happens if `diagnostics_channel` isn't available, i.e. earlier // versions of Node.js. In that event, we don't care, so ignore the error. } return fastify function throwIfAlreadyStarted (msg) { if (fastify[kState].started) throw new Error(msg) } // HTTP injection handling // If the server is not ready yet, this // utility will automatically force it. function inject (opts, cb) { // lightMyRequest is dynamically loaded as it seems very expensive // because of Ajv if (lightMyRequest === undefined) { lightMyRequest = require('light-my-request') } if (fastify[kState].started) { if (fastify[kState].closing) { // Force to return an error const error = new Error('Server is closed') if (cb) { cb(error) return } else { return Promise.reject(error) } } return lightMyRequest(httpHandler, opts, cb) } if (cb) { this.ready(err => { if (err) cb(err, null) else lightMyRequest(httpHandler, opts, cb) }) } else { return lightMyRequest((req, res) => { this.ready(function (err) { if (err) { res.emit('error', err) return } httpHandler(req, res) }) }, opts) } } function ready (cb) { let resolveReady let rejectReady // run the hooks after returning the promise process.nextTick(runHooks) if (!cb) { return new Promise(function (resolve, reject) { resolveReady = resolve rejectReady = reject }) } function runHooks () { // start loading fastify[kAvvioBoot]((err, done) => { if (err || fastify[kState].started) { manageErr(err) } else { hookRunnerApplication('onReady', fastify[kAvvioBoot], fastify, manageErr) } done() }) } function manageErr (err) { if (cb) { if (err) { cb(err) } else { cb(undefined, fastify) } } else { if (err) { return rejectReady(err) } resolveReady(fastify) } } } function use () { throw new FST_ERR_MISSING_MIDDLEWARE() } // wrapper that we expose to the user for hooks handling function addHook (name, fn) { throwIfAlreadyStarted('Cannot call "addHook" when fastify instance is already started!') if (name === 'onSend' || name === 'preSerialization' || name === 'onError') { if (fn.constructor.name === 'AsyncFunction' && fn.length === 4) { throw new Error('Async function has too many arguments. Async hooks should not use the \'done\' argument.') } } else if (name === 'onReady') { if (fn.constructor.name === 'AsyncFunction' && fn.length !== 0) { throw new Error('Async function has too many arguments. Async hooks should not use the \'done\' argument.') } } else if (name !== 'preParsing') { if (fn.constructor.name === 'AsyncFunction' && fn.length === 3) { throw new Error('Async function has too many arguments. Async hooks should not use the \'done\' argument.') } } if (name === 'onClose') { this.onClose(fn) } else if (name === 'onReady') { this[kHooks].add(name, fn) } else { this.after((err, done) => { _addHook.call(this, name, fn) done(err) }) } return this function _addHook (name, fn) { this[kHooks].add(name, fn) this[kChildren].forEach(child => _addHook.call(child, name, fn)) } } // wrapper that we expose to the user for schemas handling function addSchema (schema) { throwIfAlreadyStarted('Cannot call "addSchema" when fastify instance is already started!') this[kSchemaController].add(schema) this[kChildren].forEach(child => child.addSchema(schema)) return this } function defaultClientErrorHandler (err, socket) { // In case of a connection reset, the socket has been destroyed and there is nothing that needs to be done. // https://nodejs.org/api/http.html#http_event_clienterror if (err.code === 'ECONNRESET' || socket.destroyed) { return } const body = JSON.stringify({ error: http.STATUS_CODES['400'], message: 'Client Error', statusCode: 400 }) // Most devs do not know what to do with this error. // In the vast majority of cases, it's a network error and/or some // config issue on the load balancer side. this.log.trace({ err }, 'client error') // Copying standard node behaviour // https://github.com/nodejs/node/blob/6ca23d7846cb47e84fd344543e394e50938540be/lib/_http_server.js#L666 // If the socket is not writable, there is no reason to try to send data. if (socket.writable) { socket.write(`HTTP/1.1 400 Bad Request\r\nContent-Length: ${body.length}\r\nContent-Type: application/json\r\n\r\n${body}`) } socket.destroy(err) } // If the router does not match any route, every request will land here // req and res are Node.js core objects function defaultRoute (req, res) { if (req.headers['accept-version'] !== undefined) { // we remove the accept-version header for performance result // because we do not want to go through the constraint checking // the usage of symbol here to prevent any colision on custom header name req.headers[kRequestAcceptVersion] = req.headers['accept-version'] req.headers['accept-version'] = undefined } fourOhFour.router.lookup(req, res) } function onBadUrl (path, req, res) { if (frameworkErrors) { const id = genReqId(req) const childLogger = logger.child({ reqId: id }) childLogger.info({ req }, 'incoming request') const request = new Request(id, null, req, null, childLogger, onBadUrlContext) const reply = new Reply(res, request, childLogger) return frameworkErrors(new FST_ERR_BAD_URL(path), request, reply) } const body = `{"error":"Bad Request","message":"'${path}' is not a valid url component","statusCode":400}` res.writeHead(400, { 'Content-Type': 'application/json', 'Content-Length': body.length }) res.end(body) } function setNotFoundHandler (opts, handler) { throwIfAlreadyStarted('Cannot call "setNotFoundHandler" when fastify instance is already started!') fourOhFour.setNotFoundHandler.call(this, opts, handler, avvio, router.routeHandler) return this } function setValidatorCompiler (validatorCompiler) { throwIfAlreadyStarted('Cannot call "setValidatorCompiler" when fastify instance is already started!') this[kSchemaController].setValidatorCompiler(validatorCompiler) return this } function setSchemaErrorFormatter (errorFormatter) { throwIfAlreadyStarted('Cannot call "setSchemaErrorFormatter" when fastify instance is already started!') validateSchemaErrorFormatter(errorFormatter) this[kSchemaErrorFormatter] = errorFormatter.bind(this) return this } function setSerializerCompiler (serializerCompiler) { throwIfAlreadyStarted('Cannot call "setSerializerCompiler" when fastify instance is already started!') this[kSchemaController].setSerializerCompiler(serializerCompiler) return this } function setSchemaController (schemaControllerOpts) { throwIfAlreadyStarted('Cannot call "setSchemaController" when fastify instance is already started!') const old = this[kSchemaController] const schemaController = SchemaController.buildSchemaController(old, Object.assign({}, old.opts, schemaControllerOpts)) this[kSchemaController] = schemaController this.getSchema = schemaController.getSchema.bind(schemaController) this.getSchemas = schemaController.getSchemas.bind(schemaController) return this } function setReplySerializer (replySerializer) { throwIfAlreadyStarted('Cannot call "setReplySerializer" when fastify instance is already started!') this[kReplySerializerDefault] = replySerializer return this } // wrapper that we expose to the user for configure the custom error handler function setErrorHandler (func) { throwIfAlreadyStarted('Cannot call "setErrorHandler" when fastify instance is already started!') this[kErrorHandler] = func.bind(this) return this } function printRoutes (opts = {}) { // includeHooks:true - shortcut to include all supported hooks exported by fastify.Hooks opts.includeMeta = opts.includeHooks ? opts.includeMeta ? supportedHooks.concat(opts.includeMeta) : supportedHooks : opts.includeMeta return router.printRoutes(opts) } } function validateSchemaErrorFormatter (schemaErrorFormatter) { if (typeof schemaErrorFormatter !== 'function') { throw new Error(`schemaErrorFormatter option should be a function, instead got ${typeof schemaErrorFormatter}`) } else if (schemaErrorFormatter.constructor.name === 'AsyncFunction') { throw new Error('schemaErrorFormatter option should not be an async function') } } function wrapRouting (httpHandler, { rewriteUrl, logger }) { if (!rewriteUrl) { return httpHandler } return function preRouting (req, res) { const originalUrl = req.url const url = rewriteUrl(req) if (originalUrl !== url) { logger.debug({ originalUrl, url }, 'rewrite url') if (typeof url === 'string') { req.url = url } else { req.destroy(new Error(`Rewrite url for "${req.url}" needs to be of type "string" but received "${typeof url}"`)) } } httpHandler(req, res) } } /** * These export configurations enable JS and TS developers * to consumer fastify in whatever way best suits their needs. * Some examples of supported import syntax includes: * - `const fastify = require('fastify')` * - `const { fastify } = require('fastify')` * - `import * as Fastify from 'fastify'` * - `import { fastify, TSC_definition } from 'fastify'` * - `import fastify from 'fastify'` * - `import fastify, { TSC_definition } from 'fastify'` */ module.exports = fastify module.exports.fastify = fastify module.exports.default = fastify
Copyright ©2k19 -
Hexid
|
Tex7ure