1
0
Fork 0
mirror of https://github.com/shimataro/ssh-key-action.git synced 2025-06-19 22:52:10 +10:00

* first action! (#1)

This commit is contained in:
shimataro 2019-09-18 20:39:54 +09:00 committed by GitHub
parent 8deacc95b1
commit ace1e6a69a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3750 changed files with 1155519 additions and 0 deletions

21
node_modules/jju/LICENSE generated vendored Normal file
View file

@ -0,0 +1,21 @@
(The MIT License)
Copyright (c) 2013 Alex Kocharin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

20
node_modules/jju/Makefile generated vendored Normal file
View file

@ -0,0 +1,20 @@
PATH := node_modules/.bin:$(PATH)
all: package.json install
install: package.json
yarn
test:
mocha test/*.js
lint:
eslint -c ./.eslint.yaml ./lib
clean:
rm package.json yarn.lock
package.json: package.yaml
js-yaml package.yaml > package.json
.PHONY: clean all install lint test

249
node_modules/jju/README.md generated vendored Normal file
View file

@ -0,0 +1,249 @@
`jju` - a set of utilities to work with JSON / JSON5 documents
[![npm version badge](https://img.shields.io/npm/v/jju.svg)](https://www.npmjs.org/package/jju)
[![travis badge](http://img.shields.io/travis/rlidwka/jju.svg)](https://travis-ci.org/rlidwka/jju)
[![downloads badge](http://img.shields.io/npm/dm/jju.svg)](https://www.npmjs.org/package/jju)
## Installation
```
yarn add jju
```
or
```
npm install jju
```
## Usage
This module provides following functions:
1. [jju.parse()](#jjuparse-function) parses json/json5 text and returns a javascript value it corresponds to
2. [jju.stringify()](#jjustringify-function) converts javascript value to an appropriate json/json5 text
3. [jju.tokenize()](#jjutokenize-function) parses json/json5 text and returns an array of tokens it consists of ([see demo](http://rlidwka.github.io/jju/tokenizer.html))
4. [jju.analyze()](#jjuanalyze-function) parses json/json5 text and tries to guess indentation, quoting style, etc.
5. [jju.update()](#jjuupdate-function) changes json/json5 text, preserving original formatting as much as possible ([see demo](http://rlidwka.github.io/jju/editor.html))
All functions are able to work with a standard JSON documents. `jju.parse()` and `jju.stringify()` are better in some cases, but slower than native `JSON.parse()` and `JSON.stringify()` versions. Detailed description see below.
### jju.parse() function
```javascript
/*
* Main syntax:
*
* `text` - text to parse, type: String
* `options` - parser options, type: Object
*/
jju.parse(text[, options])
// compatibility syntax
jju.parse(text[, reviver])
```
Options:
- reserved\_keys - what to do with reserved keys (String, default="ignore")
- "ignore" - ignore reserved keys
- "throw" - throw SyntaxError in case of reserved keys
- "replace" - replace reserved keys, this is the default JSON.parse behaviour, unsafe
Reserved keys are keys that exist in an empty object (`hasOwnProperty`, `__proto__`, etc.).
```javascript
// 'ignore' will cause reserved keys to be ignored:
parse('{hasOwnProperty: 1}', {reserved_keys: 'ignore'}) == {}
parse('{hasOwnProperty: 1, x: 2}', {reserved_keys: 'ignore'}).hasOwnProperty('x') == true
// 'throw' will cause SyntaxError in these cases:
parse('{hasOwnProperty: 1}', {reserved_keys: 'throw'}) == SyntaxError
// 'replace' will replace reserved keys with new ones:
parse('{hasOwnProperty: 1}', {reserved_keys: 'replace'}) == {hasOwnProperty: 1}
parse('{hasOwnProperty: 1, x: 2}', {reserved_keys: 'replace'}).hasOwnProperty('x') == TypeError
```
- null\_prototype - create object as Object.create(null) instead of '{}' (Boolean)
if `reserved_keys != 'replace'`, default is **false**
if `reserved_keys == 'replace'`, default is **true**
It is usually unsafe and not recommended to change this option to false in the last case.
- reviver - reviver function - Function
This function should follow JSON specification
- mode - operation mode, set it to 'json' if you want to throw on non-strict json files (String)
### jju.stringify() function
```javascript
/*
* Main syntax:
*
* `value` - value to serialize, type: *
* `options` - serializer options, type: Object
*/
jju.stringify(value[, options])
// compatibility syntax
jju.stringify(value[, replacer [, indent])
```
Options:
- ascii - output ascii only (Boolean, default=false)
If this option is enabled, output will not have any characters except of 0x20-0x7f.
- indent - indentation (String, Number or Boolean, default='\t')
This option follows JSON specification.
- quote - enquoting char (String, "'" or '"', default="'")
- quote\_keys - whether keys quoting in objects is required or not (String, default=false)
If you want `{"q": 1}` instead of `{q: 1}`, set it to true.
- sort\_keys - sort all keys while stringifying (Boolean or Function, default=false)
By default sort order will depend on implementation, with v8 it's insertion order. If set to `true`, all keys (but not arrays) will be sorted alphabetically. You can provide your own sorting function as well.
- replacer - replacer function or array (Function or Array)
This option follows JSON specification.
- no\_trailing\_comma = don't output trailing comma (Boolean, default=false)
If this option is set, arrays like this `[1,2,3,]` will never be generated. Otherwise they may be generated for pretty printing.
- mode - operation mode, set it to 'json' if you want correct json in the output (String)
Currently it's either 'json' or something else. If it is 'json', following options are implied:
- options.quote = '"'
- options.no\_trailing\_comma = true
- options.quote\_keys = true
- '\x' literals are not used
### jju.tokenize() function
```javascript
/*
* Main syntax:
*
* `text` - text to tokenize, type: String
* `options` - parser options, type: Object
*/
jju.tokenize(text[, options])
```
Options are the same as for the `jju.parse` function.
Return value is an array of tokens, where each token is an object:
- raw (String) - raw text of this token, if you join all raw's, you will get the original document
- type (String) - type of the token, can be `whitespace`, `comment`, `key`, `literal`, `separator` or `newline`
- stack (Array) - path to the current token in the syntax tree
- value - value of the token if token is a `key` or `literal`
You can check tokenizer for yourself using [this demo](http://rlidwka.github.io/jju/tokenizer.html).
### jju.analyze() function
```javascript
/*
* Main syntax:
*
* `text` - text to analyze, type: String
* `options` - parser options, type: Object
*/
jju.analyze(text[, options])
```
Options are the same as for the `jju.parse` function.
Return value is an object defining a programming style in which the document was written.
- indent (String) - preferred indentation
- newline (String) - preferred newline
- quote (String) - `"` or `'` depending on which quote is preferred
- quote\_keys (Boolean) - `true` if unquoted keys were used at least once
- has\_whitespace (Boolean) - `true` if input has a whitespace token
- has\_comments (Boolean) - `true` if input has a comment token
- has\_newlines (Boolean) - `true` if input has a newline token
- has\_trailing\_comma (Boolean) - `true` if input has at least one trailing comma
### jju.update() function
```javascript
/*
* Main syntax:
*
* `text` - original text, type: String
* `new_value` - new value you want to set
* `options` - parser or stringifier options, type: Object
*/
jju.update(text, new_value[, options])
```
If you want to update a JSON document, here is the general approach:
```javascript
// here is your original JSON document:
var input = '{"foo": "bar", "baz": 123}'
// you need to parse it first:
var json = jju.parse(input, {mode: 'json'})
// json is { foo: 'bar', baz: 123 }
// then you can change it as you like:
json.foo = 'quux'
json.hello = 'world'
// then you run an update function to change the original json:
var output = jju.update(input, json, {mode: 'json'})
// output is '{"foo": "quux", "baz": 123, "hello": "world"}'
```
Look at [this demo](http://rlidwka.github.io/jju/editor.html) to test various types of json.
## Advantages over existing JSON libraries
In a few cases it makes sense to use this module instead of built-in JSON methods.
Parser:
- better error reporting with source code and line numbers
In case of syntax error, JSON.parse does not return any good information to the user. This module does:
```
$ node -e 'require("jju").parse("[1,1,1,1,invalid]")'
SyntaxError: Unexpected token 'i' at 0:9
[1,1,1,1,invalid]
^
```
This module is about 5 times slower, so if user experience matters to you more than performance, use this module. If you're working with a lot of machine-generated data, use JSON.parse instead.
Stringifier:
- util.inspect-like pretty printing
This module behaves more smart when dealing with object and arrays, and does not always print newlines in them:
```
$ node -e 'console.log(require("./").stringify([[,,,],,,[,,,,]], {mode:"json"}))'
[
[null, null, null],
null,
null,
[null, null, null, null]
]
```
JSON.stringify will split this into 15 lines, and it's hard to read.
Yet again, this feature comes with a performance hit, so if user experience matters to you more than performance, use this module. If your JSON will be consumed by machines, use JSON.stringify instead.
As a rule of thumb, if you use "space" argument to indent your JSON, you'd better use this module instead.

32
node_modules/jju/index.js generated vendored Normal file
View file

@ -0,0 +1,32 @@
module.exports.__defineGetter__('parse', function() {
return require('./lib/parse').parse
})
module.exports.__defineGetter__('stringify', function() {
return require('./lib/stringify').stringify
})
module.exports.__defineGetter__('tokenize', function() {
return require('./lib/parse').tokenize
})
module.exports.__defineGetter__('update', function() {
return require('./lib/document').update
})
module.exports.__defineGetter__('analyze', function() {
return require('./lib/analyze').analyze
})
module.exports.__defineGetter__('utils', function() {
return require('./lib/utils')
})
/**package
{ "name": "jju",
"version": "0.0.0",
"dependencies": {"js-yaml": "*"},
"scripts": {"postinstall": "js-yaml package.yaml > package.json ; npm install"}
}
**/

87
node_modules/jju/lib/analyze.js generated vendored Normal file
View file

@ -0,0 +1,87 @@
var tokenize = require('./parse').tokenize
module.exports.analyze = function analyzeJSON(input, options) {
if (options == null) options = {}
if (!Array.isArray(input)) {
input = tokenize(input, options)
}
var result = {
has_whitespace: false,
has_comments: false,
has_newlines: false,
has_trailing_comma: false,
indent: '',
newline: '\n',
quote: '"',
quote_keys: true,
}
var stats = {
indent: {},
newline: {},
quote: {},
}
for (var i=0; i<input.length; i++) {
if (input[i].type === 'newline') {
if (input[i+1] && input[i+1].type === 'whitespace') {
if (input[i+1].raw[0] === '\t') {
// if first is tab, then indent is tab
stats.indent['\t'] = (stats.indent['\t'] || 0) + 1
}
if (input[i+1].raw.match(/^\x20+$/)) {
// if all are spaces, then indent is space
// this can fail with mixed indent (4, 2 would display 3)
var ws_len = input[i+1].raw.length
var indent_len = input[i+1].stack.length + 1
if (ws_len % indent_len === 0) {
var t = Array(ws_len / indent_len + 1).join(' ')
stats.indent[t] = (stats.indent[t] || 0) + 1
}
}
}
stats.newline[input[i].raw] = (stats.newline[input[i].raw] || 0) + 1
}
if (input[i].type === 'newline') {
result.has_newlines = true
}
if (input[i].type === 'whitespace') {
result.has_whitespace = true
}
if (input[i].type === 'comment') {
result.has_comments = true
}
if (input[i].type === 'key') {
if (input[i].raw[0] !== '"' && input[i].raw[0] !== "'") result.quote_keys = false
}
if (input[i].type === 'key' || input[i].type === 'literal') {
if (input[i].raw[0] === '"' || input[i].raw[0] === "'") {
stats.quote[input[i].raw[0]] = (stats.quote[input[i].raw[0]] || 0) + 1
}
}
if (input[i].type === 'separator' && input[i].raw === ',') {
for (var j=i+1; j<input.length; j++) {
if (input[j].type === 'literal' || input[j].type === 'key') break
if (input[j].type === 'separator') result.has_trailing_comma = true
}
}
}
for (var k in stats) {
if (Object.keys(stats[k]).length) {
result[k] = Object.keys(stats[k]).reduce(function(a, b) {
return stats[k][a] > stats[k][b] ? a : b
})
}
}
return result
}

480
node_modules/jju/lib/document.js generated vendored Normal file
View file

@ -0,0 +1,480 @@
var assert = require('assert')
var tokenize = require('./parse').tokenize
var stringify = require('./stringify').stringify
var analyze = require('./analyze').analyze
function isObject(x) {
return typeof(x) === 'object' && x !== null
}
function value_to_tokenlist(value, stack, options, is_key, indent) {
options = Object.create(options)
options._stringify_key = !!is_key
if (indent) {
options._prefix = indent.prefix.map(function(x) {
return x.raw
}).join('')
}
if (options._splitMin == null) options._splitMin = 0
if (options._splitMax == null) options._splitMax = 0
var stringified = stringify(value, options)
if (is_key) {
return [ { raw: stringified, type: 'key', stack: stack, value: value } ]
}
options._addstack = stack
var result = tokenize(stringified, {
_addstack: stack,
})
result.data = null
return result
}
// '1.2.3' -> ['1','2','3']
function arg_to_path(path) {
// array indexes
if (typeof(path) === 'number') path = String(path)
if (path === '') path = []
if (typeof(path) === 'string') path = path.split('.')
if (!Array.isArray(path)) throw Error('Invalid path type, string or array expected')
return path
}
// returns new [begin, end] or false if not found
//
// {x:3, xxx: 111, y: [111, {q: 1, e: 2} ,333] }
// f('y',0) returns this B^^^^^^^^^^^^^^^^^^^^^^^^E
// then f('1',1) would reduce it to B^^^^^^^^^^E
function find_element_in_tokenlist(element, lvl, tokens, begin, end) {
while(tokens[begin].stack[lvl] != element) {
if (begin++ >= end) return false
}
while(tokens[end].stack[lvl] != element) {
if (end-- < begin) return false
}
return [begin, end]
}
function is_whitespace(token_type) {
return token_type === 'whitespace'
|| token_type === 'newline'
|| token_type === 'comment'
}
function find_first_non_ws_token(tokens, begin, end) {
while(is_whitespace(tokens[begin].type)) {
if (begin++ >= end) return false
}
return begin
}
function find_last_non_ws_token(tokens, begin, end) {
while(is_whitespace(tokens[end].type)) {
if (end-- < begin) return false
}
return end
}
/*
* when appending a new element of an object/array, we are trying to
* figure out the style used on the previous element
*
* return {prefix, sep1, sep2, suffix}
*
* ' "key" : "element" \r\n'
* prefix^^^^ sep1^ ^^sep2 ^^^^^^^^suffix
*
* begin - the beginning of the object/array
* end - last token of the last element (value or comma usually)
*/
function detect_indent_style(tokens, is_array, begin, end, level) {
var result = {
sep1: [],
sep2: [],
suffix: [],
prefix: [],
newline: [],
}
if (tokens[end].type === 'separator' && tokens[end].stack.length !== level+1 && tokens[end].raw !== ',') {
// either a beginning of the array (no last element) or other weird situation
//
// just return defaults
return result
}
// ' "key" : "value" ,'
// skipping last separator, we're now here ^^
if (tokens[end].type === 'separator')
end = find_last_non_ws_token(tokens, begin, end - 1)
if (end === false) return result
// ' "key" : "value" ,'
// skipping value ^^^^^^^
while(tokens[end].stack.length > level) end--
if (!is_array) {
while(is_whitespace(tokens[end].type)) {
if (end < begin) return result
if (tokens[end].type === 'whitespace') {
result.sep2.unshift(tokens[end])
} else {
// newline, comment or other unrecognized codestyle
return result
}
end--
}
// ' "key" : "value" ,'
// skipping separator ^
assert.equal(tokens[end].type, 'separator')
assert.equal(tokens[end].raw, ':')
while(is_whitespace(tokens[--end].type)) {
if (end < begin) return result
if (tokens[end].type === 'whitespace') {
result.sep1.unshift(tokens[end])
} else {
// newline, comment or other unrecognized codestyle
return result
}
}
assert.equal(tokens[end].type, 'key')
end--
}
// ' "key" : "value" ,'
// skipping key ^^^^^
while(is_whitespace(tokens[end].type)) {
if (end < begin) return result
if (tokens[end].type === 'whitespace') {
result.prefix.unshift(tokens[end])
} else if (tokens[end].type === 'newline') {
result.newline.unshift(tokens[end])
return result
} else {
// comment or other unrecognized codestyle
return result
}
end--
}
return result
}
function Document(text, options) {
var self = Object.create(Document.prototype)
if (options == null) options = {}
//options._structure = true
var tokens = self._tokens = tokenize(text, options)
self._data = tokens.data
tokens.data = null
self._options = options
var stats = analyze(text, options)
if (options.indent == null) {
options.indent = stats.indent
}
if (options.quote == null) {
options.quote = stats.quote
}
if (options.quote_keys == null) {
options.quote_keys = stats.quote_keys
}
if (options.no_trailing_comma == null) {
options.no_trailing_comma = !stats.has_trailing_comma
}
return self
}
// return true if it's a proper object
// throw otherwise
function check_if_can_be_placed(key, object, is_unset) {
//if (object == null) return false
function error(add) {
return Error("You can't " + (is_unset ? 'unset' : 'set') + " key '" + key + "'" + add)
}
if (!isObject(object)) {
throw error(' of an non-object')
}
if (Array.isArray(object)) {
// array, check boundary
if (String(key).match(/^\d+$/)) {
key = Number(String(key))
if (object.length < key || (is_unset && object.length === key)) {
throw error(', out of bounds')
} else if (is_unset && object.length !== key+1) {
throw error(' in the middle of an array')
} else {
return true
}
} else {
throw error(' of an array')
}
} else {
// object
return true
}
}
// usage: document.set('path.to.something', 'value')
// or: document.set(['path','to','something'], 'value')
Document.prototype.set = function(path, value) {
path = arg_to_path(path)
// updating this._data and check for errors
if (path.length === 0) {
if (value === undefined) throw Error("can't remove root document")
this._data = value
var new_key = false
} else {
var data = this._data
for (var i=0; i<path.length-1; i++) {
check_if_can_be_placed(path[i], data, false)
data = data[path[i]]
}
if (i === path.length-1) {
check_if_can_be_placed(path[i], data, value === undefined)
}
var new_key = !(path[i] in data)
if (value === undefined) {
if (Array.isArray(data)) {
data.pop()
} else {
delete data[path[i]]
}
} else {
data[path[i]] = value
}
}
// for inserting document
if (!this._tokens.length)
this._tokens = [ { raw: '', type: 'literal', stack: [], value: undefined } ]
var position = [
find_first_non_ws_token(this._tokens, 0, this._tokens.length - 1),
find_last_non_ws_token(this._tokens, 0, this._tokens.length - 1),
]
for (var i=0; i<path.length-1; i++) {
position = find_element_in_tokenlist(path[i], i, this._tokens, position[0], position[1])
if (position == false) throw Error('internal error, please report this')
}
// assume that i == path.length-1 here
if (path.length === 0) {
var newtokens = value_to_tokenlist(value, path, this._options)
// all good
} else if (!new_key) {
// replace old value with a new one (or deleting something)
var pos_old = position
position = find_element_in_tokenlist(path[i], i, this._tokens, position[0], position[1])
if (value === undefined && position !== false) {
// deleting element (position !== false ensures there's something)
var newtokens = []
if (!Array.isArray(data)) {
// removing element from an object, `{x:1, key:CURRENT} -> {x:1}`
// removing sep, literal and optional sep
// ':'
var pos2 = find_last_non_ws_token(this._tokens, pos_old[0], position[0] - 1)
assert.equal(this._tokens[pos2].type, 'separator')
assert.equal(this._tokens[pos2].raw, ':')
position[0] = pos2
// key
var pos2 = find_last_non_ws_token(this._tokens, pos_old[0], position[0] - 1)
assert.equal(this._tokens[pos2].type, 'key')
assert.equal(this._tokens[pos2].value, path[path.length-1])
position[0] = pos2
}
// removing comma in arrays and objects
var pos2 = find_last_non_ws_token(this._tokens, pos_old[0], position[0] - 1)
assert.equal(this._tokens[pos2].type, 'separator')
if (this._tokens[pos2].raw === ',') {
position[0] = pos2
} else {
// beginning of the array/object, so we should remove trailing comma instead
pos2 = find_first_non_ws_token(this._tokens, position[1] + 1, pos_old[1])
assert.equal(this._tokens[pos2].type, 'separator')
if (this._tokens[pos2].raw === ',') {
position[1] = pos2
}
}
} else {
var indent = pos2 !== false
? detect_indent_style(this._tokens, Array.isArray(data), pos_old[0], position[1] - 1, i)
: {}
var newtokens = value_to_tokenlist(value, path, this._options, false, indent)
}
} else {
// insert new key, that's tricky
var path_1 = path.slice(0, i)
// find a last separator after which we're inserting it
var pos2 = find_last_non_ws_token(this._tokens, position[0] + 1, position[1] - 1)
assert(pos2 !== false)
var indent = pos2 !== false
? detect_indent_style(this._tokens, Array.isArray(data), position[0] + 1, pos2, i)
: {}
var newtokens = value_to_tokenlist(value, path, this._options, false, indent)
// adding leading whitespaces according to detected codestyle
var prefix = []
if (indent.newline && indent.newline.length)
prefix = prefix.concat(indent.newline)
if (indent.prefix && indent.prefix.length)
prefix = prefix.concat(indent.prefix)
// adding '"key":' (as in "key":"value") to object values
if (!Array.isArray(data)) {
prefix = prefix.concat(value_to_tokenlist(path[path.length-1], path_1, this._options, true))
if (indent.sep1 && indent.sep1.length)
prefix = prefix.concat(indent.sep1)
prefix.push({raw: ':', type: 'separator', stack: path_1})
if (indent.sep2 && indent.sep2.length)
prefix = prefix.concat(indent.sep2)
}
newtokens.unshift.apply(newtokens, prefix)
// check if prev token is a separator AND they're at the same level
if (this._tokens[pos2].type === 'separator' && this._tokens[pos2].stack.length === path.length-1) {
// previous token is either , or [ or {
if (this._tokens[pos2].raw === ',') {
// restore ending comma
newtokens.push({raw: ',', type: 'separator', stack: path_1})
}
} else {
// previous token isn't a separator, so need to insert one
newtokens.unshift({raw: ',', type: 'separator', stack: path_1})
}
if (indent.suffix && indent.suffix.length)
newtokens.push.apply(newtokens, indent.suffix)
assert.equal(this._tokens[position[1]].type, 'separator')
position[0] = pos2+1
position[1] = pos2
}
newtokens.unshift(position[1] - position[0] + 1)
newtokens.unshift(position[0])
this._tokens.splice.apply(this._tokens, newtokens)
return this
}
// convenience method
Document.prototype.unset = function(path) {
return this.set(path, undefined)
}
Document.prototype.get = function(path) {
path = arg_to_path(path)
var data = this._data
for (var i=0; i<path.length; i++) {
if (!isObject(data)) return undefined
data = data[path[i]]
}
return data
}
Document.prototype.has = function(path) {
path = arg_to_path(path)
var data = this._data
for (var i=0; i<path.length; i++) {
if (!isObject(data)) return false
data = data[path[i]]
}
return data !== undefined
}
// compare old object and new one, and change differences only
Document.prototype.update = function(value) {
var self = this
change([], self._data, value)
return self
function change(path, old_data, new_data) {
if (!isObject(new_data) || !isObject(old_data)) {
// if source or dest is primitive, just replace
if (new_data !== old_data)
self.set(path, new_data)
} else if (Array.isArray(new_data) != Array.isArray(old_data)) {
// old data is an array XOR new data is an array, replace as well
self.set(path, new_data)
} else if (Array.isArray(new_data)) {
// both values are arrays here
if (new_data.length > old_data.length) {
// adding new elements, so going forward
for (var i=0; i<new_data.length; i++) {
path.push(String(i))
change(path, old_data[i], new_data[i])
path.pop()
}
} else {
// removing something, so going backward
for (var i=old_data.length-1; i>=0; i--) {
path.push(String(i))
change(path, old_data[i], new_data[i])
path.pop()
}
}
} else {
// both values are objects here
for (var i in new_data) {
path.push(String(i))
change(path, old_data[i], new_data[i])
path.pop()
}
for (var i in old_data) {
if (i in new_data) continue
path.push(String(i))
change(path, old_data[i], new_data[i])
path.pop()
}
}
}
}
Document.prototype.toString = function() {
return this._tokens.map(function(x) {
return x.raw
}).join('')
}
module.exports.Document = Document
module.exports.update = function updateJSON(source, new_value, options) {
return Document(source, options).update(new_value).toString()
}

760
node_modules/jju/lib/parse.js generated vendored Normal file
View file

@ -0,0 +1,760 @@
// RTFM: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
var Uni = require('./unicode')
function isHexDigit(x) {
return (x >= '0' && x <= '9')
|| (x >= 'A' && x <= 'F')
|| (x >= 'a' && x <= 'f')
}
function isOctDigit(x) {
return x >= '0' && x <= '7'
}
function isDecDigit(x) {
return x >= '0' && x <= '9'
}
var unescapeMap = {
'\'': '\'',
'"' : '"',
'\\': '\\',
'b' : '\b',
'f' : '\f',
'n' : '\n',
'r' : '\r',
't' : '\t',
'v' : '\v',
'/' : '/',
}
function formatError(input, msg, position, lineno, column, json5) {
var result = msg + ' at ' + (lineno + 1) + ':' + (column + 1)
, tmppos = position - column - 1
, srcline = ''
, underline = ''
var isLineTerminator = json5 ? Uni.isLineTerminator : Uni.isLineTerminatorJSON
// output no more than 70 characters before the wrong ones
if (tmppos < position - 70) {
tmppos = position - 70
}
while (1) {
var chr = input[++tmppos]
if (isLineTerminator(chr) || tmppos === input.length) {
if (position >= tmppos) {
// ending line error, so show it after the last char
underline += '^'
}
break
}
srcline += chr
if (position === tmppos) {
underline += '^'
} else if (position > tmppos) {
underline += input[tmppos] === '\t' ? '\t' : ' '
}
// output no more than 78 characters on the string
if (srcline.length > 78) break
}
return result + '\n' + srcline + '\n' + underline
}
function parse(input, options) {
// parse as a standard JSON mode
var json5 = false
var cjson = false
if (options.legacy || options.mode === 'json') {
// use json
} else if (options.mode === 'cjson') {
cjson = true
} else if (options.mode === 'json5') {
json5 = true
} else {
// use it by default
json5 = true
}
var isLineTerminator = json5 ? Uni.isLineTerminator : Uni.isLineTerminatorJSON
var isWhiteSpace = json5 ? Uni.isWhiteSpace : Uni.isWhiteSpaceJSON
var length = input.length
, lineno = 0
, linestart = 0
, position = 0
, stack = []
var tokenStart = function() {}
var tokenEnd = function(v) {return v}
/* tokenize({
raw: '...',
type: 'whitespace'|'comment'|'key'|'literal'|'separator'|'newline',
value: 'number'|'string'|'whatever',
path: [...],
})
*/
if (options._tokenize) {
;(function() {
var start = null
tokenStart = function() {
if (start !== null) throw Error('internal error, token overlap')
start = position
}
tokenEnd = function(v, type) {
if (start != position) {
var hash = {
raw: input.substr(start, position-start),
type: type,
stack: stack.slice(0),
}
if (v !== undefined) hash.value = v
options._tokenize.call(null, hash)
}
start = null
return v
}
})()
}
function fail(msg) {
var column = position - linestart
if (!msg) {
if (position < length) {
var token = '\'' +
JSON
.stringify(input[position])
.replace(/^"|"$/g, '')
.replace(/'/g, "\\'")
.replace(/\\"/g, '"')
+ '\''
if (!msg) msg = 'Unexpected token ' + token
} else {
if (!msg) msg = 'Unexpected end of input'
}
}
var error = SyntaxError(formatError(input, msg, position, lineno, column, json5))
error.row = lineno + 1
error.column = column + 1
throw error
}
function newline(chr) {
// account for <cr><lf>
if (chr === '\r' && input[position] === '\n') position++
linestart = position
lineno++
}
function parseGeneric() {
var result
while (position < length) {
tokenStart()
var chr = input[position++]
if (chr === '"' || (chr === '\'' && json5)) {
return tokenEnd(parseString(chr), 'literal')
} else if (chr === '{') {
tokenEnd(undefined, 'separator')
return parseObject()
} else if (chr === '[') {
tokenEnd(undefined, 'separator')
return parseArray()
} else if (chr === '-'
|| chr === '.'
|| isDecDigit(chr)
// + number Infinity NaN
|| (json5 && (chr === '+' || chr === 'I' || chr === 'N'))
) {
return tokenEnd(parseNumber(), 'literal')
} else if (chr === 'n') {
parseKeyword('null')
return tokenEnd(null, 'literal')
} else if (chr === 't') {
parseKeyword('true')
return tokenEnd(true, 'literal')
} else if (chr === 'f') {
parseKeyword('false')
return tokenEnd(false, 'literal')
} else {
position--
return tokenEnd(undefined)
}
}
}
function parseKey() {
var result
while (position < length) {
tokenStart()
var chr = input[position++]
if (chr === '"' || (chr === '\'' && json5)) {
return tokenEnd(parseString(chr), 'key')
} else if (chr === '{') {
tokenEnd(undefined, 'separator')
return parseObject()
} else if (chr === '[') {
tokenEnd(undefined, 'separator')
return parseArray()
} else if (chr === '.'
|| isDecDigit(chr)
) {
return tokenEnd(parseNumber(true), 'key')
} else if (json5
&& Uni.isIdentifierStart(chr) || (chr === '\\' && input[position] === 'u')) {
// unicode char or a unicode sequence
var rollback = position - 1
var result = parseIdentifier()
if (result === undefined) {
position = rollback
return tokenEnd(undefined)
} else {
return tokenEnd(result, 'key')
}
} else {
position--
return tokenEnd(undefined)
}
}
}
function skipWhiteSpace() {
tokenStart()
while (position < length) {
var chr = input[position++]
if (isLineTerminator(chr)) {
position--
tokenEnd(undefined, 'whitespace')
tokenStart()
position++
newline(chr)
tokenEnd(undefined, 'newline')
tokenStart()
} else if (isWhiteSpace(chr)) {
// nothing
} else if (chr === '/'
&& (json5 || cjson)
&& (input[position] === '/' || input[position] === '*')
) {
position--
tokenEnd(undefined, 'whitespace')
tokenStart()
position++
skipComment(input[position++] === '*')
tokenEnd(undefined, 'comment')
tokenStart()
} else {
position--
break
}
}
return tokenEnd(undefined, 'whitespace')
}
function skipComment(multi) {
while (position < length) {
var chr = input[position++]
if (isLineTerminator(chr)) {
// LineTerminator is an end of singleline comment
if (!multi) {
// let parent function deal with newline
position--
return
}
newline(chr)
} else if (chr === '*' && multi) {
// end of multiline comment
if (input[position] === '/') {
position++
return
}
} else {
// nothing
}
}
if (multi) {
fail('Unclosed multiline comment')
}
}
function parseKeyword(keyword) {
// keyword[0] is not checked because it should've checked earlier
var _pos = position
var len = keyword.length
for (var i=1; i<len; i++) {
if (position >= length || keyword[i] != input[position]) {
position = _pos-1
fail()
}
position++
}
}
function parseObject() {
var result = options.null_prototype ? Object.create(null) : {}
, empty_object = {}
, is_non_empty = false
while (position < length) {
skipWhiteSpace()
var item1 = parseKey()
skipWhiteSpace()
tokenStart()
var chr = input[position++]
tokenEnd(undefined, 'separator')
if (chr === '}' && item1 === undefined) {
if (!json5 && is_non_empty) {
position--
fail('Trailing comma in object')
}
return result
} else if (chr === ':' && item1 !== undefined) {
skipWhiteSpace()
stack.push(item1)
var item2 = parseGeneric()
stack.pop()
if (item2 === undefined) fail('No value found for key ' + item1)
if (typeof(item1) !== 'string') {
if (!json5 || typeof(item1) !== 'number') {
fail('Wrong key type: ' + item1)
}
}
if ((item1 in empty_object || empty_object[item1] != null) && options.reserved_keys !== 'replace') {
if (options.reserved_keys === 'throw') {
fail('Reserved key: ' + item1)
} else {
// silently ignore it
}
} else {
if (typeof(options.reviver) === 'function') {
item2 = options.reviver.call(null, item1, item2)
}
if (item2 !== undefined) {
is_non_empty = true
Object.defineProperty(result, item1, {
value: item2,
enumerable: true,
configurable: true,
writable: true,
})
}
}
skipWhiteSpace()
tokenStart()
var chr = input[position++]
tokenEnd(undefined, 'separator')
if (chr === ',') {
continue
} else if (chr === '}') {
return result
} else {
fail()
}
} else {
position--
fail()
}
}
fail()
}
function parseArray() {
var result = []
while (position < length) {
skipWhiteSpace()
stack.push(result.length)
var item = parseGeneric()
stack.pop()
skipWhiteSpace()
tokenStart()
var chr = input[position++]
tokenEnd(undefined, 'separator')
if (item !== undefined) {
if (typeof(options.reviver) === 'function') {
item = options.reviver.call(null, String(result.length), item)
}
if (item === undefined) {
result.length++
item = true // hack for check below, not included into result
} else {
result.push(item)
}
}
if (chr === ',') {
if (item === undefined) {
fail('Elisions are not supported')
}
} else if (chr === ']') {
if (!json5 && item === undefined && result.length) {
position--
fail('Trailing comma in array')
}
return result
} else {
position--
fail()
}
}
}
function parseNumber() {
// rewind because we don't know first char
position--
var start = position
, chr = input[position++]
, t
var to_num = function(is_octal) {
var str = input.substr(start, position - start)
if (is_octal) {
var result = parseInt(str.replace(/^0o?/, ''), 8)
} else {
var result = Number(str)
}
if (Number.isNaN(result)) {
position--
fail('Bad numeric literal - "' + input.substr(start, position - start + 1) + '"')
} else if (!json5 && !str.match(/^-?(0|[1-9][0-9]*)(\.[0-9]+)?(e[+-]?[0-9]+)?$/i)) {
// additional restrictions imposed by json
position--
fail('Non-json numeric literal - "' + input.substr(start, position - start + 1) + '"')
} else {
return result
}
}
// ex: -5982475.249875e+29384
// ^ skipping this
if (chr === '-' || (chr === '+' && json5)) chr = input[position++]
if (chr === 'N' && json5) {
parseKeyword('NaN')
return NaN
}
if (chr === 'I' && json5) {
parseKeyword('Infinity')
// returning +inf or -inf
return to_num()
}
if (chr >= '1' && chr <= '9') {
// ex: -5982475.249875e+29384
// ^^^ skipping these
while (position < length && isDecDigit(input[position])) position++
chr = input[position++]
}
// special case for leading zero: 0.123456
if (chr === '0') {
chr = input[position++]
// new syntax, "0o777" old syntax, "0777"
var is_octal = chr === 'o' || chr === 'O' || isOctDigit(chr)
var is_hex = chr === 'x' || chr === 'X'
if (json5 && (is_octal || is_hex)) {
while (position < length
&& (is_hex ? isHexDigit : isOctDigit)( input[position] )
) position++
var sign = 1
if (input[start] === '-') {
sign = -1
start++
} else if (input[start] === '+') {
start++
}
return sign * to_num(is_octal)
}
}
if (chr === '.') {
// ex: -5982475.249875e+29384
// ^^^ skipping these
while (position < length && isDecDigit(input[position])) position++
chr = input[position++]
}
if (chr === 'e' || chr === 'E') {
chr = input[position++]
if (chr === '-' || chr === '+') position++
// ex: -5982475.249875e+29384
// ^^^ skipping these
while (position < length && isDecDigit(input[position])) position++
chr = input[position++]
}
// we have char in the buffer, so count for it
position--
return to_num()
}
function parseIdentifier() {
// rewind because we don't know first char
position--
var result = ''
while (position < length) {
var chr = input[position++]
if (chr === '\\'
&& input[position] === 'u'
&& isHexDigit(input[position+1])
&& isHexDigit(input[position+2])
&& isHexDigit(input[position+3])
&& isHexDigit(input[position+4])
) {
// UnicodeEscapeSequence
chr = String.fromCharCode(parseInt(input.substr(position+1, 4), 16))
position += 5
}
if (result.length) {
// identifier started
if (Uni.isIdentifierPart(chr)) {
result += chr
} else {
position--
return result
}
} else {
if (Uni.isIdentifierStart(chr)) {
result += chr
} else {
return undefined
}
}
}
fail()
}
function parseString(endChar) {
// 7.8.4 of ES262 spec
var result = ''
while (position < length) {
var chr = input[position++]
if (chr === endChar) {
return result
} else if (chr === '\\') {
if (position >= length) fail()
chr = input[position++]
if (unescapeMap[chr] && (json5 || (chr != 'v' && chr != "'"))) {
result += unescapeMap[chr]
} else if (json5 && isLineTerminator(chr)) {
// line continuation
newline(chr)
} else if (chr === 'u' || (chr === 'x' && json5)) {
// unicode/character escape sequence
var off = chr === 'u' ? 4 : 2
// validation for \uXXXX
for (var i=0; i<off; i++) {
if (position >= length) fail()
if (!isHexDigit(input[position])) fail('Bad escape sequence')
position++
}
result += String.fromCharCode(parseInt(input.substr(position-off, off), 16))
} else if (json5 && isOctDigit(chr)) {
if (chr < '4' && isOctDigit(input[position]) && isOctDigit(input[position+1])) {
// three-digit octal
var digits = 3
} else if (isOctDigit(input[position])) {
// two-digit octal
var digits = 2
} else {
var digits = 1
}
position += digits - 1
result += String.fromCharCode(parseInt(input.substr(position-digits, digits), 8))
/*if (!isOctDigit(input[position])) {
// \0 is allowed still
result += '\0'
} else {
fail('Octal literals are not supported')
}*/
} else if (json5) {
// \X -> x
result += chr
} else {
position--
fail()
}
} else if (isLineTerminator(chr)) {
fail()
} else {
if (!json5 && chr.charCodeAt(0) < 32) {
position--
fail('Unexpected control character')
}
// SourceCharacter but not one of " or \ or LineTerminator
result += chr
}
}
fail()
}
skipWhiteSpace()
var return_value = parseGeneric()
if (return_value !== undefined || position < length) {
skipWhiteSpace()
if (position >= length) {
if (typeof(options.reviver) === 'function') {
return_value = options.reviver.call(null, '', return_value)
}
return return_value
} else {
fail()
}
} else {
if (position) {
fail('No data, only a whitespace')
} else {
fail('No data, empty input')
}
}
}
/*
* parse(text, options)
* or
* parse(text, reviver)
*
* where:
* text - string
* options - object
* reviver - function
*/
module.exports.parse = function parseJSON(input, options) {
// support legacy functions
if (typeof(options) === 'function') {
options = {
reviver: options
}
}
if (input === undefined) {
// parse(stringify(x)) should be equal x
// with JSON functions it is not 'cause of undefined
// so we're fixing it
return undefined
}
// JSON.parse compat
if (typeof(input) !== 'string') input = String(input)
if (options == null) options = {}
if (options.reserved_keys == null) options.reserved_keys = 'ignore'
if (options.reserved_keys === 'throw' || options.reserved_keys === 'ignore') {
if (options.null_prototype == null) {
options.null_prototype = true
}
}
try {
return parse(input, options)
} catch(err) {
// jju is a recursive parser, so JSON.parse("{{{{{{{") could blow up the stack
//
// this catch is used to skip all those internal calls
if (err instanceof SyntaxError && err.row != null && err.column != null) {
var old_err = err
err = SyntaxError(old_err.message)
err.column = old_err.column
err.row = old_err.row
}
throw err
}
}
module.exports.tokenize = function tokenizeJSON(input, options) {
if (options == null) options = {}
options._tokenize = function(smth) {
if (options._addstack) smth.stack.unshift.apply(smth.stack, options._addstack)
tokens.push(smth)
}
var tokens = []
tokens.data = module.exports.parse(input, options)
return tokens
}

378
node_modules/jju/lib/stringify.js generated vendored Normal file
View file

@ -0,0 +1,378 @@
var Uni = require('./unicode')
// Fix Function#name on browsers that do not support it (IE)
// http://stackoverflow.com/questions/6903762/function-name-not-supported-in-ie
if (!(function f(){}).name) {
Object.defineProperty((function(){}).constructor.prototype, 'name', {
get: function() {
var name = this.toString().match(/^\s*function\s*(\S*)\s*\(/)[1]
// For better performance only parse once, and then cache the
// result through a new accessor for repeated access.
Object.defineProperty(this, 'name', { value: name })
return name
}
})
}
var special_chars = {
0: '\\0', // this is not an octal literal
8: '\\b',
9: '\\t',
10: '\\n',
11: '\\v',
12: '\\f',
13: '\\r',
92: '\\\\',
}
// for oddballs
var hasOwnProperty = Object.prototype.hasOwnProperty
// some people escape those, so I'd copy this to be safe
var escapable = /[\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/
function _stringify(object, options, recursiveLvl, currentKey) {
var json5 = (options.mode === 'json5' || !options.mode)
/*
* Opinionated decision warning:
*
* Objects are serialized in the following form:
* { type: 'Class', data: DATA }
*
* Class is supposed to be a function, and new Class(DATA) is
* supposed to be equivalent to the original value
*/
/*function custom_type() {
return stringify({
type: object.constructor.name,
data: object.toString()
})
}*/
// if add, it's an internal indentation, so we add 1 level and a eol
// if !add, it's an ending indentation, so we just indent
function indent(str, add) {
var prefix = options._prefix ? options._prefix : ''
if (!options.indent) return prefix + str
var result = ''
var count = recursiveLvl + (add || 0)
for (var i=0; i<count; i++) result += options.indent
return prefix + result + str + (add ? '\n' : '')
}
function _stringify_key(key) {
if (options.quote_keys) return _stringify_str(key)
if (String(Number(key)) == key && key[0] != '-') return key
if (key == '') return _stringify_str(key)
var result = ''
for (var i=0; i<key.length; i++) {
if (i > 0) {
if (!Uni.isIdentifierPart(key[i]))
return _stringify_str(key)
} else {
if (!Uni.isIdentifierStart(key[i]))
return _stringify_str(key)
}
var chr = key.charCodeAt(i)
if (options.ascii) {
if (chr < 0x80) {
result += key[i]
} else {
result += '\\u' + ('0000' + chr.toString(16)).slice(-4)
}
} else {
if (escapable.exec(key[i])) {
result += '\\u' + ('0000' + chr.toString(16)).slice(-4)
} else {
result += key[i]
}
}
}
return result
}
function _stringify_str(key) {
var quote = options.quote
var quoteChr = quote.charCodeAt(0)
var result = ''
for (var i=0; i<key.length; i++) {
var chr = key.charCodeAt(i)
if (chr < 0x10) {
if (chr === 0 && json5) {
result += '\\0'
} else if (chr >= 8 && chr <= 13 && (json5 || chr !== 11)) {
result += special_chars[chr]
} else if (json5) {
result += '\\x0' + chr.toString(16)
} else {
result += '\\u000' + chr.toString(16)
}
} else if (chr < 0x20) {
if (json5) {
result += '\\x' + chr.toString(16)
} else {
result += '\\u00' + chr.toString(16)
}
} else if (chr >= 0x20 && chr < 0x80) {
// ascii range
if (chr === 47 && i && key[i-1] === '<') {
// escaping slashes in </script>
result += '\\' + key[i]
} else if (chr === 92) {
result += '\\\\'
} else if (chr === quoteChr) {
result += '\\' + quote
} else {
result += key[i]
}
} else if (options.ascii || Uni.isLineTerminator(key[i]) || escapable.exec(key[i])) {
if (chr < 0x100) {
if (json5) {
result += '\\x' + chr.toString(16)
} else {
result += '\\u00' + chr.toString(16)
}
} else if (chr < 0x1000) {
result += '\\u0' + chr.toString(16)
} else if (chr < 0x10000) {
result += '\\u' + chr.toString(16)
} else {
throw Error('weird codepoint')
}
} else {
result += key[i]
}
}
return quote + result + quote
}
function _stringify_object() {
if (object === null) return 'null'
var result = []
, len = 0
, braces
if (Array.isArray(object)) {
braces = '[]'
for (var i=0; i<object.length; i++) {
var s = _stringify(object[i], options, recursiveLvl+1, String(i))
if (s === undefined) s = 'null'
len += s.length + 2
result.push(s + ',')
}
} else {
braces = '{}'
var fn = function(key) {
var t = _stringify(object[key], options, recursiveLvl+1, key)
if (t !== undefined) {
t = _stringify_key(key) + ':' + (options.indent ? ' ' : '') + t + ','
len += t.length + 1
result.push(t)
}
}
if (Array.isArray(options.replacer)) {
for (var i=0; i<options.replacer.length; i++)
if (hasOwnProperty.call(object, options.replacer[i]))
fn(options.replacer[i])
} else {
var keys = Object.keys(object)
if (options.sort_keys)
keys = keys.sort(typeof(options.sort_keys) === 'function'
? options.sort_keys : undefined)
keys.forEach(fn)
}
}
// objects shorter than 30 characters are always inlined
// objects longer than 60 characters are always splitted to multiple lines
// anything in the middle depends on indentation level
len -= 2
if (options.indent && (len > options._splitMax - recursiveLvl * options.indent.length || len > options._splitMin) ) {
// remove trailing comma in multiline if asked to
if (options.no_trailing_comma && result.length) {
result[result.length-1] = result[result.length-1].substring(0, result[result.length-1].length-1)
}
var innerStuff = result.map(function(x) {return indent(x, 1)}).join('')
return braces[0]
+ (options.indent ? '\n' : '')
+ innerStuff
+ indent(braces[1])
} else {
// always remove trailing comma in one-lined arrays
if (result.length) {
result[result.length-1] = result[result.length-1].substring(0, result[result.length-1].length-1)
}
var innerStuff = result.join(options.indent ? ' ' : '')
return braces[0]
+ innerStuff
+ braces[1]
}
}
function _stringify_nonobject(object) {
if (typeof(options.replacer) === 'function') {
object = options.replacer.call(null, currentKey, object)
}
switch(typeof(object)) {
case 'string':
return _stringify_str(object)
case 'number':
if (object === 0 && 1/object < 0) {
// Opinionated decision warning:
//
// I want cross-platform negative zero in all js engines
// I know they're equal, but why lose that tiny bit of
// information needlessly?
return '-0'
}
if (!json5 && !Number.isFinite(object)) {
// json don't support infinity (= sucks)
return 'null'
}
return object.toString()
case 'boolean':
return object.toString()
case 'undefined':
return undefined
case 'function':
// return custom_type()
default:
// fallback for something weird
return JSON.stringify(object)
}
}
if (options._stringify_key) {
return _stringify_key(object)
}
if (typeof(object) === 'object') {
if (object === null) return 'null'
var str
if (typeof(str = object.toJSON5) === 'function' && options.mode !== 'json') {
object = str.call(object, currentKey)
} else if (typeof(str = object.toJSON) === 'function') {
object = str.call(object, currentKey)
}
if (object === null) return 'null'
if (typeof(object) !== 'object') return _stringify_nonobject(object)
if (object.constructor === Number || object.constructor === Boolean || object.constructor === String) {
object = object.valueOf()
return _stringify_nonobject(object)
} else if (object.constructor === Date) {
// only until we can't do better
return _stringify_nonobject(object.toISOString())
} else {
if (typeof(options.replacer) === 'function') {
object = options.replacer.call(null, currentKey, object)
if (typeof(object) !== 'object') return _stringify_nonobject(object)
}
return _stringify_object(object)
}
} else {
return _stringify_nonobject(object)
}
}
/*
* stringify(value, options)
* or
* stringify(value, replacer, space)
*
* where:
* value - anything
* options - object
* replacer - function or array
* space - boolean or number or string
*/
module.exports.stringify = function stringifyJSON(object, options, _space) {
// support legacy syntax
if (typeof(options) === 'function' || Array.isArray(options)) {
options = {
replacer: options
}
} else if (typeof(options) === 'object' && options !== null) {
// nothing to do
} else {
options = {}
}
if (_space != null) options.indent = _space
if (options.indent == null) options.indent = '\t'
if (options.quote == null) options.quote = "'"
if (options.ascii == null) options.ascii = false
if (options.mode == null) options.mode = 'json5'
if (options.mode === 'json' || options.mode === 'cjson') {
// json only supports double quotes (= sucks)
options.quote = '"'
// json don't support trailing commas (= sucks)
options.no_trailing_comma = true
// json don't support unquoted property names (= sucks)
options.quote_keys = true
}
// why would anyone use such objects?
if (typeof(options.indent) === 'object') {
if (options.indent.constructor === Number
|| options.indent.constructor === Boolean
|| options.indent.constructor === String)
options.indent = options.indent.valueOf()
}
// gap is capped at 10 characters
if (typeof(options.indent) === 'number') {
if (options.indent >= 0) {
options.indent = Array(Math.min(~~options.indent, 10) + 1).join(' ')
} else {
options.indent = false
}
} else if (typeof(options.indent) === 'string') {
options.indent = options.indent.substr(0, 10)
}
if (options._splitMin == null) options._splitMin = 50
if (options._splitMax == null) options._splitMax = 70
return _stringify(object, options, 0, '')
}

70
node_modules/jju/lib/unicode.js generated vendored Normal file

File diff suppressed because one or more lines are too long

46
node_modules/jju/lib/utils.js generated vendored Normal file
View file

@ -0,0 +1,46 @@
var FS = require('fs')
var jju = require('../')
// this function registers json5 extension, so you
// can do `require("./config.json5")` kind of thing
module.exports.register = function() {
var r = require, e = 'extensions'
r[e]['.json5'] = function(m, f) {
/*eslint no-sync:0*/
m.exports = jju.parse(FS.readFileSync(f, 'utf8'))
}
}
// this function monkey-patches JSON.parse, so it
// will return an exact position of error in case
// of parse failure
module.exports.patch_JSON_parse = function() {
var _parse = JSON.parse
JSON.parse = function(text, rev) {
try {
return _parse(text, rev)
} catch(err) {
// this call should always throw
require('jju').parse(text, {
mode: 'json',
legacy: true,
reviver: rev,
reserved_keys: 'replace',
null_prototype: false,
})
// if it didn't throw, but original parser did,
// this is an error in this library and should be reported
throw err
}
}
}
// this function is an express/connect middleware
// that accepts uploads in application/json5 format
module.exports.middleware = function() {
return function(req, res, next) {
throw Error('this function is removed, use express-json5 instead')
}
}

59
node_modules/jju/package.json generated vendored Normal file
View file

@ -0,0 +1,59 @@
{
"_from": "jju@^1.1.0",
"_id": "jju@1.4.0",
"_inBundle": false,
"_integrity": "sha1-o6vicYryQaKykE+EpiWXDzia4yo=",
"_location": "/jju",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "jju@^1.1.0",
"name": "jju",
"escapedName": "jju",
"rawSpec": "^1.1.0",
"saveSpec": null,
"fetchSpec": "^1.1.0"
},
"_requiredBy": [
"/json-parse-helpfulerror"
],
"_resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz",
"_shasum": "a3abe2718af241a2b2904f84a625970f389ae32a",
"_spec": "jju@^1.1.0",
"_where": "/home/shimataro/projects/actions/ssh-key-action/node_modules/json-parse-helpfulerror",
"author": {
"name": "Alex Kocharin",
"email": "alex@kocharin.ru"
},
"bugs": {
"url": "https://github.com/rlidwka/jju/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "a set of utilities to work with JSON / JSON5 documents",
"devDependencies": {
"eslint": "~0.4.2",
"js-yaml": "^3.12.0",
"mocha": "^5.2.0"
},
"homepage": "http://rlidwka.github.io/jju/",
"keywords": [
"json",
"json5",
"parser",
"serializer",
"data"
],
"license": "MIT",
"name": "jju",
"repository": {
"type": "git",
"url": "git://github.com/rlidwka/jju.git"
},
"scripts": {
"lint": "make lint",
"test": "make test"
},
"version": "1.4.0"
}

36
node_modules/jju/package.yaml generated vendored Normal file
View file

@ -0,0 +1,36 @@
# "jju" stands for "json/json5 utils"
name: jju
version: 1.4.0
description: a set of utilities to work with JSON / JSON5 documents
author:
name: Alex Kocharin
email: alex@kocharin.ru
repository:
type: git
url: git://github.com/rlidwka/jju
bugs:
url: https://github.com/rlidwka/jju/issues
homepage: http://rlidwka.github.io/jju/
devDependencies:
mocha: '^5.2.0'
js-yaml: '^3.12.0'
eslint: '~0.4.2' # TODO: update this
scripts:
test: make test
lint: make lint
keywords:
- json
- json5
- parser
- serializer
- data
license: MIT