/**
* Autobase Operation Types for Linked Repos
*
* Defines operation constants, JSON encode/decode, and validation
* for all Autobase-managed collaborative metadata.
*
* Operations are appended to Autobase writer cores and processed
* by the deterministic apply function to build the Hyperbee view.
*/
// Writer management
export const OP_ADD_WRITER = 'add-writer'
export const OP_REMOVE_WRITER = 'remove-writer'
// Git refs (appended after successful push)
export const OP_UPDATE_REF = 'update-ref'
export const OP_DELETE_REF = 'delete-ref'
// Issues
export const OP_CREATE_ISSUE = 'create-issue'
export const OP_UPDATE_ISSUE = 'update-issue'
export const OP_CREATE_COMMENT = 'create-comment'
// Labels
export const OP_CREATE_LABEL = 'create-label'
export const OP_UPDATE_LABEL = 'update-label'
export const OP_DELETE_LABEL = 'delete-label'
// Config
export const OP_SET_META = 'set-meta'
/**
* Encode an operation to a Buffer for Autobase append
*/
export function encodeOp (op) {
return Buffer.from(JSON.stringify(op))
}
/**
* Decode a Buffer back to an operation object
*/
export function decodeOp (buf) {
return JSON.parse(buf.toString())
}
/**
* Validate an operation has required fields for its type
* @returns {{ valid: boolean, error?: string }}
*/
export function validateOp (op) {
if (!op || !op.type) {
return { valid: false, error: 'Missing operation type' }
}
switch (op.type) {
case OP_ADD_WRITER:
if (!op.userId) return { valid: false, error: 'add-writer requires userId' }
if (!op.serverKey) return { valid: false, error: 'add-writer requires serverKey' }
if (!op.role || !['owner', 'writer', 'mirror'].includes(op.role)) {
return { valid: false, error: 'add-writer requires role (owner|writer|mirror)' }
}
break
case OP_REMOVE_WRITER:
if (!op.userId) return { valid: false, error: 'remove-writer requires userId' }
break
case OP_UPDATE_REF:
if (!op.ref) return { valid: false, error: 'update-ref requires ref' }
if (!op.hash) return { valid: false, error: 'update-ref requires hash' }
if (!op.userId) return { valid: false, error: 'update-ref requires userId' }
break
case OP_DELETE_REF:
if (!op.ref) return { valid: false, error: 'delete-ref requires ref' }
if (!op.userId) return { valid: false, error: 'delete-ref requires userId' }
break
case OP_CREATE_ISSUE:
if (!op.id) return { valid: false, error: 'create-issue requires id' }
if (!op.title) return { valid: false, error: 'create-issue requires title' }
if (!op.userId) return { valid: false, error: 'create-issue requires userId' }
break
case OP_UPDATE_ISSUE:
if (!op.id) return { valid: false, error: 'update-issue requires id' }
if (!op.userId) return { valid: false, error: 'update-issue requires userId' }
break
case OP_CREATE_COMMENT:
if (!op.issueId) return { valid: false, error: 'create-comment requires issueId' }
if (!op.commentId) return { valid: false, error: 'create-comment requires commentId' }
if (!op.body) return { valid: false, error: 'create-comment requires body' }
if (!op.userId) return { valid: false, error: 'create-comment requires userId' }
break
case OP_CREATE_LABEL:
if (!op.name) return { valid: false, error: 'create-label requires name' }
break
case OP_UPDATE_LABEL:
if (!op.name) return { valid: false, error: 'update-label requires name' }
break
case OP_DELETE_LABEL:
if (!op.name) return { valid: false, error: 'delete-label requires name' }
break
case OP_SET_META:
if (!op.key) return { valid: false, error: 'set-meta requires key' }
break
default:
return { valid: false, error: `Unknown operation type: ${op.type}` }
}
return { valid: true }
}