git-documentdb
Version:
Offline-first database that syncs with Git
247 lines • 9.35 kB
JavaScript
;
/**
* GitDocumentDB
* Copyright (c) Hidekazu Kubota
*
* This source code is licensed under the Mozilla Public License Version 2.0
* found in the LICENSE file in the root directory of this source tree.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CONSOLE_STYLE = exports.normalizeCommit = exports.getAllMetadata = exports.toFrontMatterMarkdown = exports.toYAML = exports.toSortedJSONString = exports.utf8encode = exports.utf8decode = exports.sleep = void 0;
const fs_extra_1 = __importDefault(require("fs-extra"));
const js_yaml_1 = __importDefault(require("js-yaml"));
const isomorphic_git_1 = require("isomorphic-git");
const const_1 = require("./const");
/**
* @internal
*/
function sleep(msec) {
return new Promise(resolve => setTimeout(resolve, msec));
}
exports.sleep = sleep;
// eslint-disable-next-line @typescript-eslint/naming-convention
const decoder = new TextDecoder(); // default 'utf-8' or 'utf8'
// eslint-disable-next-line @typescript-eslint/naming-convention
const encoder = new TextEncoder(); // default 'utf-8' or 'utf8'
/**
* utf8decode
*
* @internal
*/
function utf8decode(uint8array) {
return decoder.decode(uint8array);
}
exports.utf8decode = utf8decode;
/**
* utf8encode
*
* @internal
*/
function utf8encode(utf8) {
return encoder.encode(utf8);
}
exports.utf8encode = utf8encode;
/**
* Returns JSON string which properties are sorted.
* The sorting follows the UTF-16 (Number < Uppercase < Lowercase), except that heading underscore _ is the last.
* Its indent is 2.
*
* NOTE: Heading underscore cannot be the first because replacing '\uffff' with '\u0000' does not effect to sorting order.
*
*/
function toSortedJSONString(obj) {
return JSON.stringify(obj, (key, v) => !(Array.isArray(v) || v === null) && typeof v === 'object'
? Object.keys(v)
.sort((a, b) => {
// Heading underscore is treated as the last character.
a = a.startsWith('_') ? '\uffff' + a.slice(1) : a;
b = b.startsWith('_') ? '\uffff' + b.slice(1) : b;
return a > b ? 1 : a < b ? -1 : 0;
})
.reduce((r, k) => {
r[k] = v[k];
return r;
}, {})
: v, 2);
}
exports.toSortedJSONString = toSortedJSONString;
function toYAML(obj) {
return js_yaml_1.default.dump(obj, { sortKeys: true, lineWidth: -1 });
}
exports.toYAML = toYAML;
function toFrontMatterMarkdown(obj) {
const body = typeof obj._body === 'string' ? obj._body : '';
const clone = JSON.parse(JSON.stringify(obj));
delete clone._body;
let hasOnlyId = true;
for (const key of Object.keys(clone)) {
if (key !== '_id') {
hasOnlyId = false;
break;
}
}
if (hasOnlyId) {
return body;
}
const frontMatter = '---\n' + js_yaml_1.default.dump(clone, { sortKeys: true, lineWidth: -1 }) + '---\n';
return frontMatter + body;
}
exports.toFrontMatterMarkdown = toFrontMatterMarkdown;
/**
* Get metadata of all files from current Git index
*
* @internal
*/
// eslint-disable-next-line complexity
async function getAllMetadata(workingDir, serializeFormat) {
const files = [];
const commitOid = await (0, isomorphic_git_1.resolveRef)({ fs: fs_extra_1.default, dir: workingDir, ref: 'HEAD' }).catch(() => undefined);
if (commitOid === undefined)
return [];
const treeResult = (await (0, isomorphic_git_1.readTree)({
fs: fs_extra_1.default,
dir: workingDir,
oid: commitOid,
}).catch(() => undefined));
const directories = []; // type TreeObject = Array<TreeEntry>
const targetDir = '';
if (treeResult) {
directories.push({ path: targetDir, entries: treeResult.tree });
}
const docs = [];
while (directories.length > 0) {
const directory = directories.shift();
if (directory === undefined)
break;
const entries = directory.entries;
for (const entry of entries) {
const fullDocPath = directory.path !== '' ? `${directory.path}/${entry.path}` : entry.path;
if (entry.type === 'tree') {
if (fullDocPath !== const_1.GIT_DOCUMENTDB_METADATA_DIR) {
// eslint-disable-next-line no-await-in-loop
const { tree } = await (0, isomorphic_git_1.readTree)({
fs: fs_extra_1.default,
dir: workingDir,
oid: entry.oid,
});
directories.push({ path: fullDocPath, entries: tree });
}
}
else {
// eslint-disable-next-line no-await-in-loop
const readBlobResult = await (0, isomorphic_git_1.readBlob)({
fs: fs_extra_1.default,
dir: workingDir,
oid: commitOid,
filepath: fullDocPath,
}).catch(() => undefined);
// Skip if cannot read
if (readBlobResult === undefined)
continue;
const docType = serializeFormat.hasObjectExtension(fullDocPath)
? 'json'
: 'text';
if (docType === 'text') {
// TODO: select binary or text by .gitattribtues
}
if (docType === 'json') {
const _id = serializeFormat.removeExtension(fullDocPath);
const meta = {
_id,
name: fullDocPath,
fileOid: entry.oid,
type: 'json',
};
docs.push(meta);
}
else if (docType === 'text') {
const meta = {
name: fullDocPath,
fileOid: entry.oid,
type: 'text',
};
docs.push(meta);
}
else if (docType === 'binary') {
const meta = {
name: fullDocPath,
fileOid: entry.oid,
type: 'binary',
};
docs.push(meta);
}
}
}
}
return docs;
}
exports.getAllMetadata = getAllMetadata;
/**
* Get normalized commit
*/
function normalizeCommit(commit) {
const normalized = {
oid: commit.oid,
message: commit.commit.message.trimEnd(),
parent: commit.commit.parent,
author: {
name: commit.commit.author.name,
email: commit.commit.author.email,
timestamp: commit.commit.author.timestamp * 1000,
},
committer: {
name: commit.commit.committer.name,
email: commit.commit.committer.email,
timestamp: commit.commit.committer.timestamp * 1000,
},
};
if (commit.commit.gpgsig !== undefined) {
normalized.gpgsig = commit.commit.gpgsig;
}
return normalized;
}
exports.normalizeCommit = normalizeCommit;
/**
* Template literal tag for console style
* https://bluesock.org/~willkg/dev/ansi.html#ansicodes
*
* @internal
*/
class ConsoleStyleClass {
constructor(style) {
this._style = '';
this.tag = () => {
return (literals, ...placeholders) => {
let result = this._style;
for (let i = 0; i < placeholders.length; i++) {
result += literals[i];
result += placeholders[i].toString();
}
result += literals[literals.length - 1];
// Reset style
result += '\x1b[0m';
return result;
};
};
/*
bright = () => new ConsoleStyleClass(this._style + '\x1b[1m');
dim = () => new ConsoleStyleClass(this._style + '\x1b[2m');
underscore = () => new ConsoleStyleClass(this._style + '\x1b[4m');
blink = () => new ConsoleStyleClass(this._style + '\x1b[5m');
reverse = () => new ConsoleStyleClass(this._style + '\x1b[7m');
hidden = () => new ConsoleStyleClass(this._style + '\x1b[8m');
*/
this.fgBlack = () => new ConsoleStyleClass(this._style + '\x1b[30m');
this.bgWhite = () => new ConsoleStyleClass(this._style + '\x1b[47m');
this.fgRed = () => new ConsoleStyleClass(this._style + '\x1b[31m');
this.bgRed = () => new ConsoleStyleClass(this._style + '\x1b[41m');
this.bgGreen = () => new ConsoleStyleClass(this._style + '\x1b[42m');
this.bgYellow = () => new ConsoleStyleClass(this._style + '\x1b[43m');
this._style = style !== null && style !== void 0 ? style : '';
}
}
exports.CONSOLE_STYLE = new ConsoleStyleClass('');
//# sourceMappingURL=utils.js.map