1import { exec } from "child_process";2import { Platform } from "obsidian";3
4const XATTR_PREFIX = "com.sublimated.";5const XATTR_SUFFIX = "#PS";6
7export interface FileMetadata {8 version: string | null;9 commit: string | null;10 url: string | null;11 contentHash: string | null;12 id: string | null;13 createdBy: string | null;14 modifiedBy: string | null;15 modifiedByType: string | null;16 syncStatus: string | null;17 space: string | null;18 branch: string | null;19 modifiedAt: string | null;20 visibility: string | null;21}22
23const ATTRS: (keyof FileMetadata)[] = [24 "version",25 "commit",26 "url",27 "contentHash",28 "id",29 "createdBy",30 "modifiedBy",31 "modifiedByType",32 "syncStatus",33 "space",34 "branch",35 "modifiedAt",36];37
38function attrToXattrName(attr: string): string {39 // camelCase → kebab-case: contentHash → content-hash40 const kebab = attr.replace(/[A-Z]/g, (c) => "-" + c.toLowerCase());41 return `${XATTR_PREFIX}${kebab}${XATTR_SUFFIX}`;42}43
44function readXattr(path: string, xattrName: string): Promise<string | null> {45 return new Promise((resolve) => {46 exec(47 `xattr -p ${JSON.stringify(xattrName)} ${JSON.stringify(path)}`,48 { timeout: 2000 },49 (err, stdout) => {50 if (err) {51 resolve(null);52 return;53 }54 resolve(stdout.trim() || null);55 }56 );57 });58}59
60export async function readFileMetadata(61 path: string62): Promise<FileMetadata | null> {63 if (!Platform.isMacOS) return null;64
65 const results = await Promise.all(66 ATTRS.map((attr) => readXattr(path, attrToXattrName(attr)))67 );68
69 // If no xattrs found at all, this isn't a sublimated file70 if (results.every((r) => r === null)) return null;71
72 const meta: FileMetadata = {73 version: null, commit: null, url: null, contentHash: null,74 id: null, createdBy: null, modifiedBy: null, modifiedByType: null,75 syncStatus: null, space: null, branch: null, modifiedAt: null,76 };77 ATTRS.forEach((attr, i) => {78 meta[attr] = results[i];79 });80 return meta;81}82
83export function isMacOS(): boolean {84 return Platform.isMacOS;85} v2 of v4
commit 0286ebe
message edit xattr.ts via macOS (conflict)
author anton
date Apr 8, 2026
size 2.0 KB