Files
memind/page-data-html-detect.mjs
T

90 lines
2.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 从 MindSpace 公开 HTML 中解析 Page Data API 引用的 dataset 与读写意图。
*/
export function detectPageDataDatasetUsageFromHtml(html) {
const text = String(html ?? '');
const datasets = new Map();
for (const match of text.matchAll(/\.insertRow\(\s*['"]([^'"]+)['"]/g)) {
const name = match[1];
const prev = datasets.get(name) ?? {};
datasets.set(name, { ...prev, insert: true });
}
for (const match of text.matchAll(/\.listRows\(\s*['"]([^'"]+)['"]/g)) {
const name = match[1];
const prev = datasets.get(name) ?? {};
datasets.set(name, { ...prev, read: true });
}
return datasets;
}
export function assertPolicyMatchesHtmlDatasets(html, policyDatasets) {
const usage = detectPageDataDatasetUsageFromHtml(html);
const htmlNames = [...usage.keys()].sort();
const policyNames = Object.keys(policyDatasets ?? {}).sort();
if (!htmlNames.length) return usage;
if (htmlNames.join(',') !== policyNames.join(',')) {
throw Object.assign(
new Error(
`Page Data 策略 dataset${policyNames.join(', ') || '无'})与 HTML 中 insertRow/listRows 引用的 dataset${htmlNames.join(', ')})不一致。请使用与页面脚本相同的 dataset 名称。`,
),
{
code: 'dataset_policy_html_mismatch',
htmlDatasets: htmlNames,
policyDatasets: policyNames,
},
);
}
return usage;
}
export function buildPageDataPolicyDatasetsFromRegistry({ html, registryDatasets, usage }) {
const detected = usage ?? detectPageDataDatasetUsageFromHtml(html);
if (!detected.size) return null;
const registryMap = new Map(registryDatasets.map((dataset) => [dataset.name, dataset]));
const datasets = {};
for (const [name, perms] of detected) {
const registered = registryMap.get(name);
if (!registered) {
throw Object.assign(
new Error(`HTML 引用的 dataset「${name}」尚未注册,请先执行 private_data_register_dataset`),
{ code: 'dataset_not_registered', datasetName: name },
);
}
const entry = {
insert: false,
read: false,
update: false,
softDelete: false,
hardDelete: false,
columns: {},
};
if (perms.insert && !perms.read) {
entry.insert = true;
entry.columns.insert = registered.columns?.insert ?? [];
} else if (perms.read && !perms.insert) {
entry.read = true;
entry.columns.read = registered.columns?.read ?? [];
} else {
if (perms.insert) {
entry.insert = true;
entry.columns.insert = registered.columns?.insert ?? [];
}
if (perms.read) {
entry.read = true;
entry.columns.read = registered.columns?.read ?? [];
}
}
datasets[name] = entry;
}
return datasets;
}