@@ -73,10 +73,45 @@ export const handler = documentEventHandler<ContentDocument>(
7373 ? `https://codingcat.dev/${ data . _type } /${ slug } `
7474 : `https://dev.codingcat.dev/${ data . _type } /${ slug } ` ;
7575
76- const imgBuilder = createImageUrlBuilder ( { projectId, dataset } ) ;
76+ const DEFAULT_MEDIA_LIBRARY_ID =
77+ process . env . SANITY_MEDIA_LIBRARY_ID ||
78+ process . env . PUBLIC_SANITY_MEDIA_LIBRARY_ID ||
79+ "mlttp0BZbCpV" ;
80+ const datasetImgBuilder = createImageUrlBuilder ( { projectId, dataset } ) ;
81+ const mediaLibraryBuilders = new Map <
82+ string ,
83+ ReturnType < typeof createImageUrlBuilder >
84+ > ( ) ;
85+ const getMediaLibraryBuilder = ( libraryId : string ) => {
86+ let b = mediaLibraryBuilders . get ( libraryId ) ;
87+ if ( ! b ) {
88+ b = createImageUrlBuilder ( {
89+ mediaLibraryId : libraryId ,
90+ } as unknown as { projectId : string ; dataset : string } ) ;
91+ mediaLibraryBuilders . set ( libraryId , b ) ;
92+ }
93+ return b ;
94+ } ;
95+ const extractMediaLibraryId = ( source : any ) : string | undefined => {
96+ if ( ! source || typeof source !== "object" ) return undefined ;
97+ const mediaRef = source ?. media ?. _ref ;
98+ if (
99+ typeof mediaRef === "string" &&
100+ mediaRef . startsWith ( "media-library:" )
101+ ) {
102+ const [ , libraryId ] = mediaRef . split ( ":" ) ;
103+ if ( libraryId ) return libraryId ;
104+ }
105+ return undefined ;
106+ } ;
77107 const urlForImage = ( source : any ) => {
78108 if ( ! source || ! source . asset ) return undefined ;
79- return imgBuilder . image ( source ) . auto ( "format" ) . fit ( "max" ) ;
109+ const mediaLibraryId =
110+ extractMediaLibraryId ( source ) || DEFAULT_MEDIA_LIBRARY_ID ;
111+ const builder = mediaLibraryId
112+ ? getMediaLibraryBuilder ( mediaLibraryId )
113+ : datasetImgBuilder ;
114+ return builder . image ( source ) . auto ( "format" ) . fit ( "max" ) ;
80115 } ;
81116
82117 const extractYouTubeId = ( url : string | undefined ) : string | null => {
@@ -128,7 +163,40 @@ export const handler = documentEventHandler<ContentDocument>(
128163 "```" + ( value ?. language || "" ) + "\n" + ( value ?. code || "" ) + "\n```" ,
129164 image : ( { value } ) => {
130165 const url = urlForImage ( value ) ?. url ( ) ;
131- return url ? `` : "" ;
166+ const alt = ( value ?. alt || "" ) . replace ( / [ \[ \] \r \n ] / g, " " ) . trim ( ) ;
167+ return url ? `` : "" ;
168+ } ,
169+ table : ( { value } ) => {
170+ const rows = Array . isArray ( value ?. rows ) ? value . rows : [ ] ;
171+ if ( rows . length === 0 ) return "" ;
172+ const formatRow = ( cells : any [ ] ) =>
173+ `| ${ ( Array . isArray ( cells ) ? cells : [ ] )
174+ . map ( ( c ) =>
175+ String ( c ?? "" )
176+ . replace ( / \r ? \n / g, " " )
177+ . replace ( / \| / g, "\\|" )
178+ . trim ( ) ,
179+ )
180+ . join ( " | " ) } |`;
181+ const headerCells = Array . isArray ( rows [ 0 ] ?. cells )
182+ ? rows [ 0 ] . cells
183+ : [ ] ;
184+ if ( headerCells . length === 0 ) return "" ;
185+ const headerLine = formatRow ( headerCells ) ;
186+ const sepLine = `| ${ headerCells . map ( ( ) => "---" ) . join ( " | " ) } |` ;
187+ const bodyLines = rows
188+ . slice ( 1 )
189+ . map ( ( r : any ) => formatRow ( r ?. cells || [ ] ) ) ;
190+ const titlePrefix = value ?. title ? `### ${ value . title } \n\n` : "" ;
191+ return `${ titlePrefix } ${ [ headerLine , sepLine , ...bodyLines ] . join ( "\n" ) } ` ;
192+ } ,
193+ htmlBlock : ( { value } ) => {
194+ const rawHtml = String ( value ?. html || "" ) ;
195+ if ( ! rawHtml ) return "" ;
196+ if ( / < s t y l e | < s v g | < s c r i p t / i. test ( rawHtml ) ) {
197+ return `*[Interactive diagram available in the full article on CodingCat.dev](${ canonicalUrl } )*` ;
198+ }
199+ return rawHtml ;
132200 } ,
133201 youtube : ( { value } ) =>
134202 formatYouTubeBlock ( value ?. youtube || value ?. url || "" , targetPlatform ) ,
@@ -143,7 +211,21 @@ export const handler = documentEventHandler<ContentDocument>(
143211 const id = value ?. url ?. split ( "https://codesandbox.io/p/sandbox/" ) ?. at ( - 1 ) ;
144212 return `{% codesandbox ${ id || value ?. url || "" } %}` ;
145213 } ,
146- twitter : ( { value } ) => `{% twitter ${ value ?. id || "" } %}` ,
214+ twitter : ( { value } ) => {
215+ const id =
216+ value ?. id ||
217+ value ?. url ?. match ( / s t a t u s (?: e s ) ? \/ ( \d + ) / i) ?. [ 1 ] ||
218+ "" ;
219+ if ( targetPlatform === "devto" && id ) {
220+ return `{% twitter ${ id } %}` ;
221+ }
222+ const url =
223+ value ?. url || ( id ? `https://x.com/i/status/${ id } ` : "" ) ;
224+ if ( targetPlatform === "hashnode" && url ) {
225+ return `%[${ url } ]` ;
226+ }
227+ return url ? `[View post on X](${ url } )` : "" ;
228+ } ,
147229 quote : ( { value } ) => `> ${ serializeContent ( value ?. content , targetPlatform ) } ` ,
148230 } ,
149231 } ) ;
0 commit comments