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

joi-to-swagger

Package Overview
Dependencies
Maintainers
1
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

joi-to-swagger - npm Package Compare versions

Comparing version 3.3.0 to 4.0.0

15

CHANGELOG.md

@@ -0,1 +1,16 @@

4.0.0 / 2020-02-07
==================
* BREAKING CHANGE: Move joi to @hapi/joi package with version > 16.0 which was a major rewrite
* BREAKING CHANGE: Instead of use joi.object().unknown(false) to disallow additional properties
this is the default now. To allow additional properties use joi.object().unknown()
* BREAKING CHANGE: removed support for "swaggerIndex", because it is no longer needed due to added support of "oneOf, anyOf, allOf" keywords
* add support for OAS3 "oneOf, anyOf, allOf and not" keywords
- this functionality is reflected in the processing of `joi.when()` conditions, `joi.alternatives()` and `joi.array().items()`
* add support for "switch" condition - `joi.when('x', { is: true, switch: { ... } })`
* add support for "invalid" method - `joi.string().invalid('A','B','C')`
* add add support for "uuid" format for string type
* add support for ES6 default import syntax
* fix string token pattern
3.3.0 / 2019-10-18

@@ -2,0 +17,0 @@ ==================

2

index.d.ts

@@ -1,2 +0,2 @@

import { Schema } from 'joi';
import { Schema } from '@hapi/joi';

