You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					99 lines
				
				3.3 KiB
			
		
		
			
		
	
	
					99 lines
				
				3.3 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								'use strict'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const path = require('path')
							 | 
						||
| 
								 | 
							
								const fs = require('fs')
							 | 
						||
| 
								 | 
							
								const yaml = require('js-yaml')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = function (fastify, opts, done) {
							 | 
						||
| 
								 | 
							
								  if (!opts.specification) return done(new Error('specification is missing in the module options'))
							 | 
						||
| 
								 | 
							
								  if (typeof opts.specification !== 'object') return done(new Error('specification is not an object'))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  let swaggerObject = {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!opts.specification.path && !opts.specification.document) {
							 | 
						||
| 
								 | 
							
								    return done(new Error('both specification.path and specification.document are missing, should be path to the file or swagger document spec'))
							 | 
						||
| 
								 | 
							
								  } else if (opts.specification.path) {
							 | 
						||
| 
								 | 
							
								    if (typeof opts.specification.path !== 'string') return done(new Error('specification.path is not a string'))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!fs.existsSync(path.resolve(opts.specification.path))) return done(new Error(`${opts.specification.path} does not exist`))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const extName = path.extname(opts.specification.path).toLowerCase()
							 | 
						||
| 
								 | 
							
								    if (['.yaml', '.json'].indexOf(extName) === -1) return done(new Error("specification.path extension name is not supported, should be one from ['.yaml', '.json']"))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (opts.specification.postProcessor && typeof opts.specification.postProcessor !== 'function') return done(new Error('specification.postProcessor should be a function'))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (opts.specification.baseDir && typeof opts.specification.baseDir !== 'string') return done(new Error('specification.baseDir should be string'))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!opts.specification.baseDir) {
							 | 
						||
| 
								 | 
							
								      opts.specification.baseDir = path.resolve(path.dirname(opts.specification.path))
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      while (opts.specification.baseDir.endsWith('/')) {
							 | 
						||
| 
								 | 
							
								        opts.specification.baseDir = opts.specification.baseDir.slice(0, -1)
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // read
							 | 
						||
| 
								 | 
							
								    const source = fs.readFileSync(
							 | 
						||
| 
								 | 
							
								      path.resolve(opts.specification.path),
							 | 
						||
| 
								 | 
							
								      'utf8'
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								    switch (extName) {
							 | 
						||
| 
								 | 
							
								      case '.yaml':
							 | 
						||
| 
								 | 
							
								        swaggerObject = yaml.load(source)
							 | 
						||
| 
								 | 
							
								        break
							 | 
						||
| 
								 | 
							
								      case '.json':
							 | 
						||
| 
								 | 
							
								        swaggerObject = JSON.parse(source)
							 | 
						||
| 
								 | 
							
								        break
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // apply postProcessor, if one was passed as an argument
							 | 
						||
| 
								 | 
							
								    if (opts.specification.postProcessor) {
							 | 
						||
| 
								 | 
							
								      swaggerObject = opts.specification.postProcessor(swaggerObject)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    if (typeof opts.specification.document !== 'object') return done(new Error('specification.document is not an object'))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    swaggerObject = opts.specification.document
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.decorate('swagger', swagger)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (opts.exposeRoute === true) {
							 | 
						||
| 
								 | 
							
								    const options = {
							 | 
						||
| 
								 | 
							
								      prefix: opts.routePrefix || '/documentation',
							 | 
						||
| 
								 | 
							
								      uiConfig: opts.uiConfig || {},
							 | 
						||
| 
								 | 
							
								      initOAuth: opts.initOAuth || {},
							 | 
						||
| 
								 | 
							
								      baseDir: opts.specification.baseDir,
							 | 
						||
| 
								 | 
							
								      staticCSP: opts.staticCSP,
							 | 
						||
| 
								 | 
							
								      transformStaticCSP: opts.transformStaticCSP,
							 | 
						||
| 
								 | 
							
								      hooks: opts.uiHooks
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    fastify.register(require('../routes'), options)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const cache = {
							 | 
						||
| 
								 | 
							
								    swaggerObject: null,
							 | 
						||
| 
								 | 
							
								    swaggerString: null
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function swagger (opts) {
							 | 
						||
| 
								 | 
							
								    if (opts && opts.yaml) {
							 | 
						||
| 
								 | 
							
								      if (cache.swaggerString) return cache.swaggerString
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      if (cache.swaggerObject) return cache.swaggerObject
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (opts && opts.yaml) {
							 | 
						||
| 
								 | 
							
								      const swaggerString = yaml.dump(swaggerObject, { skipInvalid: true })
							 | 
						||
| 
								 | 
							
								      cache.swaggerString = swaggerString
							 | 
						||
| 
								 | 
							
								      return swaggerString
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    cache.swaggerObject = swaggerObject
							 | 
						||
| 
								 | 
							
								    return swaggerObject
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  done()
							 | 
						||
| 
								 | 
							
								}
							 |