Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

openapi-sampler

Package Overview
Dependencies
Maintainers
1
Versions
49
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

openapi-sampler - npm Package Compare versions

Comparing version 1.0.0-beta.18 to 1.0.0

src/types.d.ts

225

dist/openapi-sampler.js

@@ -97,4 +97,11 @@ (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(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){

if (refTokens.length === 0) {
throw Error('Can not set the root object');
}
for (var i = 0; i < refTokens.length - 1; ++i) {
var tok = refTokens[i];
if (tok === "__proto__" || tok === "constructor" || tok === "prototype") {
continue
}
if (tok === '-' && Array.isArray(obj)) {

@@ -262,27 +269,33 @@ tok = obj.length;

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function allOfSample(into, children, options, spec, context) {
var res = (0, _traverse2.traverse)(into, options, spec);
var subSamples = [];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
var _iterator = _createForOfIteratorHelper(children),
_step;
try {
for (var _iterator = children[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var subSchema = _step.value;

@@ -309,14 +322,5 @@

} catch (err) {
_didIteratorError = true;
_iteratorError = err;
_iterator.e(err);
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
_iterator.f();
}

@@ -373,3 +377,3 @@

if (schema.type !== undefined) {
return schema.type;
return Array.isArray(schema.type) ? schema.type.length === 0 ? null : schema.type[0] : schema.type;
}

@@ -420,3 +424,4 @@

function sample(schema, options, spec) {
function sample(schema, options) {
var spec = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : schema;
var opts = Object.assign({}, defaults, options);

@@ -462,6 +467,8 @@ (0, _traverse.clearCache)();

var depth = context && context.depth || 1;
var arrayLength = schema.minItems || 1;
var arrayLength = Math.min('maxItems' in schema ? schema.maxItems : Infinity, schema.minItems || 1); // for the sake of simplicity, we're treating `contains` in a similar way to `items`
if (Array.isArray(schema.items)) {
arrayLength = Math.max(arrayLength, schema.items.length);
var items = schema.items || schema.contains;
if (Array.isArray(items)) {
arrayLength = Math.max(arrayLength, items.length);
}

@@ -471,10 +478,10 @@

if (Array.isArray(schema.items)) {
return schema.items[itemNumber] || {};
return items[itemNumber] || {};
}
return schema.items || {};
return items || {};
};
var res = [];
if (!schema.items) return res;
if (!items) return res;

@@ -563,31 +570,50 @@ for (var i = 0; i < arrayLength; i++) {

function sampleNumber(schema) {
var res;
var res = 0;
if (schema.maximum && schema.minimum) {
res = schema.exclusiveMinimum ? Math.floor(schema.minimum) + 1 : schema.minimum;
if (typeof schema.exclusiveMinimum === 'boolean' || typeof schema.exclusiveMaximum === 'boolean') {
//legacy support for jsonschema draft 4 of exclusiveMaximum/exclusiveMinimum as booleans
if (schema.maximum && schema.minimum) {
res = schema.exclusiveMinimum ? Math.floor(schema.minimum) + 1 : schema.minimum;
if (schema.exclusiveMaximum && res >= schema.maximum || !schema.exclusiveMaximum && res > schema.maximum) {
res = (schema.maximum + schema.minimum) / 2;
if (schema.exclusiveMaximum && res >= schema.maximum || !schema.exclusiveMaximum && res > schema.maximum) {
res = (schema.maximum + schema.minimum) / 2;
}
return res;
}
return res;
}
if (schema.minimum) {
if (schema.exclusiveMinimum) {
return Math.floor(schema.minimum) + 1;
} else {
return schema.minimum;
}
}
if (schema.minimum) {
if (schema.exclusiveMinimum) {
return Math.floor(schema.minimum) + 1;
} else {
if (schema.maximum) {
if (schema.exclusiveMaximum) {
return schema.maximum > 0 ? 0 : Math.floor(schema.maximum) - 1;
} else {
return schema.maximum > 0 ? 0 : schema.maximum;
}
}
} else {
if (schema.minimum) {
return schema.minimum;
}
}
if (schema.maximum) {
if (schema.exclusiveMaximum) {
return schema.maximum > 0 ? 0 : Math.floor(schema.maximum) - 1;
} else {
return schema.maximum > 0 ? 0 : schema.maximum;
if (schema.exclusiveMinimum) {
res = Math.floor(schema.exclusiveMinimum) + 1;
if (res === schema.exclusiveMaximum) {
res = (res + Math.floor(schema.exclusiveMaximum) - 1) / 2;
}
} else if (schema.exclusiveMaximum) {
res = Math.floor(schema.exclusiveMaximum) - 1;
} else if (schema.maximum) {
res = schema.maximum;
}
}
return 0;
return res;
}

@@ -605,3 +631,3 @@

function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

@@ -683,4 +709,8 @@ function sampleObject(schema) {

function commonDateTimeSample(min, max, omitTime) {
var res = (0, _utils.toRFCDateTime)(new Date('2019-08-24T14:15:22.123Z'), omitTime, false);
function commonDateTimeSample(_ref) {
var min = _ref.min,
max = _ref.max,
omitTime = _ref.omitTime,
omitDate = _ref.omitDate;
var res = (0, _utils.toRFCDateTime)(new Date('2019-08-24T14:15:22.123Z'), omitTime, omitDate, false);

@@ -699,9 +729,28 @@ if (res.length < min) {

function dateTimeSample(min, max) {
return commonDateTimeSample(min, max);
return commonDateTimeSample({
min: min,
max: max,
omitTime: false,
omitDate: false
});
}
function dateSample(min, max) {
return commonDateTimeSample(min, max, true);
return commonDateTimeSample({
min: min,
max: max,
omitTime: true,
omitDate: false
});
}
function timeSample(min, max) {
return commonDateTimeSample({
min: min,
max: max,
omitTime: false,
omitDate: true
}).slice(1);
}
function defaultSample(min, max) {

@@ -733,2 +782,18 @@ var res = (0, _utils.ensureMinLength)('string', min);

function uriReferenceSample() {
return '../dictionary';
}
function uriTemplateSample() {
return 'http://example.com/{endpoint}';
}
function iriSample() {
return 'http://example.com';
}
function iriReferenceSample() {
return '../dictionary';
}
function uuidSample(_min, _max, propertyName) {

@@ -738,13 +803,41 @@ return (0, _utils.uuid)(propertyName || 'id');

function jsonPointerSample() {
return '/json/pointer';
}
function relativeJsonPointerSample() {
return '1/relative/json/pointer';
}
function regexSample() {
return '/regex/';
}
var stringFormats = {
'email': emailSample,
'idn-email': emailSample,
// https://tools.ietf.org/html/rfc6531#section-3.3
'password': passwordSample,
'date-time': dateTimeSample,
'date': dateSample,
'time': timeSample,
// full-time in https://tools.ietf.org/html/rfc3339#section-5.6
'ipv4': ipv4Sample,
'ipv6': ipv6Sample,
'hostname': hostnameSample,
'idn-hostname': hostnameSample,
// https://tools.ietf.org/html/rfc5890#section-2.3.2.3
'iri': iriSample,
// https://tools.ietf.org/html/rfc3987
'iri-reference': iriReferenceSample,
'uri': uriSample,
'uri-reference': uriReferenceSample,
// either a URI or relative-reference https://tools.ietf.org/html/rfc3986#section-4.1
'uri-template': uriTemplateSample,
'uuid': uuidSample,
'default': defaultSample
'default': defaultSample,
'json-pointer': jsonPointerSample,
'relative-json-pointer': relativeJsonPointerSample,
// https://tools.ietf.org/html/draft-handrews-relative-json-pointer-01
'regex': regexSample
};

@@ -780,5 +873,5 @@

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

@@ -810,6 +903,2 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

if (schema.$ref) {
if (!spec) {
throw new Error('Your schema contains $ref. You must provide full specification in the third parameter.');
}
var ref = decodeURIComponent(schema.$ref);

@@ -850,3 +939,3 @@

(0, _utils.popSchemaStack)(seenSchemasStack, context);
return (0, _allOf.allOfSample)(_objectSpread({}, schema, {
return (0, _allOf.allOfSample)(_objectSpread(_objectSpread({}, schema), {}, {
allOf: undefined

@@ -870,2 +959,6 @@ }), schema.allOf, options, spec, context);

if (schema.if && schema.then) {
return traverse((0, _utils.mergeDeep)(schema.if, schema.then), options, spec, context);
}
var example = null;

@@ -885,2 +978,6 @@ var type = null;

if (Array.isArray(type) && schema.type.length > 0) {
type = schema.type[0];
}
if (!type) {

@@ -919,3 +1016,3 @@ type = (0, _infer.inferType)(schema);

function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

@@ -930,4 +1027,4 @@ function pad(number) {

function toRFCDateTime(date, omitTime, milliseconds) {
var res = date.getUTCFullYear() + '-' + pad(date.getUTCMonth() + 1) + '-' + pad(date.getUTCDate());
function toRFCDateTime(date, omitTime, omitDate, milliseconds) {
var res = omitDate ? '' : date.getUTCFullYear() + '-' + pad(date.getUTCMonth() + 1) + '-' + pad(date.getUTCDate());

@@ -934,0 +1031,0 @@ if (!omitTime) {

{
"name": "openapi-sampler",
"version": "1.0.0-beta.18",
"version": "1.0.0",
"description": "Tool for generation samples based on OpenAPI payload/response schema",

@@ -39,2 +39,4 @@ "main": "dist/openapi-sampler.js",

"@babel/register": "^7.7.0",
"ajv": "^8.1.0",
"ajv-formats": "^2.0.2",
"babel-eslint": "^10.0.3",

@@ -62,2 +64,3 @@ "babel-loader": "^8.0.6",

"gulp-uglify": "^3.0.2",
"it-each": "^0.4.0",
"json-loader": "^0.5.7",

@@ -83,4 +86,5 @@ "karma": "^4.4.1",

"dependencies": {
"json-pointer": "^0.6.0"
"@types/json-schema": "^7.0.7",
"json-pointer": "^0.6.1"
}
}

@@ -8,18 +8,29 @@ # openapi-sampler

## Features
- deterministic (given a particular input, will always produce the same output)
- Supports `allOf`
- Deterministic (given a particular input, will always produce the same output)
- Supports compound keywords: `allOf`, `oneOf`, `anyOf`, `if/then/else`
- Supports `additionalProperties`
- Uses `default`, `const`, `enum` and `examples` where possible
- Full array support: supports `minItems`, and tuples (`items` as an array)
- Good array support: supports `contains`, `minItems`, `maxItems`, and tuples (`items` as an array)
- Supports `minLength`, `maxLength`, `min`, `max`, `exclusiveMinimum`, `exclusiveMaximum`
- Supports the next `string` formats:
- Supports the following `string` formats:
- email
- idn-email
- password
- date-time
- date
- time
- ipv4
- ipv6
- hostname
- idn-hostname
- uri
- uri-reference
- uri-template
- iri
- iri-reference
- uuid
- json-pointer
- relative-json-pointer
- regex
- Infers schema type automatically following same rules as [json-schema-faker](https://www.npmjs.com/package/json-schema-faker#inferred-types)

@@ -26,0 +37,0 @@ - Support for `$ref` resolving

@@ -29,3 +29,3 @@ const schemaKeywordTypes = {

if (schema.type !== undefined) {
return schema.type;
return Array.isArray(schema.type) ? schema.type.length === 0 ? null : schema.type[0] : schema.type;
}

@@ -32,0 +32,0 @@ const keywords = Object.keys(schemaKeywordTypes);

@@ -11,3 +11,3 @@ import { traverse, clearCache } from './traverse';

export function sample(schema, options, spec) {
export function sample(schema, options, spec = schema) {
let opts = Object.assign({}, defaults, options);

@@ -14,0 +14,0 @@ clearCache();

@@ -5,5 +5,7 @@ import { traverse } from '../traverse';

let arrayLength = schema.minItems || 1;
if (Array.isArray(schema.items)) {
arrayLength = Math.max(arrayLength, schema.items.length);
let arrayLength = Math.min('maxItems' in schema ? schema.maxItems : Infinity, schema.minItems || 1);
// for the sake of simplicity, we're treating `contains` in a similar way to `items`
const items = schema.items || schema.contains;
if (Array.isArray(items)) {
arrayLength = Math.max(arrayLength, items.length);
}

@@ -13,9 +15,9 @@

if (Array.isArray(schema.items)) {
return schema.items[itemNumber] || {};
return items[itemNumber] || {};
}
return schema.items || {};
return items || {};
};
let res = [];
if (!schema.items) return res;
if (!items) return res;

@@ -22,0 +24,0 @@ for (let i = 0; i < arrayLength; i++) {

export function sampleNumber(schema) {
let res;
if (schema.maximum && schema.minimum) {
res = schema.exclusiveMinimum ? Math.floor(schema.minimum) + 1 : schema.minimum;
if ((schema.exclusiveMaximum && res >= schema.maximum) ||
((!schema.exclusiveMaximum && res > schema.maximum))) {
res = (schema.maximum + schema.minimum) / 2;
let res = 0;
if (typeof schema.exclusiveMinimum === 'boolean' || typeof schema.exclusiveMaximum === 'boolean') { //legacy support for jsonschema draft 4 of exclusiveMaximum/exclusiveMinimum as booleans
if (schema.maximum && schema.minimum) {
res = schema.exclusiveMinimum ? Math.floor(schema.minimum) + 1 : schema.minimum;
if ((schema.exclusiveMaximum && res >= schema.maximum) ||
((!schema.exclusiveMaximum && res > schema.maximum))) {
res = (schema.maximum + schema.minimum) / 2;
}
return res;
}
return res;
}
if (schema.minimum) {
if (schema.exclusiveMinimum) {
return Math.floor(schema.minimum) + 1;
} else {
if (schema.minimum) {
if (schema.exclusiveMinimum) {
return Math.floor(schema.minimum) + 1;
} else {
return schema.minimum;
}
}
if (schema.maximum) {
if (schema.exclusiveMaximum) {
return (schema.maximum > 0) ? 0 : Math.floor(schema.maximum) - 1;
} else {
return (schema.maximum > 0) ? 0 : schema.maximum;
}
}
} else {
if (schema.minimum) {
return schema.minimum;
}
}
if (schema.maximum) {
if (schema.exclusiveMaximum) {
return (schema.maximum > 0) ? 0 : Math.floor(schema.maximum) - 1;
} else {
return (schema.maximum > 0) ? 0 : schema.maximum;
if (schema.exclusiveMinimum) {
res = Math.floor(schema.exclusiveMinimum) + 1;
if (res === schema.exclusiveMaximum) {
res = (res + Math.floor(schema.exclusiveMaximum) - 1) / 2;
}
} else if (schema.exclusiveMaximum) {
res = Math.floor(schema.exclusiveMaximum) - 1;
} else if (schema.maximum) {
res = schema.maximum;
}
}
return 0;
return res;
}

@@ -20,4 +20,4 @@ 'use strict';

function commonDateTimeSample(min, max, omitTime) {
let res = toRFCDateTime(new Date('2019-08-24T14:15:22.123Z'), omitTime, false);
function commonDateTimeSample({ min, max, omitTime, omitDate }) {
let res = toRFCDateTime(new Date('2019-08-24T14:15:22.123Z'), omitTime, omitDate, false);
if (res.length < min) {

@@ -33,9 +33,13 @@ console.warn(`Using minLength = ${min} is incorrect with format "date-time"`);

function dateTimeSample(min, max) {
return commonDateTimeSample(min, max);
return commonDateTimeSample({ min, max, omitTime: false, omitDate: false });
}
function dateSample(min, max) {
return commonDateTimeSample(min, max, true);
return commonDateTimeSample({ min, max, omitTime: true, omitDate: false });
}
function timeSample(min, max) {
return commonDateTimeSample({ min, max, omitTime: false, omitDate: true }).slice(1);
}
function defaultSample(min, max) {

@@ -65,2 +69,18 @@ let res = ensureMinLength('string', min);

function uriReferenceSample() {
return '../dictionary';
}
function uriTemplateSample() {
return 'http://example.com/{endpoint}';
}
function iriSample() {
return 'http://example.com';
}
function iriReferenceSample() {
return '../dictionary';
}
function uuidSample(_min, _max, propertyName) {

@@ -70,13 +90,35 @@ return uuid(propertyName || 'id');

function jsonPointerSample() {
return '/json/pointer';
}
function relativeJsonPointerSample() {
return '1/relative/json/pointer';
}
function regexSample() {
return '/regex/';
}
const stringFormats = {
'email': emailSample,
'idn-email': emailSample, // https://tools.ietf.org/html/rfc6531#section-3.3
'password': passwordSample,
'date-time': dateTimeSample,
'date': dateSample,
'time': timeSample, // full-time in https://tools.ietf.org/html/rfc3339#section-5.6
'ipv4': ipv4Sample,
'ipv6': ipv6Sample,
'hostname': hostnameSample,
'idn-hostname': hostnameSample, // https://tools.ietf.org/html/rfc5890#section-2.3.2.3
'iri': iriSample, // https://tools.ietf.org/html/rfc3987
'iri-reference': iriReferenceSample,
'uri': uriSample,
'uri-reference': uriReferenceSample, // either a URI or relative-reference https://tools.ietf.org/html/rfc3986#section-4.1
'uri-template': uriTemplateSample,
'uuid': uuidSample,
'default': defaultSample
'default': defaultSample,
'json-pointer': jsonPointerSample,
'relative-json-pointer': relativeJsonPointerSample, // https://tools.ietf.org/html/draft-handrews-relative-json-pointer-01
'regex': regexSample,
};

@@ -83,0 +125,0 @@

import { _samplers } from './openapi-sampler';
import { allOfSample } from './allOf';
import { inferType } from './infer';
import { getResultForCircular, popSchemaStack } from './utils';
import { getResultForCircular, mergeDeep, popSchemaStack } from './utils';
import JsonPointer from 'json-pointer';

@@ -31,5 +31,2 @@

if (schema.$ref) {
if (!spec) {
throw new Error('Your schema contains $ref. You must provide full specification in the third parameter.');
}
let ref = decodeURIComponent(schema.$ref);

@@ -90,2 +87,6 @@ if (ref.startsWith('#')) {

if (schema.if && schema.then) {
return traverse(mergeDeep(schema.if, schema.then), options, spec, context);
}
let example = null;

@@ -103,2 +104,5 @@ let type = null;

type = schema.type;
if (Array.isArray(type) && schema.type.length > 0) {
type = schema.type[0];
}
if (!type) {

@@ -105,0 +109,0 @@ type = inferType(schema);

@@ -10,6 +10,6 @@ 'use strict';

export function toRFCDateTime(date, omitTime, milliseconds) {
var res = date.getUTCFullYear() +
export function toRFCDateTime(date, omitTime, omitDate, milliseconds) {
var res = omitDate ? '' : (date.getUTCFullYear() +
'-' + pad(date.getUTCMonth() + 1) +
'-' + pad(date.getUTCDate());
'-' + pad(date.getUTCDate()));
if (!omitTime) {

@@ -96,2 +96,2 @@ res += 'T' + pad(date.getUTCHours()) +

}
}
}

@@ -47,2 +47,20 @@ 'use strict';

it('should support type array', function() {
schema = {
'type': ['string', 'number']
};
result = OpenAPISampler.sample(schema);
expected = 'string';
expect(result).to.deep.equal(expected);
});
it('should use null for null', function() {
schema = {
type: 'null'
};
result = OpenAPISampler.sample(schema);
expected = null;
expect(result).to.deep.equal(expected);
});
it('should use null if type is not specified', function() {

@@ -55,2 +73,11 @@ schema = {

});
it('should use null if type array is empty', function() {
schema = {
type: []
};
result = OpenAPISampler.sample(schema);
expected = null;
expect(result).to.deep.equal(expected);
});
});

@@ -433,51 +460,69 @@

describe('oneOf and anyOf', function() {
it('should support oneOf', function() {
describe('Compound keywords', () => {
it('should support basic if/then/else usage', () => {
schema = {
oneOf: [
{
type: 'string'
},
{
type: 'number'
}
]
type: 'object',
if: {properties: {foo: {type: 'string', format: 'email'}}},
then: {properties: {bar: {type: 'string'}}},
else: {properties: {baz: {type: 'number'}}},
};
result = OpenAPISampler.sample(schema);
expected = 'string';
expect(result).to.equal(expected);
});
it('should support anyOf', function() {
schema = {
anyOf: [
{
type: 'string'
},
{
type: 'number'
}
]
expected = {
foo: 'user@example.com',
bar: 'string'
};
result = OpenAPISampler.sample(schema);
expected = 'string';
expect(result).to.equal(expected);
});
expect(result).to.deep.equal(expected);
})
it('should prefer oneOf if anyOf and oneOf are on the same level ', function() {
schema = {
anyOf: [
{
type: 'string'
}
],
oneOf: [
{
type: 'number'
}
]
};
result = OpenAPISampler.sample(schema);
expected = 0;
expect(result).to.equal(expected);
describe('oneOf and anyOf', function () {
it('should support oneOf', function () {
schema = {
oneOf: [
{
type: 'string'
},
{
type: 'number'
}
]
};
result = OpenAPISampler.sample(schema);
expected = 'string';
expect(result).to.equal(expected);
});
it('should support anyOf', function () {
schema = {
anyOf: [
{
type: 'string'
},
{
type: 'number'
}
]
};
result = OpenAPISampler.sample(schema);
expected = 'string';
expect(result).to.equal(expected);
});
it('should prefer oneOf if anyOf and oneOf are on the same level ', function () {
schema = {
anyOf: [
{
type: 'string'
}
],
oneOf: [
{
type: 'number'
}
]
};
result = OpenAPISampler.sample(schema);
expected = 0;
expect(result).to.equal(expected);
});
});

@@ -488,6 +533,8 @@ });

it('should follow $ref', function() {
schema = {
$ref: '#/defs/Schema'
};
const spec = {
const schema = {
properties: {
test: {
$ref: '#/defs/Schema'
}
},
defs: {

@@ -504,5 +551,7 @@ Schema: {

};
result = OpenAPISampler.sample(schema, {}, spec);
result = OpenAPISampler.sample(schema, {});
expected = {
a: 'string'
test: {
a: 'string'
}
};

@@ -575,3 +624,3 @@ expect(result).to.deep.equal(expected);

expect(() => OpenAPISampler.sample(schema)).to
.throw(/You must provide full specification in the third parameter/);
.throw(/Invalid reference token: defs/);
});

@@ -578,0 +627,0 @@

@@ -14,4 +14,11 @@ import { sampleArray } from '../../src/samplers/array.js';

expect(res).to.deep.equal([0]);
res = sampleArray({contains: {type: 'number'}});
expect(res).to.deep.equal([0]);
});
it('should return correct number of elements based on maxItems', () => {
res = sampleArray({items: {type: 'number'}, maxItems: 0});
expect(res).to.deep.equal([]);
});
it('should return correct number of elements based on minItems', () => {

@@ -22,3 +29,3 @@ res = sampleArray({items: {type: 'number'}, minItems: 3});

it('should correcly sample tuples', () => {
it('should correctly sample tuples', () => {
res = sampleArray({items: [{type: 'number'}, {type: 'string'}, {}]});

@@ -25,0 +32,0 @@ expect(res).to.deep.equal([0, 'string', null]);

@@ -40,2 +40,7 @@ import { sampleNumber } from '../../src/samplers/number.js';

it('should return maximum -1 if maximum is negative and exclusiveMaximum', () => {
res = sampleNumber({maximum: -3, exclusiveMaximum: true, minimum: 1, exclusiveMinimum: true});
expect(res).to.equal(-1);
});
it('should return minimum if both minimum and maximum are specified', () => {

@@ -46,13 +51,34 @@ res = sampleNumber({maximum: 10, minimum: 3});

// (2, 3) -> 2.5
it('should return middle point if integer is not possible', () => {
res = sampleNumber({minimum: 2, maximum: 3, exclusiveMinimum: true, exclusiveMaximum: true});
expect(res).to.equal(2.5);
it('should return exclusiveMinimum + 1 if exclusiveMinimum is specified for openapi3.1', () => {
res = sampleNumber({exclusiveMinimum: 3});
expect(res).to.equal(4);
});
// (2, 3] -> 3
it('should return closer to minimum possible int', () => {
res = sampleNumber({minimum: 2, maximum: 3, exclusiveMinimum: true});
expect(res).to.equal(3);
it('should return exclusiveMaximum - 1 if exclusiveMaximum is specified for openapi3.1', () => {
res = sampleNumber({exclusiveMaximum: -3});
expect(res).to.equal(-4);
});
// (2, 3) -> 2.5
it('should return middle point if boundary integer is not possible for openapi3.1', () => {
res = sampleNumber({exclusiveMinimum: 2, exclusiveMaximum: 3});
expect(res).to.equal(2.5);
});
// [2, 3] -> 2
// (8, 13) -> 9
it('should return closer to minimum possible int for openapi3.1', () => {
res = sampleNumber({minimum: 2, maximum: 3});
expect(res).to.equal(2);
res = sampleNumber({exclusiveMinimum: 8, exclusiveMaximum: 13});
expect(res).to.equal(9);
});
it('should return closer to minimum possible int for openapi3.1', () => {
res = sampleNumber({minimum: 2, maximum: 3});
expect(res).to.equal(2);
res = sampleNumber({exclusiveMinimum: 8, exclusiveMaximum: 13});
expect(res).to.equal(9);
});
});
import { sampleString } from '../../src/samplers/string.js';
import Ajv from 'ajv';
import addFormats from 'ajv-formats';
const ajv = new Ajv({ allErrors: true, messages: true, strict: true });
addFormats(ajv);
require('it-each')();
const IPV4_REGEXP = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;

@@ -77,2 +86,17 @@ const IPV6_REGEXP = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;

it('should return deterministic time string for format date-time', () => {
res = sampleString({format: 'time'});
expect(res).to.equal('14:15:22Z');
});
it('should not throw if incorrect maxLength applied to time', () => {
res = sampleString({format: 'time', maxLength: 5});
expect(res).to.equal('14:15:22Z')
});
it('should not throw if incorrect minLength applied to time', () => {
res = sampleString({format: 'time', minLength: 100});
expect(res).to.equal('14:15:22Z')
});
it('should return ip for ipv4 format', () => {

@@ -109,2 +133,27 @@ res = sampleString({format: 'ipv4'});

});
it.each([
'email',
// 'idn-email', // unsupported by ajv-formats
// 'password', // unsupported by ajv-formats
'date-time',
'date',
'time',
'ipv4',
'ipv6',
'hostname',
// 'idn-hostname', // unsupported by ajv-formats
'uri',
'uri-reference',
'uri-template',
// 'iri', // unsupported by ajv-formats
// 'iri-reference', // unsupported by ajv-formats
'uuid',
'json-pointer',
'relative-json-pointer',
'regex'
], 'should return valid %s', format => {
const schema = {type: 'string',format};
expect(ajv.compile(schema)(sampleString(schema))).to.be.true;
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc