T-HUB/packages/publishing-execution/src/approval.ts
glass beadian aa5e262f3a Tactical Media Broadcast Hub — initial release
Self-hosted multi-platform broadcast newsroom for activist collectives:
publishing pipeline with group approval and DST-proof scheduling, TweetDeck-style
column wall with hostile-content-safe rendering, live control room with Auto
Director, bridged chat governance with polls and quorum, distributed sandboxed
transcode workers, encrypted content-addressed archive, monthly analytics.

MIT licensed. See README.md and docs/.
2026-10-10 11:56:42 +00:00

13 lines
785 B
TypeScript

import { createHash } from "node:crypto";
function canonical(value: unknown): unknown {
if (Array.isArray(value)) return value.map(canonical);
if (value !== null && typeof value === "object") return Object.fromEntries(Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, item]) => [key, canonical(item)]));
return value;
}
/** The target lives in providerMetadata.connectionId; execution keys are excluded. */
export function canonicalPostHash<T extends { providerMetadata: Record<string, unknown> }>(post: T): string {
const metadata = { ...post.providerMetadata };
delete metadata.idempotencyKey;
delete metadata.draftId;
return createHash("sha256").update(JSON.stringify(canonical({ ...post, providerMetadata: metadata }))).digest("hex");
}