From 7f037552e8828f994822062cf2c009e8f4bd941c Mon Sep 17 00:00:00 2001 From: Lukas Date: Sat, 17 Mar 2018 14:20:08 +0100 Subject: [PATCH 1/7] chore(tests): rename microschema variable --- test.js | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/test.js b/test.js index 616a53d..e6d0eff 100644 --- a/test.js +++ b/test.js @@ -1,9 +1,9 @@ -const microschema = require('./index') +const ms = require('./index') const test = require('ava').test const assert = require('assert') test('strictObj() creates an object with a single property', function (t) { - const schema = microschema.strictObj({foo: 'string'}) + const schema = ms.strictObj({foo: 'string'}) assert.deepEqual(schema, { type: 'object', @@ -15,7 +15,7 @@ test('strictObj() creates an object with a single property', function (t) { }) test('strictObj() creates an object with a uri string', function (t) { - const schema = microschema.strictObj({foo: 'string:uri'}) + const schema = ms.strictObj({foo: 'string:uri'}) assert.deepEqual(schema, { type: 'object', @@ -27,7 +27,7 @@ test('strictObj() creates an object with a uri string', function (t) { }) test('strictObj() creates an object with a required property', function (t) { - const schema = microschema.strictObj({ + const schema = ms.strictObj({ foo: 'string:required', bar: 'string' }) @@ -45,7 +45,7 @@ test('strictObj() creates an object with a required property', function (t) { test('enum() creates an enum of strings', function (t) { - const schema = microschema.enum('foo', 'bar') + const schema = ms.enum('foo', 'bar') assert.deepEqual(schema, { type: 'string', enum: ['foo', 'bar'] @@ -53,7 +53,7 @@ test('enum() creates an enum of strings', function (t) { }) test('enum() creates an enum from an array', function (t) { - const schema = microschema.enum(['foo', 'bar']) + const schema = ms.enum(['foo', 'bar']) assert.deepEqual(schema, { type: 'string', enum: ['foo', 'bar'] @@ -62,7 +62,7 @@ test('enum() creates an enum from an array', function (t) { test('arrayOf() creates an array with a type of its items', function (t) { - const schema = microschema.arrayOf('integer') + const schema = ms.arrayOf('integer') assert.deepEqual(schema, { type: 'array', items: {type: 'integer'} @@ -70,12 +70,12 @@ test('arrayOf() creates an array with a type of its items', function (t) { }) test('number() creates a type number', function (t) { - const schema = microschema.number() + const schema = ms.number() assert.deepEqual(schema, {type: 'number'}) }) test('number() creates a type number with min and max', function (t) { - const schema = microschema.number({min: 0, max: 10}) + const schema = ms.number({min: 0, max: 10}) assert.deepEqual(schema, { type: 'number', minimum: 0, @@ -84,12 +84,12 @@ test('number() creates a type number with min and max', function (t) { }) test('integer() creates a type number', function (t) { - const schema = microschema.integer() + const schema = ms.integer() assert.deepEqual(schema, {type: 'integer'}) }) test('integer() creates a type integer with min and max', function (t) { - const schema = microschema.integer({min: 0, max: 10}) + const schema = ms.integer({min: 0, max: 10}) assert.deepEqual(schema, { type: 'integer', minimum: 0, @@ -98,13 +98,13 @@ test('integer() creates a type integer with min and max', function (t) { }) test('chaining creates a chain object', function (t) { - const chain = microschema.required + const chain = ms.required assert.ok(chain.strictObj instanceof Function) }) test('chaining creates a required obj', function (t) { - const schema = microschema.obj({ - myProperty: microschema.required.obj({foo: 'string'}) + const schema = ms.obj({ + myProperty: ms.required.obj({foo: 'string'}) }) assert.deepEqual(schema, { @@ -122,8 +122,8 @@ test('chaining creates a required obj', function (t) { }) test('chaining creates a required strict obj', function (t) { - const schema = microschema.obj({ - myProperty: microschema.required.strictObj({foo: 'string'}) + const schema = ms.obj({ + myProperty: ms.required.strictObj({foo: 'string'}) }) assert.deepEqual(schema, { @@ -142,8 +142,8 @@ test('chaining creates a required strict obj', function (t) { }) test('chaining creates a required enum', function (t) { - const schema = microschema.obj({ - myProperty: microschema.required.enum('foo', 'bar') + const schema = ms.obj({ + myProperty: ms.required.enum('foo', 'bar') }) assert.deepEqual(schema, { From 73dc32c9515b8d49e143518ab2180ae8917c2aad Mon Sep 17 00:00:00 2001 From: Lukas Date: Sat, 17 Mar 2018 14:23:28 +0100 Subject: [PATCH 2/7] chore: add .gitignore file --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules From 2c3288c5238bfaab0d9092607112908b8b4bf3a0 Mon Sep 17 00:00:00 2001 From: Lukas Date: Sat, 17 Mar 2018 15:33:31 +0100 Subject: [PATCH 3/7] feat: add string({pattern}) method --- index.js | 16 ++++++++++++++++ test.js | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/index.js b/index.js index 94ace4f..7fc2346 100644 --- a/index.js +++ b/index.js @@ -102,6 +102,22 @@ module.exports = { }) }, + string ({pattern} = {}) { + const s = {type: 'string'} + if (pattern) { + if (pattern instanceof RegExp) { + if (pattern.flags) { + throw new Error('JSON schema does not support regexp flags: ' + + `${pattern}`) + } + s.pattern = pattern.source + } else { + s.pattern = pattern + } + } + return this.decorate(s) + }, + number ({min, max, integer} = {}) { const type = integer ? 'integer' : 'number' const s = {type: type} diff --git a/test.js b/test.js index e6d0eff..ac89cb7 100644 --- a/test.js +++ b/test.js @@ -69,6 +69,61 @@ test('arrayOf() creates an array with a type of its items', function (t) { }) }) +test('string() creates a type string', function (t) { + const schema = ms.string() + assert.deepEqual(schema, {type: 'string'}) +}) + +test('required.string() creates a required string', function (t) { + const schema = ms.obj({ + foo: ms.required.string() + }) + assert.deepEqual(schema, { + type: 'object', + required: ['foo'], + properties: { + foo: { + type: 'string' + } + } + }) +}) + +test('string({pattern}) adds a regex pattern', function (t) { + const schema = ms.string({ + pattern: '[a-z]+' + }) + + assert.deepEqual(schema, { + type: 'string', + pattern: '[a-z]+' + }) +}) + +test('string({pattern}) accepts a javascript regex', function (t) { + const schema = ms.string({ + pattern: /[a-z]+/ + }) + + assert.deepEqual(schema, { + type: 'string', + pattern: '[a-z]+' + }) +}) + +test('string({pattern}) does not accept a javascript regex with flags', function (t) { + const method = () => { + ms.string({pattern: /[a-z]+/i}) + } + + assert.throws(method, (err) => { + assert.equal(err.message, + 'JSON schema does not support regexp flags: /[a-z]+/i') + + return true + }) +}) + test('number() creates a type number', function (t) { const schema = ms.number() assert.deepEqual(schema, {type: 'number'}) From 8983293f3ea572d5be562d694aaa4c902e55bd4e Mon Sep 17 00:00:00 2001 From: Lukas Date: Sat, 17 Mar 2018 15:37:31 +0100 Subject: [PATCH 4/7] feat: add boolean() method --- index.js | 4 ++++ test.js | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/index.js b/index.js index 7fc2346..72a53b9 100644 --- a/index.js +++ b/index.js @@ -131,6 +131,10 @@ module.exports = { return this.number(opts) }, + boolean () { + return this.decorate({type: 'boolean'}) + }, + decorate (obj) { if (this[isRequired]) obj[isRequired] = true return obj diff --git a/test.js b/test.js index ac89cb7..421fc6c 100644 --- a/test.js +++ b/test.js @@ -152,6 +152,11 @@ test('integer() creates a type integer with min and max', function (t) { }) }) +test('boolean() creates a type boolean', function (t) { + const schema = ms.boolean() + assert.deepEqual(schema, {type: 'boolean'}) +}) + test('chaining creates a chain object', function (t) { const chain = ms.required assert.ok(chain.strictObj instanceof Function) From 4d8acb9d1a3c8227e1f7e452452f365fb2ea4eaa Mon Sep 17 00:00:00 2001 From: Lukas Date: Sat, 17 Mar 2018 15:39:39 +0100 Subject: [PATCH 5/7] chore: update readme --- README.md | 199 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 185 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index b73c514..9cd2bae 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,203 @@ -# microschema - -

+

Travis - - semantic-release - npm latest version + + semantic-release +

+# microschema -Helper library to create JSON Schemas in a concise way. +Small library without dependencies to create JSON Schemas in a concise way. Example: ```js -const microschema = require('microschema') +const ms = require('microschema') -microschema.strictObj({ - identity_id: 'string:required', - client_id: 'number', - redirect_uri: 'string:uri', +ms.strictObj({ + identityId: 'string:required', + clientId: 'number', + redirectUri: 'string:uri', scope: 'string', - ip_address: 'string', - children: microschema.arrayOf(microschema.strictObj({ + ipAddress: ms.string({pattern: ''}), + children: ms.arrayOf(ms.strictObj({ scope: 'string' })) }) ``` + + +## Strings + +Using the ms.string() method +```js +ms.string() +output = {type: 'string'}) +``` + +```js +ms.string({pattern: '[a-z]+'}) + +output = { + type: 'string', + pattern: '[a-z]+' +} +``` + +Setting the required flag (only possible within an object) +```js +ms.obj({ + foo: ms.required.string() +}) + +output = { + type: 'object', + required: ['foo'], + properties: { + foo: { + type: 'string' + } + } +} +``` + +Simplified usage within objects +```js +ms.obj({ + foo: 'string' +}) + +output = { + type: 'object', + properties: { + foo: { + type: 'string' + } + } +} +``` + +```js +ms.obj({ + foo: 'string:required' +}) + +output = { + type: 'object', + required: ['foo'], + properties: { + foo: { + type: 'string' + } + } +} +``` + +## Numbers and Integers + +Simplified usage within objects +```js +ms.obj({ + foo: 'string' +}) +``` + +Using the ms.number() method +```js +ms.number() +output = {type: 'number'} +``` + +```js +ms.number({min: 0, max: 10}) + +output = { + type: 'number', + minimum: 0, + maximum: 10 +} +``` + +Using the ms.integer() method +```js +ms.integer() +output = {type: 'integer'} +``` + +The `integer()` methods also accepts `min` and `max` params the same as `number()` does. + + +## Booleans + +```js +ms.boolean() +output = {type: 'boolean'}) +``` + +Simplified usage within objects +```js +ms.obj({ + foo: 'boolean:required' +}) + +output = { + type: 'object', + required: ['foo'], + properties: { + foo: { + type: 'boolean' + } + } +} +``` + +## Objects + +```js +ms.obj() +output = {type: 'object'} +``` + +Don't allow additional properties with `strictObj()` +```js +ms.strictObj({ + count: ms.integer() +}) + +output = { + type: 'object' + additionalProperties: false + properties: { + count: {type: 'integer'} + } +} +``` + + +## Arrays + +```js +ms.arrayOf(ms.string()) + +output = { + type: 'array', + items: {type: 'string'} +} +``` + + +## Enumerations + +```js +// All values in an enumeration must be of the same type. +ms.required.enum('foo', 'bar') + +output = { + type: 'string', + enum: ['foo', 'bar'] +} +``` From d07c86b0023574f55b26b1b90bb2743a7b76798b Mon Sep 17 00:00:00 2001 From: Lukas Date: Sat, 17 Mar 2018 15:50:20 +0100 Subject: [PATCH 6/7] chore: some fixes within readme --- README.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 9cd2bae..9de4158 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ ms.strictObj({ ## Strings -Using the ms.string() method +Using the `ms.string()` method: ```js ms.string() output = {type: 'string'}) @@ -42,13 +42,16 @@ output = {type: 'string'}) ```js ms.string({pattern: '[a-z]+'}) +// Passing a javascript RegExp is equivalent to the above +ms.string({pattern: /[a-z]+/}) + output = { type: 'string', pattern: '[a-z]+' } ``` -Setting the required flag (only possible within an object) +Setting the required flag (only possible within an object): ```js ms.obj({ foo: ms.required.string() @@ -65,7 +68,7 @@ output = { } ``` -Simplified usage within objects +Simplified usage within objects: ```js ms.obj({ foo: 'string' @@ -99,14 +102,14 @@ output = { ## Numbers and Integers -Simplified usage within objects +Simplified usage within objects: ```js ms.obj({ foo: 'string' }) ``` -Using the ms.number() method +Using the `ms.number()` method: ```js ms.number() output = {type: 'number'} @@ -122,7 +125,7 @@ output = { } ``` -Using the ms.integer() method +Using the `ms.integer()` method: ```js ms.integer() output = {type: 'integer'} @@ -138,7 +141,7 @@ ms.boolean() output = {type: 'boolean'}) ``` -Simplified usage within objects +Simplified usage within objects: ```js ms.obj({ foo: 'boolean:required' @@ -162,22 +165,21 @@ ms.obj() output = {type: 'object'} ``` -Don't allow additional properties with `strictObj()` +Don't allow additional properties with `strictObj()`: ```js ms.strictObj({ count: ms.integer() }) output = { - type: 'object' - additionalProperties: false + type: 'object', + additionalProperties: false, properties: { count: {type: 'integer'} } } ``` - ## Arrays ```js @@ -194,7 +196,7 @@ output = { ```js // All values in an enumeration must be of the same type. -ms.required.enum('foo', 'bar') +ms.enum('foo', 'bar') output = { type: 'string', From e541df23d29b2322fc209acdd1e57de4a642210b Mon Sep 17 00:00:00 2001 From: Lukas Date: Mon, 19 Mar 2018 11:13:19 +0100 Subject: [PATCH 7/7] chore: pr feedback --- index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/index.js b/index.js index 72a53b9..3e7883f 100644 --- a/index.js +++ b/index.js @@ -107,8 +107,7 @@ module.exports = { if (pattern) { if (pattern instanceof RegExp) { if (pattern.flags) { - throw new Error('JSON schema does not support regexp flags: ' + - `${pattern}`) + throw new Error(`JSON schema does not support regexp flags: ${pattern}`) } s.pattern = pattern.source } else {