Coder Social home page Coder Social logo

fast-json-stringify's Introduction

fast-json-stringify

CI NPM version js-standard-style NPM downloads

fast-json-stringify is significantly faster than JSON.stringify() for small payloads. Its performance advantage shrinks as your payload grows. It pairs well with flatstr, which triggers a V8 optimization that improves performance when eventually converting the string to a Buffer.

How it works

fast-json-stringify requires a JSON Schema Draft 7 input to generate a fast stringify function.

Benchmarks
  • Machine: EX41S-SSD, Intel Core i7, 4Ghz, 64GB RAM, 4C/8T, SSD.
  • Node.js v18.12.1
FJS creation x 4,129 ops/sec ±0.82% (92 runs sampled)
CJS creation x 184,196 ops/sec ±0.12% (97 runs sampled)
AJV Serialize creation x 61,130,591 ops/sec ±0.40% (92 runs sampled)
JSON.stringify array x 5,057 ops/sec ±0.10% (100 runs sampled)
fast-json-stringify array default x 6,243 ops/sec ±0.14% (98 runs sampled)
fast-json-stringify array json-stringify x 6,261 ops/sec ±0.30% (99 runs sampled)
compile-json-stringify array x 6,842 ops/sec ±0.18% (96 runs sampled)
AJV Serialize array x 6,964 ops/sec ±0.11% (95 runs sampled)
JSON.stringify large array x 248 ops/sec ±0.07% (90 runs sampled)
fast-json-stringify large array default x 99.96 ops/sec ±0.22% (74 runs sampled)
fast-json-stringify large array json-stringify x 248 ops/sec ±0.07% (90 runs sampled)
compile-json-stringify large array x 317 ops/sec ±0.09% (89 runs sampled)
AJV Serialize large array x 111 ops/sec ±0.07% (33 runs sampled)
JSON.stringify long string x 16,002 ops/sec ±0.09% (98 runs sampled)
fast-json-stringify long string x 15,979 ops/sec ±0.09% (96 runs sampled)
compile-json-stringify long string x 15,952 ops/sec ±0.31% (97 runs sampled)
AJV Serialize long string x 21,416 ops/sec ±0.08% (98 runs sampled)
JSON.stringify short string x 12,944,272 ops/sec ±0.09% (96 runs sampled)
fast-json-stringify short string x 30,585,790 ops/sec ±0.27% (97 runs sampled)
compile-json-stringify short string x 30,656,406 ops/sec ±0.12% (96 runs sampled)
AJV Serialize short string x 30,406,785 ops/sec ±0.37% (96 runs sampled)
JSON.stringify obj x 3,153,043 ops/sec ±0.33% (99 runs sampled)
fast-json-stringify obj x 6,866,434 ops/sec ±0.11% (100 runs sampled)
compile-json-stringify obj x 15,886,723 ops/sec ±0.15% (98 runs sampled)
AJV Serialize obj x 8,969,043 ops/sec ±0.36% (97 runs sampled)
JSON stringify date x 1,126,547 ops/sec ±0.09% (97 runs sampled)
fast-json-stringify date format x 1,836,188 ops/sec ±0.12% (99 runs sampled)
compile-json-stringify date format x 1,125,735 ops/sec ±0.19% (98 runs sampled)

Table of contents:

Try it out on RunKit: https://runkit.com/npm/fast-json-stringify

Example

const fastJson = require('fast-json-stringify')
const stringify = fastJson({
  title: 'Example Schema',
  type: 'object',
  properties: {
    firstName: {
      type: 'string'
    },
    lastName: {
      type: 'string'
    },
    age: {
      description: 'Age in years',
      type: 'integer'
    },
    reg: {
      type: 'string'
    }
  }
})

console.log(stringify({
  firstName: 'Matteo',
  lastName: 'Collina',
  age: 32,
  reg: /"([^"]|\\")*"/
}))

Options

Optionally, you may provide to fast-json-stringify an option object as second parameter:

const fastJson = require('fast-json-stringify')
const stringify = fastJson(mySchema, {
  schema: { ... },
  ajv: { ... },
  rounding: 'ceil'
})

API

fastJsonStringify(schema)

Build a stringify() function based on jsonschema draft 7 spec.

Supported types:

  • 'string'
  • 'integer'
  • 'number'
  • 'array'
  • 'object'
  • 'boolean'
  • 'null'

And nested ones, too.

Specific use cases

Instance Serialized as
Date string via toISOString()
RegExp string
BigInt integer via toString

JSON Schema built-in formats for dates are supported and will be serialized as:

Format Serialized format example
date-time 2020-04-03T09:11:08.615Z
date 2020-04-03
time 09:11:08

Note: In the case of string formatted Date and not Date Object, there will be no manipulation on it. It should be properly formatted.

Example with a Date object:

const stringify = fastJson({
  title: 'Example Schema with string date-time field',
  type: 'string',
  format: 'date-time'
})

const date = new Date()
console.log(stringify(date)) // '"YYYY-MM-DDTHH:mm:ss.sssZ"'

Required

You can set specific fields of an object as required in your schema by adding the field name inside the required array in your schema. Example:

const schema = {
  title: 'Example Schema with required field',
  type: 'object',
  properties: {
    nickname: {
      type: 'string'
    },
    mail: {
      type: 'string'
    }
  },
  required: ['mail']
}

If the object to stringify is missing the required field(s), fast-json-stringify will throw an error.

Missing fields

If a field is present in the schema (and is not required) but it is not present in the object to stringify, fast-json-stringify will not write it in the final string. Example:

const stringify = fastJson({
  title: 'Example Schema',
  type: 'object',
  properties: {
    nickname: {
      type: 'string'
    },
    mail: {
      type: 'string'
    }
  }
})

const obj = {
  mail: '[email protected]'
}

console.log(stringify(obj)) // '{"mail":"[email protected]"}'

Defaults

fast-json-stringify supports default jsonschema key in order to serialize a value if it is undefined or not present.

Example:

const stringify = fastJson({
  title: 'Example Schema',
  type: 'object',
  properties: {
    nickname: {
      type: 'string',
      default: 'the default string'
    }
  }
})

