Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: phadej/relaxed-json
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 6857996a67f077390726214ae327bb77dcbdf5d2
Choose a base ref
...
head repository: phadej/relaxed-json
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 525675fb7d9c67a683971dc526aac27fca437457
Choose a head ref

Commits on Feb 25, 2015

  1. Copy the full SHA
    3788810 View commit details
  2. Copy the full SHA
    d29df01 View commit details

Commits on Mar 22, 2015

  1. Fix typo in readme

    phadej committed Mar 22, 2015
    Copy the full SHA
    e8466ed View commit details
  2. Update dependencies

    phadej committed Mar 22, 2015
    Copy the full SHA
    4887d1a View commit details
  3. Fix mocha

    phadej committed Mar 22, 2015
    Copy the full SHA
    09cc59e View commit details

Commits on Jun 4, 2015

  1. Update eslint

    phadej committed Jun 4, 2015
    Copy the full SHA
    f0110f7 View commit details
  2. Copy the full SHA
    bf6be30 View commit details

Commits on Jul 13, 2015

  1. Update eslint

    phadej committed Jul 13, 2015
    Copy the full SHA
    2bfa9b2 View commit details
  2. Copy the full SHA
    ac1b22e View commit details
  3. Add sudo: false to .travis.yml

    phadej committed Jul 13, 2015
    Copy the full SHA
    2f8bb5d View commit details
  4. Bump version to 1.0.0

    phadej committed Jul 13, 2015
    Copy the full SHA
    eee5cb4 View commit details
  5. Update badges

    phadej committed Jul 13, 2015
    Copy the full SHA
    ae00521 View commit details

Commits on Aug 28, 2015

  1. Update dev deps

    phadej committed Aug 28, 2015
    Copy the full SHA
    e250830 View commit details

Commits on Mar 8, 2017

  1. Update dependencies

    phadej committed Mar 8, 2017
    Copy the full SHA
    c07321c View commit details
  2. issue with module exports in certain frameworks (Meteor, Electrion). r…

    …esolves #9
    Lucas Geiger authored and phadej committed Mar 8, 2017
    Copy the full SHA
    f79df73 View commit details
  3. Bump version to 1.0.1

    phadej committed Mar 8, 2017
    Copy the full SHA
    f332f57 View commit details
  4. Update .travis.yml

    phadej committed Mar 8, 2017
    Copy the full SHA
    b3c6783 View commit details
  5. Merge pull request #15 from phadej/meteor

    issue with module exports in certain frameworks (Meteor, Electrion). …
    phadej authored Mar 8, 2017
    Copy the full SHA
    f3826d9 View commit details

Commits on Mar 4, 2019

  1. Update deps

    phadej committed Mar 4, 2019
    Copy the full SHA
    3d17e49 View commit details
  2. Add tolerant option to documentation.

    18steps authored and phadej committed Mar 4, 2019
    Copy the full SHA
    458e575 View commit details
  3. Export module or set global variable, but not both

    This prevents the library from being both exported and set as a global variable in a webpack build.
    kevinphelps authored and phadej committed Mar 4, 2019
    Copy the full SHA
    0478e00 View commit details
  4. Merge pull request #21 from phadej/prapare-1.0.2

    Prapare 1.0.2
    phadej authored Mar 4, 2019
    Copy the full SHA
    525675f View commit details
Showing with 691 additions and 135 deletions.
  1. +530 −10 .eslintrc
  2. +1 −0 .gitignore
  3. +2 −7 .jscsrc
  4. +17 −2 .travis.yml
  5. +5 −11 Makefile
  6. +17 −5 README.md
  7. +3 −1 bin/rjson.js
  8. +9 −15 package.json
  9. +85 −74 relaxed-json.js
  10. +1 −2 relaxed-json.min.js
  11. +1 −1 relaxed-json.min.js.map
  12. +20 −7 test/tests.js
540 changes: 530 additions & 10 deletions .eslintrc

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
node_modules
.nyc_output/
bower_components
npm-debug.log
web.min.css
9 changes: 2 additions & 7 deletions .jscsrc
Original file line number Diff line number Diff line change
@@ -44,19 +44,14 @@
"disallowSpacesInsideArrayBrackets": "all",
"disallowSpacesInsideParentheses": true,

