file-cms
Version:
File based Content Management System, easy to use with content stored in native file system
111 lines (110 loc) • 5.59 kB
JavaScript
import { __awaiter, __generator, __rest } from "tslib";
import path from "path";
import { Config } from "./Config";
import { listDirCached } from "./internal/listDirCached";
import { fetchContentCached } from "./internal/fetchContentCached";
import { attributeFilter } from "./internal/attributeFilter";
export var listContent = function (filters, attributes, sort) {
if (filters === void 0) { filters = {}; }
if (attributes === void 0) { attributes = []; }
return __awaiter(void 0, void 0, void 0, function () {
var rootDir, typeFilter, slugFilter, contentFilters, filesToFetch, allTypes, typeFilterPredicate, typesToFetch, allContents, contentPredicate, filteredContents, partialContents;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
rootDir = Config.getRootDir();
typeFilter = filters.type, slugFilter = filters.slug, contentFilters = __rest(filters, ["type", "slug"]);
filesToFetch = [];
return [4 /*yield*/, listDirCached(rootDir)];
case 1:
allTypes = _a.sent();
typeFilterPredicate = expressionToProvider(typeFilter);
typesToFetch = typeFilter
? allTypes.filter(typeFilterPredicate)
: allTypes;
return [4 /*yield*/, Promise.all(typesToFetch.map(function (type) { return __awaiter(void 0, void 0, void 0, function () {
var allSlugFileNames, allSlugs, slugFilterPredicate, slugsToFetch, _i, slugsToFetch_1, slug;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, listDirCached(path.join(rootDir, type))];
case 1:
allSlugFileNames = _a.sent();
allSlugs = allSlugFileNames
.filter(function (slug) { return slug.endsWith(".md"); })
.map(function (slug) { return slug.substring(0, slug.length - 3); });
slugFilterPredicate = expressionToProvider(slugFilter);
slugsToFetch = slugFilter
? allSlugs.filter(slugFilterPredicate)
: allSlugs;
for (_i = 0, slugsToFetch_1 = slugsToFetch; _i < slugsToFetch_1.length; _i++) {
slug = slugsToFetch_1[_i];
filesToFetch.push({ type: type, slug: slug });
}
return [2 /*return*/];
}
});
}); }))];
case 2:
_a.sent();
return [4 /*yield*/, Promise.all(filesToFetch.map(function (_a) {
var type = _a.type, slug = _a.slug;
return __awaiter(void 0, void 0, void 0, function () {
return __generator(this, function (_b) {
return [2 /*return*/, fetchContentCached(rootDir, type, slug)];
});
});
}))];
case 3:
allContents = _a.sent();
contentPredicate = getContentFilterPredicate(contentFilters);
filteredContents = contentPredicate
? allContents.filter(contentPredicate)
: allContents;
// apply sort if present
if (sort) {
filteredContents.sort(sort);
}
partialContents = filteredContents.map(function (content) {
return attributeFilter(content, attributes);
});
return [2 /*return*/, partialContents];
}
});
});
};
var getContentFilterPredicate = function (filters) {
var filterKeys = Object.keys(filters);
if (filterKeys.length > 0) {
var providers_1 = {};
filterKeys.forEach(function (key) {
providers_1[key] = expressionToProvider(filters[key]);
});
return function (content) {
for (var _i = 0, filterKeys_1 = filterKeys; _i < filterKeys_1.length; _i++) {
var key = filterKeys_1[_i];
var provider = providers_1[key];
if (!(provider && provider(content[key]))) {
return false;
}
}
return true;
};
}
};
var expressionToProvider = function (expression) {
if (expression === undefined) {
return;
}
var fullExpression = expression === null ||
typeof expression == "string" ||
typeof expression == "number" ||
typeof expression == "boolean"
? { eq: expression }
: expression;
var exprName = Object.keys(fullExpression)[0];
var exprArg = Object.values(fullExpression)[0];
var provider = Config.getFilterProvider(exprName);
return function (data) {
return provider(data, exprArg);
};
};