console.log(stringify({})) // '{"nickname":"the default string"}'
console.log(stringify({nickname: 'my-nickname'})) // '{"nickname":"my-nickname"}'

Pattern properties

fast-json-stringify supports pattern properties as defined by JSON schema. patternProperties must be an object, where the key is a valid regex and the value is an object, declared in this way: { type: 'type' }. patternProperties will work only for the properties that are not explicitly listed in the properties object. Example:

const stringify = fastJson({
  title: 'Example Schema',
  type: 'object',
  properties: {
    nickname: {
      type: 'string'
    }
  },
  patternProperties: {
    'num': {
      type: 'number'
    },
    '.*foo$': {
      type: 'string'
    }
  }
})

const obj = {
  nickname: 'nick',
  matchfoo: 42,
  otherfoo: 'str',
  matchnum: 3
}

console.log(stringify(obj)) // '{"matchfoo":"42","otherfoo":"str","matchnum":3,"nickname":"nick"}'

Additional properties

fast-json-stringify supports additional properties as defined by JSON schema. additionalProperties must be an object or a boolean, declared in this way: { type: 'type' }. additionalProperties will work only for the properties that are not explicitly listed in the properties and patternProperties objects.

If additionalProperties is not present or is set to false, every property that is not explicitly listed in the properties and patternProperties objects,will be ignored, as described in Missing fields. Missing fields are ignored to avoid having to rewrite objects before serializing. However, other schema rules would throw in similar situations. If additionalProperties is set to true, it will be used by JSON.stringify to stringify the additional properties. If you want to achieve maximum performance, we strongly encourage you to use a fixed schema where possible. The additional properties will always be serialized at the end of the object. Example:

const stringify = fastJson({
  title: 'Example Schema',
  type: 'object',
  properties: {
    nickname: {
      type: 'string'
    }
  },
  patternProperties: {
    'num': {
      type: 'number'
    },
    '.*foo$': {
      type: 'string'
    }
  },
  additionalProperties: {
    type: 'string'
  }
})

const obj = {
  nickname: 'nick',
  matchfoo: 42,
  otherfoo: 'str',
  matchnum: 3,
  nomatchstr: 'valar morghulis',
  nomatchint: 313
}

console.log(stringify(obj)) // '{"nickname":"nick","matchfoo":"42","otherfoo":"str","matchnum":3,"nomatchstr":"valar morghulis",nomatchint:"313"}'

AnyOf and OneOf

fast-json-stringify supports the anyOf and oneOf keywords as defined by JSON schema. Both must be an array of valid JSON schemas. The different schemas will be tested in the specified order. The more schemas stringify has to try before finding a match, the slower it will be.

anyOf and oneOf use ajv as a JSON schema validator to find the schema that matches the data. This has an impact on performance—only use it as a last resort.

Example:

const stringify = fastJson({
  title: 'Example Schema',
  type: 'object',
  properties: {
    'undecidedType': {
      'anyOf': [{
	type: 'string'
      }, {
	type: 'boolean'
      }]
    }
  }
})

When specifying object JSON schemas for anyOf, add required validation keyword to match only the objects with the properties you want.

Example:

const stringify = fastJson({
  title: 'Example Schema',
  type: 'array',
  items: {
    anyOf: [
      {
        type: 'object',
        properties: {
          savedId: { type: 'string' }
        },
        // without "required" validation any object will match
        required: ['savedId']
      },
      {
        type: 'object',
        properties: {
          error: { type: 'string' }
        },
        required: ['error']
      }
    ]
  }
})

If/then/else

fast-json-stringify supports if/then/else jsonschema feature. See ajv documentation.

Example:

const stringify = fastJson({
  'type': 'object',
  'properties': {
  },
  'if': {
    'properties': {
      'kind': { 'type': 'string', 'enum': ['foobar'] }
    }
  },
  'then': {
    'properties': {
      'kind': { 'type': 'string', 'enum': ['foobar'] },
      'foo': { 'type': 'string' },
      'bar': { 'type': 'number' }
    }
  },
  'else': {
    'properties': {
      'kind': { 'type': 'string', 'enum': ['greeting'] },
      'hi': { 'type': 'string' },
      'hello': { 'type': 'number' }
    }
  }
})

console.log(stringify({
  kind: 'greeting',
  foo: 'FOO',
  bar: 42,
  hi: 'HI',
  hello: 45
})) // {"kind":"greeting","hi":"HI","hello":45}
console.log(stringify({
  kind: 'foobar',
  foo: 'FOO',
  bar: 42,
  hi: 'HI',
  hello: 45
})) // {"kind":"foobar","foo":"FOO","bar":42}

NB Do not declare the properties twice or you will print them twice!

Reuse - $ref

If you want to reuse a definition of a value, you can use the property $ref. The value of $ref must be a string in JSON Pointer format. Example:

const schema = {
  title: 'Example Schema',
  definitions: {
    num: {
      type: 'object',
      properties: {
        int: {
          type: 'integer'
        }
      }
    },
    str: {
      type: 'string'
    }
  },
  type: 'object',
  properties: {
    nickname: {
      $ref: '#/definitions/str'
    }
  },
  patternProperties: {
    'num': {
      $ref: '#/definitions/num'
    }
  },
  additionalProperties: {
    $ref: '#/definitions/def'
  }
}

const stringify = fastJson(schema)

If you need to use an external definition, you can pass it as an option to fast-json-stringify. Example:

const schema = {
  title: 'Example Schema',
  type: 'object',
  properties: {
    nickname: {
      $ref: 'strings#/definitions/str'
    }
  },
  patternProperties: {
    'num': {
      $ref: 'numbers#/definitions/num'
    }
  },
  additionalProperties: {
    $ref: 'strings#/definitions/def'
  }
}

const externalSchema = {
  numbers: {
    definitions: {
      num: {
        type: 'object',
        properties: {
          int: {
            type: 'integer'
          }
        }
      }
    }
  },
  strings: require('./string-def.json')
}

const stringify = fastJson(schema, { schema: externalSchema })

External definitions can also reference each other. Example:

const schema = {
  title: 'Example Schema',
  type: 'object',
  properties: {
    foo: {
      $ref: 'strings#/definitions/foo'
    }
  }
}

