Skip to content

Commit

Permalink
Merge pull request #12 from livingdocsIO/add-new-methods
Browse files Browse the repository at this point in the history
Add $id(), $ref(), definitions(), anyOf(), allOf(), oneOf()
  • Loading branch information
peyerluk authored Jun 12, 2019
2 parents c211f85 + 0f9cd2e commit 1da574a
Show file tree
Hide file tree
Showing 3 changed files with 299 additions and 17 deletions.
65 changes: 65 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -268,3 +268,68 @@ output = {
const: 'foo'
}
```

## anyOf / oneOf / allOf

```js
ms.anyOf('number', ms.obj({foo: 'string'}))

output = {
anyOf: [
{type: 'number'},
{
type: 'object',
properties: {
foo: {type: 'string'}
}
}
]
}
```
Note: you can also pass an array as the first argument


## $id / $ref

```js
ms.$id('#user').obj({
name: 'string',
friend: ms.$ref('#user')
})

output = {
$id: '#user',
type: 'object',
properties: {
name: {type: 'string'}
friend: {$ref: '#user'}
}
}
```

## definitions

```js
ms.definitions({
user: ms.obj({name: 'string'})
}).obj({
name: 'string',
friend: ms.$ref('#/definitions/user')
})

output = {
definitions: {
user: {
type: 'object',
properties: {
name: {type: 'string'}
}
}
}
type: 'object',
properties: {
name: {type: 'string'}
friend: {$ref: '#/definitions/user'}
}
}
```
77 changes: 60 additions & 17 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Symbols
const isChain = Symbol('chainedMicroschema')
const isRequired = Symbol('required')
const chained = Symbol('chained')

// Helper library to create JsonSchemas
// in a concise way.
Expand All @@ -17,16 +17,16 @@ const isRequired = Symbol('required')
// scope: 'string'
// }))
// })

module.exports = {

// Chaining Properties
// -------------------

get required () {
const chain = Object.create(this)
chain[isChain] = true
chain[isRequired] = true
return chain
const self = chain(this)
self[isRequired] = true
return self
},


Expand Down Expand Up @@ -66,7 +66,7 @@ module.exports = {
jsonSchema.properties[propertyName] = propertySchema
}

return this.decorate(jsonSchema)
return decorate(this, jsonSchema)
},

// An object with no additional properties allowed
Expand All @@ -84,15 +84,15 @@ module.exports = {
enum (...enums) {
if (Array.isArray(enums[0])) enums = enums[0]

return this.decorate({
return decorate(this, {
type: getJsonType(enums[0]),
enum: enums
})
},


const (value) {
return this.decorate({
return decorate(this, {
type: getJsonType(value),
const: value
})
Expand All @@ -105,10 +105,10 @@ module.exports = {
// 2. {Object} JSON Schema
// Example: microschema.arrayOf({type: 'object', properties: {...}})
arrayOf (schemaOrType, {minItems, maxItems, uniqueItems} = {}) {
const items = isString(schemaOrType) ? {type: schemaOrType} : schemaOrType
const s = this.decorate({
const itemSchema = strToSchema(schemaOrType)
const s = decorate(this, {
type: 'array',
items: items
items: itemSchema
})

if (minItems) s.minItems = minItems
Expand All @@ -135,15 +135,15 @@ module.exports = {
if (minLength) s.minLength = minLength
if (maxLength) s.maxLength = maxLength

return this.decorate(s)
return decorate(this, s)
},

number ({min, max, integer} = {}) {
const type = integer ? 'integer' : 'number'
const s = {type: type}
if (min != null) s.minimum = min
if (max != null) s.maximum = max
return this.decorate(s)
return decorate(this, s)
},

integer (opts = {}) {
Expand All @@ -152,15 +152,47 @@ module.exports = {
},

boolean () {
return this.decorate({type: 'boolean'})
return decorate(this, {type: 'boolean'})
},

definitions (obj) {
const self = chain(this)
self[chained].definitions = obj
return self
},

$ref (reference) {
return decorate(this, {$ref: reference})
},

$id (id) {
const self = chain(this)
self[chained].$id = id
return self
},

anyOf (...args) {
const defs = Array.isArray(args[0]) ? args[0] : args
return decorate(this, {anyOf: defs.map(strToSchema)})
},

decorate (obj) {
if (this[isRequired]) obj[isRequired] = true
return obj
oneOf (...args) {
const defs = Array.isArray(args[0]) ? args[0] : args
return decorate(this, {oneOf: defs.map(strToSchema)})
},

allOf (...args) {
const defs = Array.isArray(args[0]) ? args[0] : args
return decorate(this, {allOf: defs})
}
}

function decorate (self, obj) {
if (self[isRequired]) obj[isRequired] = true
if (self[chained]) Object.assign(obj, self[chained])
return obj
}

function parseTypeDescription (parentSchema, name, typeDesc) {
const [type, ...options] = typeDesc.split(':')
const propertySchema = {type: type}
Expand All @@ -184,6 +216,17 @@ function parseTypeDescription (parentSchema, name, typeDesc) {
return propertySchema
}

function strToSchema (schemaOrType) {
return isString(schemaOrType) ? {type: schemaOrType} : schemaOrType
}

function chain (self) {
if (self[chained]) return self
self = Object.create(self)
self[chained] = {}
return self
}

function getJsonType (obj) {
if (isString(obj)) return 'string'
if (Array.isArray(obj)) return 'array'
Expand Down
Loading

0 comments on commit 1da574a

Please sign in to comment.