pax_global_header00006660000000000000000000000064134350102320014503gustar00rootroot0000000000000052 comment=ab0f350b5e6c715b56329308ffc73761ff10b98f buffer-json-2.0.0/000077500000000000000000000000001343501023200137225ustar00rootroot00000000000000buffer-json-2.0.0/.gitignore000066400000000000000000000000161343501023200157070ustar00rootroot00000000000000node_modules/ buffer-json-2.0.0/.npmignore000066400000000000000000000000241343501023200157150ustar00rootroot00000000000000test.js fixtures.js buffer-json-2.0.0/CHANGELOG.md000066400000000000000000000001751343501023200155360ustar00rootroot000000000000002.0.0 / 2019-02-25 ------------------- - rewrite to fix edge cases 1.0.0 / 2015-06-18 ------------------ - initial release buffer-json-2.0.0/README.md000066400000000000000000000054521343501023200152070ustar00rootroot00000000000000# buffer-json ``` npm install buffer-json ``` ```js const BJSON = require('buffer-json') const str = BJSON.stringify({ buf: Buffer.from('hello') }) // => '{"buf":{"type":"Buffer","data":"base64:aGVsbG8="}}' BJSON.parse(str) // => { buf: } ``` The [`Buffer`](https://nodejs.org/api/buffer.html#buffer_buffer) class in Node.js is used to represent binary data. JSON does not specify a way to encode binary data, so the Node.js implementation of `JSON.stringify` represents buffers as an object of shape `{ type: "Buffer", data: [] }`. Unfortunately, `JSON.parse` does not turn this structure back into a `Buffer` object: ``` $ node > JSON.parse(JSON.stringify({ buf: Buffer.from('hello world') })) { buf: { type: 'Buffer', data: [ 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100 ] } } ``` `JSON.stringify` and `JSON.parse` accept arguments called [`replacer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#The_replacer_parameter) and [`reviver`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Using_the_reviver_parameter) respectively which allow customizing the parsing/encoding behavior. This module provides a replacer which encodes Buffer data as a base64-encoded string, and a reviver which turns JSON objects which contain buffer-like data (either as arrays of numbers or strings) into `Buffer` instances. All other types of values are parsed/encoded as normal. ## API ### `stringify(value[, space])` Convenience wrapper for [`JSON.stringify`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) with the `replacer` described below. ### `parse(text)` Convenience wrapper for [`JSON.parse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse) with the `reviver` described below. ### `replacer(key, value)` A [`replacer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#The_replacer_parameter) implementation which turns every value that is a `Buffer` instance into an object of shape `{ type: 'Buffer', data: 'base64:' }`. Empty buffers are encoded as `{ type: 'Buffer', data: '' }`. ### `reviver(key, value)` A [`reviver`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Using_the_reviver_parameter) implementation which turns every object of shape `{ type: 'Buffer', data: }` into a `Buffer` instance. ## Related modules - [`buffer-json-encoding`](https://github.com/lachenmayer/buffer-json-encoding): an [`abstract-encoding`](https://github.com/mafintosh/abstract-encoding) compatible JSON encoder/decoder which uses this module. ## License MITbuffer-json-2.0.0/fixtures.js000066400000000000000000000016301343501023200161310ustar00rootroot00000000000000module.exports = { notBuffers: { foo: 'bar', baz: 5, removeMe: undefined, boing: null }, valid: [ { obj: Buffer.from('hello'), str: '{"type":"Buffer","data":"base64:aGVsbG8="}' }, { obj: Buffer.from('☃ ★ ☺ ♤ ✓ ♛ ∭'), str: '{"type":"Buffer","data":"base64:4piDIOKYhSDimLog4pmkIOKckyDimZsg4oit"}' }, { obj: Buffer.from(''), str: '{"type":"Buffer","data":""}' }, { obj: Buffer.from('🌈'), str: '{"type":"Buffer","data":"base64:8J+MiA=="}' }, { obj: { buf: Buffer.from('🌈'), test: 'yep' }, str: '{"buf":{"type":"Buffer","data":"base64:8J+MiA=="},"test":"yep"}' } ], utf8: [ { obj: { foo: Buffer.from('🌈') }, str: '{"foo":{"type":"Buffer","data":"🌈"}}' } ], invalid: [ { type: 'Buffer' }, { type: 'Buffer', data: 500 }, { type: 'Buffer', whatever: [123, 124, 125] } ] } buffer-json-2.0.0/index.js000066400000000000000000000023061343501023200153700ustar00rootroot00000000000000function stringify (value, space) { return JSON.stringify(value, replacer, space) } function parse (text) { return JSON.parse(text, reviver) } function replacer (key, value) { if (isBufferLike(value)) { if (isArray(value.data)) { if (value.data.length > 0) { value.data = 'base64:' + Buffer.from(value.data).toString('base64') } else { value.data = '' } } } return value } function reviver (key, value) { if (isBufferLike(value)) { if (isArray(value.data)) { return Buffer.from(value.data) } else if (isString(value.data)) { if (value.data.startsWith('base64:')) { return Buffer.from(value.data.slice('base64:'.length), 'base64') } // Assume that the string is UTF-8 encoded (or empty). return Buffer.from(value.data) } } return value } function isBufferLike (x) { return ( isObject(x) && x.type === 'Buffer' && (isArray(x.data) || isString(x.data)) ) } function isArray (x) { return Array.isArray(x) } function isString (x) { return typeof x === 'string' } function isObject (x) { return typeof x === 'object' && x !== null } module.exports = { stringify, parse, replacer, reviver } buffer-json-2.0.0/package.json000066400000000000000000000013211343501023200162050ustar00rootroot00000000000000{ "name": "buffer-json", "version": "2.0.0", "description": "JSON.stringify & JSON.parse which can encode/decode buffers.", "main": "index.js", "scripts": { "test": "standard --fix && node test.js" }, "repository": { "type": "git", "url": "git+https://github.com/jprichardson/buffer-json.git" }, "keywords": [ "JSON", "parse", "stringify", "buffer", "reviver", "replacer", "base64" ], "author": "JP Richardson", "license": "MIT", "bugs": { "url": "https://github.com/jprichardson/buffer-json/issues" }, "homepage": "https://github.com/jprichardson/buffer-json#readme", "devDependencies": { "standard": "^12.0.1", "tape": "^4.10.1" } } buffer-json-2.0.0/test.js000066400000000000000000000016151343501023200152420ustar00rootroot00000000000000const test = require('tape') const BJSON = require('.') const fixtures = require('./fixtures') test("don't touch anything other than buffers", t => { t.deepEquals( BJSON.stringify(fixtures.notBuffers), JSON.stringify(fixtures.notBuffers) ) t.end() }) test('buffers encoded/decoded as expected', t => { for (const test of fixtures.valid) { t.deepEquals(BJSON.stringify(test.obj), test.str) t.deepEquals(BJSON.parse(test.str), test.obj) t.deepEquals(BJSON.parse(BJSON.stringify(test.obj)), test.obj) t.deepEquals(BJSON.parse(JSON.stringify(test.obj)), test.obj) } t.end() }) test('utf8', t => { for (const test of fixtures.utf8) { t.deepEquals(BJSON.parse(test.str), test.obj) } t.end() }) test('not actually a buffer', t => { for (const obj of fixtures.invalid) { const str = JSON.stringify(obj) t.deepEquals(BJSON.parse(str), obj) } t.end() })