const externalSchema = {
  strings: {
    definitions: {
      foo: {
        $ref: 'things#/definitions/foo'
      }
    }
  },
  things: {
    definitions: {
      foo: {
        type: 'string'
      }
    }
  }
}

const stringify = fastJson(schema, { schema: externalSchema })

Long integers

By default the library will handle automatically BigInt.

Integers

The type: integer property will be truncated if a floating point is provided. You can customize this behaviour with the rounding option that will accept round, ceil, floor or trunc. Default is trunc:

const stringify = fastJson(schema, { rounding: 'ceil' })

Nullable

According to the Open API 3.0 specification, a value that can be null must be declared nullable.

Nullable object
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

Otherwise, instead of raising an error, null values will be coerced as follows:

  • integer -> 0
  • number -> 0
  • string -> ""
  • boolean -> false
  • object -> {}
  • array -> []

Large Arrays

Large arrays are, for the scope of this document, defined as arrays containing, by default, 20000 elements or more. That value can be adjusted via the option parameter largeArraySize.

At some point the overhead caused by the default mechanism used by fast-json-stringify to handle arrays starts increasing exponentially, leading to slow overall executions.

Settings

In order to improve that the user can set the largeArrayMechanism and largeArraySize options.

largeArrayMechanism's default value is default. Valid values for it are:

  • default - This option is a compromise between performance and feature set by still providing the expected functionality out of this lib but giving up some possible performance gain. With this option set, large arrays would be stringified by joining their stringified elements using Array.join instead of string concatenation for better performance
  • json-stringify - This option will remove support for schema validation within large arrays completely. By doing so the overhead previously mentioned is nulled, greatly improving execution time. Mind there's no change in behavior for arrays not considered large

largeArraySize's default value is 20000. Valid values for it are integer-like values, such as:

  • 20000
  • 2e4
  • '20000'
  • '2e4' - note this will be converted to 2, not 20000
  • 1.5 - note this will be converted to 1

Unsafe string

By default, the library escapes all strings. With the 'unsafe' format, the string isn't escaped. This has a potentially dangerous security issue. You can use it only if you are sure that your data doesn't need escaping. The advantage is a significant performance improvement.

Example:

const stringify = fastJson({
  title: 'Example Schema',
  type: 'object',
  properties: {
    'code': {
	    type: 'string',
	    format 'unsafe'
    }
  }
})
Benchmarks

For reference, here goes some benchmarks for comparison over the three mechanisms. Benchmarks conducted on an old machine.

  • Machine: ST1000LM024 HN-M 1TB HDD, Intel Core i7-3610QM @ 2.3GHz, 12GB RAM, 4C/8T.
  • Node.js v16.13.1
JSON.stringify large array x 157 ops/sec ±0.73% (86 runs sampled)
fast-json-stringify large array default x 48.72 ops/sec ±4.92% (48 runs sampled)
fast-json-stringify large array json-stringify x 157 ops/sec ±0.76% (86 runs sampled)
compile-json-stringify large array x 175 ops/sec ±4.47% (79 runs sampled)
AJV Serialize large array x 58.76 ops/sec ±4.59% (60 runs sampled)

Security notice

Treat the schema definition as application code, it is not safe to use user-provided schemas.

To achieve low cost and high performance redaction fast-json-stringify creates and compiles a function (using the Function constructor) on initialization. While the schema is currently validated for any developer errors, there is no guarantee that supplying user-generated schema could not expose your application to remote attacks.

Users are responsible for sending trusted data. fast-json-stringify guarantees that you will get a valid output only if your input matches the schema or can be coerced to the schema. If your input doesn't match the schema, you will get undefined behavior.

Debug Mode

The debug mode can be activated during your development to understand what is going on when things do not work as you expect.

const debugCompiled = fastJson({
  title: 'default string',
  type: 'object',
  properties: {
    firstName: {
      type: 'string'
    }
  }
}, { mode: 'debug' })

console.log(debugCompiled) // it is a object contain code, ajv instance
const rawString = debugCompiled.code // it is the generated code
console.log(rawString) 

const stringify = fastJson.restore(debugCompiled) // use the generated string to get back the `stringify` function
console.log(stringify({ firstName: 'Foo', surname: 'bar' })) // '{"firstName":"Foo"}'

Standalone Mode

The standalone mode is used to compile the code that can be directly run by node itself. You need to have fast-json-stringify installed for the standalone code to work.

const fs = require('fs')
const code = fastJson({
  title: 'default string',
  type: 'object',
  properties: {
    firstName: {
      type: 'string'
    }
  }
}, { mode: 'standalone' })

fs.writeFileSync('stringify.js', code)
const stringify = require('stringify.js')
console.log(stringify({ firstName: 'Foo', surname: 'bar' })) // '{"firstName":"Foo"}'

Acknowledgements

This project was kindly sponsored by nearForm.

License

MIT

fast-json-stringify's People

Contributors

allevo avatar artemruts avatar cemremengu avatar cesco69 avatar davidebianchi avatar delvedor avatar dependabot-preview[bot] avatar dependabot[bot] avatar elliotttf avatar eomm avatar fdawgs avatar florianreinhart avatar greenkeeper[bot] avatar is2ei avatar ivan-tymoshenko avatar keldorus avatar l2jliga avatar matthyk avatar mcollina avatar mjwwit avatar mse99 avatar nigrosimone avatar rochdev avatar ruiaraujo avatar simenb avatar sinclairzx81 avatar srmarjani avatar uzlopak avatar yaki3355 avatar zekth avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fast-json-stringify's Issues

AnyOf not supported

When trying to validate against a JSON schema containing anyOf type, the parser throw an error.

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "properties": {
    "key1": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "object"
        }
      ]
    }
  },
  "additionalProperties": false
}

throws undefined unsupported.

I'll make a PR with a failing test case so it can be clearer.

Stringify a Date as number instead of string.

I did this bench, and the result is remarkable.

'use strict'

const benchmark = require('benchmark')
const suite = new benchmark.Suite()
const date = new Date()

suite
  .add('toISOString()', function () {
    date.toISOString()
  })
  .add('getTime()', function () {
    date.getTime()
  })
  .on('cycle', function (event) {
    console.log(String(event.target))
  })
  .on('complete', function () {})
  .run()