@@ -3,0 +3,0 @@ interface SwaggerSchema {

'use strict';
var joi = require('joi');
var { find, get, set, merge } = require('lodash');
const joi = require('@hapi/joi');
const { find, get, isEqual, isNumber, isPlainObject, isString, merge, set, uniqWith } = require('lodash');
var patterns = {
const patterns = {
alphanum: '^[a-zA-Z0-9]*$',
alphanumLower: '^[a-z0-9]*$',
alphanumUpper: '^[A-Z0-9]*$',
token: '^[a-zA-Z0-9_]*$',
};
var isJoi = function (joiObj) {
return !!((joiObj && joiObj.isJoi));
};
function meta (schema, key) {
const flattened = Object.assign.apply(null, [ {} ].concat(schema.$_terms.metas));
var hasJoiMeta = function (joiObj) {
return !!((isJoi(joiObj) && Array.isArray(joiObj._meta)));
};
return get(flattened, key);
}
var getJoiMetaProperty = function (joiObj, propertyName) {
function refDef (type, name) {
return { $ref: '#/components/' + type + '/' + name };
}
// get headers added using meta function
if (isJoi(joiObj) && hasJoiMeta(joiObj)) {
function getMinMax (schema, suffix = 'Length') {
const swagger = {};
for (let i = 0; i < schema._rules.length; i++) {
const test = schema._rules[i];
if (test.name === 'min') {
swagger[`min${suffix}`] = test.args.limit;
}
var joiMeta = joiObj._meta;
let i = joiMeta.length;
while (i--) {
if (joiMeta[i][propertyName]) {
return joiMeta[i][propertyName];
}
if (test.name === 'max') {
swagger[`max${suffix}`] = test.args.limit;
}
}
return undefined;
};
module.exports = exports = function parse (schema, existingComponents) {
// inspect(schema);
if (!schema) throw new Error('No schema was passed.');
if (typeof schema === 'object' && !schema.isJoi) {
schema = joi.object().keys(schema);
if (test.name === 'length') {
swagger[`min${suffix}`] = test.args.limit;
swagger[`max${suffix}`] = test.args.limit;
}
}
return swagger;
}
if (!schema.isJoi) throw new TypeError('Passed schema does not appear to be a joi schema.');
var override = meta(schema, 'swagger');
if (override && meta(schema, 'swaggerOverride')) {
return { swagger: override, components: {} };
function getCaseSuffix (schema) {
const caseRule = find(schema._rules, { name: 'case' });
if (caseRule && caseRule.args.direction === 'lower') {
return 'Lower';
} else if (caseRule && caseRule.args.direction === 'upper') {
return 'Upper';
}
return '';
}
var metaDefName = meta(schema, 'className');
var metaDefType = meta(schema, 'classTarget') || 'schemas';
function parseWhens (schema, existingComponents, newComponentsByRef) {
const whens = get(schema, '$_terms.whens');
const mode = whens.length > 1 ? 'anyOf' : 'oneOf';
// if the schema has a definition class name, and that
// definition is already defined, just use that definition
if (metaDefName && get(existingComponents, [ metaDefType, metaDefName ])) {
return { swagger: refDef(metaDefType, metaDefName) };
const alternatives = [];
for (const w of whens) {
if (w.then) alternatives.push(w.then);
if (w.otherwise) alternatives.push(w.otherwise);
if (w.switch) {
for (const s of w.switch) {
if (s.then) alternatives.push(s.then);
if (s.otherwise) alternatives.push(s.otherwise);
}
}
}
if (get(schema, '_flags.presence') === 'forbidden') {
return false;
}
return schemaForAlternatives(alternatives, existingComponents, newComponentsByRef, mode);
}
var swagger;
var components = {};
function schemaForAlternatives (alternatives, existingComponents, newComponentsByRef, mode) {
let swaggers = [];
for (const joiSchema of alternatives) {
const { swagger, components } = parse(joiSchema, merge({}, existingComponents || {}, newComponentsByRef || {}));
if (!swagger) continue; // swagger is falsy if joi.forbidden()
if (get(joiSchema, '_flags.presence') === 'required') {
swagger['x-required'] = true;
}
merge(newComponentsByRef, components || {});
const type = meta(schema, 'baseType') || schema._type;
if (parseAsType[type]) {
swagger = parseAsType[type](schema, existingComponents, components);
} else {
throw new TypeError(`${type} is not a recognized Joi type.`);
swaggers.push(swagger);
}
swaggers = uniqWith(swaggers, isEqual);
if (!swagger) return { swagger, components };
return swaggers.length > 0 ? { [mode]: swaggers } : {};
}
if (schema._valids && schema._valids.has(null)) {
swagger.nullable = true;
function parseValidsAndInvalids (schema, filterFunc) {
const swagger = {};
if (schema._valids) {
const valids = schema._valids.values().filter(filterFunc);
if (get(schema, '_flags.only') && valids.length) {
swagger.enum = valids;
}
}
if (schema._description) {
swagger.description = schema._description;
}
if (schema._examples.length) {
if (schema._examples.length === 1) {
swagger.example = extractExampleValue(schema._examples[0]);
} else {
swagger.examples = schema._examples.map(extractExampleValue);
if (schema._invalids) {
const invalids = schema._invalids.values().filter(filterFunc);
if (invalids.length) {
swagger.not = { enum: invalids };
}
}
var label = get(schema, '_flags.label');
if (label) {
swagger.title = label;
}
return swagger;
}
var defaultValue = get(schema, '_flags.default');
if (defaultValue && typeof defaultValue !== 'function') {
swagger.default = defaultValue;
}
if (metaDefName) {
set(components, [ metaDefType, metaDefName ], swagger);
return { swagger: refDef(metaDefType, metaDefName), components };
}
if (override) {
Object.assign(swagger, override);
}
return { swagger, components };
};
var parseAsType = {
const parseAsType = {
number: (schema) => {
var swagger = {};
const swagger = {};
if (find(schema._tests, { name: 'integer' })) {
if (find(schema._rules, { name: 'integer' })) {
swagger.type = 'integer';
} else {
swagger.type = 'number';
if (find(schema._tests, { name: 'precision' })) {
if (find(schema._rules, { name: 'precision' })) {
swagger.format = 'double';

@@ -131,24 +123,22 @@ } else {

if (find(schema._tests, { name: 'positive' })) {
swagger.minimum = 1;
const sign = find(schema._rules, { name: 'sign' });
if (sign) {
if (sign.args.sign === 'positive') {
swagger.minimum = 1;
} else if (sign.args.sign === 'negative') {
swagger.maximum = -1;
}
}
if (find(schema._tests, { name: 'negative' })) {
swagger.maximum = -1;
}
var min = find(schema._tests, { name: 'min' });
const min = find(schema._rules, { name: 'min' });
if (min) {
swagger.minimum = min.arg;
swagger.minimum = min.args.limit;
}
var max = find(schema._tests, { name: 'max' });
const max = find(schema._rules, { name: 'max' });
if (max) {
swagger.maximum = max.arg;
swagger.maximum = max.args.limit;
}
var valids = schema._valids.values().filter((s) => typeof s === 'number');
if (get(schema, '_flags.allowOnly') && valids.length) {
swagger.enum = valids;
}
Object.assign(swagger, parseValidsAndInvalids(schema, (s) => isNumber(s)));

@@ -158,26 +148,14 @@ return swagger;

string: (schema) => {
var swagger = { type: 'string' };
var strict = get(schema, '_settings.convert') === false;
const swagger = { type: 'string' };
if (find(schema._tests, { name: 'alphanum' })) {
if (strict && find(schema._tests, { name: 'lowercase' })) {
swagger.pattern = patterns.alphanumLower;
} else if (strict && find(schema._tests, { name: 'uppercase' })) {
swagger.pattern = patterns.alphanumUpper;
} else {
swagger.pattern = patterns.alphanum;
}
if (find(schema._rules, { name: 'alphanum' })) {
const strict = get(schema, '_preferences.convert') === false;
swagger.pattern = patterns[`alphanum${strict ? getCaseSuffix(schema) : ''}`];
}
if (find(schema._tests, { name: 'token' })) {
if (find(schema._tests, { name: 'lowercase' })) {
swagger.pattern = patterns.alphanumLower;
} else if (find(schema._tests, { name: 'uppercase' })) {
swagger.pattern = patterns.alphanumUpper;
} else {
swagger.pattern = patterns.alphanum;
}
if (find(schema._rules, { name: 'token' })) {
swagger.pattern = patterns.token;
}
if (find(schema._tests, { name: 'email' })) {
if (find(schema._rules, { name: 'email' })) {
swagger.format = 'email';

@@ -187,3 +165,3 @@ if (swagger.pattern) delete swagger.pattern;

if (find(schema._tests, { name: 'isoDate' })) {
if (find(schema._rules, { name: 'isoDate' })) {
swagger.format = 'date-time';

@@ -193,27 +171,14 @@ if (swagger.pattern) delete swagger.pattern;

var pattern = find(schema._tests, { name: 'regex' });
if (pattern) {
swagger.pattern = pattern.arg.pattern.toString().slice(1, -1);
if (find(schema._rules, { name: 'guid' })) {
swagger.format = 'uuid';
if (swagger.pattern) delete swagger.pattern;
}
for (let i = 0; i < schema._tests.length; i++) {
const test = schema._tests[i];
if (test.name === 'min') {
swagger.minLength = test.arg;
}
if (test.name === 'max') {
swagger.maxLength = test.arg;
}
if (test.name === 'length') {
swagger.minLength = test.arg;
swagger.maxLength = test.arg;
}
const pattern = find(schema._rules, { name: 'pattern' });
if (pattern) {
swagger.pattern = pattern.args.regex.toString().slice(1, -1);
}
var valids = schema._valids.values().filter((s) => typeof s === 'string');
if (get(schema, '_flags.allowOnly') && valids.length) {
swagger.enum = valids;
}
Object.assign(swagger, getMinMax(schema));
Object.assign(swagger, parseValidsAndInvalids(schema, (s) => isString(s)));

@@ -223,3 +188,3 @@ return swagger;

binary: (schema) => {
var swagger = { type: 'string', format: 'binary' };
const swagger = { type: 'string', format: 'binary' };

@@ -230,18 +195,4 @@ if (get(schema, '_flags.encoding') === 'base64') {

for (let i = 0; i < schema._tests.length; i++) {
const test = schema._tests[i];
if (test.name === 'min') {
swagger.minLength = test.arg;
}
Object.assign(swagger, getMinMax(schema));
if (test.name === 'max') {
swagger.maxLength = test.arg;
}
if (test.name === 'length') {
swagger.minLength = test.arg;
swagger.maxLength = test.arg;
}
}
return swagger;

@@ -252,97 +203,92 @@ },

alternatives: (schema, existingComponents, newComponentsByRef) => {
var index = meta(schema, 'swaggerIndex') || 0;
const matches = get(schema, '$_terms.matches');
const mode = `${get(schema, '_flags.match') || 'any'}Of`;
var matches = get(schema, [ '_inner', 'matches' ]);
var firstItem = get(matches, [ 0 ]);
var itemsSchema;
if (firstItem.ref) {
if (schema._baseType && !firstItem.otherwise) {
itemsSchema = index ? firstItem.then : schema._baseType;
const alternatives = [];
for (const m of matches) {
if (m.ref) {
if (m.then) alternatives.push(m.then);
if (m.otherwise) alternatives.push(m.otherwise);
if (m.switch) {
for (const s of m.switch) {
if (s.then) alternatives.push(s.then);
if (s.otherwise) alternatives.push(s.otherwise);
}
}
} else {
itemsSchema = index ? firstItem.otherwise : firstItem.then;
alternatives.push(m.schema);
}
} else if (index) {
itemsSchema = get(matches, [ index, 'schema' ]);
} else {
itemsSchema = firstItem.schema;
}
var items = exports(itemsSchema, merge({}, existingComponents || {}, newComponentsByRef || {}));
if (get(itemsSchema, '_flags.presence') === 'required') {
items.swagger.__required = true;
}
merge(newComponentsByRef, items.components || {});
return items.swagger;
return schemaForAlternatives(alternatives, existingComponents, newComponentsByRef, mode);
},
array: (schema, existingComponents, newComponentsByRef) => {
var index = meta(schema, 'swaggerIndex') || 0;
var itemsSchema = get(schema, [ '_inner', 'items', index ]);
const items = get(schema, '$_terms.items');
const mode = 'oneOf';
if (!itemsSchema) throw Error('Array schema does not define an items schema at index ' + index);
const alternatives = items;
var items = exports(itemsSchema, merge({}, existingComponents || {}, newComponentsByRef || {}));
let swaggers = [];
for (const joiSchema of alternatives) {
// eslint-disable-next-line max-len
const { swagger, components } = parse(joiSchema, merge({}, existingComponents || {}, newComponentsByRef || {}));
if (!swagger) continue; // swagger is falsy if joi.forbidden()
merge(newComponentsByRef, items.components || {});
merge(newComponentsByRef, components || {});
var swagger = { type: 'array' };
swaggers.push(swagger);
}
swaggers = uniqWith(swaggers, isEqual);
for (let i = 0; i < schema._tests.length; i++) {
const test = schema._tests[i];
if (test.name === 'min') {
swagger.minItems = test.arg;
}
const openapi = {
type: 'array',
items: { [mode]: swaggers },
};
if (swaggers.length <= 1) {
openapi.items = get(swaggers, [ 0 ]) || {};
}
if (test.name === 'max') {
swagger.maxItems = test.arg;
}
Object.assign(openapi, getMinMax(schema, 'Items'));
if (test.name === 'length') {
swagger.minItems = test.arg;
swagger.maxItems = test.arg;
}
if (find(schema._rules, { name: 'unique' })) {
openapi.uniqueItems = true;
}
if (find(schema._tests, { name: 'unique' })) {
swagger.uniqueItems = true;
}
swagger.items = items.swagger;
return swagger;
return openapi;
},
object: (schema, existingComponents, newComponentsByRef) => {
var requireds = [];
var properties = {};
const requireds = [];
const properties = {};
var combinedComponents = merge({}, existingComponents || {}, newComponentsByRef || {});
const combinedComponents = merge({}, existingComponents || {}, newComponentsByRef || {});
var children = get(schema, '_inner.children') || [];
const children = get(schema, '$_terms.keys') || [];
children.forEach((child) => {
var key = child.key;
var prop = exports(child.schema, combinedComponents);
if (!prop.swagger) { // swagger is falsy if joi.forbidden()
const key = child.key;
const { swagger, components } = parse(child.schema, combinedComponents);
if (!swagger) { // swagger is falsy if joi.forbidden()
return;
}
merge(newComponentsByRef, prop.components || {});
merge(combinedComponents, prop.components || {});
merge(newComponentsByRef, components || {});
merge(combinedComponents, components || {});
properties[key] = prop.swagger;
properties[key] = swagger;
if (get(child, 'schema._flags.presence') === 'required' || prop.swagger.__required) {
if (get(child, 'schema._flags.presence') === 'required') {
requireds.push(key);
delete prop.swagger.__required;
}
});
var swagger = { type: 'object' };
const swagger = {
type: 'object',
properties,
};
if (requireds.length) {
swagger.required = requireds;
}
swagger.properties = properties;
if (get(schema, '_flags.allowUnknown') === false) {
if (get(schema, '_flags.unknown') !== true) {
swagger.additionalProperties = false;

@@ -354,11 +300,11 @@ }

any: (schema) => {
var swagger = {};
const swagger = {};
// convert property to file upload, if indicated by meta property
if (getJoiMetaProperty(schema, 'swaggerType') === 'file') {
if (meta(schema, 'swaggerType') === 'file') {
swagger.type = 'file';
swagger.in = 'formData';
}
if (schema._description) {
swagger.description = schema._description;
}
Object.assign(swagger, parseValidsAndInvalids(schema, (s) => isString(s) || isNumber(s)));
return swagger;

@@ -368,19 +314,92 @@ },

function meta (schema, key) {
var flattened = Object.assign.apply(null, [ {} ].concat(schema._meta));
function parse (schema, existingComponents) {
// inspect(schema);
return get(flattened, key);
}
if (!schema) throw new Error('No schema was passed.');
function refDef (type, name) {
return { $ref: '#/components/' + type + '/' + name };
}
if (isPlainObject(schema)) {
schema = joi.object().keys(schema);
}
function extractExampleValue (example) {
return joi.version < '14' ? example : example.value;
if (!joi.isSchema(schema)) throw new TypeError('Passed schema does not appear to be a joi schema.');
const flattenMeta = Object.assign.apply(null, [ {} ].concat(schema.$_terms.metas));
const override = flattenMeta.swagger;
if (override && flattenMeta.swaggerOverride) {
return { swagger: override, components: {} };
}
const metaDefName = flattenMeta.className;
const metaDefType = flattenMeta.classTarget || 'schemas';
// if the schema has a definition class name, and that
// definition is already defined, just use that definition
if (metaDefName && get(existingComponents, [ metaDefType, metaDefName ])) {
return { swagger: refDef(metaDefType, metaDefName) };
}
if (get(schema, '_flags.presence') === 'forbidden') {
return false;
}
const type = meta(schema, 'baseType') || schema.type;
if (!parseAsType[type]) {
throw new TypeError(`${type} is not a recognized Joi type.`);
}
const components = {};
const swagger = parseAsType[type](schema, existingComponents, components);
if (get(schema, '$_terms.whens')) {
Object.assign(swagger, parseWhens(schema, existingComponents, components));
}
if (!swagger) return { swagger, components };
if (schema._valids && schema._valids.has(null)) {
swagger.nullable = true;
}
const description = get(schema, '_flags.description');
if (description) {
swagger.description = description;
}
if (schema.$_terms.examples) {
if (schema.$_terms.examples.length === 1) {
swagger.example = schema.$_terms.examples[0];
} else {
swagger.examples = schema.$_terms.examples;
}
}
const label = get(schema, '_flags.label');
if (label) {
swagger.title = label;
}
const defaultValue = get(schema, '_flags.default');
if (defaultValue && typeof defaultValue !== 'function') {
swagger.default = defaultValue;
}
if (metaDefName) {
set(components, [ metaDefType, metaDefName ], swagger);
return { swagger: refDef(metaDefType, metaDefName), components };
}
if (override) {
Object.assign(swagger, override);
}
return { swagger, components };
}
// var inspectU = require('util').inspect;
module.exports = exports = parse;
exports.default = parse;
// const inspectU = require('util').inspect;
// function inspect (value) {
// console.error(inspectU(value, { colors: true, depth: 10 }));
// console.error(inspectU(value, { colors: true, depth: 10 }));
// }
{
"name": "joi-to-swagger",
"version": "3.3.0",
"version": "4.0.0",
"description": "",

@@ -9,2 +9,3 @@ "main": "index.js",

"test": "tap tests.js",
"test:debug": "tap --node-arg=--inspect --no-timeout tests.js",
"test:travis": "tap --reporter=tap tests.js",

@@ -35,3 +36,3 @@ "lint": "eslint ./"

"eslint-plugin-promise": "^4.2.1",
"joi": "^14.3.1",
"@hapi/joi": "^17.1.0",
"tap": "^14.7.2",

@@ -41,3 +42,3 @@ "tapsuite": "^2.0.1"

"peerDependencies": {
"joi": ">= 13"
"@hapi/joi": ">=16"
},

@@ -44,0 +45,0 @@ "files": [

@@ -5,2 +5,3 @@ joi-to-swagger

[![npm](https://img.shields.io/npm/v/joi-to-swagger.svg?logo=npm)](https://www.npmjs.com/package/joi-to-swagger)
[![travis](https://img.shields.io/travis/Twipped/joi-to-swagger/master.svg?label=tests&logo=travis-ci)](https://travis-ci.org/Twipped/joi-to-swagger)
[![Dependency Status](https://img.shields.io/david/Twipped/joi-to-swagger.svg?style=flat-square)](https://david-dm.org/Twipped/joi-to-swagger)

@@ -47,3 +48,4 @@ [![Download Status](https://img.shields.io/npm/dm/joi-to-swagger.svg?style=flat-square)](https://www.npmjs.com/package/joi-to-swagger)

}
}
},
"additionalProperties": false
}

@@ -55,7 +57,14 @@ ```

```js
var j2s = require('joi-to-swagger');
const j2s = require('joi-to-swagger');
var {swagger, components} = j2s(mySchema, existingComponents);
const { swagger, components } = j2s(mySchema, existingComponents);
```
_- in case of ES6 module syntax:_
```js
import j2s from 'joi-to-swagger';
const { swagger, components } = j2s(mySchema, existingComponents);
```
J2S takes two arguments, the first being the Joi object you wish to convert. The second optional argument is a collection of existing components to reference against for the meta `className` identifiers (see below).

@@ -71,3 +80,3 @@

- `joi.array().items()` defines the structure using the first schema provided on `.items()` (see below for how to override)
- `joi.array().items()` - in case of multiple provided schemas using `items()` method, the "oneOf" (OAS3) keyword is used
- `.min(4)` -> `"minItems": 4`

@@ -86,2 +95,4 @@ - `.max(10)` -> `"maxItems": 10`

- `.negative()` -> `"maximum": -1`
- `.valid(1, 2)` -> `"enum": [1, 2]`
- `.invalid(1, 2)` -> `"not": { "enum": [1, 2] }`

@@ -102,2 +113,5 @@ - `joi.string()` produces `"type": "string"` with no formatting

- `.max(10)` -> `"maxLength": 10`
- `.uuid()` -> `"format": "uuid"`
- `.valid('A', 'B')` -> `"enum": ['A', 'B']`
- `.invalid('A', 'B')` -> `"not": { "enum": ['A', 'B'] }`

@@ -113,4 +127,10 @@ - `joi.binary()` produces `"type": "string"` with a format of `"binary"`.

- `joi.alternatives()` defines the structure using the first schema provided on `.items()` (see below for how to override)
- `joi.alternatives()` - structure of alternative schemas is defined by "anyOf", "oneOf" or "allOf (OAS3) keywords
- `.mode('one')` -> produces `"oneOf": [ { ... } ]`
- in case of `joi.required()` alternative schema, the custom property option "x-required" is added to subschema -> `"x-required": true`
- `joi.when()` conditions are transformed to `"oneOf": [ { ... }, { ... } ]` keyword
- if multiple `joi.when().when()` conditions are provided, they are transformed to `"anyOf": [ { ... }, { ... } ]` keyword
- in case of `joi.required()` condition, the custom property option "x-required" is added to subschema -> `"x-required": true`
- `any.default()` sets the `"default"` detail.

@@ -120,6 +140,8 @@

- `.example('hi')` -> `"example": "hi"`
- joi < v14: `.example('hi').example('hey')` -> `"examples": ["hi", "hey"]`
- joi v14: `.example('hi', 'hey')` -> `"examples": ["hi", "hey"]`
- `.example('hi', 'hey')` -> `"examples": ["hi", "hey"]`
- `joi.any().meta({ swaggerType: 'file' }).description('simpleFile')` add a file to the swagger structure
- `joi.any()`
- `.meta({ swaggerType: 'file' }).description('simpleFile')` add a file to the swagger structure
- `.valid(1, 'A')` -> `"enum": [1, 'A']`
- `.invalid(1, 'A')` -> `"not": { "enum": [1, 'A'] }`

@@ -134,4 +156,2 @@ ## Meta Overrides

**swaggerIndex**: Swagger's deterministic design disallows for supporting multiple type components. Because of this, only a single schema from `.alternatives()` and `.array().items()` may be converted to swagger. By default J2S will use the first component. Defining a different zero based index for this meta tag will override that behavior.
**swagger**: To explicitly define your own swagger component for a joi schema object, place that swagger object in the `swagger` meta tag. It will be mixed in to the schema that J2S produces.

@@ -149,3 +169,3 @@

const customJoi = joi.extend({
name: 'customStringType',
type: 'customStringType',
base: joi.string().meta({ baseType: 'string' }),

@@ -152,0 +172,0 @@ // ...

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