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 "visibility",37];38
39function attrToXattrName(attr: string): string {40 // camelCase → kebab-case: contentHash → content-hash41 const kebab = attr.replace(/[A-Z]/g, (c) => "-" + c.toLowerCase());42 return `${XATTR_PREFIX}${kebab}${XATTR_SUFFIX}`;43}44
45function readXattr(path: string, xattrName: string): Promise<string | null> {46 return new Promise((resolve) => {47 exec(48 `xattr -p ${JSON.stringify(xattrName)} ${JSON.stringify(path)}`,49 { timeout: 2000 },50 (err, stdout) => {51 if (err) {52 resolve(null);53 return;54 }55 resolve(stdout.trim() || null);56 }57 );58 });59}60
61export async function readFileMetadata(62 path: string63): Promise<FileMetadata | null> {64 if (!Platform.isMacOS) return null;65
66 const results = await Promise.all(67 ATTRS.map((attr) => readXattr(path, attrToXattrName(attr)))68 );69
70 // If no xattrs found at all, this isn't a sublimated file71 if (results.every((r) => r === null)) return null;72
73 const meta: FileMetadata = {74 version: null, commit: null, url: null, contentHash: null,75 id: null, createdBy: null, modifiedBy: null, modifiedByType: null,76 syncStatus: null, space: null, branch: null, modifiedAt: null,77 };78 ATTRS.forEach((attr, i) => {79 meta[attr] = results[i];80 });81 return meta;82}83
84export function isMacOS(): boolean {85 return Platform.isMacOS;86} v3 of v4
commit 4425759
message edit xattr.ts via macOS
author anton
date Apr 8, 2026
size 2.0 KB