feat: harden orchestrator execution runtime

This commit is contained in:
john
2026-07-24 23:53:32 +08:00
parent 396bb78200
commit f6f2cd0933
55 changed files with 5122 additions and 194 deletions
+11 -1
View File
@@ -41,6 +41,9 @@ export function detectPageDataDatasetUsageFromHtml(html) {
for (const match of text.matchAll(/\.listRows\(\s*['"]([^'"]+)['"]/g)) {
remember(match[1], { read: true });
}
for (const match of text.matchAll(/\.updateRow\(\s*['"]([^'"]+)['"]/g)) {
remember(match[1], { update: true });
}
for (const match of text.matchAll(/\.deleteRow\(\s*['"]([^'"]+)['"]/g)) {
// The browser client's deleteRow endpoint intentionally falls back to a
// soft delete unless a policy explicitly grants hard_delete. A page using
@@ -57,6 +60,9 @@ export function detectPageDataDatasetUsageFromHtml(html) {
for (const match of text.matchAll(/\.listRows\(\s*(?!\$\{)([A-Za-z_$][\w$]*)/g)) {
remember(constants.get(match[1]) ?? match[1], { read: true });
}
for (const match of text.matchAll(/\.updateRow\(\s*(?!\$\{)([A-Za-z_$][\w$]*)/g)) {
remember(constants.get(match[1]) ?? match[1], { update: true });
}
for (const match of text.matchAll(/\.deleteRow\(\s*(?!\$\{)([A-Za-z_$][\w$]*)/g)) {
remember(constants.get(match[1]) ?? match[1], { softDelete: true });
}
@@ -91,7 +97,7 @@ export function assertPolicyMatchesHtmlDatasets(html, policyDatasets) {
if (htmlNames.join(',') !== policyNames.join(',')) {
throw Object.assign(
new Error(
`Page Data 策略 dataset${policyNames.join(', ') || '无'})与 HTML 中 insertRow/listRows 引用的 dataset${htmlNames.join(', ')})不一致。请使用与页面脚本相同的 dataset 名称。`,
`Page Data 策略 dataset${policyNames.join(', ') || '无'})与 HTML 中 insertRow/listRows/updateRow/deleteRow 引用的 dataset${htmlNames.join(', ')})不一致。请使用与页面脚本相同的 dataset 名称。`,
),
{
code: 'dataset_policy_html_mismatch',
@@ -148,6 +154,10 @@ export function buildPageDataPolicyDatasetsFromRegistry({ html, registryDatasets
entry.softDelete = true;
entry.columns.soft_delete = registered.columns?.soft_delete ?? ['id'];
}
if (perms.update) {
entry.update = true;
entry.columns.update = registered.columns?.update ?? [];
}
datasets[name] = entry;
}