mirror of https://gitee.com/bigwinds/arangodb
225 lines
6.1 KiB
JavaScript
225 lines
6.1 KiB
JavaScript
'use strict';
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief ArangoDB utilities
|
|
// /
|
|
// / @file
|
|
// /
|
|
// / DISCLAIMER
|
|
// /
|
|
// / Copyright 2016 triagens GmbH, Cologne, Germany
|
|
// /
|
|
// / Licensed under the Apache License, Version 2.0 (the "License")
|
|
// / you may not use this file except in compliance with the License.
|
|
// / You may obtain a copy of the License at
|
|
// /
|
|
// / http://www.apache.org/licenses/LICENSE-2.0
|
|
// /
|
|
// / Unless required by applicable law or agreed to in writing, software
|
|
// / distributed under the License is distributed on an "AS IS" BASIS,
|
|
// / WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// / See the License for the specific language governing permissions and
|
|
// / limitations under the License.
|
|
// /
|
|
// / Copyright holder is triAGENS GmbH, Cologne, Germany
|
|
// /
|
|
// / @author Alan Plum
|
|
// / @author Copyright 2016, triAGENS GmbH, Cologne, Germany
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
const _ = require('lodash');
|
|
const fs = require('fs');
|
|
const Chalk = require('chalk').constructor;
|
|
const chalk = new Chalk({enabled: true});
|
|
const dedent = require('dedent');
|
|
const internal = require('internal');
|
|
const codeFrame = require('babel-code-frame');
|
|
const stackParser = require('error-stack-parser');
|
|
|
|
exports.union = function union () {
|
|
const things = Array.prototype.slice.call(arguments);
|
|
if (!things.slice(1).some(Boolean)) {
|
|
return things[0];
|
|
}
|
|
let result;
|
|
if (things[0] instanceof Map) {
|
|
result = new Map();
|
|
for (let map of things) {
|
|
for (let entry of map.entries()) {
|
|
result.set(entry[0], entry[1]);
|
|
}
|
|
}
|
|
} else if (things[0] instanceof Set) {
|
|
result = new Set();
|
|
for (let set of things) {
|
|
for (let value of set.values()) {
|
|
result.add(value);
|
|
}
|
|
}
|
|
} else if (Array.isArray(things[0])) {
|
|
result = Array.prototype.concat.apply([], things);
|
|
} else {
|
|
things.unshift({});
|
|
result = Object.assign(...things);
|
|
}
|
|
return result;
|
|
};
|
|
|
|
exports.drain = function (generator) {
|
|
let results = [];
|
|
for (let result of generator) {
|
|
results.push(result);
|
|
}
|
|
return results;
|
|
};
|
|
|
|
exports.codeFrame = function (e, basePath, withColor = internal.COLOR_OUTPUT) {
|
|
try {
|
|
let ctx;
|
|
let err = e;
|
|
while (err) {
|
|
try {
|
|
if (
|
|
err.fileName &&
|
|
err.lineNumber &&
|
|
err.columnNumber &&
|
|
(!basePath || err.fileName.indexOf(basePath) === 0)
|
|
) {
|
|
ctx = {
|
|
fileName: err.fileName,
|
|
lineNumber: Number(err.lineNumber),
|
|
columnNumber: Number(err.columnNumber)
|
|
};
|
|
break;
|
|
} else {
|
|
const stack = stackParser.parse(err);
|
|
for (const step of stack) {
|
|
if (!basePath || step.fileName.indexOf(basePath) === 0) {
|
|
ctx = step;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} catch (e) {}
|
|
err = err.cause;
|
|
}
|
|
if (ctx) {
|
|
const source = fs.readFileSync(ctx.fileName, 'utf-8');
|
|
const frame = codeFrame(source, ctx.lineNumber, ctx.columnNumber, {
|
|
highlightCode: withColor,
|
|
forceColor: withColor
|
|
});
|
|
const location = `@ ${
|
|
basePath ? ctx.fileName.slice(basePath.length + 1) : ctx.fileName
|
|
}:${ctx.lineNumber}:${ctx.columnNumber}\n`;
|
|
return (withColor ? chalk.grey(location) : location) + frame;
|
|
}
|
|
} catch (e) {}
|
|
return null;
|
|
};
|
|
|
|
exports.inline = function (strs) {
|
|
let str;
|
|
if (typeof strs === 'string') {
|
|
str = strs;
|
|
} else {
|
|
const strb = [strs[0]];
|
|
const vars = Array.prototype.slice.call(arguments, 1);
|
|
for (let i = 0; i < vars.length; i++) {
|
|
strb.push(vars[i], strs[i + 1]);
|
|
}
|
|
str = strb.join('');
|
|
}
|
|
return str.replace(/\s*\n\s*/g, ' ').replace(/(^\s|\s$)/g, '');
|
|
};
|
|
|
|
exports.redent = function ([start, ...strs], ...vars) {
|
|
const body = start.split('\n');
|
|
for (let i = 0; i < vars.length; i++) {
|
|
const current = body[body.length - 1];
|
|
const match = current.match(/^(\s+)/);
|
|
const padding = match ? match[1] : '';
|
|
const lines = String(vars[i]).split('\n');
|
|
body.push(body.pop() + lines[0]);
|
|
if (lines.length > 1) {
|
|
body.push(...lines.slice(1).map(line => padding + line));
|
|
}
|
|
const append = strs[i].split('\n');
|
|
body.push(body.pop() + append[0]);
|
|
if (append.length > 1) {
|
|
body.push(...append.slice(1));
|
|
}
|
|
}
|
|
return body.join('\n');
|
|
};
|
|
|
|
exports.dedent = function (...args) {
|
|
return dedent(exports.redent(...args));
|
|
};
|
|
|
|
exports.propertyKeys = function (obj) {
|
|
return Object.keys(obj).filter((key) => (
|
|
key.charAt(0) !== '_' && key.charAt(0) !== '$'
|
|
));
|
|
};
|
|
|
|
exports.shallowCopy = function (src) {
|
|
const dest = {};
|
|
if (src === undefined || src === null) {
|
|
return dest;
|
|
}
|
|
for (const key of exports.propertyKeys(src)) {
|
|
dest[key] = src[key];
|
|
}
|
|
return dest;
|
|
};
|
|
|
|
exports.indentation = function (level, indentWith) {
|
|
if (!indentWith) {
|
|
indentWith = ' ';
|
|
}
|
|
let padding = '';
|
|
for (let i = 0; i < level; i++) {
|
|
padding += indentWith;
|
|
}
|
|
return padding;
|
|
};
|
|
|
|
function xmlAttrValue (str) {
|
|
return String(str)
|
|
.replace(/&/g, '&')
|
|
.replace(/"/g, '"');
|
|
}
|
|
|
|
function xmlCharacterData (str) {
|
|
return String(str)
|
|
.replace(/&/g, '&')
|
|
.replace(/</g, '<');
|
|
}
|
|
|
|
exports.jsonml2xml = function (jsonml, html = false, indentLevel = 0) {
|
|
if (typeof jsonml === 'string') {
|
|
return jsonml.split('\n')
|
|
.map((line) => exports.indentation(indentLevel, '\t') + xmlCharacterData(line))
|
|
.join('\n');
|
|
}
|
|
const [tagname, attrs, ...children] = jsonml;
|
|
const xml = (
|
|
children.length
|
|
? children.map((child) => exports.jsonml2xml(child, html, indentLevel + 1)).join('\n') + '\n'
|
|
: ''
|
|
);
|
|
return exports.indentation(indentLevel, '\t') + `<${
|
|
tagname
|
|
} ${
|
|
Object.keys(attrs).map((name) => `${name}="${xmlAttrValue(attrs[name])}"`).join(' ')
|
|
}${
|
|
xml || html
|
|
? `>\n${xml}${exports.indentation(indentLevel, '\t')}</${tagname}>`
|
|
: '/>'
|
|
}`;
|
|
};
|
|
|
|
exports.isZipBuffer = function (buffer) {
|
|
return buffer instanceof Buffer && buffer.length >= 4 && buffer.utf8Slice(0, 4) === 'PK\u0003\u0004';
|
|
};
|