Result:

toISOString() x 2,132,610 ops/sec ±0.84% (91 runs sampled)
getTime() x 86,037,830 ops/sec ±0.96% (92 runs sampled)

Should we move from .toISOString() to .getTime()?

Improve string serialization?

Hello @addaleax!
Me and @mcollina are working on this project, Fastify a web framework focused on performances and other very nice stuff :)
Part of the project is this module, that as you can easily image is a schema based json serializator.

I saw your talk at NodeConfBarcellona where you talked about character encoding.
We had some little trouble with that and our solution was this one.
I was wondering if you'd like to check out the function, and help us to improve it :)

Thank you and have a nice day! :)

Properties of nested objects aren't always serialized

If a nested object has a property, which is also present in the parent, it is not serialized.

I've already created a test case.

'use strict'

const test = require('tap').test
const build = require('..')

test('nested objects with same properties', (t) => {
  t.plan(1)

  const schema = {
    title: 'nested objects with same propertie',
    type: 'object',
    properties: {
      stringProperty: {
        type: 'string'
      },
      objectProperty: {
        type: 'object',
        additionalProperties: true
      }
    }
  }
  const stringify = build(schema)

  try {
    const value = stringify({
      stringProperty: 'string1',
      objectProperty: {
        stringProperty: 'string2',
        numberProperty: 42
      }
    })
    t.is(value, '{"stringProperty":"string1","objectProperty":{"stringProperty":"string2","numberProperty":42}}')
  } catch (e) {
    t.fail()
  }
})

Expected result

{
  "stringProperty": "string1",
  "objectProperty": {
    "stringProperty": "string2",
    "numberProperty": 42
  }
}

Actual result

{
  "stringProperty": "string1",
  "objectProperty": {
    "numberProperty": 42
  }
}

anyOf coercion

Hi!

