openapi-sampler
Advanced tools
Comparing version 0.4.3 to 1.0.0-beta.0
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.OpenAPISampler = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | ||
var hasOwn = Object.prototype.hasOwnProperty; | ||
var toString = Object.prototype.toString; | ||
module.exports = function forEach (obj, fn, ctx) { | ||
if (toString.call(fn) !== '[object Function]') { | ||
throw new TypeError('iterator must be a function'); | ||
} | ||
var l = obj.length; | ||
if (l === +l) { | ||
for (var i = 0; i < l; i++) { | ||
fn.call(ctx, obj[i], i, obj); | ||
} | ||
} else { | ||
for (var k in obj) { | ||
if (hasOwn.call(obj, k)) { | ||
fn.call(ctx, obj[k], k, obj); | ||
} | ||
} | ||
} | ||
}; | ||
},{}],2:[function(require,module,exports){ | ||
'use strict'; | ||
var each = require('foreach'); | ||
module.exports = api; | ||
/** | ||
* Convenience wrapper around the api. | ||
* Calls `.get` when called with an `object` and a `pointer`. | ||
* Calls `.set` when also called with `value`. | ||
* If only supplied `object`, returns a partially applied function, mapped to the object. | ||
* | ||
* @param {Object} obj | ||
* @param {String|Array} pointer | ||
* @param value | ||
* @returns {*} | ||
*/ | ||
function api (obj, pointer, value) { | ||
// .set() | ||
if (arguments.length === 3) { | ||
return api.set(obj, pointer, value); | ||
} | ||
// .get() | ||
if (arguments.length === 2) { | ||
return api.get(obj, pointer); | ||
} | ||
// Return a partially applied function on `obj`. | ||
var wrapped = api.bind(api, obj); | ||
// Support for oo style | ||
for (var name in api) { | ||
if (api.hasOwnProperty(name)) { | ||
wrapped[name] = api[name].bind(wrapped, obj); | ||
} | ||
} | ||
return wrapped; | ||
} | ||
/** | ||
* Lookup a json pointer in an object | ||
* | ||
* @param {Object} obj | ||
* @param {String|Array} pointer | ||
* @returns {*} | ||
*/ | ||
api.get = function get (obj, pointer) { | ||
var refTokens = Array.isArray(pointer) ? pointer : api.parse(pointer); | ||
for (var i = 0; i < refTokens.length; ++i) { | ||
var tok = refTokens[i]; | ||
if (!(typeof obj == 'object' && tok in obj)) { | ||
throw new Error('Invalid reference token: ' + tok); | ||
} | ||
obj = obj[tok]; | ||
} | ||
return obj; | ||
}; | ||
/** | ||
* Sets a value on an object | ||
* | ||
* @param {Object} obj | ||
* @param {String|Array} pointer | ||
* @param value | ||
*/ | ||
api.set = function set (obj, pointer, value) { | ||
var refTokens = Array.isArray(pointer) ? pointer : api.parse(pointer), | ||
nextTok = refTokens[0]; | ||
for (var i = 0; i < refTokens.length - 1; ++i) { | ||
var tok = refTokens[i]; | ||
if (tok === '-' && Array.isArray(obj)) { | ||
tok = obj.length; | ||
} | ||
nextTok = refTokens[i + 1]; | ||
if (!(tok in obj)) { | ||
if (nextTok.match(/^(\d+|-)$/)) { | ||
obj[tok] = []; | ||
} else { | ||
obj[tok] = {}; | ||
} | ||
} | ||
obj = obj[tok]; | ||
} | ||
if (nextTok === '-' && Array.isArray(obj)) { | ||
nextTok = obj.length; | ||
} | ||
obj[nextTok] = value; | ||
return this; | ||
}; | ||
/** | ||
* Removes an attribute | ||
* | ||
* @param {Object} obj | ||
* @param {String|Array} pointer | ||
*/ | ||
api.remove = function (obj, pointer) { | ||
var refTokens = Array.isArray(pointer) ? pointer : api.parse(pointer); | ||
var finalToken = refTokens[refTokens.length -1]; | ||
if (finalToken === undefined) { | ||
throw new Error('Invalid JSON pointer for remove: "' + pointer + '"'); | ||
} | ||
var parent = api.get(obj, refTokens.slice(0, -1)); | ||
if (Array.isArray(parent)) { | ||
var index = +finalToken; | ||
if (finalToken === '' && isNaN(index)) { | ||
throw new Error('Invalid array index: "' + finalToken + '"'); | ||
} | ||
Array.prototype.splice.call(parent, index, 1); | ||
} else { | ||
delete parent[finalToken]; | ||
} | ||
}; | ||
/** | ||
* Returns a (pointer -> value) dictionary for an object | ||
* | ||
* @param obj | ||
* @param {function} descend | ||
* @returns {} | ||
*/ | ||
api.dict = function dict (obj, descend) { | ||
var results = {}; | ||
api.walk(obj, function (value, pointer) { | ||
results[pointer] = value; | ||
}, descend); | ||
return results; | ||
}; | ||
/** | ||
* Iterates over an object | ||
* Iterator: function (value, pointer) {} | ||
* | ||
* @param obj | ||
* @param {function} iterator | ||
* @param {function} descend | ||
*/ | ||
api.walk = function walk (obj, iterator, descend) { | ||
var refTokens = []; | ||
descend = descend || function (value) { | ||
var type = Object.prototype.toString.call(value); | ||
return type === '[object Object]' || type === '[object Array]'; | ||
}; | ||
(function next (cur) { | ||
each(cur, function (value, key) { | ||
refTokens.push(String(key)); | ||
if (descend(value)) { | ||
next(value); | ||
} else { | ||
iterator(value, api.compile(refTokens)); | ||
} | ||
refTokens.pop(); | ||
}); | ||
}(obj)); | ||
}; | ||
/** | ||
* Tests if an object has a value for a json pointer | ||
* | ||
* @param obj | ||
* @param pointer | ||
* @returns {boolean} | ||
*/ | ||
api.has = function has (obj, pointer) { | ||
try { | ||
api.get(obj, pointer); | ||
} catch (e) { | ||
return false; | ||
} | ||
return true; | ||
}; | ||
/** | ||
* Escapes a reference token | ||
* | ||
* @param str | ||
* @returns {string} | ||
*/ | ||
api.escape = function escape (str) { | ||
return str.toString().replace(/~/g, '~0').replace(/\//g, '~1'); | ||
}; | ||
/** | ||
* Unescapes a reference token | ||
* | ||
* @param str | ||
* @returns {string} | ||
*/ | ||
api.unescape = function unescape (str) { | ||
return str.replace(/~1/g, '/').replace(/~0/g, '~'); | ||
}; | ||
/** | ||
* Converts a json pointer into a array of reference tokens | ||
* | ||
* @param pointer | ||
* @returns {Array} | ||
*/ | ||
api.parse = function parse (pointer) { | ||
if (pointer === '') { return []; } | ||
if (pointer.charAt(0) !== '/') { throw new Error('Invalid JSON pointer: ' + pointer); } | ||
return pointer.substring(1).split(/\//).map(api.unescape); | ||
}; | ||
/** | ||
* Builds a json pointer from a array of reference tokens | ||
* | ||
* @param refTokens | ||
* @returns {string} | ||
*/ | ||
api.compile = function compile (refTokens) { | ||
if (refTokens.length === 0) { return ''; } | ||
return '/' + refTokens.map(api.escape).join('/'); | ||
}; | ||
},{"foreach":1}],3:[function(require,module,exports){ | ||
'use strict'; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.mergeAllOf = mergeAllOf; | ||
var _utils = require('./utils'); | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
function mergeAllOf(schema) { | ||
merge(schema, schema.allOf); | ||
schema.allOf = null; | ||
}; | ||
exports.allOfSample = allOfSample; | ||
function merge(into, schemas) { | ||
var _traverse = require('./traverse'); | ||
function allOfSample(into, children, options, spec) { | ||
var type = into.type; | ||
var subSamples = []; | ||
var _iteratorNormalCompletion = true; | ||
@@ -22,20 +270,13 @@ var _didIteratorError = false; | ||
try { | ||
for (var _iterator = schemas[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | ||
for (var _iterator = children[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | ||
var subSchema = _step.value; | ||
if (into.type && subSchema.type && into.type !== subSchema.type) { | ||
var errMessage = 'allOf merging: schemas with different types can\'t be merged'; | ||
if (type && subSchema.type && type !== subSchema.type) { | ||
var errMessage = 'allOf: schemas with different types can\'t be merged'; | ||
throw new Error(errMessage); | ||
} | ||
if (into.type === 'array') { | ||
throw new Error('allOf merging: subschemas with type array are not supported yet'); | ||
throw new Error('allOf: subschemas with type array are not supported yet'); | ||
} | ||
into.type = into.type || subSchema.type; | ||
if (into.type === 'object' && subSchema.properties) { | ||
into.properties || (into.properties = {}); | ||
Object.assign(into.properties, subSchema.properties); | ||
} | ||
// TODO merging constrains: maximum, minimum, etc. | ||
(0, _utils.defaults)(into, subSchema); | ||
type = type || subSchema.type; | ||
} | ||
@@ -56,5 +297,38 @@ } catch (err) { | ||
} | ||
var mainSample = (0, _traverse.traverse)(_extends({ type: type }, into), options, spec); | ||
var _iteratorNormalCompletion2 = true; | ||
var _didIteratorError2 = false; | ||
var _iteratorError2 = undefined; | ||
try { | ||
for (var _iterator2 = children[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { | ||
var _subSchema = _step2.value; | ||
var subSample = (0, _traverse.traverse)(_extends({ type: type }, _subSchema), options, spec); | ||
if (type === 'object') { | ||
Object.assign(mainSample, subSample); | ||
} else { | ||
mainSample = subSample; | ||
} | ||
} | ||
} catch (err) { | ||
_didIteratorError2 = true; | ||
_iteratorError2 = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion2 && _iterator2.return) { | ||
_iterator2.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError2) { | ||
throw _iteratorError2; | ||
} | ||
} | ||
} | ||
return mainSample; | ||
} | ||
},{"./utils":10}],2:[function(require,module,exports){ | ||
},{"./traverse":12}],4:[function(require,module,exports){ | ||
'use strict'; | ||
@@ -65,6 +339,64 @@ | ||
}); | ||
exports._samplers = undefined; | ||
exports.inferType = inferType; | ||
var schemaKeywordTypes = { | ||
multipleOf: 'number', | ||
maximum: 'number', | ||
exclusiveMaximum: 'number', | ||
minimum: 'number', | ||
exclusiveMinimum: 'number', | ||
maxLength: 'string', | ||
minLength: 'string', | ||
pattern: 'string', | ||
items: 'array', | ||
maxItems: 'array', | ||
minItems: 'array', | ||
uniqueItems: 'array', | ||
additionalItems: 'array', | ||
maxProperties: 'object', | ||
minProperties: 'object', | ||
required: 'object', | ||
additionalProperties: 'object', | ||
properties: 'object', | ||
patternProperties: 'object', | ||
dependencies: 'object' | ||
}; | ||
function inferType(schema) { | ||
if (schema.type !== undefined) { | ||
return schema.type; | ||
} | ||
var keywords = Object.keys(schemaKeywordTypes); | ||
for (var i = 0; i < keywords.length; i++) { | ||
var keyword = keywords[i]; | ||
var type = schemaKeywordTypes[keyword]; | ||
if (schema[keyword] !== undefined) { | ||
return type; | ||
} | ||
} | ||
return 'any'; | ||
} | ||
},{}],5:[function(require,module,exports){ | ||
'use strict'; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.inferType = exports._samplers = undefined; | ||
exports.sample = sample; | ||
exports._registerSampler = _registerSampler; | ||
var _infer = require('./infer'); | ||
Object.defineProperty(exports, 'inferType', { | ||
enumerable: true, | ||
get: function get() { | ||
return _infer.inferType; | ||
} | ||
}); | ||
var _traverse = require('./traverse'); | ||
@@ -74,4 +406,2 @@ | ||
var _normalize = require('./normalize'); | ||
var _samplers = exports._samplers = {}; | ||
@@ -83,5 +413,6 @@ | ||
function sample(schema, options) { | ||
function sample(schema, options, spec) { | ||
var opts = Object.assign({}, defaults, options); | ||
return (0, _traverse.traverse)(schema, opts); | ||
(0, _traverse.clearCache)(); | ||
return (0, _traverse.traverse)(schema, opts, spec); | ||
}; | ||
@@ -100,3 +431,3 @@ | ||
},{"./normalize":1,"./samplers/index":5,"./traverse":9}],3:[function(require,module,exports){ | ||
},{"./infer":4,"./samplers/index":8,"./traverse":12}],6:[function(require,module,exports){ | ||
'use strict'; | ||
@@ -113,2 +444,3 @@ | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
var spec = arguments[2]; | ||
@@ -132,3 +464,3 @@ var arrayLength = schema.minItems || 1; | ||
var itemSchema = itemSchemaGetter(i); | ||
var sample = (0, _traverse.traverse)(itemSchema, options); | ||
var sample = (0, _traverse.traverse)(itemSchema, options, spec); | ||
res.push(sample); | ||
@@ -139,3 +471,3 @@ } | ||
},{"../traverse":9}],4:[function(require,module,exports){ | ||
},{"../traverse":12}],7:[function(require,module,exports){ | ||
"use strict"; | ||
@@ -151,3 +483,3 @@ | ||
},{}],5:[function(require,module,exports){ | ||
},{}],8:[function(require,module,exports){ | ||
'use strict'; | ||
@@ -204,3 +536,3 @@ | ||
},{"./array":3,"./boolean":4,"./number":6,"./object":7,"./string":8}],6:[function(require,module,exports){ | ||
},{"./array":6,"./boolean":7,"./number":9,"./object":10,"./string":11}],9:[function(require,module,exports){ | ||
"use strict"; | ||
@@ -239,3 +571,3 @@ | ||
},{}],7:[function(require,module,exports){ | ||
},{}],10:[function(require,module,exports){ | ||
'use strict'; | ||
@@ -255,2 +587,3 @@ | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
var spec = arguments[2]; | ||
@@ -263,8 +596,8 @@ var res = {}; | ||
} | ||
res[propertyName] = (0, _traverse.traverse)(schema.properties[propertyName], options); | ||
res[propertyName] = (0, _traverse.traverse)(schema.properties[propertyName], options, spec); | ||
}); | ||
} | ||
if (schema && _typeof(schema.additionalProperties) === 'object') { | ||
res.property1 = (0, _traverse.traverse)(schema.additionalProperties, options); | ||
res.property2 = (0, _traverse.traverse)(schema.additionalProperties, options); | ||
res.property1 = (0, _traverse.traverse)(schema.additionalProperties, options, spec); | ||
res.property2 = (0, _traverse.traverse)(schema.additionalProperties, options, spec); | ||
} | ||
@@ -274,3 +607,3 @@ return res; | ||
},{"../traverse":9}],8:[function(require,module,exports){ | ||
},{"../traverse":12}],11:[function(require,module,exports){ | ||
'use strict'; | ||
@@ -361,3 +694,3 @@ | ||
},{"../utils":10}],9:[function(require,module,exports){ | ||
},{"../utils":13}],12:[function(require,module,exports){ | ||
'use strict'; | ||
@@ -368,2 +701,6 @@ | ||
}); | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
exports.clearCache = clearCache; | ||
exports.traverse = traverse; | ||
@@ -373,18 +710,53 @@ | ||
var _normalize = require('./normalize'); | ||
var _allOf = require('./allOf'); | ||
function traverse(schema, options) { | ||
if (schema.allOf) { | ||
(0, _normalize.mergeAllOf)(schema); | ||
var _infer = require('./infer'); | ||
var _jsonPointer = require('json-pointer'); | ||
var _jsonPointer2 = _interopRequireDefault(_jsonPointer); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
var $refCache = {}; | ||
function clearCache() { | ||
$refCache = {}; | ||
} | ||
function traverse(schema, options, spec) { | ||
if (schema.$ref) { | ||
if (!spec) { | ||
throw new Error('Your schema contains $ref. You must provide specification in the third parameter.'); | ||
} | ||
var ref = schema.$ref; | ||
if (ref.startsWith('#')) { | ||
ref = ref.substring(1); | ||
} | ||
var referenced = _jsonPointer2.default.get(spec, ref); | ||
var referencedType = (0, _infer.inferType)(referenced); | ||
var result = referencedType === 'object' ? {} : referencedType === 'array' ? [] : undefined; | ||
if ($refCache[ref] !== true) { | ||
$refCache[ref] = true; | ||
result = traverse(referenced, options, spec); | ||
} | ||
$refCache[ref] = false; | ||
return result; | ||
} | ||
if (schema.example != null) { | ||
if (schema.allOf !== undefined) { | ||
return (0, _allOf.allOfSample)(_extends({}, schema, { allOf: undefined }), schema.allOf, spec); | ||
} | ||
if (schema.example !== undefined) { | ||
return schema.example; | ||
} | ||
if (schema.default != null) { | ||
if (schema.default !== undefined) { | ||
return schema.default; | ||
} | ||
if (schema.enum && schema.enum.length) { | ||
if (schema.enum !== undefined && schema.enum.length) { | ||
return schema.enum[0]; | ||
@@ -394,8 +766,14 @@ } | ||
var type = schema.type; | ||
if (!type) { | ||
type = (0, _infer.inferType)(schema); | ||
} | ||
var sampler = _openapiSampler._samplers[type]; | ||
if (sampler) return sampler(schema, options); | ||
if (sampler) { | ||
return sampler(schema, options, spec); | ||
} | ||
return null; | ||
} | ||
},{"./normalize":1,"./openapi-sampler":2}],10:[function(require,module,exports){ | ||
},{"./allOf":3,"./infer":4,"./openapi-sampler":5,"json-pointer":2}],13:[function(require,module,exports){ | ||
'use strict'; | ||
@@ -446,3 +824,3 @@ | ||
},{}]},{},[2])(2) | ||
},{}]},{},[5])(5) | ||
}); |
{ | ||
"name": "openapi-sampler", | ||
"version": "0.4.3", | ||
"version": "1.0.0-beta.0", | ||
"description": "Tool for generation samples based on OpenAPI payload/response schema", | ||
@@ -15,4 +15,3 @@ "main": "dist/openapi-sampler.js", | ||
"coverage": "gulp coverage", | ||
"prepublish": "npm run build", | ||
"branch-release": "branch-release" | ||
"prepublish": "npm run build" | ||
}, | ||
@@ -40,2 +39,3 @@ "repository": { | ||
"babel-loader": "^6.2.0", | ||
"babel-plugin-transform-object-rest-spread": "^6.26.0", | ||
"babel-polyfill": "^6.3.14", | ||
@@ -45,3 +45,2 @@ "babel-preset-es2015": "^6.3.13", | ||
"babelify": "^7.3.0", | ||
"branch-release": "^1.0.3", | ||
"browserify": "^14.1.0", | ||
@@ -87,3 +86,6 @@ "browserify-istanbul": "^2.0.0", | ||
"watchify": "^3.7.0" | ||
}, | ||
"dependencies": { | ||
"json-pointer": "^0.6.0" | ||
} | ||
} |
@@ -23,5 +23,7 @@ # openapi-sampler | ||
- uri | ||
- Infers schema type automatically following same rules as [json-schema-faker](https://www.npmjs.com/package/json-schema-faker#inferred-types) | ||
- Support for `$ref` resolving | ||
## Installation | ||
#### Node | ||
Install using [npm](https://docs.npmjs.com/getting-started/what-is-npm) | ||
@@ -37,18 +39,4 @@ | ||
#### Web Browsers | ||
Install using [bower](https://bower.io/): | ||
bower install openapi-sampler | ||
Then reference `openapi-sampler.js` in your HTML: | ||
```html | ||
<script src="bower_components/openapi-sampler/openapi-sampler.js"></script> | ||
``` | ||
Then use it via global exposed variable `OpenAPISampler` | ||
## Usage | ||
#### `OpenAPISampler.sample(schema, [options])` | ||
#### `OpenAPISampler.sample(schema, [options], [spec])` | ||
- **schema** (_required_) - `object` | ||
@@ -60,2 +48,3 @@ A [OpenAPI Schema Object](http://swagger.io/specification/#schemaObject) | ||
Don't include `readOnly` object properties | ||
- **spec** - whole specification where the schema is taken from. Required only when schema may contain `$ref`. **spec** must not contain any external references | ||
@@ -62,0 +51,0 @@ ## Example |
@@ -1,4 +0,3 @@ | ||
import { traverse } from './traverse'; | ||
import { sampleArray, sampleBoolean, sampleNumber, sampleObject, sampleString} from './samplers/index'; | ||
import { normalize } from './normalize'; | ||
import { traverse, clearCache } from './traverse'; | ||
import { sampleArray, sampleBoolean, sampleNumber, sampleObject, sampleString } from './samplers/index'; | ||
@@ -11,5 +10,6 @@ export var _samplers = {}; | ||
export function sample(schema, options) { | ||
export function sample(schema, options, spec) { | ||
let opts = Object.assign({}, defaults, options); | ||
return traverse(schema, opts); | ||
clearCache(); | ||
return traverse(schema, opts, spec); | ||
}; | ||
@@ -21,2 +21,4 @@ | ||
export { inferType } from './infer'; | ||
_registerSampler('array', sampleArray); | ||
@@ -23,0 +25,0 @@ _registerSampler('boolean', sampleBoolean); |
import { traverse } from '../traverse'; | ||
export function sampleArray(schema, options = {}) { | ||
export function sampleArray(schema, options = {}, spec) { | ||
let arrayLength = schema.minItems || 1; | ||
@@ -20,3 +20,3 @@ if (Array.isArray(schema.items)) { | ||
let itemSchema = itemSchemaGetter(i); | ||
let sample = traverse(itemSchema, options); | ||
let sample = traverse(itemSchema, options, spec); | ||
res.push(sample); | ||
@@ -23,0 +23,0 @@ } |
import { traverse } from '../traverse'; | ||
export function sampleObject(schema, options = {}) { | ||
export function sampleObject(schema, options = {}, spec) { | ||
let res = {}; | ||
@@ -9,10 +9,10 @@ if (schema && typeof schema.properties === 'object') { | ||
} | ||
res[propertyName] = traverse(schema.properties[propertyName], options); | ||
res[propertyName] = traverse(schema.properties[propertyName], options, spec); | ||
}); | ||
} | ||
if (schema && typeof schema.additionalProperties === 'object') { | ||
res.property1 = traverse(schema.additionalProperties, options); | ||
res.property2 = traverse(schema.additionalProperties, options); | ||
res.property1 = traverse(schema.additionalProperties, options, spec); | ||
res.property2 = traverse(schema.additionalProperties, options, spec); | ||
} | ||
return res; | ||
} |
import { _samplers } from './openapi-sampler'; | ||
import { mergeAllOf } from './normalize'; | ||
import { allOfSample } from './allOf'; | ||
import { inferType } from './infer'; | ||
import JsonPointer from 'json-pointer'; | ||
export function traverse(schema, options) { | ||
if (schema.allOf) { | ||
mergeAllOf(schema); | ||
let $refCache = {}; | ||
export function clearCache() { | ||
$refCache = {}; | ||
} | ||
export function traverse(schema, options, spec) { | ||
if (schema.$ref) { | ||
if (!spec) { | ||
throw new Error('Your schema contains $ref. You must provide specification in the third parameter.'); | ||
} | ||
let ref = schema.$ref; | ||
if (ref.startsWith('#')) { | ||
ref = ref.substring(1); | ||
} | ||
const referenced = JsonPointer.get(spec, ref); | ||
const referencedType = inferType(referenced); | ||
let result = referencedType === 'object' ? | ||
{} | ||
: referencedType === 'array' ? | ||
[] | ||
: undefined; | ||
if ($refCache[ref] !== true) { | ||
$refCache[ref] = true; | ||
result = traverse(referenced, options, spec); | ||
} | ||
$refCache[ref] = false; | ||
return result; | ||
} | ||
if (schema.example != null) { | ||
if (schema.allOf !== undefined) { | ||
return allOfSample({ ...schema, allOf: undefined }, schema.allOf, spec); | ||
} | ||
if (schema.example !== undefined) { | ||
return schema.example; | ||
} | ||
if (schema.default != null) { | ||
if (schema.default !== undefined) { | ||
return schema.default; | ||
} | ||
if (schema.enum && schema.enum.length) { | ||
if (schema.enum !== undefined && schema.enum.length) { | ||
return schema.enum[0]; | ||
@@ -22,5 +55,11 @@ } | ||
let type = schema.type; | ||
if (!type) { | ||
type = inferType(schema); | ||
} | ||
let sampler = _samplers[type]; | ||
if (sampler) return sampler(schema, options); | ||
if (sampler) { | ||
return sampler(schema, options, spec); | ||
} | ||
return null; | ||
} |
@@ -173,2 +173,74 @@ 'use strict'; | ||
}); | ||
it('should throw for schemas with allOf with different types', function() { | ||
schema = { | ||
'allOf': [ | ||
{ | ||
'type': 'string' | ||
}, | ||
{ | ||
'type': 'object', | ||
'properties': { | ||
'amount': { | ||
'type': 'number', | ||
'default': 1 | ||
} | ||
} | ||
} | ||
] | ||
}; | ||
expect(() => OpenAPISampler.sample(schema)).to.throw(); | ||
}); | ||
it('should sample schema with allOf even if some type is not specified', function() { | ||
schema = { | ||
'properties': { | ||
'title': { | ||
'type': 'string' | ||
} | ||
}, | ||
'allOf': [ | ||
{ | ||
'type': 'object', | ||
'properties': { | ||
'amount': { | ||
'type': 'number', | ||
'default': 1 | ||
} | ||
} | ||
} | ||
] | ||
}; | ||
result = OpenAPISampler.sample(schema); | ||
expected = { | ||
'title': 'string', | ||
'amount': 1 | ||
}; | ||
expect(result).to.deep.equal(expected); | ||
schema = { | ||
'type': 'object', | ||
'properties': { | ||
'title': { | ||
'type': 'string' | ||
} | ||
}, | ||
'allOf': [ | ||
{ | ||
'properties': { | ||
'amount': { | ||
'type': 'number', | ||
'default': 1 | ||
} | ||
} | ||
} | ||
] | ||
}; | ||
result = OpenAPISampler.sample(schema); | ||
expected = { | ||
'title': 'string', | ||
'amount': 1 | ||
}; | ||
expect(result).to.deep.equal(expected); | ||
}); | ||
}); | ||
@@ -215,2 +287,87 @@ | ||
}); | ||
describe('Detection', function() { | ||
it('should detect autodetect types based on props', function() { | ||
schema = { | ||
properties: { | ||
a: { | ||
minimum: 10 | ||
}, | ||
b: { | ||
minLength: 1 | ||
} | ||
} | ||
}; | ||
result = OpenAPISampler.sample(schema); | ||
expected = { | ||
a: 10, | ||
b: 'string' | ||
}; | ||
expect(result).to.deep.equal(expected); | ||
}); | ||
}); | ||
describe('$refs', function() { | ||
it('should follow $ref', function() { | ||
schema = { | ||
$ref: '#/defs/Schema' | ||
}; | ||
const spec = { | ||
defs: { | ||
Schema: { | ||
type: 'object', | ||
properties: { | ||
a: { | ||
type: 'string' | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
result = OpenAPISampler.sample(schema, {}, spec); | ||
expected = { | ||
a: 'string' | ||
}; | ||
expect(result).to.deep.equal(expected); | ||
}); | ||
it('should not follow circular $ref', function() { | ||
schema = { | ||
$ref: '#/defs/Schema' | ||
}; | ||
const spec = { | ||
defs: { | ||
str: { | ||
type: 'string' | ||
}, | ||
Schema: { | ||
type: 'object', | ||
properties: { | ||
a: { | ||
$ref: '#/defs/str' | ||
}, | ||
b: { | ||
$ref: '#/defs/Schema' | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
result = OpenAPISampler.sample(schema, {}, spec); | ||
expected = { | ||
a: 'string', | ||
b: {} | ||
}; | ||
expect(result).to.deep.equal(expected); | ||
}); | ||
it('should throw if schema has $ref and spec is not provided', function() { | ||
schema = { | ||
$ref: '#/defs/Schema' | ||
}; | ||
expect(() => OpenAPISampler.sample(schema)).to | ||
.throw(/You must provide specification in the third parameter/); | ||
}); | ||
}); | ||
}); |
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 not supported yet
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
256585
1768
1
61
+ Addedjson-pointer@^0.6.0
+ Addedforeach@2.0.6(transitive)
+ Addedjson-pointer@0.6.2(transitive)