git-documentdb
Version:
Offline-first database that syncs with Git
201 lines • 9.26 kB
JavaScript
"use strict";
/**
* 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.findImpl = void 0;
const fs_1 = __importDefault(require("fs"));
const isomorphic_git_1 = require("isomorphic-git");
const const_1 = require("../const");
const error_1 = require("../error");
const blob_1 = require("./blob");
const get_1 = require("./get");
/**
* Implementation of find()
*
* @throws {@link Err.DatabaseClosingError}
* @throws {@link Err.RepositoryNotOpenError}
* @throws {@link Err.InvalidJsonObjectError}
*/
// eslint-disable-next-line complexity
async function findImpl(gitDDB, collectionPath, serializeFormat, findOnlyJson, withMetadata, options) {
var _a, _b, _c, _d;
if (gitDDB.isClosing) {
return Promise.reject(new error_1.Err.DatabaseClosingError());
}
if (!gitDDB.isOpened) {
return Promise.reject(new error_1.Err.RepositoryNotOpenError());
}
options !== null && options !== void 0 ? options : (options = {
descending: undefined,
recursive: undefined,
prefix: undefined,
forceDocType: undefined,
});
(_a = options.descending) !== null && _a !== void 0 ? _a : (options.descending = false);
(_b = options.recursive) !== null && _b !== void 0 ? _b : (options.recursive = true);
(_c = options.prefix) !== null && _c !== void 0 ? _c : (options.prefix = '');
options.prefix = collectionPath + options.prefix;
const commitOid = await (0, isomorphic_git_1.resolveRef)({ fs: fs_1.default, dir: gitDDB.workingDir, ref: 'HEAD' });
// Normalize prefix and targetDir
let prefix = options.prefix;
let targetDir = '';
const prefixArray = prefix.split('/'); // returns number which is equal or larger than 1
if (prefixArray.length === 1) {
// prefix equals '' or prefix includes no slash
// nop
}
else if (prefixArray[prefixArray.length - 1] === '') {
// prefix ends with slash
targetDir = prefix.slice(0, -1); // remove trailing slash
prefix = '';
}
else {
// prefix does not end with slash
prefix = prefixArray.pop();
targetDir = prefixArray.join('/');
}
// Breadth-first search
const directories = []; // type TreeObject = Array<TreeEntry>
const specifiedTreeResult = await (0, isomorphic_git_1.readTree)({
fs: fs_1.default,
dir: gitDDB.workingDir,
oid: commitOid,
filepath: targetDir,
}).catch(() => undefined);
if (specifiedTreeResult) {
directories.push({ path: targetDir, entries: specifiedTreeResult.tree });
}
const docs = [];
while (directories.length > 0) {
const directory = directories.shift();
if (directory === undefined)
break;
let filteredEntries;
if (prefix === '') {
filteredEntries = directory.entries;
}
else {
filteredEntries = [];
let matchPrefix = false;
for (const entry of directory.entries) {
if (entry.path.startsWith(prefix)) {
filteredEntries.push(entry);
matchPrefix = true;
}
else if (matchPrefix) {
// Can break because entries are alphabetical order.
// https://github.com/isomorphic-git/isomorphic-git/blob/1316820b5665346414f9bd1287d4701f9cf77727/src/models/GitTree.js#L93-L95
// Not that Git sorts tree entries as if there is a trailing slash on directory names.
// See https://github.com/isomorphic-git/isomorphic-git/blob/89c0da78d5ebf3c9f2754b3c8d557155dd70c8d7/src/utils/compareTreeEntryPath.js
break;
}
}
}
// Ascendant alphabetical order (default)
// let sortFunc = (a: TreeEntry, b: TreeEntry) =>
// a.path.localeCompare(b.path);
// Descendant alphabetical order
if (options.descending) {
const sortFunc = (a, b) => -a.path.localeCompare(b.path);
filteredEntries.sort(sortFunc);
}
for (const entry of filteredEntries) {
const fullDocPath = directory.path !== '' ? `${directory.path}/${entry.path}` : entry.path;
if (entry.type === 'tree') {
if (options.recursive && 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_1.default,
dir: gitDDB.workingDir,
oid: entry.oid,
});
directories.push({ path: fullDocPath, entries: tree });
prefix = '';
}
}
else {
if (findOnlyJson && !serializeFormat.hasObjectExtension(fullDocPath)) {
continue;
}
const docType = (_d = options.forceDocType) !== null && _d !== void 0 ? _d : (serializeFormat.hasObjectExtension(fullDocPath) ? 'json' : 'text');
if (docType === 'text') {
// TODO: select binary or text by .gitattribtues
}
const shortName = fullDocPath.replace(new RegExp('^' + collectionPath), '');
if (docType === 'json') {
const [, extension] = fullDocPath.match(/.+(\..+?)$/);
const shortId = serializeFormat.removeExtension(shortName);
if (withMetadata) {
// eslint-disable-next-line no-await-in-loop
const readBlobResult = await (0, isomorphic_git_1.readBlob)({
fs: fs_1.default,
dir: gitDDB.workingDir,
oid: commitOid,
filepath: fullDocPath,
}).catch(() => undefined);
// Skip if cannot read
if (readBlobResult) {
docs.push((0, blob_1.blobToJsonDoc)(shortId, readBlobResult, true, serializeFormat, extension));
}
}
else {
docs.push(
// eslint-disable-next-line no-await-in-loop
(await (0, get_1.getJsonDocFromWorkingDir)(gitDDB, shortName, collectionPath, serializeFormat)));
}
}
else if (docType === 'text') {
if (withMetadata) {
// eslint-disable-next-line no-await-in-loop
const readBlobResult = await (0, isomorphic_git_1.readBlob)({
fs: fs_1.default,
dir: gitDDB.workingDir,
oid: commitOid,
filepath: fullDocPath,
}).catch(() => undefined);
// Skip if cannot read
if (readBlobResult) {
docs.push((0, blob_1.blobToText)(shortName, readBlobResult, true));
}
}
else {
docs.push(
// eslint-disable-next-line no-await-in-loop
(await (0, get_1.getTextDocFromWorkingDir)(gitDDB, shortName, collectionPath, serializeFormat)));
}
}
else if (docType === 'binary') {
if (withMetadata) {
// eslint-disable-next-line no-await-in-loop
const readBlobResult = await (0, isomorphic_git_1.readBlob)({
fs: fs_1.default,
dir: gitDDB.workingDir,
oid: commitOid,
filepath: fullDocPath,
}).catch(() => undefined);
// Skip if cannot read
if (readBlobResult) {
docs.push((0, blob_1.blobToBinary)(shortName, readBlobResult, true));
}
}
else {
docs.push(
// eslint-disable-next-line no-await-in-loop
(await (0, get_1.getBinaryDocFromWorkingDir)(gitDDB, shortName, collectionPath, serializeFormat)));
}
}
}
}
}
return docs;
}
exports.findImpl = findImpl;
//# sourceMappingURL=find.js.map