I'm trying to understand whether what I see is a bug or an expected behavior. String coercion doesn't seem to happen when inside an anyOf (see https://runkit.com/embed/1aoibrghntr5), so my question is should it and if not is there any way to do it?

Thanks!

Remove dynamic requirements

I use webpack on the server side. ES 6 expects static imports. As a result 'long' and 'uglify-es' emit the following warnings. In general, I believe it is bad practice to include dynamic requirements in a module - even while a dynamic import is being considered in ES.

Let's think of a better way to handle adding these capabilities. I have replaced my project path with '/path/to/project' in the traces below:

WARNING in ./node_modules/fast-json-stringify/index.js
Module not found: Error: Can't resolve 'long' in '/path/to/project/node_modules/fast-json-stringify'
 @ ./node_modules/fast-json-stringify/index.js 9:11-26
 @ ./node_modules/fastify/lib/reply.js
 @ ./node_modules/fastify/fastify.js
 @ ./es6/lib/app/index.js
 @ ./es6/index.js

WARNING in ./node_modules/fast-json-stringify/index.js
Module not found: Error: Can't resolve 'uglify-es' in '/path/to/project/node_modules/fast-json-stringify'
 @ ./node_modules/fast-json-stringify/index.js 608:13-33
 @ ./node_modules/fastify/lib/reply.js
 @ ./node_modules/fastify/fastify.js
 @ ./es6/lib/app/index.js
 @ ./es6/index.js

WARNING in ./node_modules/fast-json-stringify/index.js
Module not found: Error: Can't resolve 'uglify-es/package.json' in '/path/to/project/node_modules/fast-json-stringify'
 @ ./node_modules/fast-json-stringify/index.js 609:24-57
 @ ./node_modules/fastify/lib/reply.js
 @ ./node_modules/fastify/fastify.js
 @ ./es6/lib/app/index.js
 @ ./es6/index.js

How "anyOf" is working?

Hi. I can see that this lib supports anyOf. But according to description it looks like it acts like oneOf.
For example in ajv anyOf should match 1 or more and oneOf should match exactly one.

Also it seems working correctly if anyOf items differ by type. However if they not, it will fail and just take the last object to validate.

Under the hood it converts anyOf to if-else clause with ajv.validate. But ajv supports oneOf and allOf. Why it just not pass the whole parent object (that has oneOf or anyOf) directly to ajv?

test('object with multiple objects', (t) => {
  t.plan(2)

  const schema = {
    title: 'object with multiple objects',
    type: 'object',
    properties: {
      prop: {
        anyOf: [{
          type: 'object',
          properties: {
            str: {
              type: 'string'
            },
            str1: {
              type: 'string'
            }
          }
        },{
          type: 'object',
          properties: {
            str: {
              type: 'string'
            }
          }
        }, {
          type: 'object',
          properties: {
            str1: {
              type: 'string'
            }
          }
        }]
      }
    }
  }
  const stringify = build(schema)

  try {
    const value = stringify({
      prop: {str: 'string', str1: 'string1'}
    })
    t.is(value, '{"prop":{"str":"string", "str1":"string1"}}')
  } catch (e) {
    t.fail()
  }
})
    +++ found
    --- wanted
    -{"prop":{"str":"string", "str1":"string1"}}
    +{"prop":{"str1":"string1"}}

I've tried to make a fix for that, but seems I'm missing something and if I add the code it throws ajv is not defined exception during tests.

Support for long integers

Support for 64bit integers as numbers instead of strings would be very useful. The use case being 3rd-party APIs that enforce it.

From my understanding, the $asNumber function could simply not convert the input to a Number and it would pretty much work as it (since the source long would be a string anyway). However, I don't know if that would introduce a backward compatibility issue.

Alternatively, the string could be validated with regex, but that might be too slow.

I thought about adding a long type but that doesn't exist in the JSON Schema specification.

What do you think?

array type in response schema

Moving this issue fastify/fastify#331 (comment) to here

Hi,

I am playing with the framework to know if I should keep using it and this crashes the server when I npm server. Not sure why and I couldn't find anything in the docs. Thanks for your insight!


const userSchema = {
  schema: {
    response: {
      200: {
        type: 'object',
        properties: {
          users: { type: 'array' }
        }
      }
    }
  }


TypeError: Cannot read property '$ref' of undefined
    at buildArray (/Users/om/Documents/projects/ch/node-api/node_modules/fast-json-stringify/index.js:401:19)
    at nested (/Users/m/Documents/projects/ch/node-api/node_modules/fast-json-stringify/index.js:518:19)
    at Object.keys.forEach (/Users/m/Documents/projects/ch/node-api/node_modules/fast-json-stringify/index.js:365:18)
    at Array.forEach (native)
    at buildObject (/Users/m/Documents/projects/ch/node-api/node_modules/fast-json-stringify/index.js:352:40)
    at build (/Users/m/Documents/projects/crowdhub/node-api/node_modules/fast-json-stringify/index.js:56:14)
    at getValidatorForStatusCodeSchema (/Users/m/Documents/projects/ch/node-api/node_modules/fastify/lib/validation.js:15:10)
    at /Users/m/Documents/projects/ch/node-api/node_modules/fastify/lib/validation.js:21:21
    at Array.reduce (native)
    at getResponseSchema (/Users/m/Documents/projects/ch/node-api/node_modules/fastify/lib/validation.js:20:22)
    at build (/Users/m/Documents/projects/ch/node-api/node_modules/fastify/lib/validation.js:44:28)
    at _fastify.after (/Users/m/Documents/projects/ch/node-api/node_modules/fastify/fastify.js:400:7)
    at Function._encapsulateThreeParam (/Users/m/Documents/projects/ch/node-api/node_modules/avvio/boot.js:271:7)
    at Boot.callWithCbOrNextTick (/Users/m/Documents/projects/ch/node-api/node_modules/avvio/boot.js:223:5)
    at Boot._after (/Users/m/Documents/projects/ch/node-api/node_modules/avvio/boot.js:180:26)
    at process.nextTick (/Users/m/Documents/projects/ch/node-api/node_modules/avvio/plugin.js:30:5)

Version 10 of node.js has been released

Version 10 of Node.js (code name Dubnium) has been released! 🎊

To see what happens to your code in Node.js 10, Greenkeeper has created a branch with the following changes:

  • Added the new Node.js version to your .travis.yml

If you’re interested in upgrading this repo to Node.js 10, you can open a PR with these changes. Please note that this issue is just intended as a friendly reminder and the PR as a possible starting point for getting your code running on Node.js 10.

More information on this issue

Greenkeeper has checked the engines key in any package.json file, the .nvmrc file, and the .travis.yml file, if present.

  • engines was only updated if it defined a single version, not a range.
  • .nvmrc was updated to Node.js 10
  • .travis.yml was only changed if there was a root-level node_js that didn’t already include Node.js 10, such as node or lts/*. In this case, the new version was appended to the list. We didn’t touch job or matrix configurations because these tend to be quite specific and complex, and it’s difficult to infer what the intentions were.

For many simpler .travis.yml configurations, this PR should suffice as-is, but depending on what you’re doing it may require additional work or may not be applicable at all. We’re also aware that you may have good reasons to not update to Node.js 10, which is why this was sent as an issue and not a pull request. Feel free to delete it without comment, I’m a humble robot and won’t feel rejected 🤖


FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Root references require the hash

Gist with the issue here

Node Version: v8.0.0
fast-json-stringify-version: 0.15.1
OS: Windows 10, 64bit

References that do not have a hash cause an exception.

Good:

const goodSchema = {
  title: 'Example Schema',
  type: 'object',
  properties: {
    nickname: {
      $ref: 'strings#'
    }
  }
}

Bad:

const badSchema = {
  title: 'Example Schema',
  type: 'object',
  properties: {
    nickname: {
      $ref: 'strings' // <-------- note the missing hash
    }
  }
}

Exception that is thrown looks like this:

...\node_modules\fast-json-stringify\index.js:354
  var walk = ref[1].split('/')
                   ^
TypeError: Cannot read property 'split' of undefined

As far as I can tell, not having the hash is valid. example1, example2

It looks like here it should handle the case where there is no hash present - it could skip the walk.

Thoughts?

Thank you for your work with this library, it's incredibly useful. 😄

Allowing the use of a modified Ajv instance

Hi, thanks for all the great work!

I'm having a bit of a problem with reusing a schema in Fastify in the response that has a custom format and as I read the code I tracked it down (I think) to the fact Fastify uses this package to compile the response schemas, but since this package uses an internal instance of Ajv it does not have the custom format.

I'm wondering if you'd be open to a PR that would allow you to specify an instance of Ajv to use?

Loose Object property checking support

Co-related to my issue raised here:
#44

I have a use case to just have a loose object inside of a well-defined schema.

I suppose this issue would satisfy this use case as well:
#29

because then I could just specify the Object had a pattern property of ".*" with types ['string', 'number', 'null', 'boolean', 'object', 'array'] and then refs in the properties and items. This may even be better (read: more feasible) than loose Objects because it still forces you to be declarative about the types of the expected properties in the Object.

However, this still seems like abusive use of the multiple typing. Unfortunately, as much as I'd like to say that it was always possible to predict the types of properties in all of the Objects I'm attempting to stringify, there's always going to be a use case for Objects containing loosely-defined payloads.

Any thoughts on this as a feature? Or thoughts on solving it with the multi-typing functionality issue?

An in-range update of is-my-json-valid is breaking the build 🚨

Version 2.18.0 of is-my-json-valid was just published.

Branch Build failing 🚨
Dependency is-my-json-valid
Current Version 2.17.2
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

is-my-json-valid is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push: The Travis CI build could not complete due to an error (Details).

Commits

The new version differs by 3 commits.

  • 8ef04cc 2.18.0
  • 5247819 Merge pull request #164 from mafintosh/typescript
  • 7103fd3 Add TypeScript typings

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Throw if toString is not present

Example:

const fastJson = require('fast-json-stringify')
const stringify = fastJson({
  type: 'object',
  properties: {
    field: { type: 'string' }
  }
})

console.log(stringify({ field: null }))
// => TypeError: Cannot read property 'toString' of null

What we want to do in the above case?

  • 'null'
  • ''

Other options?

Remove uglifier support

This is only relevant for Node 6 now, and I think we should drop this feature in the next major release.

A string with one double quote at the beginning is not correctly stringified

If a string begins with a double quote and it never contains another one it is stringified without escaping the double quote.
The following test fails

'use strict'

const test = require('tap').test
const validator = require('is-my-json-valid')
const build = require('..')

test('render a single quote as JSON', (t) => {
  t.plan(2)

  const schema = {
    type: 'string'
  }
  const toStringify = '" double quote'

  const validate = validator(schema)
  const stringify = build(schema)
  const output = stringify(toStringify)

  t.equal(output, JSON.stringify(toStringify))
  t.ok(validate(JSON.parse(output)), 'valid schema')
})

This is the output of the test

    +++ found
    --- wanted
    -"\" double quote"
    +"" double quote"

The test does not fail if there is another double quote anywhere in the string...

An in-range update of ajv is breaking the build 🚨

The dependency ajv was updated from 6.5.3 to 6.5.4.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

ajv is a direct dependency of this project, and it is very likely causing it to break. If other packages depend on yours, this update is probably also breaking those in turn.

Status Details
  • continuous-integration/travis-ci/push: The Travis CI build failed (Details).

Commits

The new version differs by 8 commits.

  • 8578816 6.5.4
  • 5c41a84 Merge pull request #863 from epoberezkin/fix-861-property-names
  • c1f929b fix: propertyNames with empty schema, closes #861
  • 70362b9 test: failing test for #861
  • 12e1655 Merge pull request #862 from billytrend/patch-2
  • f01e92a Fixes grammar
  • 851b73c Merge pull request #858 from epoberezkin/greenkeeper/bluebird-pin-3.5.1
  • 9aa65f7 fix: pin bluebird to 3.5.1

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Support for array of types in JSON schema

The following is a valid schema, but currently unsupported by fast-json-stringify:

{
    "type": "object",
    "properties": {
      "stringOrNumber": {"type": ["string", "number"], "maxLength": 10}
    }
}

General regression

After some test I saw a general regression in the benchmarks.
Both in Node v4 and v6.

The bench:

JSON.stringify array x 3,796 ops/sec ±0.83% (92 runs sampled)
fast-json-stringify array x 1,629 ops/sec ±1.20% (90 runs sampled)

JSON.stringify long string x 13,905 ops/sec ±0.75% (93 runs sampled)
fast-json-stringify long string x 13,805 ops/sec ±0.86% (91 runs sampled)

JSON.stringify short string x 5,121,081 ops/sec ±0.90% (88 runs sampled)
fast-json-stringify short string x 4,957,411 ops/sec ±0.85% (90 runs sampled)

JSON.stringify obj x 1,814,632 ops/sec ±0.93% (87 runs sampled)
fast-json-stringify obj x 1,583,802 ops/sec ±0.79% (92 runs sampled)

I'll do more test.
Related: fastify/fastify#34

Stream Support?

Are there plans to support streams or is there already an example?

For instance, a large collection of schema objects sent to the client in chunks.

An in-range update of ajv is breaking the build 🚨

The dependency ajv was updated from 6.5.4 to 6.5.5.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

ajv is a direct dependency of this project, and it is very likely causing it to break. If other packages depend on yours, this update is probably also breaking those in turn.

Status Details
  • continuous-integration/travis-ci/push: The Travis CI build failed (Details).

Commits

The new version differs by 7 commits.

  • 494026e 6.5.5
  • 6478687 Merge pull request #860 from ossdev07/master
  • 2acd5f3 Merge pull request #865 from jsdevel/adding-logger-to-ts
  • d5edde4 Merge pull request #871 from nwoltman/patch-1
  • 8d769b6 Remove duplicated character in email regex
  • ae68416 Adding logger to typescript Options declaration.
  • 85b7f52 replacing phantomjs with headless chrome

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

array

I'm unable to set a response schema for an array in Fastify.

Version

Error

/Users/seb/Code/sebdeckers/fastify/node_modules/fast-json-stringify/index.js:559
      } else throw new Error(`${schema} unsupported`)
             ^

Error: [object Object] unsupported
    at nested (/Users/seb/Code/sebdeckers/fastify/node_modules/fast-json-stringify/index.js:559:20)
    at buildArray (/Users/seb/Code/sebdeckers/fastify/node_modules/fast-json-stringify/index.js:475:14)
    at build (/Users/seb/Code/sebdeckers/fastify/node_modules/fast-json-stringify/index.js:76:14)
    at getValidatorForStatusCodeSchema (/Users/seb/Code/sebdeckers/fastify/lib/validation.js:15:10)
    at /Users/seb/Code/sebdeckers/fastify/lib/validation.js:21:21
    at Array.reduce (<anonymous>)
    at getResponseSchema (/Users/seb/Code/sebdeckers/fastify/lib/validation.js:20:22)
    at build (/Users/seb/Code/sebdeckers/fastify/lib/validation.js:47:28)
    at _fastify.after (/Users/seb/Code/sebdeckers/fastify/fastify.js:411:7)
    at Function._encapsulateThreeParam (/Users/seb/Code/sebdeckers/fastify/node_modules/avvio/boot.js:282:7)

Reproducible Code

const fastify = require('fastify')({logger: true})

fastify.route({
  url: '/',
  method: 'GET',
  schema: {
    response: {
      200: {
        type: 'array',
        items: {
          hello: { type: 'string' }
        }
      }
    }
  },
  handler: async (request, reply) => {
    reply.send([
      { hello: 'world' }
    ])
  }
})

fastify.listen(0, () => {
  console.log(`Listening at port ${fastify.server.address().port}`)
})

Weird issue with 0.13.0: multiple tuple item type support

In an ill advised effort to use the new multitype tuple feature to allow any type in an object in any position of an Array, I think I've uncovered a weird bug:

here is my schema for an Array property "args":

        args: {
            items: [
                {
                    type: 'object',
                    patternProperties: {
                        '.*': {
                            type: 'string',
                        },
                    },
                },
                {
                    type: 'object',
                    patternProperties: {
                        '.*': {
                            type: 'number',
                        },
                    },
                },
                {
                    type: 'object',
                    patternProperties: {
                        '.*': {
                            type: 'null',
                        },
                    },
                },
                {
                    type: 'object',
                    patternProperties: {
                        '.*': {
                            type: 'boolean',
                        },
                    },
                },
            ],
            type: 'array',
        },

and then here is my object:

const obj = {
    args: [
        'foo', 
        {
            foo: 1,
            bar: 'foo',
        }
     ],
};

This is the result:

{"args":[,{"foo":"1","bar":"foo"}{"foo":1,"bar":null}{"foo":null,"bar":null}{"foo":true,"bar":true}]}

I was just attempting to use this for which it wasn't intended, but at the same time, this returns an invalid JSON string, which I don't think is desirable behavior.

Error when using anyOf with null and object type

I ran into this issue when trying to create a JSON schema for fastify. We have a property that can either be null or be an object. I've created a simple example to reproduce the issue:

const fastJson = require("fast-json-stringify")

const mySchema = {
    type: "object",
    properties: {
        myProperty: {
            anyOf: [
                {
                    type: "object",
                    properties: {
                        propertyA: {
                            type: "string"
                        }
                    }
                },
                {
                    type: "null",
                }
            ]
        }
    }
}

const stringify = fastJson(mySchema)

let json = stringify({
    myProperty: null
})
console.log(json)

json = stringify({
    myProperty: {
        propertyA: "hello"
    }
})
console.log(json)

It looks like fast-json-stringify generates invalid code:

ReferenceError: $mainmyPropertyundefined is not defined
    at $main (eval at build (/test/fast-json-stringify/node_modules/fast-json-stringify/index.js:99:20), <anonymous>:77:9)
    at Object.<anonymous> (/test/fast-json-stringify/index.js:31:8)
    at Module._compile (module.js:643:30)
    at Object.Module._extensions..js (module.js:654:10)
    at Module.load (module.js:556:32)
    at tryModuleLoad (module.js:499:12)
    at Function.Module._load (module.js:491:3)
    at Function.Module.runMain (module.js:684:10)
    at startup (bootstrap_node.js:187:16)
    at bootstrap_node.js:608:3

Nested additionalProperties throw at runtime

As titled, test to reproduce:

test('nested additionalProperties', (t) => {
  t.plan(1)
  const stringify = build({
    title: 'additionalProperties',
    type: 'object',
    properties: {
      ap: {
        type: 'object',
        additionalProperties: { type: 'string' }
      }
    }
  })

  let obj = { ap: { value: 'string' } }
  t.equal('{"ap":{"value":"string"}}', stringify(obj))
})

The output:

  nested additionalProperties
  not ok Cannot convert undefined or null to object
    stack: |
      buildObject (index.js:267:10)
      nested (index.js:381:19)
      Object.keys.forEach (index.js:279:20)
      Array.forEach (native)
      buildObject (index.js:267:34)
      build (index.js:28:14)
      Test.test (test/additionalProperties.test.js:186:21)
    at:
      line: 267
      column: 10
      file: index.js
      function: buildObject
    type: TypeError
    test: additionalProperties
    source: |
      Object.keys(schema.properties).forEach((key, i, a) => {

An in-range update of uglify-es is breaking the build 🚨

Version 3.0.26 of uglify-es just got published.

Branch Build failing 🚨
Dependency uglify-es
Current Version 3.0.25
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As uglify-es is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this 💪

Status Details
  • continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details

Release Notes v3.0.26

 

Commits

The new version differs by 7 commits.

See the full diff

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

Serialization of an object with unknown attributes

Hi all, sorry this is a question and not an issue ... in a library I'm writing fastify-cloudevents, I need to serialize even an object 'data' (usually it's an object, but could be even a Map or a Set ... and with the if/then/else jsonschema feature I should be able to handle it, ok), anyway data is an object provided by consumers of the library, so I can't define more in detail its structure in the schema ... and in this way if I serialize in JSON I only get an empty object, so the solution seems to enable the additionalProperties flag, right ?
But in this case is there a way for me to let the schema handle only attributes of the 'data' object (and filter out other attributes maybe present in the main data structure), like some kind of 'allow-nested-properties' but not other 'top-level-properties' ?
Hope to explain my problem well ... otherwise I can provide more details; note that current code in my repo show the behavior.
Thanks a lot for now, Sandro

An in-range update of is-my-json-valid is breaking the build 🚨

Version 2.17.0 of is-my-json-valid was just published.

Branch Build failing 🚨
Dependency is-my-json-valid
Current Version 2.16.1
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

is-my-json-valid is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push The Travis CI build failed Details

Commits

The new version differs by 4 commits.

  • 030467a 2.17.0
  • 928417d Merge pull request #148 from deBhal/add/schemaPath
  • 1edfc55 Add schemaPath to README
  • ddb520e Add schemaPath to verbose output

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Pattern and Additional properties

Below the proposal to how implement pattern and additional properties.

patternProperties:

Must be an object, where the key is a valid regex and the value is an object.
Example:

"patternProperties": {
    "^S_": { "type": "string" },
    "^I_": { "type": "integer" }
  }

patternProperties will work only for the properties that are not explicitly listed in the properties object.

additionalProperties:

Must be a boolean or an object.
If the is setted to false and there are properties that are not explicitly listed in the properties object we should throw an error.
If additionalProperties is used in conjunction with patternProperties the pecking order will be:
properties -> patternProperties -> additionalProperties
Example:

"additionalProperties": {
  "type": "string"
}

Discussion:

The json schema is very bad documented, so before start to implement these functionalities we need to discuss about few things.

  • additionalProperties
    If is setted to { type: 'string' } and any additional property is not a string we have two possible cases:
    1. throw an error
    2. stringify the property as string
  • patternProperties
    Basically the same as above, if a property matches to a pattern with { type: 'number' } but the property is not a number we have two cases:
    1. throw an error
    2. stringify the property as number

If I forgot or I didn't see some edge case please write it below.

An in-range update of ajv is breaking the build 🚨

Version 5.4.0 of ajv was just published.

Branch Build failing 🚨
Dependency ajv
Current Version 5.3.0
Type dependency

This version is covered by your current version range and after updating it in your project the build failed.

ajv is a direct dependency of this project, and it is very likely causing it to break. If other packages depend on yours, this update is probably also breaking those in turn.

Status Details
  • continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details

Release Notes v5.4.0

Option logger to disable logging or to specify a custom logger (#618, @meirotstein).

Commits

The new version differs by 20 commits.

  • f336cda 5.4.0
  • 00be319 Merge branch 'meirotstein-master'
  • 89a80ca check that console has log, warn and error methods as well
  • 5ba22a3 remove Logger class, resolve logger object on Ajv ctor instead
  • e0c7eac create logger instance per Ajv instance
  • 4cdfcaa Merge branch 'master' into master
  • 4fe1c21 update readme with logger option
  • ceb552a logger option tests
  • b0e28ee logger component tests
  • 91374ac add logger option
  • cdd93a6 Merge pull request #621 from stuartpb/patch-1
  • 0196611 Update draft-06 meta-schema
  • 0cafcf6 docs: version 6 beta
  • c73ff44 Merge pull request #616 from kpping/patch-1
  • bddda60 make available types more noticeable

There are 20 commits in total.

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Is allOf a possible keyword in schema ?

Hi,

I got a schema like that for a route on fastify.

{
  "200": {
    "type": "object",
    "allOf": [
      {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "tag": {
            "type": "string"
          }
        }
      },
      {
        "required": [
          "id"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          }
        }
      }
    ]
  },
  "default": {
    "type": "object",
    "required": [
      "code",
      "message"
    ],
    "properties": {
      "code": {
        "type": "integer"
      },
      "message": {
        "type": "string"
      }
    }
  }
}

And sadly, my validation function for the 200 (responseSchemaDef[statusCode]) look like this :

$main(obj) {
      var json = '{'
      var addComma = false
  
      json += '}'
      return json
}

I'm guessing that allOf is not available, but it's a JSON schema official keywork.

Can you add it?

Same for oneOf ?

Regards

Support for toJSON

I'd like to have a little different model structure internally in my app than returning it externally via API. Unfortunately, using fastify and fast-json-stringify this can't be done as fast-json-stringify does not use the objects toJSON function to map the data somehow.

I guess it could be on purpose to improve the performance, but this is a little bit unintuitive to do:

reply.send(model.toJSON());

and what even worse:

const models = [arrayOfModels];
reply.send(models.map(model => model.toJSON()));

This doesn't make much sense as there's no difference if I have to do this manually or if it would be done by fast-json-stringify - just as I'd expect.

Here's a little reproduction:

const fastJson = require("fast-json-stringify");

const stringify = fastJson({
    type: "object",
    properties: {
        groups: {
            type: "array",
            items: {
                type: "string"
            }
        }
    }
});

class User {
    constructor() {
        this.groups = [{ name: "admin" }, { name: "subscriber" }];
    }

    toJSON() {
        return {
            ...this,
            groups: this.groups.map(group => group.name)
        };
    }
}

const user = new User();

console.log(stringify(user)); // returns: {"groups":["[object Object]","[object Object]"]}
console.log(JSON.stringify(user)); // returns: {"groups":["admin","subscriber"]}

Could you somehow relate to this issue? And maybe you have some idea for a solution in fastify?

Array Object Schema

[
{
id: "string"
}
]

I have json like that. How to build my schema ?

Thanks

Handle object property starting with `@`

We have a logging contract which says timestamp should be called @timstamp and version should be @version. This module throws when it tries to serialise it (on node@6 at least).

Example:

require('fast-json-stringify')({
    title: 'Logging Schema',
    type: 'object',
    properties: {
        '@version': {
            type: 'integer',
        },
    },
});
undefined:61
      if (obj.@version !== undefined) {
              ^
SyntaxError: Invalid or unexpected token
    at build (/Users/simbekkh/repos/node-fiaas-logger/node_modules/fast-json-stringify/index.js:80:11)
    at Object.<anonymous> (/Users/simbekkh/repos/node-fiaas-logger/sup.js:5:19)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:393:7)
    at startup (bootstrap_node.js:150:9)

Properties should be optional

If you pass just the additionalProperties and not the properties, fast-json-stringify will throw.
properties should be optional.

Here the line that must be changed.

Any way to run in an environment where new Function() and eval are not allowed?

Hi. Cloudflare Edge Workers allow you to write javascript that runs in an embedded V8 environment in all >150 of Cloudflare's data centres at the 'edge'. However for security reasons they don't allow you to use eval() and new Function().

I was wondering if there's a way of using fast-json-stringify given these constraints. I can see that new Function() is used by the library here:

return (new Function('schema', code))(schema)

I had a quick look through the source code and can't think of a way of removing new Function(), it seems very central to how the library works. But then again I'm not very advanced in js so thought I'd post a quick issue to ask.

One thought I'd did have: could there somehow be a way of using fast-json-stringify to generate the javascript needed for a specific schema in a code-generation step in advance, and then just ship that js code to cloudflare? I've done code-generation in golang before (strongly typed but no generics so it's a common approach) but I'm not very advanced in javascript to know if this could work in this case. I haven't looked into how fast-json-stringify works enough to know if this makes any sense so ignore me if it doesn't.

Thanks. Mike

PS: the environment isn't node.js in cloudflare's edge - it's essentially a V8 service-worker. Not sure if that's relevant - perhaps fast-json-stringify relies on other node.js-specific stuff so I should just give up on this idea entirely.

Use with multiple types

I'm using this in conjunction with Fastify, and am trying to pass back some SQL results. Many of the fields can be null, or contain a value.

I haven't figured out a way to use this and say that a value, for example deletedAt is a string, but may also be null.

Is that possible?

\d in patternproperties seems to not work

Hi, I have an object whose keys represents date in the format YYYY-MM-DD and I am trying to build a schema that matches it, but without any result. It looks like.

const fastJson = require('fast-json-stringify')
const stringify = fastJson({
  title: 'RabbitMQ Message',
  type: 'object',
  patternProperties: {
    '^\d{4}-\d{2}-\d{2}$': {
      type: 'string'
    }
  }
})

console.log(stringify({
  '2018-01-01': "foo",
}))

returns {}.

Using '^[0-9]{4}-[0-9]{2}-[0-9]{2}$'works, instead

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.