diff --git a/README.md b/README.md index d8d9beb0..b454cb70 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ fast-json-stringify-uglified obj x 5,331,581 ops/sec ±0.73% (91 runs sampled) - `Reuse - $ref` - `Long integers` - `Uglify` + - `Nullable` - `Acknowledgements` - `License` @@ -462,6 +463,35 @@ const stringify = fastJson({ console.log(stringify({ some: 'object' })) // '{"some":"object"}' ``` + +#### Nullable + +According to the [Open API 3.0 specification](https://swagger.io/docs/specification/data-models/data-types/#null), a value that can be null must be declared `nullable`. + +##### Nullable object +```javascript +const stringify = fastJson({ + 'title': 'Nullable schema', + 'type': 'object', + 'nullable': true, + 'properties': { + 'product': { + 'nullable': true, + 'type': 'object', + 'properties': { + 'name': { + 'type': 'string' + } + } + } + } +}) + +console.log(stringify({product: {name: "hello"}})) // "{"product":{"name":"hello"}}" +console.log(stringify({product: null})) // "{"product":null}" +console.log(stringify(null)) // null +``` + ## Acknowledgements diff --git a/index.js b/index.js index dca5cd47..d56665a1 100644 --- a/index.js +++ b/index.js @@ -621,6 +621,15 @@ function toJSON (variableName) { function buildObject (schema, code, name, externalSchema, fullSchema) { code += ` function ${name} (input) { + ` + if (schema.nullable) { + code += ` + if(input === null) { + return '${$asNull()}'; + } + ` + } + code += ` var obj = ${toJSON('input')} var json = '{' var addComma = false diff --git a/test/toJSON.test.js b/test/toJSON.test.js index 25fd23d4..04ac2975 100644 --- a/test/toJSON.test.js +++ b/test/toJSON.test.js @@ -81,3 +81,94 @@ test('not use toJSON if does not exist', (t) => { t.equal('{"product":{"name":"cola"}}', stringify(object)) }) + +test('not fail on null object declared nullable', (t) => { + t.plan(1) + + const stringify = build({ + title: 'simple object', + type: 'object', + nullable: true, + properties: { + product: { + type: 'object', + properties: { + name: { + type: 'string' + } + } + } + } + }) + t.equal('null', stringify(null)) +}) + +test('not fail on null sub-object declared nullable', (t) => { + t.plan(1) + + const stringify = build({ + title: 'simple object', + type: 'object', + properties: { + product: { + nullable: true, + type: 'object', + properties: { + name: { + type: 'string' + } + } + } + } + }) + const object = { + product: null + } + t.equal('{"product":null}', stringify(object)) +}) + +test('throw an error on non nullable null sub-object', (t) => { + t.plan(1) + + const stringify = build({ + title: 'simple object', + type: 'object', + properties: { + product: { + nullable: false, + type: 'object', + properties: { + name: { + type: 'string' + } + } + } + } + }) + const object = { + product: null + } + t.throws(() => { stringify(object) }) +}) + +test('throw an error on non nullable null object', (t) => { + t.plan(1) + + const stringify = build({ + title: 'simple object', + nullable: false, + type: 'object', + properties: { + product: { + nullable: false, + type: 'object', + properties: { + name: { + type: 'string' + } + } + } + } + }) + t.throws(() => { stringify(null) }) +})