ci: auto build & obfuscate [2026-04-19 03:01:12] (Jenkins #16)

This commit is contained in:
Jenkins CI
2026-04-19 03:01:12 +08:00
parent 58ff3c3faf
commit 8d590073f4
28 changed files with 761 additions and 384 deletions

View File

@@ -0,0 +1,291 @@
import { extension_settings } from "/scripts/extensions.js";
import { saveSettingsDebounced } from "/script.js";
import { extensionName } from "../settings.js";
const RULE_PROFILE_KEY = 'ruleProfiles';
const RULE_ASSIGNMENTS_KEY = 'ruleProfileAssignments';
// ── 功能槽定义 ──────────────────────────────────────────────────────────────────
export const RULE_SLOTS = {
table: { label: '表格提取规则' },
historiography: { label: '史官/总结提取规则' },
condensation: { label: '翰林院·浓缩规则' },
queryPreprocessing:{ label: '翰林院·查询预处理规则' },
};
function sanitizeRuleProfile(profile = {}) {
const exclusionRules = Array.isArray(profile.exclusionRules)
? profile.exclusionRules
.map(rule => ({
start: String(rule?.start ?? '').trim(),
end: String(rule?.end ?? '').trim(),
}))
.filter(rule => rule.start)
: [];
return {
id: String(profile.id ?? '').trim(),
name: String(profile.name ?? '').trim(),
tagExtractionEnabled: Boolean(profile.tagExtractionEnabled),
tags: String(profile.tags ?? ''),
exclusionRules,
};
}
function cloneRuleProfile(profile = {}) {
return {
id: profile.id || '',
name: profile.name || '',
tagExtractionEnabled: Boolean(profile.tagExtractionEnabled),
tags: profile.tags || '',
exclusionRules: Array.isArray(profile.exclusionRules)
? profile.exclusionRules.map(rule => ({
start: rule.start || '',
end: rule.end || '',
}))
: [],
};
}
function createRuleProfileId(name = 'rule-profile') {
const base = String(name || 'rule-profile')
.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.replace(/^-+|-+$/g, '') || 'rule-profile';
return `${base}-${Date.now().toString(36)}`;
}
function ensureSettingsRoot() {
if (!extension_settings[extensionName]) {
extension_settings[extensionName] = {};
}
return extension_settings[extensionName];
}
function ensureProfileMap() {
const settings = ensureSettingsRoot();
if (!settings[RULE_PROFILE_KEY] || typeof settings[RULE_PROFILE_KEY] !== 'object' || Array.isArray(settings[RULE_PROFILE_KEY])) {
settings[RULE_PROFILE_KEY] = {};
}
return settings[RULE_PROFILE_KEY];
}
function ensureAssignments() {
const settings = ensureSettingsRoot();
if (!settings[RULE_ASSIGNMENTS_KEY] || typeof settings[RULE_ASSIGNMENTS_KEY] !== 'object' || Array.isArray(settings[RULE_ASSIGNMENTS_KEY])) {
settings[RULE_ASSIGNMENTS_KEY] = {};
}
return settings[RULE_ASSIGNMENTS_KEY];
}
function mergeRuleConfig(profile, fallback = {}) {
const safeFallback = sanitizeRuleProfile({
id: fallback.id,
name: fallback.name,
tagExtractionEnabled: fallback.tagExtractionEnabled,
tags: fallback.tags,
exclusionRules: fallback.exclusionRules,
});
if (!profile) {
return safeFallback;
}
return {
id: profile.id,
name: profile.name,
tagExtractionEnabled: profile.tagExtractionEnabled,
tags: profile.tags,
exclusionRules: cloneRuleProfile(profile).exclusionRules.length > 0
? cloneRuleProfile(profile).exclusionRules
: safeFallback.exclusionRules,
};
}
export class RuleProfileManager {
listProfiles() {
const profiles = Object.values(ensureProfileMap())
.map(profile => cloneRuleProfile(profile))
.sort((left, right) => {
const leftName = left.name || left.id;
const rightName = right.name || right.id;
return leftName.localeCompare(rightName, 'zh-Hans-CN');
});
return profiles;
}
getProfile(id) {
if (!id) return null;
const profile = ensureProfileMap()[id];
return profile ? cloneRuleProfile(profile) : null;
}
saveProfile(profile) {
const normalized = sanitizeRuleProfile(profile);
const profileId = normalized.id || createRuleProfileId(normalized.name);
const nextProfile = {
...normalized,
id: profileId,
name: normalized.name || profileId,
};
ensureProfileMap()[profileId] = nextProfile;
saveSettingsDebounced();
return cloneRuleProfile(nextProfile);
}
deleteProfile(id) {
if (!id) return false;
const profiles = ensureProfileMap();
if (!profiles[id]) return false;
delete profiles[id];
saveSettingsDebounced();
return true;
}
resolveProfile(id, fallback = {}) {
return mergeRuleConfig(this.getProfile(id), fallback);
}
// ── 功能槽分配 ──────────────────────────────────────────────────────────────
getAssignment(slot) {
if (!RULE_SLOTS[slot]) return null;
return ensureAssignments()[slot] || null;
}
setAssignment(slot, profileId) {
if (!RULE_SLOTS[slot]) return false;
const assignments = ensureAssignments();
if (profileId) {
assignments[slot] = profileId;
} else {
delete assignments[slot];
}
saveSettingsDebounced();
return true;
}
getAssignedProfile(slot) {
const id = this.getAssignment(slot);
if (!id) return null;
const profile = ensureProfileMap()[id];
return profile ? cloneRuleProfile(profile) : null;
}
}
export const ruleProfileManager = new RuleProfileManager();
export function resolveRuleConfig(ruleProfileId, fallback = {}) {
return ruleProfileManager.resolveProfile(ruleProfileId, fallback);
}
/**
* 通过功能槽名解析规则配置(推荐方式)
* 先查 assignments再回退到旧字段
*/
export function resolveSlotRuleConfig(slot, legacyFallback = {}) {
const assignedId = ruleProfileManager.getAssignment(slot);
if (assignedId) {
const profile = ruleProfileManager.getProfile(assignedId);
if (profile) return profile;
}
// 回退到旧的 resolve 路径
return sanitizeRuleProfile(legacyFallback);
}
export function resolveCondensationRuleConfig(settings = {}) {
const condensation = settings.condensation || {};
return resolveSlotRuleConfig('condensation', {
...condensation,
ruleProfileId: condensation.ruleProfileId,
});
}
export function resolveQueryPreprocessingRuleConfig(settings = {}) {
const queryPreprocessing = settings.queryPreprocessing || {};
return resolveSlotRuleConfig('queryPreprocessing', {
...queryPreprocessing,
ruleProfileId: queryPreprocessing.ruleProfileId,
});
}
export function resolveTableRuleConfig(settings = {}) {
return resolveSlotRuleConfig('table', {
id: settings.table_rule_profile_id,
tagExtractionEnabled: Boolean(settings.table_tags_to_extract),
tags: settings.table_tags_to_extract || '',
exclusionRules: settings.table_exclusion_rules || [],
});
}
export function resolveHistoriographyRuleConfig(settings = {}) {
return resolveSlotRuleConfig('historiography', {
id: settings.historiographyRuleProfileId,
tagExtractionEnabled: settings.historiographyTagExtractionEnabled ?? false,
tags: settings.historiographyTags || '',
exclusionRules: settings.historiographyExclusionRules || [],
});
}
// ── 一次性迁移:旧分散 profileId 字段 → 统一 assignments ─────────────────────
;(() => {
const settings = ensureSettingsRoot();
const assignments = ensureAssignments();
let changed = false;
// table: table_rule_profile_id → assignments.table
if (settings.table_rule_profile_id && !assignments.table) {
assignments.table = settings.table_rule_profile_id;
changed = true;
}
// historiography: historiographyRuleProfileId → assignments.historiography
if (settings.historiographyRuleProfileId && !assignments.historiography) {
assignments.historiography = settings.historiographyRuleProfileId;
changed = true;
}
// condensation: condensation.ruleProfileId → assignments.condensation
const condensation = settings.condensation || {};
if (condensation.ruleProfileId && !assignments.condensation) {
assignments.condensation = condensation.ruleProfileId;
changed = true;
}
// queryPreprocessing: queryPreprocessing.ruleProfileId → assignments.queryPreprocessing
const queryPreprocessing = settings.queryPreprocessing || {};
if (queryPreprocessing.ruleProfileId && !assignments.queryPreprocessing) {
assignments.queryPreprocessing = queryPreprocessing.ruleProfileId;
changed = true;
}
if (changed) {
saveSettingsDebounced();
console.log('[RuleProfiles] 已迁移旧规则配置分配到统一 assignments。', assignments);
}
})();
setTimeout(() => {
try {
const ctx = window.Amily2Bus?.register('RuleProfiles');
if (!ctx) {
console.warn('[RuleProfiles] Amily2Bus 尚未就绪,注册跳过。');
return;
}
ctx.expose({
listProfiles: () => ruleProfileManager.listProfiles(),
getProfile: (id) => ruleProfileManager.getProfile(id),
saveProfile: (profile) => ruleProfileManager.saveProfile(profile),
deleteProfile: (id) => ruleProfileManager.deleteProfile(id),
resolveProfile: (id, fallback) => ruleProfileManager.resolveProfile(id, fallback),
getAssignment: (slot) => ruleProfileManager.getAssignment(slot),
setAssignment: (slot, id) => ruleProfileManager.setAssignment(slot, id),
getAssignedProfile: (slot) => ruleProfileManager.getAssignedProfile(slot),
RULE_SLOTS,
});
ctx.log('RuleProfiles', 'info', 'RuleProfiles 服务已注册到 Bus。');
} catch (error) {
console.error('[RuleProfiles] Bus 注册失败:', error);
}
}, 0);