lib/project-logs-access-scope.js
Rama main · réplica de lectura del repositorio original.
// Authorization and record scoping for a Project Logs binding. Worktree-only
// principals share storage with the parent but never inherit its ledger view.
function attachProjectLogsAccessScope(ctx) {
var projectFor = ctx.projectFor;
var isMultiUser = ctx.isMultiUser;
var canAccessProject = ctx.canAccessProject;
var hasFullProjectAccess = ctx.hasFullProjectAccess;
var openStore = ctx.openStore;
function effectiveStatus(status) {
if (!status || status.isWorktree !== true || !status.parentSlug) return status;
var parent = projectFor(status.parentSlug);
if (!parent) return status;
return parent.getStatus() || status;
}
function ownsProject(principal, status) {
if (!status) return false;
if (isMultiUser()) return !!principal.userId && status.projectOwnerId === principal.userId;
return !status.projectOwnerId || (!!principal.singleUserOwnerId && status.projectOwnerId === principal.singleUserOwnerId);
}
function projectAuthorization(principal, status) {
var denied = { allowed: false, worktreeOnly: false };
if (!status || status.isMate === true) return denied;
var governing = effectiveStatus(status);
if (ownsProject(principal, governing)) return { allowed: true, worktreeOnly: false };
if (!isMultiUser() || !principal.userId || typeof canAccessProject !== "function") return denied;
if (canAccessProject(principal.userId, status) !== true) return denied;
var full = status.isWorktree !== true;
if (!full && typeof hasFullProjectAccess === "function") {
full = hasFullProjectAccess(principal.userId, status) === true;
}
return { allowed: true, worktreeOnly: !full };
}
function authorizedProject(principal, status) {
return projectAuthorization(principal, status).allowed === true;
}
function storeForStatus(status) {
var governing = effectiveStatus(status);
if (!governing || !governing.path) throw new Error("Project Logs are unavailable for this project.");
return openStore(governing.path, { projectKnowledgeId: governing.projectKnowledgeId || null });
}
function recordContext(status) {
if (!status || status.isWorktree !== true || !status.changeSetId) return null;
return {
kind: "worktree",
changeSetId: status.changeSetId,
branch: status.branch || null,
baseCommit: status.baseCommit || null,
headCommit: status.headCommit || null,
status: "active",
};
}
function scopedArgs(args, status, worktreeOnly) {
var out = Object.assign({}, args || {});
if (worktreeOnly) {
out.contextMode = "current";
out.exactChangeSet = true;
} else if (!out.contextMode) {
out.contextMode = status && status.isWorktree ? "current" : "project";
}
out.currentChangeSetId = status && status.changeSetId || null;
return out;
}
function visibleEntry(store, ref, status, worktreeOnly) {
var entry = store.read(ref, false);
if (!entry) throw new Error("Log entry not found.");
if (worktreeOnly) {
var changeSetId = entry.context && entry.context.changeSetId;
if (!changeSetId || changeSetId !== status.changeSetId) throw new Error("Log entry not found.");
}
return entry;
}
return {
effectiveStatus: effectiveStatus,
ownsProject: ownsProject,
projectAuthorization: projectAuthorization,
authorizedProject: authorizedProject,
storeForStatus: storeForStatus,
recordContext: recordContext,
scopedArgs: scopedArgs,
visibleEntry: visibleEntry,
};
}
module.exports = { attachProjectLogsAccessScope: attachProjectLogsAccessScope };