"validateJSDoc": {
"checkParamNames": true,
"requireParamTypes": true
},

"disallowMultipleLineBreaks": true,

"requireParenthesesAroundIIFE": true,
"maximumLineLength": 300,
"validateIndentation": 2,
"validateQuoteMarks": {
"escape": true,
"mark": "\""
"escape": true,
"mark": "\""
},

"requireCamelCaseOrUpperCaseIdentifiers": "ignoreProperties",
19 changes: 17 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
sudo: false
language: node_js

node_js:
- "0.11"
- "0.10"
- "11"
- "10"
- "8"
- "8.10" # bionic

# Timeouts?
# - "6"

# eslint doesn't support node 4 anymore?
# - "4"
# - "4.2" # xenial

branches:
only:
- master
16 changes: 5 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ all : test
BINDIR=node_modules/.bin

MOCHA=$(BINDIR)/_mocha
ISTANBUL=$(BINDIR)/istanbul
ISTANBUL=$(BINDIR)/nyc
JSHINT=$(BINDIR)/jshint
ESLINT=$(BINDIR)/eslint
UGLIFY=$(BINDIR)/uglifyjs
@@ -14,26 +14,20 @@ JSCS=$(BINDIR)/jscs

SRC=relaxed-json.js bin/rjson.js

test : jshint eslint jscs mocha istanbul david

jshint :
$(JSHINT) $(SRC)
test : eslint mocha istanbul david

eslint :
$(ESLINT) $(SRC)

jscs :
$(JSCS) $(SRC)

mocha :
mocha :
$(MOCHA) --reporter=spec test

istanbul :
$(ISTANBUL) cover $(MOCHA) test
$(ISTANBUL) $(MOCHA) test
$(ISTANBUL) check-coverage --statements -1 --branches -2 --functions 100 --lines -1

uglify : relaxed-json.js
$(UGLIFY) -o relaxed-json.min.js --source-map relaxed-json.min.js.map relaxed-json.js
$(UGLIFY) relaxed-json.js -o relaxed-json.min.js --source-map

david :
$(DAVID)
22 changes: 17 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -2,16 +2,17 @@

