1
- import { readFileSync , readdirSync } from 'fs' ;
2
- import { join , basename } from 'path' ;
1
+ import { readFileSync , readdirSync , accessSync , constants } from 'fs' ;
2
+ import { join , basename , parse , resolve } from 'path' ;
3
3
import { extractFrontmatter } from '@nx/nx-dev/ui-markdoc' ;
4
4
import { sortPosts } from './blog.util' ;
5
5
import { BlogPostDataEntry } from './blog.model' ;
@@ -42,6 +42,8 @@ export class BlogApi {
42
42
const content = await readFile ( filePath , 'utf8' ) ;
43
43
const frontmatter = extractFrontmatter ( content ) ;
44
44
const slug = this . calculateSlug ( filePath , frontmatter ) ;
45
+ const { image, type } = this . determineOgImage ( frontmatter . cover_image ) ;
46
+
45
47
const post = {
46
48
content,
47
49
title : frontmatter . title ?? null ,
@@ -56,6 +58,8 @@ export class BlogApi {
56
58
tags : frontmatter . tags ?? [ ] ,
57
59
reposts : frontmatter . reposts ?? [ ] ,
58
60
pinned : frontmatter . pinned ?? false ,
61
+ ogImage : image ,
62
+ ogImageType : type ,
59
63
filePath,
60
64
slug,
61
65
} ;
@@ -81,6 +85,7 @@ export class BlogApi {
81
85
const content = readFileSync ( filePath , 'utf8' ) ;
82
86
const frontmatter = extractFrontmatter ( content ) ;
83
87
const slug = this . calculateSlug ( filePath , frontmatter ) ;
88
+ const { image, type } = this . determineOgImage ( frontmatter . cover_image ) ;
84
89
const post = {
85
90
content,
86
91
title : frontmatter . title ?? null ,
@@ -95,6 +100,8 @@ export class BlogApi {
95
100
tags : frontmatter . tags ?? [ ] ,
96
101
reposts : frontmatter . reposts ?? [ ] ,
97
102
pinned : frontmatter . pinned ?? false ,
103
+ ogImage : image ,
104
+ ogImageType : type ,
98
105
filePath,
99
106
slug,
100
107
} ;
@@ -143,4 +150,50 @@ export class BlogApi {
143
150
}
144
151
}
145
152
}
153
+
154
+ private fileExists ( filePath : string ) : boolean {
155
+ try {
156
+ accessSync ( filePath , constants . F_OK ) ;
157
+ return true ;
158
+ } catch ( error ) {
159
+ return false ;
160
+ }
161
+ }
162
+
163
+ private determineOgImage ( imagePath : string ) : {
164
+ image : string ;
165
+ type : string ;
166
+ } {
167
+ const allowedExtensions = [ '.png' , '.webp' , '.jpg' , '.jpeg' ] ;
168
+ const defaultImage = 'https://nx.dev/socials/nx-media.png' ;
169
+ const defaultType = 'png' ;
170
+
171
+ if ( ! imagePath ) {
172
+ return { image : defaultImage , type : defaultType } ;
173
+ }
174
+ const { ext } = parse ( imagePath ) ;
175
+
176
+ if ( ! allowedExtensions . includes ( ext ) ) {
177
+ const foundExt = allowedExtensions . find ( ( allowedExt ) => {
178
+ const ogImagePath = imagePath . replace ( ext , allowedExt ) ;
179
+ return this . fileExists (
180
+ join (
181
+ 'public' ,
182
+ 'documentation' ,
183
+ resolve ( this . options . blogRoot , ogImagePath )
184
+ )
185
+ ) ;
186
+ } ) ;
187
+
188
+ if ( ! foundExt ) {
189
+ return { image : defaultImage , type : defaultType } ;
190
+ }
191
+
192
+ return {
193
+ image : imagePath . replace ( ext , foundExt ) ,
194
+ type : foundExt . replace ( '.' , '' ) ,
195
+ } ;
196
+ }
197
+ return { image : imagePath , type : ext . replace ( '.' , '' ) } ;
198
+ }
146
199
}
0 commit comments