Skip to content

Commit

Permalink
feat: allow type combinations
Browse files Browse the repository at this point in the history
  • Loading branch information
peyerluk committed Nov 26, 2020
1 parent e339c9a commit acff5ed
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 0 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,22 @@ output = {
}
```

## Combining Types

```js
ms.types('string', 'number')
output = {
type: ['string', 'number']
}

ms.types(ms.string({format: 'uri'}), ms.number({min: 0}))
output = {
type: ['string', 'number'],
format: 'uri',
minimum: 0
}
```

## anyOf / oneOf / allOf

```js
Expand Down
26 changes: 26 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,18 @@ module.exports = {
return decorate(this, {type: 'null'})
},

types (...params) {
const result = {}
for (let obj of params) {
if (isString(obj)) {
obj = parseTypeDescription({}, '', obj)
}
mergeTypes(obj, result)
Object.assign(result, obj)
}
return decorate(this, result)
},

definitions (obj) {
const self = chain(this)
self[chained].definitions = obj
Expand Down Expand Up @@ -197,6 +209,20 @@ function decorate (self, obj) {
return obj
}

function mergeTypes (obj, other) {
if (obj.type && other.type) {
const first = Array.isArray(obj.type)
? obj.type
: [obj.type]
const second = Array.isArray(other.type)
? other.type
: [other.type]

second.push(...first)
obj.type = second
}
}

function parseTypeDescription (parentSchema, name, typeDesc) {
const [type, ...options] = typeDesc.split(':')
const propertySchema = {type: type}
Expand Down
48 changes: 48 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,54 @@ test('null() can be parsed as string', function (t) {
})
})

test('types() can create composite types from strings', function (t) {
const schema = ms.types('string', 'null')
assert.deepEqual(schema, {type: ['string', 'null']})
})

test('types() works with required', function (t) {
const schema = ms.obj({
foo: ms.required.types('string', 'null')
})
assert.deepEqual(schema, {
type: 'object',
required: ['foo'],
properties: {
foo: {
type: ['string', 'null']
}
}
})
})

test('types() can create composite types', function (t) {
const schema = ms.types(ms.string(), ms.null())
assert.deepEqual(schema, {type: ['string', 'null']})
})

test('types() can create composite types with configs', function (t) {
const schema = ms.types(ms.enum('foo'), ms.number({min: 0}))
assert.deepEqual(schema, {
type: ['string', 'number'],
enum: ['foo'],
minimum: 0
})
})

test('types() can create composite types with one object', function (t) {
const schema = ms.types(ms.number({min: 0}), ms.obj({
foo: 'string:required'
}))
assert.deepEqual(schema, {
type: ['number', 'object'],
minimum: 0,
required: ['foo'],
properties: {
foo: {type: 'string'}
}
})
})

test('$ref() creates a reference', function (t) {
const schema = ms.$ref('#/definitions/address')
assert.deepEqual(schema, {$ref: '#/definitions/address'})
Expand Down

0 comments on commit acff5ed

Please sign in to comment.