11import type { FrontMatterCache , TFile } from "obsidian" ;
22import type { default as DiscourseGraphPlugin } from "~/index" ;
33import { getLoggedInClient , getSupabaseContext } from "./supabaseContext" ;
4+ import { addFile } from "@repo/database/lib/files" ;
5+ import mime from "mime-types" ;
46
57export const publishNode = async ( {
68 plugin,
@@ -26,21 +28,88 @@ export const publishNode = async ({
2628 if ( ! myGroup ) throw new Error ( "Cannot get group" ) ;
2729 const existingPublish =
2830 ( frontmatter . publishedToGroups as undefined | string [ ] ) || [ ] ;
29- if ( existingPublish . includes ( myGroup ) ) return ; // already published
30- const publishResponse = await client . from ( "ResourceAccess" ) . insert ( {
31- /* eslint-disable @typescript-eslint/naming-convention */
32- account_uid : myGroup ,
33- source_local_id : nodeId ,
34- space_id : spaceId ,
35- /* eslint-enable @typescript-eslint/naming-convention */
36- } ) ;
31+ const idResponse = await client
32+ . from ( "Content" )
33+ . select ( "last_modified" )
34+ . eq ( "source_local_id" , nodeId )
35+ . eq ( "space_id" , spaceId )
36+ . eq ( "variant" , "full" )
37+ . maybeSingle ( ) ;
38+ if ( idResponse . error || ! idResponse . data ) {
39+ throw idResponse . error || new Error ( "no data while fetching node" ) ;
40+ }
41+ const lastModifiedDb = new Date (
42+ idResponse . data . last_modified + "Z" ,
43+ ) . getTime ( ) ;
44+ const embeds = plugin . app . metadataCache . getFileCache ( file ) ?. embeds ?? [ ] ;
45+ const attachments = embeds
46+ . map ( ( { link } ) => {
47+ const attachment = plugin . app . metadataCache . getFirstLinkpathDest (
48+ link ,
49+ file . path ,
50+ ) ;
51+ if ( attachment === null ) {
52+ console . warn ( "Could not find file for " + link ) ;
53+ }
54+ return attachment ;
55+ } )
56+ . filter ( ( a ) => ! ! a ) ;
57+ const lastModified = Math . max (
58+ file . stat . mtime ,
59+ ...attachments . map ( ( a ) => a . stat . mtime ) ,
60+ ) ;
61+
62+ if ( existingPublish . includes ( myGroup ) && lastModified <= lastModifiedDb )
63+ return ; // already published
64+ const publishResponse = await client . from ( "ResourceAccess" ) . upsert (
65+ {
66+ /* eslint-disable @typescript-eslint/naming-convention */
67+ account_uid : myGroup ,
68+ source_local_id : nodeId ,
69+ space_id : spaceId ,
70+ /* eslint-enable @typescript-eslint/naming-convention */
71+ } ,
72+ { ignoreDuplicates : true } ,
73+ ) ;
3774 if ( publishResponse . error && publishResponse . error . code !== "23505" )
3875 // 23505 is duplicate key, which counts as a success.
3976 throw publishResponse . error ;
40- await plugin . app . fileManager . processFrontMatter (
41- file ,
42- ( fm : Record < string , unknown > ) => {
43- fm . publishedToGroups = [ ...existingPublish , myGroup ] ;
44- } ,
45- ) ;
77+
78+ const existingFiles : string [ ] = [ ] ;
79+ for ( const attachment of attachments ) {
80+ const mimetype = mime . lookup ( attachment . path ) || "application/octet-stream" ;
81+ if ( mimetype . startsWith ( "text/" ) ) continue ;
82+ existingFiles . push ( attachment . path ) ;
83+ const content = await plugin . app . vault . readBinary ( attachment ) ;
84+ await addFile ( {
85+ client,
86+ spaceId,
87+ sourceLocalId : nodeId ,
88+ fname : attachment . path ,
89+ mimetype,
90+ created : new Date ( attachment . stat . ctime ) ,
91+ lastModified : new Date ( attachment . stat . mtime ) ,
92+ content,
93+ } ) ;
94+ }
95+ let cleanupCommand = client
96+ . from ( "FileReference" )
97+ . delete ( )
98+ . eq ( "space_id" , spaceId )
99+ . eq ( "source_local_id" , nodeId ) ;
100+ if ( existingFiles . length )
101+ cleanupCommand = cleanupCommand . notIn ( "filepath" , [
102+ ...new Set ( existingFiles ) ,
103+ ] ) ;
104+ const cleanupResult = await cleanupCommand ;
105+ // do not fail on cleanup
106+ if ( cleanupResult . error ) console . error ( cleanupResult . error ) ;
107+
108+ if ( ! existingPublish . includes ( myGroup ) )
109+ await plugin . app . fileManager . processFrontMatter (
110+ file ,
111+ ( fm : Record < string , unknown > ) => {
112+ fm . publishedToGroups = [ ...existingPublish , myGroup ] ;
113+ } ,
114+ ) ;
46115} ;
0 commit comments