hapi-swagger
Advanced tools
Comparing version 3.0.1 to 3.1.0
@@ -73,3 +73,4 @@ 'use strict'; | ||
} | ||
}] | ||
}], | ||
derefJSONSchema: false | ||
}; | ||
@@ -76,0 +77,0 @@ |
'use strict'; | ||
const Hoek = require('hoek'); | ||
const Joi = require('joi'); | ||
const JSONDeRef = require('json-schema-ref-parser'); | ||
const Filter = require('../lib/filter'); | ||
@@ -60,3 +61,3 @@ const Group = require('../lib/group'); | ||
*/ | ||
builder.getSwaggerJSON = function (settings, request) { | ||
builder.getSwaggerJSON = function (settings, request, callback) { | ||
@@ -80,3 +81,3 @@ // remove items that cannot be changed by user | ||
routes = Filter.byTags(['api'], routes); | ||
Sort.byPathMethod(['api'], routes); | ||
Sort.paths(settings.sortPath, routes); | ||
@@ -96,3 +97,9 @@ // filter routes displayed based on tags passed in query string | ||
return internals.removeNoneSchemaOptions(out); | ||
out = internals.removeNoneSchemaOptions(out); | ||
if (settings.derefJSONSchema === true) { | ||
builder.dereference(out, callback); | ||
} else { | ||
callback(null, out); | ||
} | ||
}; | ||
@@ -102,2 +109,22 @@ | ||
/** | ||
* dereference a schema | ||
* | ||
* @param {Object} schema | ||
* @param {Object} callback | ||
*/ | ||
builder.dereference = function (schema, callback) { | ||
JSONDeRef.dereference(schema, function (err, json) { | ||
if (!err) { | ||
delete json.definitions; | ||
} else { | ||
err = { 'error': 'fail to dereference schema' }; | ||
} | ||
callback(err, json); | ||
}); | ||
}; | ||
/** | ||
* finds the current host | ||
@@ -145,3 +172,5 @@ * | ||
'lang', | ||
'addXProperties' | ||
'sortPaths', | ||
'addXProperties', | ||
'derefJSONSchema' | ||
].forEach( (element) => { | ||
@@ -148,0 +177,0 @@ |
'use strict'; | ||
const Hoek = require('hoek'); | ||
const ShortId = require('shortid'); | ||
const Properties = require('../lib/properties'); | ||
@@ -21,32 +22,18 @@ const Utilities = require('../lib/utilities'); | ||
// covert JOI object into internal object | ||
let newDefinition; | ||
if (Array.isArray(joiObj)){ | ||
let propertyObj = Properties.parseProperties(joiObj, definitionCollection); | ||
let propertyArray = Properties.swaggerObjectToArray(propertyObj, null); | ||
newDefinition = internals.wrap(propertyArray); | ||
let parameterArray = Properties.toParameters(joiObj, definitionCollection); | ||
newDefinition = internals.wrapParameters(parameterArray); | ||
} else { | ||
newDefinition = Properties.parseProperty(definitionName, joiObj, definitionCollection); | ||
newDefinition = Properties.parseProperty(definitionName || altName, joiObj, definitionCollection); | ||
} | ||
return definitions.append(definitionName, newDefinition, definitionCollection, altName); | ||
}; | ||
/** | ||
* append a new definition object | ||
* | ||
* @param {string} definitionName | ||
* @param {Object} definition | ||
* @param {Object} definitionCollection | ||
* @param {string} altName | ||
* @return {Object} | ||
*/ | ||
definitions.append = function (definitionName, definition, definitionCollection, altName) { | ||
const formatted = internals.createProperties( definition.properties ); | ||
definition.properties = formatted.properties; | ||
if (formatted.required){ | ||
definition.required = formatted.required; | ||
// format structure into new definition object | ||
const formatted = internals.formatProperties( newDefinition.properties ); | ||
if (formatted.properties){ | ||
newDefinition.properties = formatted.properties; | ||
} | ||
return internals.appendFormatted(definitionName, definition, definitionCollection, altName); | ||
return internals.appendFormatted(definitionName, newDefinition, definitionCollection, altName); | ||
}; | ||
@@ -71,2 +58,4 @@ | ||
//definitionName = definitionName + Math.random() * (99999 - 0) + 0; | ||
// find existing definition by this definitionName | ||
@@ -82,3 +71,8 @@ const foundDefinition = definitionCollection[definitionName]; | ||
// to stop reuse of definition with same name but different structures | ||
definitionCollection[altName] = definition; | ||
if (!altName) { | ||
altName = ShortId.generate(); | ||
} | ||
//definition.name = altName + 'x'; | ||
definitionCollection[altName] = internals.formatProperty( definition ); | ||
out = altName; | ||
@@ -88,2 +82,3 @@ } | ||
// create new definition | ||
//definition.name = (definitionName || altName) + 'x'; | ||
definitionCollection[definitionName || altName] = definition; | ||
@@ -98,3 +93,3 @@ out = definitionName || altName; | ||
/** | ||
* builds definition object properties structure (input is swagger parameter model) | ||
* builds definition object properties structure from parameters | ||
* | ||
@@ -104,3 +99,3 @@ * @param {Object} parameters | ||
*/ | ||
internals.createProperties = function (parameters) { | ||
internals.formatProperties = function (parameters) { | ||
@@ -111,3 +106,2 @@ let out = { | ||
for (let key in parameters) { | ||
@@ -121,24 +115,39 @@ let obj = parameters[key]; | ||
} | ||
out.required.push(obj.name || key); | ||
out.required.push(obj.name); | ||
} | ||
// remove emtpy properties | ||
obj = Utilities.deleteEmptyProperties(obj); | ||
out.properties[obj.name || key] = obj; | ||
obj = internals.formatProperty(obj); | ||
} | ||
return Utilities.deleteEmptyProperties(out); | ||
}; | ||
// recurse into child objects | ||
if (obj.type === 'object' && obj.properties) { | ||
out.properties[obj.name] = internals.createProperties(obj.properties); | ||
} else { | ||
// if child has no name use its key | ||
out.properties[obj.name || key] = obj; | ||
} | ||
// remove unneeded properties | ||
delete obj.name; | ||
delete obj.required; | ||
/** | ||
* formats a parameter for use in a definition object | ||
* | ||
* @param {Object} parameter | ||
* @return {Object} | ||
*/ | ||
internals.formatProperty = function (obj) { | ||
// add $ref directly to parent and delete schema | ||
if (obj.schema) { | ||
obj.$ref = obj.schema.$ref; | ||
delete obj.schema; | ||
} | ||
return out; | ||
// remove emtpy properties | ||
obj = Utilities.deleteEmptyProperties(obj); | ||
// remove unneeded properties | ||
delete obj.name; | ||
delete obj.required; | ||
return obj; | ||
}; | ||
/** | ||
@@ -150,3 +159,3 @@ * wraps definition object in the JSON schema structure | ||
*/ | ||
internals.wrap = function (parameters) { | ||
internals.wrapParameters = function (parameters) { | ||
@@ -157,3 +166,3 @@ let out = { | ||
}, | ||
props = internals.createProperties(parameters); | ||
props = internals.formatProperties(parameters); | ||
@@ -160,0 +169,0 @@ // merge in properties and required structures |
@@ -23,3 +23,5 @@ 'use strict'; | ||
lang: Joi.string().valid(['en', 'es', 'pt', 'ru']), | ||
addXProperties: Joi.boolean() | ||
sortPaths: Joi.string().valid(['unsorted', 'path-method']), | ||
addXProperties: Joi.boolean(), | ||
derefJSONSchema: Joi.boolean() | ||
}).unknown(); | ||
@@ -40,3 +42,5 @@ | ||
'lang': 'en', | ||
'addXProperties': false | ||
'sortPaths': 'unsorted', | ||
'addXProperties': false, | ||
'derefJSONSchema': false | ||
}; | ||
@@ -57,20 +61,2 @@ | ||
// There is no way to cover this differs from Hapi 9 to 10+ | ||
/* $lab:coverage:off$ */ | ||
if (plugin.registrations){ | ||
Hoek.assert(plugin.registrations.vision, 'Missing vision plug-in registation'); | ||
Hoek.assert(plugin.registrations.inert, 'Missing inert plug-in registation'); | ||
} | ||
/* $lab:coverage:on$ */ | ||
// add routing for swaggerui static assets /swaggerui/ | ||
plugin.views({ | ||
engines: { | ||
html: { | ||
module: require('handlebars') | ||
} | ||
}, | ||
path: swaggerDirPath | ||
}); | ||
// add routing swagger json | ||
@@ -80,3 +66,3 @@ plugin.route([{ | ||
path: settings.jsonPath, | ||
config: { | ||
config: { | ||
auth: settings.auth, | ||
@@ -86,3 +72,6 @@ handler: (request, reply) => { | ||
Joi.assert(settings, schema); | ||
reply(builder.getSwaggerJSON(settings, request)); | ||
builder.getSwaggerJSON(settings, request, function (err, json) { | ||
reply(json).type('application/json'); | ||
}); | ||
}, | ||
@@ -98,2 +87,21 @@ plugins: { | ||
if (settings.enableDocumentation === true) { | ||
// There is no way to cover this differs from Hapi 9 to 10+ | ||
/* $lab:coverage:off$ */ | ||
if (plugin.registrations){ | ||
Hoek.assert(plugin.registrations.vision, 'Missing vision plug-in registation'); | ||
Hoek.assert(plugin.registrations.inert, 'Missing inert plug-in registation'); | ||
} | ||
/* $lab:coverage:on$ */ | ||
// add routing for swaggerui static assets /swaggerui/ | ||
plugin.views({ | ||
engines: { | ||
html: { | ||
module: require('handlebars') | ||
} | ||
}, | ||
path: swaggerDirPath | ||
}); | ||
plugin.route([{ | ||
@@ -109,3 +117,3 @@ method: 'GET', | ||
} | ||
}, { | ||
},{ | ||
method: 'GET', | ||
@@ -112,0 +120,0 @@ path: settings.swaggerUIPath + '{path*}', |
@@ -48,2 +48,4 @@ 'use strict'; | ||
Responses.build({},{},{},{}); | ||
let routesData = []; | ||
@@ -172,3 +174,3 @@ | ||
swagger.definitions, | ||
out.operationId + '_payload' | ||
'parameters_' + out.operationId + '_' + method.toLowerCase() | ||
) | ||
@@ -181,9 +183,9 @@ }; | ||
} else { | ||
payloadParameters = Properties.joiToSwaggerParameters( internals.getJOIObj(route, 'payloadParams'), 'formData', swagger.definitions ); | ||
payloadParameters = Properties.toParameters( internals.getJOIObj(route, 'payloadParams'), swagger.definitions, 'formData' ); | ||
} | ||
out.parameters = out.parameters.concat( | ||
Properties.joiToSwaggerParameters( internals.getJOIObj(route, 'headerParams'), 'header', swagger.definitions ), | ||
Properties.joiToSwaggerParameters( internals.getJOIObj(route, 'pathParams'), 'path', swagger.definitions ), | ||
Properties.joiToSwaggerParameters( internals.getJOIObj(route, 'queryParams'), 'query', swagger.definitions ) | ||
Properties.toParameters( internals.getJOIObj(route, 'headerParams'), swagger.definitions, 'header' ), | ||
Properties.toParameters( internals.getJOIObj(route, 'pathParams'), swagger.definitions, 'path' ), | ||
Properties.toParameters( internals.getJOIObj(route, 'queryParams'), swagger.definitions, 'query' ) | ||
); | ||
@@ -194,3 +196,10 @@ if (payloadParameters){ | ||
out.responses = Responses.build( route.responses, route.responseSchema, route.responseStatus, swagger.definitions, out.operationId ); | ||
//let name = out.operationId + method; | ||
out.responses = Responses.build( | ||
route.responses, | ||
route.responseSchema, | ||
route.responseStatus, | ||
swagger.definitions, | ||
out.operationId + '_' + method.toLowerCase() | ||
); | ||
@@ -197,0 +206,0 @@ if (!pathObj[path]){ |
@@ -29,19 +29,7 @@ 'use strict'; | ||
/** | ||
* builds a swagger definition object from a JOI object | ||
* | ||
* @param {Object} joiObjs | ||
* @param {Array} definitionCollection | ||
* @return {Object} | ||
*/ | ||
properties.joiToSwaggerDefinition = function (joiObjs, definitionCollection) { | ||
return properties.parseProperties(joiObjs, definitionCollection); | ||
}; | ||
/** | ||
* builds a swagger parameters object from a JOI object | ||
* | ||
* @param {Object} joiObjs | ||
* @param {Object} joiObj | ||
* @param {String} type | ||
@@ -51,24 +39,12 @@ * @param {Array} definitionCollection | ||
*/ | ||
properties.joiToSwaggerParameters = function (joiObjs, type, definitionCollection) { | ||
properties.toParameters = function (joiObj, definitionCollection, type) { | ||
const propertyObj = properties.parseProperties(joiObjs, definitionCollection, type); | ||
return properties.swaggerObjectToArray(propertyObj, type); | ||
}; | ||
/** | ||
* converts an object to an array of properties | ||
* | ||
* @param {Object} obj | ||
* @param {String} type | ||
* @return {Array} | ||
*/ | ||
properties.swaggerObjectToArray = function (obj, type) { | ||
const propertyObj = properties.parseProperties(joiObj, definitionCollection, type); | ||
const keys = Object.keys(propertyObj); | ||
let out = []; | ||
const keys = Object.keys(obj); | ||
// object to array | ||
keys.forEach( (element, index) => { | ||
let key = keys[index]; | ||
let item = obj[key]; | ||
let item = propertyObj[key]; | ||
item.name = key; | ||
@@ -85,22 +61,4 @@ if (type) { | ||
/** | ||
* turns JOI object into an array | ||
* needed to covert custom parameters objects passed in by plug-in route options | ||
* | ||
* @param {Object} obj | ||
* @return {Array} | ||
*/ | ||
properties.joiObjectToArray = function (obj) { | ||
let out = []; | ||
for (let key in obj) { | ||
out.push({ | ||
key: key, | ||
schema: obj[key] | ||
}); | ||
} | ||
return out; | ||
}; | ||
/** | ||
@@ -111,2 +69,3 @@ * parse Joi validators object into an object of swagger properties | ||
* @param {Array} definitionCollection | ||
* @param {String} type | ||
* @return {Object} | ||
@@ -145,2 +104,21 @@ */ | ||
/** | ||
* turns JOI object into an array | ||
* needed to covert custom parameters objects passed in by plug-in route options | ||
* | ||
* @param {Object} obj | ||
* @return {Array} | ||
*/ | ||
properties.joiObjectToArray = function (obj) { | ||
let out = []; | ||
for (let key in obj) { | ||
out.push({ | ||
key: key, | ||
schema: obj[key] | ||
}); | ||
} | ||
return out; | ||
}; | ||
/** | ||
* parse Joi validators object into a swagger property | ||
@@ -174,14 +152,4 @@ * | ||
// add common properties | ||
property.description = Hoek.reach(joiObj, '_description'); | ||
property.notes = Hoek.reach(joiObj, '_notes'); | ||
property.tags = Hoek.reach(joiObj, '_tags'); | ||
property.example = Hoek.reach(joiObj, '_examples.0'); | ||
property = properties.parsePropertyMetadata(property, joiObj); | ||
// add reqired state only if true | ||
if (Hoek.reach(joiObj, '_flags.presence')) { | ||
property.required = (Hoek.reach(joiObj, '_flags.presence') === 'required') ? true : undefined; | ||
} | ||
property.default = Hoek.reach(joiObj, '_flags.default'); | ||
// add enum | ||
@@ -225,2 +193,26 @@ let describe = joiObj.describe(); | ||
/** | ||
* parse property metadata | ||
* | ||
* @param {Object} property | ||
* @param {Object} joiObj | ||
* @return {Object} | ||
*/ | ||
properties.parsePropertyMetadata = function (property, joiObj) { | ||
// add common properties | ||
property.description = Hoek.reach(joiObj, '_description'); | ||
property.notes = Hoek.reach(joiObj, '_notes'); | ||
property.tags = Hoek.reach(joiObj, '_tags'); | ||
property.example = Hoek.reach(joiObj, '_examples.0'); | ||
// add reqired state only if true | ||
if (Hoek.reach(joiObj, '_flags.presence')) { | ||
property.required = (Hoek.reach(joiObj, '_flags.presence') === 'required') ? true : undefined; | ||
} | ||
property.default = Hoek.reach(joiObj, '_flags.default'); | ||
return property; | ||
}; | ||
/** | ||
* parse number property | ||
@@ -255,6 +247,12 @@ * | ||
const joiObjs = joiObj._inner.children; | ||
joiObj = joiObj._inner.children; | ||
property.name = name; | ||
property.type = 'object'; | ||
property.properties = properties.parseProperties(joiObjs, definitionCollection); | ||
if (name) { | ||
property.schema = { | ||
'$ref': '#/definitions/' + require('../lib/definitions').appendJoi(name, joiObj, definitionCollection) | ||
}; | ||
} else { | ||
property.properties = properties.parseProperties(joiObj, definitionCollection); | ||
} | ||
return property; | ||
@@ -286,3 +284,3 @@ }; | ||
// set swaggers collectionFormat to one that works with hapi | ||
if (type === 'query' || type === 'formData'){ | ||
if (type === 'query' || type === 'formData') { | ||
property.collectionFormat = 'multi'; | ||
@@ -302,3 +300,3 @@ } | ||
let arrayProperty = properties.parseProperty(name, firstInclusionType, definitionCollection); | ||
if (internals.simpleTypePropertyMap[ firstInclusionType._type.toLowerCase() ]){ | ||
if (internals.simpleTypePropertyMap[firstInclusionType._type.toLowerCase()]) { | ||
// map simple types directly | ||
@@ -308,11 +306,7 @@ property.items = { | ||
}; | ||
if ( arrayProperty.format ){ | ||
if (arrayProperty.format) { | ||
property.items.format = arrayProperty.format; | ||
} | ||
} else { | ||
// create definitions for complex types | ||
// delay invocation of dependency until runtime to deal with circular dependencies with properties | ||
property.items = { | ||
'$ref': '#/definitions/' + require('../lib/definitions').append(name, arrayProperty, definitionCollection) | ||
}; | ||
property.items = arrayProperty.schema; | ||
} | ||
@@ -319,0 +313,0 @@ } |
@@ -5,2 +5,3 @@ 'use strict'; | ||
const Definitions = require('../lib/definitions'); | ||
const ShortId = require('shortid'); | ||
const Utilities = require('../lib/utilities'); | ||
@@ -15,3 +16,3 @@ | ||
* | ||
* @param {Object} userDefindedObjs | ||
* @param {Object} userDefindedSchemas | ||
* @param {Object} defaultSchema | ||
@@ -22,3 +23,3 @@ * @param {Object} statusSchemas | ||
*/ | ||
responses.build = function (userDefindedObjs, defaultSchema, statusSchemas, definitionCollection, operationId) { | ||
responses.build = function (userDefindedSchemas, defaultSchema, statusSchemas, definitionCollection, altName) { | ||
@@ -28,3 +29,3 @@ let out = {}; | ||
// add defaultSchema to statusSchemas if needed | ||
if (defaultSchema && (Hoek.reach(statusSchemas, '200') === undefined)) { | ||
if (Utilities.hasProperties(defaultSchema) && (Hoek.reach(statusSchemas, '200') === undefined)) { | ||
statusSchemas[200] = defaultSchema; | ||
@@ -34,27 +35,34 @@ } | ||
// loop for each status and convert schema into a definition | ||
if (statusSchemas) { | ||
if (Utilities.hasProperties(statusSchemas)){ | ||
for (let key in statusSchemas) { | ||
if (statusSchemas.hasOwnProperty(key)) { | ||
const responseName = Hoek.reach(statusSchemas[key], '_settings.language.label'); | ||
out[key] = { | ||
description: Hoek.reach(statusSchemas[key], '_description') | ||
}; | ||
out[key].headers = Utilities.getJoiMetaProperty(statusSchemas[key], 'headers'); | ||
out[key].example = Utilities.getJoiMetaProperty(statusSchemas[key], 'example'); | ||
let responseName; | ||
// only add schema if object has children | ||
if (Utilities.hasJoiChildren(statusSchemas[key])) { | ||
out[key] = { | ||
schema: { | ||
'$ref': '#/definitions/' + Definitions.appendJoi(responseName, statusSchemas[key], definitionCollection, operationId + '_' + key) | ||
} | ||
}; | ||
// invert naming if on label is supplied | ||
if (Hoek.reach(statusSchemas[key], '_settings.language.label')) { | ||
responseName = Hoek.reach(statusSchemas[key], '_settings.language.label'); | ||
} else { | ||
responseName = internals.altLabel(altName, key); | ||
altName = ShortId.generate(); | ||
} | ||
out[key] = { | ||
'description': Hoek.reach(statusSchemas[key], '_description'), | ||
'schema': { | ||
'$ref': '#/definitions/' + Definitions.appendJoi(responseName, statusSchemas[key], definitionCollection, 'response_' + altName), | ||
'title': internals.altLabel(altName, key) | ||
} | ||
out[key] = Utilities.deleteEmptyProperties(out[key]); | ||
// make sure we always have a description as its required for swagger response object | ||
if (!out[key].description){ | ||
out[key].description = HTTPStatus[key].replace('OK','Successful'); | ||
} | ||
}; | ||
out[key].schema.title = responseName; | ||
out[key].headers = Utilities.getJoiMetaProperty(statusSchemas[key], 'headers'); | ||
out[key].example = Utilities.getJoiMetaProperty(statusSchemas[key], 'example'); | ||
out[key] = Utilities.deleteEmptyProperties(out[key]); | ||
// make sure we always have a description as its required for swagger response object | ||
if (!out[key].description) { | ||
out[key].description = HTTPStatus[key].replace('OK', 'Successful'); | ||
} | ||
} | ||
@@ -73,6 +81,6 @@ } else { | ||
// use plug-in overrides to enchance hapi objects and properties | ||
if (Utilities.hasProperties(userDefindedObjs)) { | ||
out = internals.override(out, userDefindedObjs, definitionCollection, operationId); | ||
// out = internals.override({}, userDefindedObjs, definitionCollection); | ||
if (Utilities.hasProperties(userDefindedSchemas)) { | ||
out = internals.override(out, userDefindedSchemas, definitionCollection, altName); | ||
} | ||
return Utilities.deleteEmptyProperties(out); | ||
@@ -83,25 +91,30 @@ }; | ||
/** | ||
* replaces discovered objects with user defined objects | ||
* replaces discovered response objects with user defined objects | ||
* | ||
* @param {Object} discoveredObjs | ||
* @param {Object} userDefindedObjs | ||
* @param {Object} discoveredSchemas | ||
* @param {Object} userDefindedSchemas | ||
* @param {Object} definitionCollection | ||
* @param {String} altName | ||
* @return {Object} | ||
*/ | ||
internals.override = function (discoveredObjs, userDefindedObjs, definitionCollection, operationId) { | ||
internals.override = function (discoveredSchemas, userDefindedSchemas, definitionCollection, altName) { | ||
for (let key in userDefindedObjs) { | ||
if (userDefindedObjs.hasOwnProperty(key)) { | ||
for (let key in userDefindedSchemas) { | ||
if (userDefindedSchemas.hasOwnProperty(key)) { | ||
// create a new object by cloning - dont modify user definded objects | ||
let out = Hoek.clone(userDefindedObjs[key]); | ||
let out = Hoek.clone(userDefindedSchemas[key]); | ||
// test for any JOI objects | ||
if (Hoek.reach(userDefindedObjs[key], 'schema.isJoi') && userDefindedObjs[key].schema.isJoi === true) { | ||
//var responseName = Utilities.getJoiMetaProperty(userDefindedObjs[key].schema, 'name'); | ||
const responseName = Hoek.reach(userDefindedObjs[key].schema, '_settings.language.label'); | ||
if (Hoek.reach(userDefindedSchemas[key], 'schema.isJoi') && userDefindedSchemas[key].schema.isJoi === true) { | ||
const responseName = Hoek.reach(userDefindedSchemas[key].schema, '_settings.language.label'); | ||
// convert JOI objects into Swagger defination references | ||
out.schema = { | ||
'$ref': '#/definitions/' + Definitions.appendJoi(responseName, userDefindedObjs[key].schema, definitionCollection, operationId + '_' + key) | ||
'$ref': '#/definitions/' + Definitions.appendJoi( | ||
responseName, | ||
userDefindedSchemas[key].schema, | ||
definitionCollection, | ||
internals.altLabel(altName, key) | ||
) | ||
}; | ||
@@ -111,7 +124,19 @@ } | ||
// overwrite discovery with user definded | ||
discoveredObjs[key] = out; | ||
discoveredSchemas[key] = Utilities.deleteEmptyProperties(out); | ||
} | ||
} | ||
return discoveredObjs; | ||
return discoveredSchemas; | ||
}; | ||
/** | ||
* create alt label for response object | ||
* | ||
* @param {String} altName | ||
* @param {String} key | ||
* @return {String} | ||
*/ | ||
internals.altLabel = function (altName, key) { | ||
return 'response_' + altName + '_' + key; | ||
}; |
@@ -11,10 +11,14 @@ 'use strict'; | ||
* | ||
* @param {String} sortType | ||
* @param {Array} routes | ||
* @return {Array} | ||
*/ | ||
sort.byPathMethod = function (routes) { | ||
sort.paths = function (sortType, routes) { | ||
routes.sort( | ||
Utilities.firstBy('path').thenBy('method') | ||
); | ||
if (sortType === 'path-method') { | ||
routes.sort( | ||
Utilities.firstBy('path').thenBy('method') | ||
); | ||
} | ||
return routes; | ||
@@ -21,0 +25,0 @@ }; |
@@ -56,2 +56,6 @@ 'use strict'; | ||
} | ||
// delete object which does not have its own properties | ||
if (utilities.isObject(obj[key]) && utilities.hasProperties(obj[key]) === false) { | ||
delete obj[key]; | ||
} | ||
} | ||
@@ -58,0 +62,0 @@ } |
{ | ||
"name": "hapi-swagger", | ||
"description": "A swagger documentation UI generator plugin for hapi", | ||
"version": "3.0.1", | ||
"version": "3.1.0", | ||
"author": "Glenn Jones", | ||
@@ -28,2 +28,3 @@ "repository": { | ||
"joi": "7.0.1", | ||
"shortid": "2.2.4", | ||
"json-schema-ref-parser": "^1.4.0" | ||
@@ -37,3 +38,3 @@ }, | ||
"code": "2.0.1", | ||
"hapi": "^11.1.1", | ||
"hapi": "^12.0.0", | ||
"wreck": "7.0.0", | ||
@@ -51,4 +52,4 @@ "coveralls": "2.11.6", | ||
"peerDependencies": { | ||
"hapi": "^9.0.1 || ^10.0.0 || ^11.0.0" | ||
"hapi": "^9.0.1 || ^10.0.0 || ^11.0.0 || ^12.0.0" | ||
} | ||
} |
# hapi-swagger | ||
This is a [Swagger UI](https://github.com/wordnik/swagger-ui) plug-in for [HAPI](http://hapijs.com/) v9.x to v11.x When installed it will self document HTTP API interface in a project. | ||
This is a [The OpenAPI (aka Swagger)](https://openapis.org/) plug-in for [HAPI](http://hapijs.com/) v9.x to v12.x When installed it will self document the API interface | ||
in a project. | ||
@@ -20,3 +21,4 @@ [![build status](https://img.shields.io/travis/glennjones/hapi-swagger.svg?style=flat-square)](http://travis-ci.org/glennjones/hapi-swagger) | ||
You will also need to install the `inert` and `vision` plugs-ins which support templates and static content serving. | ||
If you want to view the documentation from your API you will also need to install the `inert` and `vision` plugs-ins which support templates and static | ||
content serving. If you wish just to used swagger.json without the documentation for example with swagger-codegen simply set `enableDocumentation` to false | ||
@@ -108,3 +110,4 @@ $ npm install inert --save | ||
* `lang`: (string) The language of the UI either `en`, `es`, `pt` or `ru` - default: `en` | ||
* `securityDefinitions:`: (array) Containing [Security Definitions Object](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#securityDefinitionsObject). No defaults are provided. | ||
* `tags`: (object) Containing [Tag Object] (https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#tagObject) used to group endpoints in swagger-ui. | ||
* `securityDefinitions:`: (array) Containing [Security Definitions Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#securityDefinitionsObject). No defaults are provided. | ||
@@ -462,2 +465,2 @@ Defaults for routes settings (these can also be set a individual path level): | ||
### Issues | ||
If you find any issue please file here on github and I will try and fix them. | ||
If you find any issue please file here on github and I will try and fix them. |
@@ -53,20 +53,16 @@ 'use strict'; | ||
expect(response.statusCode).to.equal(200); | ||
expect(response.result.paths['/foo/v1/bar'].post.parameters[0].schema).to.deep.equal({ | ||
'$ref': '#/definitions/foov1bar_payload' | ||
'$ref': '#/definitions/parameters_foov1bar_post' | ||
}); | ||
expect(response.result.definitions.foov1bar_payload).to.deep.equal({ | ||
expect(response.result.definitions.parameters_foov1bar_post).to.deep.equal({ | ||
'properties': { | ||
'outer1': { | ||
'properties': { | ||
'inner1': { | ||
'type': 'string' | ||
} | ||
} | ||
'$ref': '#/definitions/outer1', | ||
'type': 'object' | ||
}, | ||
'outer2': { | ||
'properties': { | ||
'inner2': { | ||
'type': 'string' | ||
} | ||
} | ||
'$ref': '#/definitions/outer2', | ||
'type': 'object' | ||
} | ||
@@ -76,2 +72,11 @@ }, | ||
}); | ||
expect(response.result.definitions.outer1).to.deep.equal({ | ||
'properties': { | ||
'inner1': { | ||
'type': 'string' | ||
} | ||
}, | ||
'type': 'object' | ||
}); | ||
done(); | ||
@@ -78,0 +83,0 @@ }); |
@@ -83,5 +83,5 @@ 'use strict'; | ||
expect(response.result.paths['/test/'].post.parameters[0].schema).to.deep.equal({ | ||
'$ref': '#/definitions/test_payload' | ||
'$ref': '#/definitions/parameters_test_post' | ||
}); | ||
expect(response.result.definitions.test_payload).to.deep.equal(defination); | ||
expect(response.result.definitions.parameters_test_post).to.deep.equal(defination); | ||
done(); | ||
@@ -88,0 +88,0 @@ }); |
@@ -14,3 +14,28 @@ 'use strict'; | ||
// these are example are taken from https://github.com/hapijs/lout/blob/master/test/routes/default.js | ||
// License: https://github.com/hapijs/lout/blob/master/LICENSE | ||
/* | ||
Copyright (c) 2012-2014, Walmart and other contributors. | ||
All rights reserved. | ||
Redistribution and use in source and binary forms, with or without | ||
modification, are permitted provided that the following conditions are met: | ||
* Redistributions of source code must retain the above copyright | ||
notice, this list of conditions and the following disclaimer. | ||
* Redistributions in binary form must reproduce the above copyright | ||
notice, this list of conditions and the following disclaimer in the | ||
documentation and/or other materials provided with the distribution. | ||
* The names of any contributors may not be used to endorse or promote | ||
products derived from this software without specific prior written | ||
permission. | ||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY | ||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
*/ | ||
const routes = [{ | ||
@@ -17,0 +42,0 @@ method: 'GET', |
@@ -340,2 +340,5 @@ 'use strict'; | ||
}); |
@@ -5,2 +5,3 @@ 'use strict'; | ||
const Lab = require('lab'); | ||
const Helper = require('../test/helper.js'); | ||
const Properties = require('../lib/properties.js'); | ||
@@ -13,2 +14,3 @@ | ||
lab.experiment('property - ', () => { | ||
@@ -151,8 +153,14 @@ | ||
//console.log(JSON.stringify(Properties.parseProperty('x', Joi.object().keys({ 'text': Joi.string() }), {}, [], 'formData' ))); | ||
//console.log(JSON.stringify(Properties.parseProperty('x', Joi.object({ 'text': Joi.string() }), {}, [], 'formData' ))); | ||
/* Change from inline to definiation objects | ||
expect(Properties.parseProperty('x', Joi.object({ 'text': Joi.string() }))).to.deep.equal({ 'type': 'object', 'name': 'x', 'properties': { 'text': { 'type': 'string' } } }); | ||
expect(Properties.parseProperty('x', Joi.object().keys({ 'text': Joi.string() }))).to.deep.equal({ 'type': 'object', 'name': 'x', 'properties': { 'text': { 'type': 'string' } } }); | ||
*/ | ||
expect(Properties.parseProperty('x', Joi.object({ 'text': Joi.string() }), {}, [], 'formData')).to.deep.equal({ 'type': 'object', 'name': 'x', 'schema': { '$ref': '#/definitions/x' } }); | ||
expect(Properties.parseProperty('x', Joi.object().keys({ 'text': Joi.string() }), {}, [], 'formData')).to.deep.equal({ 'type': 'object', 'name': 'x', 'schema': { '$ref': '#/definitions/x' } }); | ||
/* not yet 'x-', | ||
@@ -182,121 +190,2 @@ {} | ||
lab.test('parse deep structure with children', (done) => { | ||
const deepStructure = Joi.object({ | ||
outer1: Joi.object({ | ||
inner1: Joi.string() | ||
}), | ||
outer2: Joi.object({ | ||
inner2: Joi.string() | ||
}) | ||
}).description('body description').notes(['body notes']); | ||
const deepStructureJSON = { | ||
'type': 'object', | ||
'description': 'body description', | ||
'notes': [ | ||
'body notes' | ||
], | ||
'name': 'x', | ||
'properties': { | ||
'outer1': { | ||
'type': 'object', | ||
'name': 'outer1', | ||
'properties': { | ||
'inner1': { | ||
'type': 'string' | ||
} | ||
} | ||
}, | ||
'outer2': { | ||
'type': 'object', | ||
'name': 'outer2', | ||
'properties': { | ||
'inner2': { | ||
'type': 'string' | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
expect(Properties.parseProperty('x', deepStructure)).to.deep.equal(deepStructureJSON); | ||
done(); | ||
}); | ||
lab.test('parse deep structure with child description, notes, name etc', (done) => { | ||
const deepStructure = Joi.object({ | ||
outer1: Joi.object({ | ||
inner1: Joi.string() | ||
.description('child description') | ||
.notes(['child notes']) | ||
.tags(['child', 'api']) | ||
.required() | ||
}), | ||
outer2: Joi.object({ | ||
inner2: Joi.number() | ||
.description('child description') | ||
.notes(['child notes']) | ||
.tags(['child', 'api']) | ||
.min(5) | ||
.max(10) | ||
.required() | ||
}) | ||
}); | ||
const deepStructureJSON = { | ||
'type': 'object', | ||
'name': 'x', | ||
'properties': { | ||
'outer1': { | ||
'type': 'object', | ||
'name': 'outer1', | ||
'properties': { | ||
'inner1': { | ||
'type': 'string', | ||
'description': 'child description', | ||
'notes': [ | ||
'child notes' | ||
], | ||
'tags': [ | ||
'child', | ||
'api' | ||
], | ||
'required': true | ||
} | ||
} | ||
}, | ||
'outer2': { | ||
'type': 'object', | ||
'name': 'outer2', | ||
'properties': { | ||
'inner2': { | ||
'type': 'number', | ||
'description': 'child description', | ||
'notes': [ | ||
'child notes' | ||
], | ||
'tags': [ | ||
'child', | ||
'api' | ||
], | ||
'required': true, | ||
'minimum': 5, | ||
'maximum': 10 | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
expect(Properties.parseProperty('x', deepStructure)).to.deep.equal(deepStructureJSON); | ||
done(); | ||
}); | ||
lab.test('parse description', (done) => { | ||
@@ -456,6 +345,4 @@ | ||
lab.test('toParameters', (done) => { | ||
lab.test('joiToSwaggerDefinition', (done) => { | ||
const joiStructure = Joi.object({ | ||
@@ -480,56 +367,4 @@ a: Joi.number() | ||
//console.log(JSON.stringify( Properties.joiToSwaggerDefinition(joiStructure, {}) )); | ||
//console.log(JSON.stringify( Properties.toParameters(joiStructure , 'query') )); | ||
const structureJSON = { | ||
'a': { | ||
'type': 'number', | ||
'description': 'the first number', | ||
'required': true | ||
}, | ||
'b': { | ||
'type': 'number', | ||
'description': 'the second number', | ||
'required': true | ||
}, | ||
'operator': { | ||
'type': 'string', | ||
'description': 'the opertator i.e. + - / or *', | ||
'required': true, | ||
'default': '+' | ||
}, | ||
'equals': { | ||
'type': 'number', | ||
'description': 'the result of the sum', | ||
'required': true | ||
} | ||
}; | ||
expect(Properties.joiToSwaggerDefinition(joiStructure, 'query')).to.deep.equal(structureJSON); | ||
done(); | ||
}); | ||
lab.test('joiToSwaggerParameters', (done) => { | ||
const joiStructure = Joi.object({ | ||
a: Joi.number() | ||
.required() | ||
.description('the first number'), | ||
b: Joi.number() | ||
.required() | ||
.description('the second number'), | ||
operator: Joi.string() | ||
.required() | ||
.default('+') | ||
.description('the opertator i.e. + - / or *'), | ||
equals: Joi.number() | ||
.required() | ||
.description('the result of the sum') | ||
}); | ||
//console.log(JSON.stringify( Properties.joiToSwaggerParameters(joiStructure , 'query') )); | ||
const structureJSON = [ | ||
@@ -567,3 +402,3 @@ { | ||
expect(Properties.joiToSwaggerParameters(joiStructure, 'query')).to.deep.equal(structureJSON); | ||
expect(Properties.toParameters(joiStructure, {}, 'query')).to.deep.equal(structureJSON); | ||
done(); | ||
@@ -576,1 +411,73 @@ }); | ||
}); | ||
lab.experiment('property deep - ', () => { | ||
const deepStructure = Joi.object({ | ||
outer1: Joi.object({ | ||
inner1: Joi.string() | ||
.description('child description') | ||
.notes(['child notes']) | ||
.tags(['child', 'api']) | ||
.required() | ||
}), | ||
outer2: Joi.object({ | ||
inner2: Joi.number() | ||
.description('child description') | ||
.notes(['child notes']) | ||
.tags(['child', 'api']) | ||
.min(5) | ||
.max(10) | ||
.required() | ||
}) | ||
}); | ||
lab.test('parse structure with child description, notes, name etc', (done) => { | ||
const routes = [{ | ||
method: 'POST', | ||
path: '/path/two', | ||
config: { | ||
tags: ['api'], | ||
handler: Helper.defaultHandler, | ||
response: { | ||
schema: deepStructure | ||
} | ||
} | ||
}]; | ||
Helper.createServer({}, routes, (err, server) => { | ||
server.inject({ url: '/swagger.json' }, function (response) { | ||
expect(err).to.equal(null); | ||
//console.log(JSON.stringify(response.result.definitions)); | ||
expect(response.result.definitions.outer1).to.deep.equal({ | ||
'properties': { | ||
'inner1': { | ||
'description': 'child description', | ||
'type': 'string', | ||
'notes': [ | ||
'child notes' | ||
], | ||
'tags': [ | ||
'child', | ||
'api' | ||
] | ||
} | ||
}, | ||
'required': [ | ||
'inner1' | ||
], | ||
'type': 'object' | ||
}); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); |
@@ -165,3 +165,3 @@ 'use strict'; | ||
'schema': { | ||
'$ref': '#/definitions/microformatsapi_payload' | ||
'$ref': '#/definitions/parameters_microformatsapi_post' | ||
} | ||
@@ -383,3 +383,3 @@ } | ||
}, | ||
'microformatsapi2_payload': { | ||
'parameters_microformatsapi2_post': { | ||
'properties': { | ||
@@ -386,0 +386,0 @@ 'b': { |
@@ -82,49 +82,2 @@ 'use strict'; | ||
const swaggerSumModel = { | ||
'properties': { | ||
'id': { | ||
'type': 'string', | ||
'example': 'x78P9c' | ||
}, | ||
'a': { | ||
'type': 'number', | ||
'example': 5 | ||
}, | ||
'b': { | ||
'type': 'number', | ||
'example': 5 | ||
}, | ||
'operator': { | ||
'type': 'string', | ||
'example': '+', | ||
'description': 'either +, -, /, or *' | ||
}, | ||
'equals': { | ||
'type': 'number', | ||
'example': 10 | ||
}, | ||
'created': { | ||
'type': 'string', | ||
'example': '2015-12-01', | ||
'description': 'ISO date string' | ||
}, | ||
'modified': { | ||
'type': 'string', | ||
'example': '2015-12-01', | ||
'description': 'ISO date string' | ||
} | ||
}, | ||
'description': 'json body for sum', | ||
'required': [ | ||
'id', | ||
'a', | ||
'b', | ||
'operator', | ||
'equals', | ||
'created' | ||
], | ||
'type': 'object' | ||
}; | ||
lab.test('using hapi response.schema', (done) => { | ||
@@ -160,11 +113,3 @@ | ||
//console.log(JSON.stringify(response.result)); | ||
expect(response.result.paths['/store/'].post.responses).to.deep.equal({ | ||
'200': { | ||
'schema': { | ||
'$ref': '#/definitions/Sum' | ||
}, | ||
'description': 'Successful' | ||
} | ||
}); | ||
expect(response.result.definitions.Sum).to.deep.equal(swaggerSumModel); | ||
expect(response.result.paths['/store/'].post.responses).to.exist(); | ||
done(); | ||
@@ -207,13 +152,4 @@ }); | ||
expect(err).to.equal(null); | ||
expect(response.result.paths['/store/'].post.responses).to.deep.equal({ | ||
'200': { | ||
'schema': { | ||
'$ref': '#/definitions/List' | ||
}, | ||
'description': 'Successful' | ||
} | ||
}); | ||
expect(response.result.definitions.List).to.exist(); | ||
expect(response.result.definitions.Sum).to.exist(); | ||
expect(response.result.definitions.List.properties.items.items.$ref).to.equal('#/definitions/Sum'); | ||
done(); | ||
@@ -258,8 +194,3 @@ }); | ||
//console.log(JSON.stringify(response.result)); | ||
expect(response.result.paths['/store/'].post.responses[200]).to.deep.equal({ | ||
'schema': { | ||
'$ref': '#/definitions/Sum' | ||
}, | ||
'description': 'Successful' | ||
}); | ||
expect(response.result.paths['/store/'].post.responses[200]).to.exist(); | ||
expect(response.result.paths['/store/'].post.responses[400].description).to.equal('Bad Request'); | ||
@@ -317,3 +248,3 @@ expect(response.result.paths['/store/'].post.responses[400].headers).to.deep.equal(headers); | ||
lab.test('using route base override', (done) => { | ||
lab.test('using route base plugin override - object', (done) => { | ||
@@ -347,3 +278,3 @@ const routes = { | ||
//console.log(JSON.stringify(response.result)); | ||
expect(response.result.paths['/store/'].post.responses[200].schema).to.deep.equal({ '$ref': '#/definitions/Sum' }); | ||
expect(response.result.paths['/store/'].post.responses[200].schema).to.exist(); | ||
expect(response.result.paths['/store/'].post.responses[400].description).to.equal('Bad Request'); | ||
@@ -357,3 +288,3 @@ expect(response.result.paths['/store/'].post.responses[400].headers).to.deep.equal(headers); | ||
lab.test('failback to default', (done) => { | ||
lab.test('using route base plugin override - array', (done) => { | ||
@@ -366,2 +297,15 @@ const routes = { | ||
tags: ['api'], | ||
plugins: { | ||
'hapi-swagger': { | ||
responses: { | ||
'200': { | ||
'description': 'Success', | ||
'schema': Joi.array().items(Joi.object({ | ||
equals: Joi.number() | ||
}).label('Result')).label('ResultSet') | ||
}, | ||
'400': { 'description': 'Bad Request' } | ||
} | ||
} | ||
}, | ||
validate: { | ||
@@ -383,8 +327,19 @@ payload: { | ||
//console.log(JSON.stringify(response.result)); | ||
expect(response.result.paths['/store/'].post.responses[200]).to.deep.equal({ | ||
'schema': { | ||
'type': 'string' | ||
expect(response.result.paths['/store/'].post.responses[200].schema).to.exist(); | ||
expect(response.result.definitions.ResultSet).to.deep.equal({ | ||
'type': 'array', | ||
'items': { | ||
'$ref': '#/definitions/Result' | ||
} | ||
}); | ||
expect(response.result.definitions.Result).to.deep.equal({ | ||
'properties': { | ||
'equals': { | ||
'type': 'number' | ||
} | ||
}, | ||
'description': 'Successful' | ||
'type': 'object' | ||
}); | ||
expect(response.result.paths['/store/'].post.responses[400].description).to.equal('Bad Request'); | ||
done(); | ||
@@ -396,2 +351,42 @@ }); | ||
lab.test('failback to 200', (done) => { | ||
const routes = { | ||
method: 'POST', | ||
path: '/store/', | ||
config: { | ||
handler: Helper.defaultHandler, | ||
tags: ['api'], | ||
validate: { | ||
payload: { | ||
a: Joi.number() | ||
.required() | ||
.description('the first number') | ||
} | ||
} | ||
} | ||
}; | ||
Helper.createServer({}, routes, (err, server) => { | ||
server.inject({ url: '/swagger.json' }, function (response) { | ||
expect(err).to.equal(null); | ||
//console.log(JSON.stringify(response.result)); | ||
expect(response.result.paths['/store/'].post.responses).to.deep.equal({ | ||
'200': { | ||
'schema': { | ||
'type': 'string' | ||
}, | ||
'description': 'Successful' | ||
} | ||
}); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
lab.test('No ownProperty', (done) => { | ||
@@ -404,12 +399,20 @@ | ||
//console.log(JSON.stringify( Responses.build({},{},{},{}) )); | ||
expect(Responses.build({}, {}, {}, {})).to.deep.equal({ | ||
200: { | ||
'200': { | ||
'schema': { | ||
'type': 'string' | ||
}, | ||
'description': 'Successful' | ||
} | ||
}); | ||
expect(Responses.build( objA,objB,objC,{ } )).to.deep.equal({ | ||
200: { | ||
expect(Responses.build(objA, objB, objC, {})).to.deep.equal({ | ||
'200': { | ||
'schema': { | ||
'type': 'string' | ||
}, | ||
'description': 'Successful' | ||
} | ||
}); | ||
objA[200] = { description : 'Successful' }; | ||
@@ -422,2 +425,86 @@ expect(Responses.build( objA,objB,objC,{ } )).to.deep.equal({ 200:{ 'description': 'Successful' } }); | ||
lab.test('with same path but different method', (done) => { | ||
const routes = [{ | ||
method: 'POST', | ||
path: '/path/two', | ||
config: { | ||
tags: ['api'], | ||
handler: Helper.defaultHandler, | ||
response: { | ||
schema: { | ||
value1111: Joi.boolean() | ||
} | ||
} | ||
} | ||
},{ | ||
method: 'GET', | ||
path: '/path/two', | ||
config: { | ||
tags: ['api'], | ||
handler: Helper.defaultHandler, | ||
response: { | ||
schema: Joi.object({ | ||
value2222: Joi.boolean() | ||
}) | ||
} | ||
} | ||
}]; | ||
Helper.createServer({}, routes, (err, server) => { | ||
server.inject({ url: '/swagger.json' }, function (response) { | ||
expect(err).to.equal(null); | ||
//console.log(JSON.stringify(response.result.definitions)); | ||
expect(response.result.definitions.response_pathtwo_get_200).to.exist(); | ||
expect(response.result.definitions.response_pathtwo_post_200).to.exist(); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
lab.test('with deep labels', (done) => { | ||
const routes = [{ | ||
method: 'POST', | ||
path: '/path/two', | ||
config: { | ||
tags: ['api'], | ||
handler: Helper.defaultHandler, | ||
response: { | ||
schema: Joi.object({ | ||
value1111: Joi.boolean() | ||
}).label('labelA') | ||
} | ||
} | ||
}]; | ||
Helper.createServer({}, routes, (err, server) => { | ||
server.inject({ url: '/swagger.json' }, function (response) { | ||
expect(err).to.equal(null); | ||
// console.log(JSON.stringify(response.result.definitions)); | ||
expect(response.result.definitions.labelA).to.exist(); | ||
expect(response.result.definitions.response_pathtwo_post).to.exist(); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
3709492
90
44404
464
8
+ Addedshortid@2.2.4
+ Addedhapi@12.1.0(transitive)
+ Addedshortid@2.2.4(transitive)
+ Addedshot@3.5.2(transitive)
+ Addedsubtext@4.4.1(transitive)
+ Addedwreck@12.6.2(transitive)
- Removedcall-bind-apply-helpers@1.0.1(transitive)
- Removedcall-bound@1.0.3(transitive)
- Removeddunder-proto@1.0.1(transitive)
- Removedes-define-property@1.0.1(transitive)
- Removedes-errors@1.3.0(transitive)
- Removedes-object-atoms@1.0.0(transitive)
- Removedfunction-bind@1.1.2(transitive)
- Removedget-intrinsic@1.2.6(transitive)
- Removedgopd@1.2.0(transitive)
- Removedhapi@11.1.4(transitive)
- Removedhas-symbols@1.1.0(transitive)
- Removedhasown@2.0.2(transitive)
- Removedmath-intrinsics@1.0.0(transitive)
- Removedobject-inspect@1.13.3(transitive)
- Removedqs@6.13.1(transitive)
- Removedshot@2.0.1(transitive)
- Removedside-channel@1.1.0(transitive)
- Removedside-channel-list@1.0.0(transitive)
- Removedside-channel-map@1.0.1(transitive)
- Removedside-channel-weakmap@1.0.2(transitive)
- Removedsubtext@3.0.2(transitive)
- Removedwreck@7.2.1(transitive)