[![Build Status](https://secure.travis-ci.org/phadej/relaxed-json.svg?branch=master)](http://travis-ci.org/phadej/relaxed-json)
[![NPM version](https://badge.fury.io/js/relaxed-json.svg)](http://badge.fury.io/js/relaxed-json)
[![Dependency Status](https://gemnasium.com/phadej/relaxed-json.svg)](https://gemnasium.com/phadej/relaxed-json)
[![Code Climate](https://img.shields.io/codeclimate/github/phadej/relaxed-json.svg))](https://codeclimate.com/github/phadej/relaxed-json)
[![Dependency Status](https://david-dm.org/phadej/relaxed-json.svg)](https://david-dm.org/phadej/relaxed-json)
[![devDependency Status](https://david-dm.org/phadej/relaxed-json/dev-status.svg)](https://david-dm.org/phadej/relaxed-json#info=devDependencies)
[![Code Climate](https://img.shields.io/codeclimate/github/phadej/relaxed-json.svg)](https://codeclimate.com/github/phadej/relaxed-json)

Are you frustrated that you cannot add comments into your configuration JSON
Relaxed JSON is a simple solution.
Small JavaScript library with only one exposed function `RJSON.transform(text : string) : string`
(and few convenient helpers).

[Relaxed JSON](http://oleg.fi/relaxed-json) (modified BSD license) is a strict superset of JSON,
relaxing strictness of valilla JSON.
relaxing strictness of vanilla JSON.
Valid, vanilla JSON will not be changed by `RJSON.transform`. But there are few additional
features helping writing JSON by hand.

@@ -31,7 +32,8 @@ features helping writing JSON by hand.
You could pass a reviver function or an options object as the second argument. Supported options:
- `reviver`: you could still pass a reviver
- `relaxed`: use relaxed version of JSON (default: true)
- `warnings`: use relaxed JSON own parser, supports better error messages (default: false).
- `warnings`: use relaxed JSON own parser, supports better error messages (default: false)
- `tolerant`: wait until the end to throw errors
- `duplicate`: fail if there are duplicate keys in objects

## Executable
@@ -45,7 +47,7 @@ $ rjson relaxed-json.js
Error on line 27: Unexpected character: (
(function () {

% rjson package.json
% rjson package.json
{
"name": "relaxed-json",
"description": "Relaxed JSON is strict superset JSON, relaxing strictness of valilla JSON",
@@ -55,6 +57,12 @@ Error on line 27: Unexpected character: (
## Changelog
- 1.0.1 — 2017-03-08 — Meteor compatibility
- [#9](https://github.com/phadej/relaxed-json/issues/9)
[#14](https://github.com/phadej/relaxed-json/pull/14)
[#15](https://github.com/phadej/relaxed-json/pull/15)
- 1.0.0 — 2015-07-13 — Stable release
- Forward slashes bug fixed
- 0.2.9 Dependencies bump
- 0.2.8 Dev dependencies update
- 0.2.7 `rjson` executable
@@ -81,3 +89,7 @@ Error on line 27: Unexpected character: (
## Related projects
- [strip-json-comments](https://www.npmjs.org/package/strip-json-comments)
For truly human writable configuration consider using [YAML](http://yaml.org/).
- [js-yaml](https://www.npmjs.com/package/js-yaml)
4 changes: 3 additions & 1 deletion bin/rjson.js
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ function cli(argv) {
if (program.args.length !== 1) {
console.error("Error: input file is required");
console.log(program.help());
return 0;
return 1;
}

var opts = {
@@ -42,6 +42,8 @@ function cli(argv) {
console.log(chalk.grey(contents.split(/\n/)[e.line - 1]));
}
}

return 0;
}

var ret = cli(process.argv);
24 changes: 9 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "relaxed-json",
"description": "Relaxed JSON is strict superset JSON, relaxing strictness of valilla JSON",
"version": "0.2.9",
"version": "1.0.2",
"homepage": "https://github.com/phadej/relaxed-json",
"author": {
"name": "Oleg Grenrus",
@@ -15,12 +15,7 @@
"bugs": {
"url": "https://github.com/phadej/relaxed-json/issues"
},
"licenses": [
{
"type": "BSD3",
"url": "https://github.com/phadej/relaxed-json/blob/master/LICENSE"
}
],
"license": "BSD-3-Clause",
"main": "relaxed-json.js",
"bin": {
"rjson": "./bin/rjson.js"
@@ -32,13 +27,12 @@
"test": "make"
},
"devDependencies": {
"eslint": "^0.15.0",
"istanbul": "~0.3.0",
"jscs": "^1.11.3",
"jshint": "^2.6.0",
"jsverify": "^0.5.1",
"mocha": "^2.1.0",
"uglify-js": "~2.4.13",
"david": "^11.0.0",
"eslint": "^5.15.0",
"nyc": "^13.3.0",
"jsverify": "^0.8.4",
"mocha": "^6.0.2",
"uglify-js": "^3.4.9",
"underscore": "^1.8.2"
},
"keywords": [
@@ -48,7 +42,7 @@
"config"
],
"dependencies": {
"chalk": "^1.0.0",
"chalk": "^2.4.2",
"commander": "^2.6.0"
}
}
159 changes: 85 additions & 74 deletions relaxed-json.js
Original file line number Diff line number Diff line change
@@ -57,6 +57,8 @@
raw: raw,
matched: tokenSpec.f(m, line),
};
} else {
return undefined;
}
});
}
@@ -65,7 +67,7 @@
var matched = findToken();

if (!matched) {
var err = new SyntaxError("Unexpected character: " + contents[0]);
var err = new SyntaxError("Unexpected character: " + contents[0] + "; input: " + contents.substr(0, 100));
err.line = line;
throw err;
}
@@ -123,9 +125,12 @@

function fComment(m) {
// comments are whitespace, leave only linefeeds
return { type: " ", match: m[0].replace(/./g, function (c) {
return (/\s/).test(c) ? c : " ";
}) };
return {
type: " ",
match: m[0].replace(/./g, function (c) {
return (/\s/).test(c) ? c : " ";
}),
};
}

function fNumber(m) {
@@ -139,9 +144,10 @@
function fKeyword(m) {
var value;
switch (m[1]) {
case "null": value = null; break;
case "true": value = true; break;
case "false": value = false; break;
case "null": value = null; break;
case "true": value = true; break;
case "false": value = false; break;
// no default
}
return {
type: "atom",
@@ -167,13 +173,13 @@
{ re: /^:/, f: f(":") },
{ re: /^(true|false|null)/, f: fKeyword },
{ re: /^\-?\d+(\.\d+)?([eE][+-]?\d+)?/, f: fNumber },
{ re: /^"([^"\\]|\\["bnrtf\\]|\\u[0-9a-fA-F]{4})*"/, f: fStringDouble },
{ re: /^"([^"\\]|\\["bnrtf\\\/]|\\u[0-9a-fA-F]{4})*"/, f: fStringDouble },
];

// additional stuff
if (relaxed) {
ret = ret.concat([
{ re: /^'(([^'\\]|\\['bnrtf\\]|\\u[0-9a-fA-F]{4})*)'/, f: fStringSingle },
{ re: /^'(([^'\\]|\\['bnrtf\\\/]|\\u[0-9a-fA-F]{4})*)'/, f: fStringSingle },
{ re: /^\/\/.*?(?:\r\n|\r|\n)/, f: fComment },
{ re: /^\/\*[\s\S]*?\*\//, f: fComment },
{ re: /^[$a-zA-Z0-9_\-+\.\*\?!\|&%\^\/#\\]+/, f: fIdentifier },
@@ -192,6 +198,7 @@
return index;
}
}
return undefined;
}

function stripTrailingComma(tokens) {
@@ -247,14 +254,14 @@

function strToken(token) {
switch (token.type) {
case "atom":
case "string":
case "number":
return token.type + " " + token.match;
case "eof":
return "end-of-file";
default:
return "'" + token.type + "'";
case "atom":
case "string":
case "number":
return token.type + " " + token.match;
case "eof":
return "end-of-file";
default:
return "'" + token.type + "'";
}
}

@@ -280,7 +287,7 @@
function skipPunctuation(tokens, state, valid) {
var punctuation = [",", ":", "]", "}"];
var token = popToken(tokens, state);
while (true) {
while (true) { // eslint-disable-line no-constant-condition
if (valid && valid.indexOf(token.type) !== -1) {
return token;
} else if (token.type === "eof") {
@@ -344,50 +351,51 @@
if (token.type !== "string") {
raiseUnexpected(state, token, "string");
switch (token.type) {
case ":":
token = {
type: "string",
value: "null",
line: token.line,
};

state.pos -= 1;
break;
case ":":
token = {
type: "string",
value: "null",
line: token.line,
};

case "number":
case "atom":
token = {
type: "string",
value: "" + token.value,
line: token.line,
};
break;
state.pos -= 1;
break;

case "[":
case "{":
state.pos -= 1;
value = parseAny(tokens, state);
appendPair(state, obj, "null", value);
return;
case "number":
case "atom":
token = {
type: "string",
value: "" + token.value,
line: token.line,
};
break;

case "[":
case "{":
state.pos -= 1;
value = parseAny(tokens, state); // eslint-disable-line no-use-before-define
appendPair(state, obj, "null", value);
return;
// no default
}
}

checkDuplicates(state, obj, token);
key = token.value;
skipColon(tokens, state);
value = parseAny(tokens, state);
value = parseAny(tokens, state); // eslint-disable-line no-use-before-define

appendPair(state, obj, key, value);
}

function parseElement(tokens, state, arr) {
var key = arr.length;
var value = parseAny(tokens, state);
var value = parseAny(tokens, state); // eslint-disable-line no-use-before-define
arr[key] = state.reviver ? state.reviver("" + key, value) : value;
}

function parseObject(tokens, state) {
return parseMany(tokens, state, {}, {
return parseMany(tokens, state, {}, { // eslint-disable-line no-use-before-define
skip: [":", "}"],
elementParser: parsePair,
elementName: "string",
@@ -396,7 +404,7 @@
}

function parseArray(tokens, state) {
return parseMany(tokens, state, [], {
return parseMany(tokens, state, [], { // eslint-disable-line no-use-before-define
skip: ["]"],
elementParser: parseElement,
elementName: "json object",
@@ -417,17 +425,17 @@
}

switch (token.type) {
case opts.endSymbol:
return obj;
case opts.endSymbol:
return obj;

default:
state.pos -= 1; // push the token back
opts.elementParser(tokens, state, obj);
break;
default:
state.pos -= 1; // push the token back
opts.elementParser(tokens, state, obj);
break;
}

// Rest
while (true) {
while (true) { // eslint-disable-line no-constant-condition
token = popToken(tokens, state);

if (token.type !== opts.endSymbol && token.type !== ",") {
@@ -442,12 +450,13 @@
}

switch (token.type) {
case opts.endSymbol:
return obj;
case opts.endSymbol:
return obj;

case ",":
opts.elementParser(tokens, state, obj);
break;
case ",":
opts.elementParser(tokens, state, obj);
break;
// no default
}
}
}
@@ -478,17 +487,18 @@
}

switch (token.type) {
case "{":
ret = parseObject(tokens, state);
break;
case "[":
ret = parseArray(tokens, state);
break;
case "string":
case "number":
case "atom":
ret = token.value;
break;
case "{":
ret = parseObject(tokens, state);
break;
case "[":
ret = parseArray(tokens, state);
break;
case "string":
case "number":
case "atom":
ret = token.value;
break;
// no default
}

if (end) {
@@ -502,7 +512,7 @@
function parse(text, opts) {
if (typeof opts === "function" || opts === undefined) {
return JSON.parse(transform(text), opts);
} else if (new Object(opts) !== opts) {
} else if (new Object(opts) !== opts) { // eslint-disable-line no-new-object
throw new TypeError("opts/reviver should be undefined, a function or an object");
}

@@ -540,7 +550,7 @@
}

function stringifyPair(obj, key) {
return JSON.stringify(key) + ":" + stringify(obj[key]);
return JSON.stringify(key) + ":" + stringify(obj[key]); // eslint-disable-line no-use-before-define
}

function stringify(obj) {
@@ -549,11 +559,12 @@
case "number":
case "boolean":
return JSON.stringify(obj);
// no default
}
if (Array.isArray(obj)) {
return "[" + obj.map(stringify).join(",") + "]";
}
if (new Object(obj) === obj) {
if (new Object(obj) === obj) { // eslint-disable-line no-new-object
var keys = Object.keys(obj);
keys.sort();
return "{" + keys.map(stringifyPair.bind(null, obj)) + "}";
@@ -569,9 +580,9 @@
};

/* global window, module */
if (typeof window !== "undefined") {
window.RJSON = RJSON;
} else if (typeof module !== "undefined") {
if (typeof module !== "undefined") {
module.exports = RJSON;
} else if (typeof window !== "undefined") {
window.RJSON = RJSON;
}
}());
3 changes: 1 addition & 2 deletions relaxed-json.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion relaxed-json.min.js.map

Large diffs are not rendered by default.

27 changes: 20 additions & 7 deletions test/tests.js
Original file line number Diff line number Diff line change
@@ -233,21 +233,22 @@ describe("parse() with opts { warnings: true } ", function () {

it("terminates always", function () {
var token = {
generator: function (size) {
size = jsc.random(0, 8);
switch (size) {
generator: jsc.generator.bless(function (size) {
switch (jsc.random(0, 8)) {
case 0: return "[";
case 1: return "]";
case 2: return "{";
case 3: return "}";
case 4: return ",";
case 5: return ":";
case 6: return "\"" + jsc.string().generator(size).replace(/["\\]/g, "") + "\"";
case 7: return jsc.integer().generator(size);
case 6: return "\"" + jsc.string.generator(size).replace(/["\\]/g, "") + "\"";
case 7: return jsc.integer.generator(size);
case 8: return jsc.elements([null, true, false]).generator();
}
},
shrink: function () { return []; },
}),
shrink: jsc.shrink.noop,
show: jsc.show.def,
smap: jsc.nat.smap
};

var property = jsc.forall(jsc.array(token), function (l) {
@@ -409,3 +410,15 @@ describe("stringify", function () {
assert.equal(rjson.stringify(undefined), "null");
});
});

describe("regressions", function () {
it("forward slash", function () {
var data = { foo: "///" };
var json = JSON.stringify(data);
var jsonEscaped = json.replace(/\//g, "\\\/");
assert.deepEqual(rjson.parse(json), data);
assert.deepEqual(rjson.parse(jsonEscaped), data);
assert.deepEqual(JSON.parse(json), data);
assert.deepEqual(JSON.parse(jsonEscaped), data);
});
});