This commit is contained in:
17
node_modules/tomlify-j0.4/CHANGELOG.md
generated
vendored
Normal file
17
node_modules/tomlify-j0.4/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
### v3.0.0
|
||||
|
||||
* New API interface: `tomlify.toToml(obj, opts)`, `tomlify.toValue(obj, opts)`.
|
||||
`tomlify` is no longer a function. (incompatible changes)
|
||||
* New option `sort` to specify a compare function for sorting table keys.
|
||||
|
||||
### v2.1.1
|
||||
|
||||
* New API `tomlify.toToml()`.
|
||||
* Check for circular data structure in `tomlify.toValue()`.
|
||||
|
||||
### v2.0.0
|
||||
|
||||
Breaking change:
|
||||
|
||||
* In any case, do not indent array elements when `space` is empty.
|
||||
* Now `tomlify.toValue` always make every inline-table fit into one line.
|
||||
21
node_modules/tomlify-j0.4/LICENSE
generated
vendored
Normal file
21
node_modules/tomlify-j0.4/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Jak Wings
|
||||
|
||||
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.
|
||||
230
node_modules/tomlify-j0.4/README.md
generated
vendored
Normal file
230
node_modules/tomlify-j0.4/README.md
generated
vendored
Normal file
@@ -0,0 +1,230 @@
|
||||
# TOMLify-j0.4
|
||||
|
||||
[](https://travis-ci.org/jakwings/tomlify-j0.4)
|
||||
[](http://badge.fury.io/js/tomlify-j0.4)
|
||||
|
||||
As its name *TOMLify-j0.4* says, this is a [TOML] v[0.4.0] compliant encoder.
|
||||
(JavaScript Object -> TOML text)
|
||||
|
||||
[TOML]: https://github.com/toml-lang/toml
|
||||
[0.4.0]: https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md
|
||||
|
||||
|
||||
### Live Demo
|
||||
|
||||
<https://jakwings.github.io/tomlify-j0.4/demo/>
|
||||
|
||||
You can see the result from tomlify-j0.4 in the debug console of your browser.
|
||||
|
||||
The parser used in the demo is [toml-j0.4]
|
||||
|
||||
[toml-j0.4]: https://github.com/jakwings/toml-j0.4
|
||||
|
||||
|
||||
### Usage
|
||||
|
||||
You can install it via `npm install tomlify-j0.4`, or just include the script
|
||||
`tomlify.js` or `dist/tomlify.min.js` in your web pages.
|
||||
|
||||
```javascript
|
||||
var tomlify = require('tomlify-j0.4');
|
||||
|
||||
var table = {
|
||||
about: {
|
||||
name: 'tomlify-j0.4',
|
||||
maintainers: ['Jak Wings'],
|
||||
todos: [
|
||||
{
|
||||
done: false,
|
||||
priority: 'important',
|
||||
text: 'Add some test scripts.'
|
||||
},
|
||||
{
|
||||
done: true,
|
||||
priority: 'normal',
|
||||
text: 'Open source this project.'
|
||||
}
|
||||
]
|
||||
},
|
||||
more: {
|
||||
version: [2, 0, 0],
|
||||
date: new Date('2017-04-14T00:08:00+08:00')
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
var text = tomlify.toToml(table, {space: 2}); // indent with 2 spaces
|
||||
/* OUTPUT:
|
||||
* [about]
|
||||
* name = "tomlify-j0.4"
|
||||
* maintainers = [
|
||||
* "Jak Wings"
|
||||
* ]
|
||||
*
|
||||
* [[about.todos]]
|
||||
* done = false
|
||||
* priority = "important"
|
||||
* text = "Add some test scripts."
|
||||
*
|
||||
* [[about.todos]]
|
||||
* done = true
|
||||
* priority = "normal"
|
||||
* text = "Open source this project."
|
||||
*
|
||||
* [more]
|
||||
* version = [
|
||||
* 2.0,
|
||||
* 0.0,
|
||||
* 0.0
|
||||
* ]
|
||||
* date = 2017-04-13T16:08:00.000Z
|
||||
*/
|
||||
var text = tomlify.toToml(table, {
|
||||
space: ' ',
|
||||
replace: function (key, value) {
|
||||
var context = this;
|
||||
var path = tomlify.toKey(context.path);
|
||||
if (/^more\.version\.\[\d+\]$/.test(path)) {
|
||||
return value.toFixed(0); // Change the text transformed from the value.
|
||||
}
|
||||
if (context.path[0] === 'about' &&
|
||||
context.path[1] === 'todos' &&
|
||||
context.path[2] === 1) {
|
||||
return null; // Drop one table from the todo array.
|
||||
}
|
||||
return false; // Let tomlify decide for you.
|
||||
}
|
||||
});
|
||||
/* OUTPUT:
|
||||
* [about]
|
||||
* name = "tomlify-j0.4"
|
||||
* maintainers = [
|
||||
* "Jak Wings"
|
||||
* ]
|
||||
*
|
||||
* [[about.todos]]
|
||||
* done = false
|
||||
* priority = "important"
|
||||
* text = "Add some test scripts."
|
||||
*
|
||||
* [more]
|
||||
* version = [
|
||||
* 2,
|
||||
* 0,
|
||||
* 0
|
||||
* ]
|
||||
* date = 2017-04-13T16:08:00.000Z
|
||||
*/
|
||||
var text = tomlify.toToml({
|
||||
null: null,
|
||||
undefined: undefined,
|
||||
numbers: [1, 2, null, , 3, 4]
|
||||
});
|
||||
/* OUTPUT:
|
||||
* numbers = [1.0, 2.0, 3.0, 4.0]
|
||||
*/
|
||||
} catch (err) {
|
||||
// do something
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### APIs
|
||||
|
||||
#### tomlify.toToml(table, options)
|
||||
|
||||
Use it to transform a table object into TOML text.
|
||||
|
||||
* `table`: must be an object other than an instance of Array or Date.
|
||||
|
||||
By default, all numbers are transformed into floats and arrays of numbers
|
||||
will become arrays of floats. And `null` or `undefined` in an array or
|
||||
object property whose value is `null` or `undefined` will be ignored. You
|
||||
can change this behavior through `options.replace`.
|
||||
|
||||
* options.replace - `{function(this: Context, key: String|Number, value:Mixed): Mixed}`:
|
||||
|
||||
The function used to change the default text output.
|
||||
|
||||
* `@this {Context}`:
|
||||
* `@property {Array.<String|Number>}` path: The key path to current value.
|
||||
* `@property {Table|Array}` table: The direct parent object.
|
||||
* `@param {String|Number}` key: The key of the value in current parent object.
|
||||
* `@param {Mixed}` value: The current value.
|
||||
* `@return {Mixed}` A string to change the value output, `false` to
|
||||
cancel, `null` or `undefined` to remove the output.
|
||||
|
||||
* options.space - `{String|Number}`:
|
||||
|
||||
Specify the padding string for indentation.
|
||||
|
||||
If it is a non-negative integer N, then use N space " " for indentation. If
|
||||
it is a string, then use this string for indentation. Otherwise, no
|
||||
indentation will be performed.
|
||||
|
||||
* options.sort - `{function(a: String, b: String): Number}`:
|
||||
|
||||
The compare function for sorting table keys.
|
||||
|
||||
It is used for `Array.prototype.sort()`.
|
||||
|
||||
#### tomlify.toValue(value, options)
|
||||
|
||||
Just like `tomlify.toToml(table, options)`, it is used to transform a value into TOML
|
||||
value for a key-value pair. `value` cannot be null or undefined.
|
||||
|
||||
However, an inline-table always fits into one line, no matter what it contains.
|
||||
|
||||
E.g.
|
||||
|
||||
```javascript
|
||||
tomlify.toValue({one: 1, two: 2});
|
||||
//=> {one = 1.0, two = 2.0}
|
||||
|
||||
tomlify.toValue(["apple", "banana"], {space: 2});
|
||||
//=>
|
||||
//[
|
||||
// "apple",
|
||||
// "banana"
|
||||
//]
|
||||
|
||||
tomlify.toValue([
|
||||
{people: ["Alice", "Bob"]},
|
||||
{fruits: ["apple", "banana"]}
|
||||
], {space: 2});
|
||||
//=>
|
||||
//[
|
||||
// {people = ["Alice", "Bob"]},
|
||||
// {fruits = ["apple", "banana"]}
|
||||
//]
|
||||
```
|
||||
|
||||
#### tomlify.toKey(path, alternative)
|
||||
|
||||
* path - `{String|Array.<String|Number>}`: A key or a key path.
|
||||
* alternative - `{Boolean}`: Whether numbers in the key path will be ignored.
|
||||
|
||||
Use it to get a TOML key or key path for the key-value pair. E.g.
|
||||
|
||||
```javascript
|
||||
tomlify.toKey('money'); //=> money
|
||||
tomlify.toKey('$'); //=> "$"
|
||||
|
||||
tomlify.toKey(['sir', 'Mr. Smith']); //=> sir."Mr. Smith"
|
||||
tomlify.toKey(['food', 0, 'price']); //=> food.[0].price
|
||||
tomlify.toKey(['food', 0, 'price'], true); //=> food.price
|
||||
```
|
||||
|
||||
|
||||
### Known Problems
|
||||
|
||||
* JavaScript does not have any integer type.
|
||||
|
||||
All numbers are floats in JavaScript. Any integer bigger than
|
||||
Number.MAX_SAFE_INTEGER (9007199254740991 < 2^63 - 1) or smaller than
|
||||
Number.MIN_SAFE_INTEGER (-9007199254740991 > -(2^63 - 1)) is not safe when
|
||||
being converted or used as a pure integer! You should store big integers in
|
||||
strings.
|
||||
|
||||
All numbers are transformed into floats by default. You can change this
|
||||
behavior by using a replacer function with tomlify-j0.4.
|
||||
1
node_modules/tomlify-j0.4/dist/tomlify.min.js
generated
vendored
Normal file
1
node_modules/tomlify-j0.4/dist/tomlify.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
43
node_modules/tomlify-j0.4/package.json
generated
vendored
Normal file
43
node_modules/tomlify-j0.4/package.json
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"name": "tomlify-j0.4",
|
||||
"version": "3.0.0",
|
||||
"description": "A Object->TOML encoder/converter only for TOML v0.4.0",
|
||||
"main": "tomlify.js",
|
||||
"scripts": {
|
||||
"dist": "uglifyjs --verbose --compress --mangle -o dist/tomlify.min.js tomlify.js",
|
||||
"prepare": "npm run dist",
|
||||
"test": "mocha --bail --reporter min test/*.js"
|
||||
},
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"README.md",
|
||||
"CHANGELOG.md",
|
||||
"dist/tomlify.min.js",
|
||||
"tomlify.js"
|
||||
],
|
||||
"keywords": [
|
||||
"toml",
|
||||
"tomlify",
|
||||
"stringify",
|
||||
"encoder",
|
||||
"ini",
|
||||
"toml-j0.4"
|
||||
],
|
||||
"author": "Jak Wings <jakwings@gmail.com>",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:jakwings/tomlify-j0.4.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jakwings/tomlify-j0.4/issues"
|
||||
},
|
||||
"homepage": "https://github.com/jakwings/tomlify-j0.4",
|
||||
"devDependencies": {
|
||||
"js-yaml": "~3.9.0",
|
||||
"mocha": "~3.4.2",
|
||||
"should": "~11.2.1",
|
||||
"uglify-js": "~3.0.25",
|
||||
"toml-j0.4": "~1.1.0"
|
||||
}
|
||||
}
|
||||
568
node_modules/tomlify-j0.4/tomlify.js
generated
vendored
Normal file
568
node_modules/tomlify-j0.4/tomlify.js
generated
vendored
Normal file
@@ -0,0 +1,568 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var pathToKey = function (path, alt) {
|
||||
if (path.length === 0) {
|
||||
return '';
|
||||
}
|
||||
var s = '';
|
||||
for (var i = 0, l = path.length; i < l; i++) {
|
||||
if (isString(path[i]) && path[i]) {
|
||||
s += (s ? '.' : '') + escapeKey(path[i]);
|
||||
} else if (isNumber(path[i])) {
|
||||
if (!alt) {
|
||||
s += (s ? '.' : '') + '[' + path[i] + ']';
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return s ? s : false;
|
||||
};
|
||||
|
||||
var genErrMsg = function (path, msg) {
|
||||
return (pathToKey(path) || '<root>') + ': ' + msg;
|
||||
};
|
||||
|
||||
var typeOf = function (obj) {
|
||||
return Object.prototype.toString.call(obj);
|
||||
};
|
||||
typeOf.Boolean = typeOf(false);
|
||||
typeOf.String = typeOf('');
|
||||
typeOf.Number = typeOf(0);
|
||||
typeOf.Array = typeOf([]);
|
||||
typeOf.Date = typeOf(new Date(0));
|
||||
|
||||
var isBoolean = function (obj) {
|
||||
return obj === true || obj === false;
|
||||
};
|
||||
var isString = function (obj) {
|
||||
return typeof obj === 'string';
|
||||
};
|
||||
var isNumber = function (obj) {
|
||||
return typeof obj === 'number';
|
||||
};
|
||||
var isArray = Array.isArray || function (obj) {
|
||||
return typeOf(obj) === typeOf.Array;
|
||||
};
|
||||
var isDate = function (obj) {
|
||||
return typeOf(obj) === typeOf.Date;
|
||||
};
|
||||
var isTable = function (obj) {
|
||||
return obj !== null && typeof obj === 'object' &&
|
||||
!(isArray(obj) || isDate(obj));
|
||||
};
|
||||
|
||||
var isMixedTypeArray = function (arr) {
|
||||
if (arr.length < 2) {
|
||||
return false;
|
||||
}
|
||||
var type = typeOf(arr[0]);
|
||||
for (var i = 1, l = arr.length; i < l; i++) {
|
||||
if (arr[i] != null && typeOf(arr[i]) !== type) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
var containArrays = function (arr) {
|
||||
if (arr.length < 1) {
|
||||
return false;
|
||||
}
|
||||
for (var i = 0, l = arr.length; i < l; i++) {
|
||||
if (isArray(arr[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
var containTables = function (arr) {
|
||||
if (arr.length < 1) {
|
||||
return false;
|
||||
}
|
||||
for (var i = 0, l = arr.length; i < l; i++) {
|
||||
if (isTable(arr[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
var hasOwnProperty = function (obj, key) {
|
||||
return Object.prototype.hasOwnProperty.call(obj, key);
|
||||
};
|
||||
|
||||
var isCircular = function (obj) {
|
||||
var isCircular_ = function (obj, stack) {
|
||||
if (!(isArray(obj) || isTable(obj))) {
|
||||
return false;
|
||||
}
|
||||
if (stack.indexOf(obj) !== -1) {
|
||||
return true;
|
||||
}
|
||||
stack.push(obj);
|
||||
for (var k in obj) {
|
||||
if (hasOwnProperty(obj, k)) {
|
||||
var size = stack.length;
|
||||
var ret = isCircular_(obj[k], stack);
|
||||
if (ret) {
|
||||
return true;
|
||||
}
|
||||
stack.splice(size);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
return isCircular_(obj, []);
|
||||
};
|
||||
|
||||
var escapeBoolean = function (context, key, obj) {
|
||||
return obj ? 'true' : 'false';
|
||||
};
|
||||
var escapeString = function (context, key, obj) {
|
||||
if (typeof JSON === 'object' && JSON) {
|
||||
return JSON.stringify(obj);
|
||||
}
|
||||
return '"' + String(obj).replace(/[\x00-\x1F"\\]/g, function (c) {
|
||||
switch (c) {
|
||||
case '"': case '\\': return '\\' + c;
|
||||
case '\t': return '\\t';
|
||||
case '\n': return '\\n';
|
||||
case '\r': return '\\r';
|
||||
case '\b': return '\\b';
|
||||
case '\f': return '\\f';
|
||||
default:
|
||||
var hex = c.charCodeAt(0).toString(16);
|
||||
return '\\u' + '0000'.substr(hex.length) + hex;
|
||||
}
|
||||
}) + '"';
|
||||
};
|
||||
var escapeNumber = function (context, key, obj) {
|
||||
if (!isFinite(obj)) {
|
||||
throw new Error(genErrMsg(context.path, 'Number must be finite.'));
|
||||
}
|
||||
// Cast everything to floats due to [0, 0.0]! Even 9223372036854775807.3
|
||||
// is an integer, and 9223372036854775807 is equal to 9223372036854776832.
|
||||
// We should use strings to store big integers.
|
||||
var s;
|
||||
if (Number.isInteger ? Number.isInteger(obj) : Math.floor(obj) === obj) {
|
||||
s = obj.toFixed(1);
|
||||
} else {
|
||||
s = String(obj);
|
||||
}
|
||||
s = s.replace(/([eE])(\d)/, '$1+$2');
|
||||
return /[.eE]/.test(s) ? s : s + '.0';
|
||||
};
|
||||
var escapeArray = function (context, key, obj) {
|
||||
if (isMixedTypeArray(obj)) {
|
||||
throw new Error(genErrMsg(context.path,
|
||||
'Array cannot contain values of different types.'));
|
||||
}
|
||||
var table = context.table;
|
||||
context.table = obj;
|
||||
var lines = [];
|
||||
var inPair = context.inPair;
|
||||
if (containTables(obj)) {
|
||||
context.inPair = true;
|
||||
}
|
||||
for (var i = 0, l = obj.length; i < l; i++) {
|
||||
context.path.push(i);
|
||||
var valueText = escapeValue_(context, i, obj[i]);
|
||||
if (isString(valueText)) {
|
||||
lines.push(valueText);
|
||||
}
|
||||
context.path.pop();
|
||||
}
|
||||
context.inPair = inPair;
|
||||
context.table = table;
|
||||
if (!context.inPair && lines.length > 0 && context.space) {
|
||||
return '[\n' + indent(lines.join(',\n'), 1, context.space) + '\n]';
|
||||
}
|
||||
return '[' + lines.join(', ') + ']';
|
||||
};
|
||||
var escapeDate = function (context, key, obj) {
|
||||
if (!isFinite(obj.getTime())) {
|
||||
throw new Error(genErrMsg(context.path, 'Invalid Date'));
|
||||
}
|
||||
return obj.toISOString();
|
||||
};
|
||||
var escapeInlineTable = function (context, key, obj) {
|
||||
var table = context.table;
|
||||
context.table = obj;
|
||||
var inPair = context.inPair;
|
||||
context.inPair = true;
|
||||
var lines = [];
|
||||
var keys = Object.keys(obj);
|
||||
if (context.sort) {
|
||||
keys.sort(context.sort);
|
||||
}
|
||||
for (var i = 0, l = keys.length; i < l; i++) {
|
||||
var k = keys[i];
|
||||
if (hasOwnProperty(obj, k) && obj[k] != null) {
|
||||
if (!k) {
|
||||
throw new Error(
|
||||
genErrMsg(context.path, 'Key cannot be an empty string.'));
|
||||
}
|
||||
context.path.push(k);
|
||||
var valueText = escapeValue_(context, k, obj[k]);
|
||||
if (isString(valueText)) {
|
||||
lines.push(escapeKey(k) + ' = ' + valueText);
|
||||
}
|
||||
context.path.pop();
|
||||
}
|
||||
}
|
||||
context.inPair = inPair;
|
||||
context.table = table;
|
||||
return '{' + lines.join(', ') + '}';
|
||||
};
|
||||
|
||||
var escapeValue_ = function (context, key, obj) {
|
||||
if (context.replace) {
|
||||
var valueText = context.replace.call(wrapContext(context), key, obj);
|
||||
if (isString(valueText)) {
|
||||
return valueText;
|
||||
} else if (valueText == null) {
|
||||
return null;
|
||||
} else if (valueText !== false) {
|
||||
throw new Error(genErrMsg(context.path,
|
||||
'Replacer must return a string, false, null or undefined.'));
|
||||
}
|
||||
}
|
||||
switch (typeOf(obj)) {
|
||||
case typeOf.Boolean:
|
||||
return escapeBoolean(context, key, obj);
|
||||
case typeOf.String:
|
||||
return escapeString(context, key, obj);
|
||||
case typeOf.Number:
|
||||
return escapeNumber(context, key, obj);
|
||||
case typeOf.Array:
|
||||
return escapeArray(context, key, obj);
|
||||
case typeOf.Date:
|
||||
return escapeDate(context, key, obj);
|
||||
default:
|
||||
if (obj == null) {
|
||||
return null;
|
||||
}
|
||||
return escapeInlineTable(context, key, obj);
|
||||
}
|
||||
};
|
||||
var escapeValue = function (obj, opts) {
|
||||
return escapeValue_({
|
||||
path: [],
|
||||
table: {'': obj},
|
||||
inPair: false,
|
||||
inTableArray: false,
|
||||
sort: opts.sort,
|
||||
replace: opts.replace,
|
||||
level: 0,
|
||||
space: toSpace(opts.space)
|
||||
}, '', obj);
|
||||
};
|
||||
|
||||
var escapeKey = function (key) {
|
||||
if (!key) {
|
||||
return false;
|
||||
}
|
||||
return /^[a-zA-Z0-9\-_]+$/.test(key) ? key : escapeString(null, null, key);
|
||||
};
|
||||
var escapeKeyValue = function (context, key, obj) {
|
||||
var tKey = escapeKey(key);
|
||||
if (!tKey) {
|
||||
throw new Error(
|
||||
genErrMsg(context.path, 'Key cannot be an empty string.'));
|
||||
}
|
||||
var tValue = escapeValue_(context, key, obj);
|
||||
if (isString(tValue)) {
|
||||
return tKey + ' = ' + tValue;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
var wrapContext = function (context) {
|
||||
return {
|
||||
path: context.path.slice(0),
|
||||
table: context.table
|
||||
};
|
||||
};
|
||||
|
||||
var getReplacement = function (context, key, obj) {
|
||||
if (context.replace) {
|
||||
var valueText = context.replace.call(wrapContext(context), key, obj);
|
||||
if (isString(valueText)) {
|
||||
return escapeKey(key) + ' = ' + valueText;
|
||||
} else if (valueText == null) {
|
||||
return null;
|
||||
} else if (valueText !== false) {
|
||||
throw new Error(genErrMsg(context.path,
|
||||
'Replacer must return a string, false, null or undefined.'));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
var traverse = function (context, key, obj, callback) {
|
||||
var line;
|
||||
if (context.replace && context.path.length === 0) {
|
||||
line = getReplacement(context, key, obj);
|
||||
if (isString(line)) {
|
||||
context.lines.push(line);
|
||||
}
|
||||
if (line !== false) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (callback(context, key, obj)) {
|
||||
return;
|
||||
}
|
||||
var table = context.table;
|
||||
context.table = obj;
|
||||
if (isArray(obj)) {
|
||||
var inTableArray = context.inTableArray;
|
||||
context.inTableArray = containTables(obj);
|
||||
for (var i = 0, l = obj.length; i < l; i++) {
|
||||
context.path.push(i);
|
||||
traverse(context, i, obj[i], callback);
|
||||
context.path.pop();
|
||||
}
|
||||
context.inTableArray = inTableArray;
|
||||
} else if (isTable(obj)) {
|
||||
var inTableArray = context.inTableArray;
|
||||
context.inTableArray = false;
|
||||
var tables = [];
|
||||
var keys = Object.keys(obj);
|
||||
if (context.sort) {
|
||||
keys.sort(context.sort);
|
||||
}
|
||||
for (var i = 0, l = keys.length; i < l; i++) {
|
||||
var k = keys[i];
|
||||
if (hasOwnProperty(obj, k)) {
|
||||
var v = obj[k];
|
||||
var toIndent = context.path.length > 0 &&
|
||||
(isArray(v) ? containTables(v) : isTable(v));
|
||||
if (isArray(v) && containTables(v)) {
|
||||
tables.push([true, k, v, toIndent]);
|
||||
} else if (isTable(v)) {
|
||||
tables.push([false, k, v, toIndent]);
|
||||
} else {
|
||||
context.path.push(k);
|
||||
traverse(context, k, v, callback);
|
||||
context.path.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
keys = null;
|
||||
if (context.replace) {
|
||||
for (var i = 0, l = tables.length; i < l; i ++) {
|
||||
var table = tables[i];
|
||||
if (!table[0]) {
|
||||
context.path.push(table[1]);
|
||||
line = getReplacement(context, table[1], table[2]);
|
||||
if (line !== false) {
|
||||
if (isString(line)) {
|
||||
context.lines.push(indent(line, context.level, context.space));
|
||||
}
|
||||
table[2] = null;
|
||||
}
|
||||
context.path.pop();
|
||||
} else {
|
||||
context.path.push(table[1]);
|
||||
line = getReplacement(context, table[1], table[2]);
|
||||
if (line !== false) {
|
||||
if (isString(line)) {
|
||||
context.lines.push(indent(line, context.level, context.space));
|
||||
}
|
||||
table[2] = null;
|
||||
context.path.pop();
|
||||
continue;
|
||||
}
|
||||
var subTables = table[2];
|
||||
for (var j = 0, k = subTables.length; j < k; j++) {
|
||||
var subTable = subTables[j];
|
||||
context.path.push(j);
|
||||
line = getReplacement(context, j, subTable);
|
||||
context.path.pop();
|
||||
if (line !== false) {
|
||||
if (line == null) {
|
||||
subTables[j] = null;
|
||||
continue;
|
||||
}
|
||||
line = escapeKeyValue(context, table[1], table[2]);
|
||||
if (isString(line)) {
|
||||
context.lines.push(indent(line, context.level, context.space));
|
||||
}
|
||||
table[2] = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
context.path.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
for (var i = 0, l = tables.length; i < l; i++) {
|
||||
var table = tables[i];
|
||||
if (table[2] == null) {
|
||||
continue;
|
||||
}
|
||||
context.path.push(table[1]);
|
||||
if (table[3]) {
|
||||
context.level++;
|
||||
}
|
||||
traverse(context, table[1], table[2], callback);
|
||||
if (table[3]) {
|
||||
context.level--;
|
||||
}
|
||||
context.path.pop();
|
||||
}
|
||||
context.inTableArray = inTableArray;
|
||||
}
|
||||
context.table = table;
|
||||
};
|
||||
|
||||
var repeatString = function (str, n) {
|
||||
if (str.repeat) {
|
||||
return str.repeat(n);
|
||||
}
|
||||
var s = '';
|
||||
var c = '';
|
||||
while (n > 0) {
|
||||
c += c || str;
|
||||
if (n & 1) {
|
||||
s += c;
|
||||
}
|
||||
n >>>= 1;
|
||||
}
|
||||
return s;
|
||||
};
|
||||
|
||||
var indent = function (str, level, space) {
|
||||
var padding = repeatString(space, level);
|
||||
return str.replace(/^(?!$)/mg, padding);
|
||||
};
|
||||
|
||||
var toSpace = function (space) {
|
||||
if (isString(space)) {
|
||||
return space;
|
||||
} else if (isNumber(space) && space >= 0 && isFinite(space) &&
|
||||
Math.floor(space) === space) {
|
||||
return repeatString(' ', space);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
var check = function (obj, opts) {
|
||||
if (obj == null) {
|
||||
throw new Error('Undefined or null cannot be stringified.');
|
||||
}
|
||||
if (isCircular(obj)) {
|
||||
throw new Error('Converting circular structure to TOML.');
|
||||
}
|
||||
if (opts != null && typeof opts !== 'object') {
|
||||
throw new Error('Options must be an object.');
|
||||
}
|
||||
// @type {function(this: Context, key: String|Number, value: Mixed): Mixed}
|
||||
if (opts.replace != null && typeof opts.replace !== 'function') {
|
||||
throw new Error('Replacer must be a function.');
|
||||
}
|
||||
// @type {function(a: String, b: String): Number}
|
||||
if (opts.sort != null && typeof opts.sort !== 'function') {
|
||||
throw new Error('Compare function for sorting must be a function.');
|
||||
}
|
||||
};
|
||||
|
||||
var escapeTable = function (table, opts) {
|
||||
var lines = [];
|
||||
var callback = function (context, key, obj) {
|
||||
var line = null;
|
||||
if (isTable(obj)) {
|
||||
if (key !== '') {
|
||||
if (lines.length > 0) {
|
||||
lines.push('');
|
||||
}
|
||||
if (!context.inTableArray) {
|
||||
line = '[' + pathToKey(context.path, true) + ']';
|
||||
} else {
|
||||
line = '[[' + pathToKey(context.path, true) + ']]';
|
||||
}
|
||||
lines.push(indent(line, context.level, context.space));
|
||||
}
|
||||
} else if (isArray(obj)) {
|
||||
if (isString(key)) {
|
||||
if (!containTables(obj)) {
|
||||
line = escapeKeyValue(context, key, obj);
|
||||
if (isString(line)) {
|
||||
lines.push(indent(line, context.level, context.space));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (isString(key)) {
|
||||
line = escapeKeyValue(context, key, obj);
|
||||
if (isString(line)) {
|
||||
lines.push(indent(line, context.level, context.space));
|
||||
}
|
||||
}
|
||||
return true; // Always return true.
|
||||
}
|
||||
};
|
||||
traverse({
|
||||
path: [],
|
||||
table: {'': table},
|
||||
inPair: false,
|
||||
inTableArray: false,
|
||||
replace: opts.replace,
|
||||
sort: opts.sort,
|
||||
level: 0,
|
||||
space: toSpace(opts.space),
|
||||
lines: lines // So special...
|
||||
}, '', table, callback);
|
||||
return lines.join('\n');
|
||||
};
|
||||
|
||||
var tomlify = {};
|
||||
|
||||
tomlify.toToml = function (table, opts) {
|
||||
if (!isTable(table)) {
|
||||
throw new Error('An object other than Array or Date is expected.');
|
||||
}
|
||||
opts = opts != null ? opts : {};
|
||||
check(table, opts);
|
||||
return escapeTable(table, opts);
|
||||
};
|
||||
|
||||
tomlify.toKey = function (path, alt) {
|
||||
if (isString(path)) {
|
||||
var key = escapeKey(path);
|
||||
if (!key) {
|
||||
throw new Error('Key cannot be an empty string.');
|
||||
}
|
||||
return key;
|
||||
} else if (isArray(path)) {
|
||||
var key = pathToKey(path, alt);
|
||||
if (key === false) {
|
||||
throw new Error('Key path must consist of non-empty string(s).');
|
||||
}
|
||||
return key;
|
||||
}
|
||||
throw new Error('Invalid Arguments for tomlify.toKey({String | Array})');
|
||||
};
|
||||
|
||||
tomlify.toValue = function (obj, opts) {
|
||||
opts = opts != null ? opts : {};
|
||||
check(obj, opts);
|
||||
return escapeValue(obj, opts);
|
||||
};
|
||||
|
||||
if ((typeof module !== 'undefined' && module !== null ? module.exports : void 0) != null) {
|
||||
module.exports = tomlify;
|
||||
} else if (typeof define === 'function' && define.amd) {
|
||||
define([], function() {
|
||||
return tomlify;
|
||||
});
|
||||
} else {
|
||||
this.tomlify = tomlify;
|
||||
}
|
||||
}).call(this);
|
||||
Reference in New Issue
Block a user