TOPVERSE_Official/.output/server/chunks/app/_nuxt/client-db-d3e6e918.mjs

412 lines
14 KiB
JavaScript
Raw Normal View History

2023-05-30 00:33:57 +08:00
import memory from 'unstorage/drivers/memory';
import { prefixStorage, createStorage } from 'unstorage';
import { m as useNuxtApp, u as useRuntimeConfig } from '../server.mjs';
import { withBase } from 'ufo';
import { c as createQuery, g as get, a as assertArray, b as ensureArray, s as sortList, d as apply, w as withoutKeys, f as withKeys } from './query-e0164f92.mjs';
import { pascalCase } from 'scule';
import { u as useContentPreview } from './preview-38d6e135.mjs';
import 'vue';
import 'ofetch';
import 'hookable';
import 'unctx';
import 'h3';
import '@unhead/ssr';
import 'unhead';
import '@unhead/shared';
import 'vue-router';
import '@intlify/core-base';
import 'cookie-es';
import 'is-https';
import 'anu-vue';
import 'vue/server-renderer';
import 'defu';
import '../../nitro/node-server.mjs';
import 'node-fetch-native/polyfill';
import 'node:http';
import 'node:https';
import 'destr';
import 'unenv/runtime/fetch/index';
import 'klona';
import 'ohash';
import 'unstorage/drivers/fs';
import 'unstorage/drivers/overlay';
import 'radix3';
import 'node:fs';
import 'node:url';
import 'pathe';
import '@intlify/bundle-utils';
import 'unified';
import 'mdast-util-to-string';
import 'micromark/lib/preprocess.js';
import 'micromark/lib/postprocess.js';
import 'unist-util-stringify-position';
import 'micromark-util-character';
import 'micromark-util-chunked';
import 'micromark-util-resolve-all';
import 'remark-emoji';
import 'rehype-slug';
import 'remark-squeeze-paragraphs';
import 'rehype-external-links';
import 'remark-gfm';
import 'rehype-sort-attribute-values';
import 'rehype-sort-attributes';
import 'rehype-raw';
import 'remark-mdc';
import 'remark-parse';
import 'remark-rehype';
import 'mdast-util-to-hast';
import 'detab';
import 'unist-builder';
import 'mdurl';
import 'slugify';
import 'unist-util-position';
import 'unist-util-visit';
import 'shiki-es';
import 'unenv/runtime/npm/consola';
import './utils-6d756e03.mjs';
function createMatch(opts = {}) {
const operators = createOperators(match, opts.operators);
function match(item, conditions) {
if (typeof conditions !== "object" || conditions instanceof RegExp) {
return operators.$eq(item, conditions);
}
return Object.keys(conditions || {}).every((key) => {
const condition = conditions[key];
if (key.startsWith("$") && operators[key]) {
const fn = operators[key];
return typeof fn === "function" ? fn(item, condition) : false;
}
return match(get(item, key), condition);
});
}
return match;
}
function createOperators(match, operators = {}) {
return {
$match: (item, condition) => match(item, condition),
/**
* Match if item equals condition
**/
$eq: (item, condition) => condition instanceof RegExp ? condition.test(item) : item === condition,
/**
* Match if item not equals condition
**/
$ne: (item, condition) => condition instanceof RegExp ? !condition.test(item) : item !== condition,
/**
* Match is condition is false
**/
$not: (item, condition) => !match(item, condition),
/**
* Match only if all of nested conditions are true
**/
$and: (item, condition) => {
assertArray(condition, "$and requires an array as condition");
return condition.every((cond) => match(item, cond));
},
/**
* Match if any of nested conditions is true
**/
$or: (item, condition) => {
assertArray(condition, "$or requires an array as condition");
return condition.some((cond) => match(item, cond));
},
/**
* Match if item is in condition array
**/
$in: (item, condition) => ensureArray(condition).some(
(cond) => Array.isArray(item) ? match(item, { $contains: cond }) : match(item, cond)
),
/**
* Match if item contains every condition or math every rule in condition array
**/
$contains: (item, condition) => {
item = Array.isArray(item) ? item : String(item);
return ensureArray(condition).every((i) => item.includes(i));
},
/**
* Ignore case contains
**/
$icontains: (item, condition) => {
if (typeof condition !== "string") {
throw new TypeError("$icontains requires a string, use $contains instead");
}
item = String(item).toLocaleLowerCase();
return ensureArray(condition).every((i) => item.includes(i.toLocaleLowerCase()));
},
/**
* Match if item contains at least one rule from condition array
*/
$containsAny: (item, condition) => {
assertArray(condition, "$containsAny requires an array as condition");
item = Array.isArray(item) ? item : String(item);
return condition.some((i) => item.includes(i));
},
/**
* Check key existence
*/
$exists: (item, condition) => condition ? typeof item !== "undefined" : typeof item === "undefined",
/**
* Match if type of item equals condition
*/
$type: (item, condition) => typeof item === String(condition),
/**
* Provides regular expression capabilities for pattern matching strings.
*/
$regex: (item, condition) => {
if (!(condition instanceof RegExp)) {
const matched = String(condition).match(/\/(.*)\/([dgimsuy]*)$/);
condition = matched ? new RegExp(matched[1], matched[2] || "") : new RegExp(condition);
}
return condition.test(String(item || ""));
},
/**
* Check if item is less than condition
*/
$lt: (item, condition) => {
return item < condition;
},
/**
* Check if item is less than or equal to condition
*/
$lte: (item, condition) => {
return item <= condition;
},
/**
* Check if item is greater than condition
*/
$gt: (item, condition) => {
return item > condition;
},
/**
* Check if item is greater than or equal to condition
*/
$gte: (item, condition) => {
return item >= condition;
},
...operators || {}
};
}
function createPipelineFetcher(getContentsList) {
const match = createMatch();
const surround = (data, { query, before, after }) => {
const matchQuery = typeof query === "string" ? { _path: query } : query;
const index = data.findIndex((item) => match(item, matchQuery));
before = before ?? 1;
after = after ?? 1;
const slice = new Array(before + after).fill(null, 0);
return index === -1 ? slice : slice.map((_, i) => data[index - before + i + Number(i >= before)] || null);
};
const pipelines = [
// Conditions
(data, params) => data.filter((item) => ensureArray(params.where).every((matchQuery) => match(item, matchQuery))),
// Sort data
(data, params) => ensureArray(params.sort).forEach((options) => sortList(data, options)),
// Surround logic
(data, params) => params.surround ? surround(data, params.surround) : data,
// Skip first items
(data, params) => params.skip ? data.slice(params.skip) : data,
// Pick first items
(data, params) => params.limit ? data.slice(0, params.limit) : data,
// Remove unwanted fields
(data, params) => apply(withoutKeys(params.without))(data),
// Select only wanted fields
(data, params) => apply(withKeys(params.only))(data)
];
return async (query) => {
const data = await getContentsList();
const params = query.params();
const filteredData = pipelines.reduce(($data, pipe) => pipe($data, params) || $data, data);
if (params.first) {
return filteredData[0];
}
return filteredData;
};
}
const generateTitle = (path) => path.split(/[\s-]/g).map(pascalCase).join(" ");
function createNav(contents, configs) {
const { navigation } = useRuntimeConfig().public.content;
const pickNavigationFields = (content) => ({
...pick(["title", ...navigation.fields])(content),
...isObject(content == null ? void 0 : content.navigation) ? content.navigation : {}
});
const nav = contents.sort((a, b) => a._path.localeCompare(b._path)).reduce((nav2, content) => {
const parts = content._path.substring(1).split("/");
const idParts = content._id.split(":").slice(1);
const isIndex = !!idParts[idParts.length - 1].match(/([1-9][0-9]*\.)?index.md/g);
const getNavItem = (content2) => ({
title: content2.title,
_path: content2._path,
_file: content2._file,
children: [],
...pickNavigationFields(content2),
...content2._draft ? { _draft: true } : {}
});
const navItem = getNavItem(content);
if (isIndex) {
const dirConfig = configs[navItem._path];
if (typeof (dirConfig == null ? void 0 : dirConfig.navigation) !== "undefined" && !(dirConfig == null ? void 0 : dirConfig.navigation)) {
return nav2;
}
if (content._path !== "/") {
const indexItem = getNavItem(content);
navItem.children.push(indexItem);
}
Object.assign(
navItem,
pickNavigationFields(dirConfig)
);
}
if (parts.length === 1) {
nav2.push(navItem);
return nav2;
}
const siblings = parts.slice(0, -1).reduce((nodes, part, i) => {
const currentPathPart = "/" + parts.slice(0, i + 1).join("/");
const conf = configs[currentPathPart];
if (typeof (conf == null ? void 0 : conf.navigation) !== "undefined" && !conf.navigation) {
return [];
}
let parent = nodes.find((n) => n._path === currentPathPart);
if (!parent) {
parent = {
title: generateTitle(part),
_path: currentPathPart,
_file: content._file,
children: [],
...pickNavigationFields(conf)
};
nodes.push(parent);
}
return parent.children;
}, nav2);
siblings.push(navItem);
return nav2;
}, []);
return sortAndClear(nav);
}
const collator = new Intl.Collator(void 0, { numeric: true, sensitivity: "base" });
function sortAndClear(nav) {
var _a;
const sorted = nav.sort((a, b) => collator.compare(a._file, b._file));
for (const item of sorted) {
if ((_a = item.children) == null ? void 0 : _a.length) {
sortAndClear(item.children);
} else {
delete item.children;
}
delete item._file;
}
return nav;
}
function pick(keys) {
return (obj) => {
obj = obj || {};
if (keys && keys.length) {
return keys.filter((key) => typeof obj[key] !== "undefined").reduce((newObj, key) => Object.assign(newObj, { [key]: obj[key] }), {});
}
return obj;
};
}
function isObject(obj) {
return Object.prototype.toString.call(obj) === "[object Object]";
}
const withContentBase = (url) => withBase(url, useRuntimeConfig().public.content.api.baseURL);
const contentStorage = prefixStorage(createStorage({ driver: memory() }), "@content");
function createDB(storage) {
async function getItems() {
const keys = new Set(await storage.getKeys("cache:"));
const previewToken = useContentPreview().getPreviewToken();
if (previewToken) {
const previewMeta = await storage.getItem(`${previewToken}$`).then((data) => data || {});
if (Array.isArray(previewMeta.ignoreSources)) {
const sources = previewMeta.ignoreSources.map((s) => `cache:${s.trim()}:`);
for (const key of keys) {
if (sources.some((s) => key.startsWith(s))) {
keys.delete(key);
}
}
}
const previewKeys = await storage.getKeys(`${previewToken}:`);
const previewContents = await Promise.all(previewKeys.map((key) => storage.getItem(key)));
for (const pItem of previewContents) {
keys.delete(`cache:${pItem._id}`);
if (!pItem.__deleted) {
keys.add(`${previewToken}:${pItem._id}`);
}
}
}
const items = await Promise.all(Array.from(keys).map((key) => storage.getItem(key)));
return items;
}
return {
storage,
fetch: createPipelineFetcher(getItems),
query: (query) => createQuery(createPipelineFetcher(getItems), query)
};
}
let contentDatabase = null;
let contentDatabaseInitPromise = null;
async function useContentDatabase() {
if (contentDatabaseInitPromise) {
await contentDatabaseInitPromise;
} else if (!contentDatabase) {
contentDatabaseInitPromise = initContentDatabase();
contentDatabase = await contentDatabaseInitPromise;
}
return contentDatabase;
}
async function initContentDatabase() {
const nuxtApp = useNuxtApp();
const { content } = useRuntimeConfig().public;
const _contentDatabase = createDB(contentStorage);
const integrity = await _contentDatabase.storage.getItem("integrity");
if (content.integrity !== +(integrity || 0)) {
const { contents, navigation } = await $fetch(withContentBase(content.integrity ? `cache.${content.integrity}.json` : "cache.json"));
await Promise.all(
contents.map((content2) => _contentDatabase.storage.setItem(`cache:${content2._id}`, content2))
);
await _contentDatabase.storage.setItem("navigation", navigation);
await _contentDatabase.storage.setItem("integrity", content.integrity);
}
await nuxtApp.callHook("content:storage", _contentDatabase.storage);
return _contentDatabase;
}
async function generateNavigation(query) {
const db = await useContentDatabase();
if (!useContentPreview().getPreviewToken() && Object.keys(query || {}).length === 0) {
return db.storage.getItem("navigation");
}
const contents = await db.query(query).where({
/**
* Partial contents are not included in the navigation
* A partial content is a content that has `_` prefix in its path
*/
_partial: false,
/**
* Exclude any pages which have opted out of navigation via frontmatter.
*/
navigation: {
$ne: false
}
}).find();
const dirConfigs = await db.query().where({ _path: /\/_dir$/i, _partial: true }).find();
const configs = dirConfigs.reduce((configs2, conf) => {
var _a;
if (((_a = conf.title) == null ? void 0 : _a.toLowerCase()) === "dir") {
conf.title = void 0;
}
const key = conf._path.split("/").slice(0, -1).join("/") || "/";
configs2[key] = {
...conf,
// Extract meta from body. (non MD files)
...conf.body
};
return configs2;
}, {});
return createNav(contents, configs);
}
export { contentStorage, createDB, generateNavigation, useContentDatabase };
//# sourceMappingURL=client-db-d3e6e918.mjs.map