astro-opengraph-images 1.15.0-dev.971 → 1.15.0-dev.974
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -0
- package/README.md.tmpl +35 -0
- package/dist/hook.d.ts +3 -2
- package/dist/hook.d.ts.map +1 -1
- package/dist/hook.js +14 -4
- package/dist/hook.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/integration.d.ts +1 -1
- package/dist/integration.d.ts.map +1 -1
- package/dist/integration.js +2 -1
- package/dist/integration.js.map +1 -1
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +1 -1
- package/dist/util.js.map +1 -1
- package/dist/util.test.js +11 -0
- package/dist/util.test.js.map +1 -1
- package/package.json +1 -1
- package/src/hook.ts +19 -2
- package/src/index.ts +2 -0
- package/src/integration.ts +2 -0
- package/src/types.ts +6 -0
- package/src/util.test.ts +17 -0
- package/src/util.ts +4 -1
package/README.md
CHANGED
|
@@ -213,6 +213,41 @@ If you're using this project, [open a PR](https://github.com/shepherdjerred/astr
|
|
|
213
213
|
|
|
214
214
|
- [sjer.red](https://sjer.red) ([source](https://github.com/shepherdjerred/sjer.red))
|
|
215
215
|
|
|
216
|
+
## Filtering Pages
|
|
217
|
+
|
|
218
|
+
By default, this integration generates an Open Graph image for every page in your build output. Pass an optional `filter` callback to skip pages — for example, the 404 page, utility routes, or sections where images don't apply.
|
|
219
|
+
|
|
220
|
+
The callback receives the same `RenderFunctionInput` as your renderer (pathname, parsed DOM, Open Graph metadata). Return `true` to render the image, `false` to skip it. The callback may be synchronous or return a `Promise<boolean>`.
|
|
221
|
+
|
|
222
|
+
```diff
|
|
223
|
+
import opengraphImages, { presets } from "astro-opengraph-images";
|
|
224
|
+
|
|
225
|
+
export default defineConfig({
|
|
226
|
+
integrations: [
|
|
227
|
+
opengraphImages({
|
|
228
|
+
options: { fonts: [/* ... */] },
|
|
229
|
+
render: presets.blackAndWhite,
|
|
230
|
+
+ // Only generate images for blog posts
|
|
231
|
+
+ filter: ({ pathname }) => pathname.startsWith("/blog/"),
|
|
232
|
+
}),
|
|
233
|
+
],
|
|
234
|
+
});
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
More examples:
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
// Exclude utility pages
|
|
241
|
+
filter: ({ pathname }) => !["/404/", "/"].includes(pathname);
|
|
242
|
+
|
|
243
|
+
// Filter on DOM content or async data
|
|
244
|
+
filter: async ({ document, pathname }) =>
|
|
245
|
+
document.querySelector('meta[property="og:image"]') !== null &&
|
|
246
|
+
pathname.startsWith("/blog/");
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
When `verbose: true` is set on `options`, skipped pages are logged.
|
|
250
|
+
|
|
216
251
|
## Custom Renderers
|
|
217
252
|
|
|
218
253
|
You can create your own custom images with a render function. Take a look at how [a preset](https://github.com/shepherdjerred/astro-opengraph-images/blob/main/src/presets/blackAndWhite.tsx) works.
|
package/README.md.tmpl
CHANGED
|
@@ -216,6 +216,41 @@ If you're using this project, [open a PR](https://github.com/shepherdjerred/astr
|
|
|
216
216
|
|
|
217
217
|
* [sjer.red](https://sjer.red) ([source](https://github.com/shepherdjerred/sjer.red))
|
|
218
218
|
|
|
219
|
+
## Filtering Pages
|
|
220
|
+
|
|
221
|
+
By default, this integration generates an Open Graph image for every page in your build output. Pass an optional `filter` callback to skip pages — for example, the 404 page, utility routes, or sections where images don't apply.
|
|
222
|
+
|
|
223
|
+
The callback receives the same `RenderFunctionInput` as your renderer (pathname, parsed DOM, Open Graph metadata). Return `true` to render the image, `false` to skip it. The callback may be synchronous or return a `Promise<boolean>`.
|
|
224
|
+
|
|
225
|
+
```diff
|
|
226
|
+
import opengraphImages, { presets } from "astro-opengraph-images";
|
|
227
|
+
|
|
228
|
+
export default defineConfig({
|
|
229
|
+
integrations: [
|
|
230
|
+
opengraphImages({
|
|
231
|
+
options: { fonts: [/* ... */] },
|
|
232
|
+
render: presets.blackAndWhite,
|
|
233
|
+
+ // Only generate images for blog posts
|
|
234
|
+
+ filter: ({ pathname }) => pathname.startsWith("/blog/"),
|
|
235
|
+
}),
|
|
236
|
+
],
|
|
237
|
+
});
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
More examples:
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
// Exclude utility pages
|
|
244
|
+
filter: ({ pathname }) => !["/404/", "/"].includes(pathname);
|
|
245
|
+
|
|
246
|
+
// Filter on DOM content or async data
|
|
247
|
+
filter: async ({ document, pathname }) =>
|
|
248
|
+
document.querySelector('meta[property="og:image"]') !== null &&
|
|
249
|
+
pathname.startsWith("/blog/");
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
When `verbose: true` is set on `options`, skipped pages are logged.
|
|
253
|
+
|
|
219
254
|
## Custom Renderers
|
|
220
255
|
|
|
221
256
|
You can create your own custom images with a render function. Take a look at how [a preset](https://github.com/shepherdjerred/astro-opengraph-images/blob/main/src/presets/blackAndWhite.tsx) works.
|
package/dist/hook.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type { AstroBuildDoneHookInput, IntegrationOptions, RenderFunction } from "./types.ts";
|
|
2
|
-
export declare function buildDoneHook({ logger, pages, options, dir, render, }: AstroBuildDoneHookInput & {
|
|
1
|
+
import type { AstroBuildDoneHookInput, FilterFunction, IntegrationOptions, RenderFunction } from "./types.ts";
|
|
2
|
+
export declare function buildDoneHook({ logger, pages, options, dir, render, filter, }: AstroBuildDoneHookInput & {
|
|
3
3
|
options: IntegrationOptions;
|
|
4
4
|
render: RenderFunction;
|
|
5
|
+
filter: FilterFunction | undefined;
|
|
5
6
|
}): Promise<void>;
|
|
6
7
|
//# sourceMappingURL=hook.d.ts.map
|
package/dist/hook.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../src/hook.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,uBAAuB,EACvB,kBAAkB,EAElB,cAAc,EACf,MAAM,YAAY,CAAC;AASpB,wBAAsB,aAAa,CAAC,EAClC,MAAM,EACN,KAAK,EACL,OAAO,EACP,GAAG,EACH,MAAM,GACP,EAAE,uBAAuB,GAAG;IAC3B,OAAO,EAAE,kBAAkB,CAAC;IAC5B,MAAM,EAAE,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../src/hook.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,uBAAuB,EACvB,cAAc,EACd,kBAAkB,EAElB,cAAc,EACf,MAAM,YAAY,CAAC;AASpB,wBAAsB,aAAa,CAAC,EAClC,MAAM,EACN,KAAK,EACL,OAAO,EACP,GAAG,EACH,MAAM,EACN,MAAM,GACP,EAAE,uBAAuB,GAAG;IAC3B,OAAO,EAAE,kBAAkB,CAAC;IAC5B,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,cAAc,GAAG,SAAS,CAAC;CACpC,iBAMA"}
|
package/dist/hook.js
CHANGED
|
@@ -6,12 +6,12 @@ import { getFilePath } from "./util.js";
|
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
import * as jsdom from "jsdom";
|
|
8
8
|
import path from "node:path";
|
|
9
|
-
export async function buildDoneHook({ logger, pages, options, dir, render, }) {
|
|
9
|
+
export async function buildDoneHook({ logger, pages, options, dir, render, filter, }) {
|
|
10
10
|
logger.info("Generating Open Graph images");
|
|
11
|
-
const promises = pages.map((page) => handlePage({ page, options, render, dir, logger }));
|
|
11
|
+
const promises = pages.map((page) => handlePage({ page, options, render, dir, logger, filter }));
|
|
12
12
|
await Promise.all(promises);
|
|
13
13
|
}
|
|
14
|
-
async function handlePage({ page, options, render, dir, logger, }) {
|
|
14
|
+
async function handlePage({ page, options, render, dir, logger, filter, }) {
|
|
15
15
|
// gets the absolute path to the HTML file. E.g. /home/user/project/dist/blog/index.html
|
|
16
16
|
// fileURLToPath() converts the URL to a file path. Without it, the path would start with a leading slash on Windows
|
|
17
17
|
// systems, resulting in an invalid path.
|
|
@@ -25,8 +25,18 @@ async function handlePage({ page, options, render, dir, logger, }) {
|
|
|
25
25
|
const document = new jsdom.JSDOM(sanitizeHtml(html)).window.document;
|
|
26
26
|
// extract the OpenGraph properties from the HTML file
|
|
27
27
|
const pageDetails = extract(document);
|
|
28
|
+
const renderInput = { ...page, ...pageDetails, dir, document };
|
|
29
|
+
if (filter) {
|
|
30
|
+
const shouldRender = await filter(renderInput);
|
|
31
|
+
if (!shouldRender) {
|
|
32
|
+
if (options.verbose) {
|
|
33
|
+
logger.info(`Skipping page ${page.pathname}.`);
|
|
34
|
+
}
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
28
38
|
// render the image using Satori and Resvg
|
|
29
|
-
const reactNode = await render(
|
|
39
|
+
const reactNode = await render(renderInput);
|
|
30
40
|
const svg = await satori(reactNode, options);
|
|
31
41
|
const resvg = new Resvg(svg, {
|
|
32
42
|
font: {
|
package/dist/hook.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hook.js","sourceRoot":"","sources":["../src/hook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,MAAM,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"hook.js","sourceRoot":"","sources":["../src/hook.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getImagePath as importedGetImagePath } from "./util.ts";
|
|
2
2
|
import { astroOpenGraphImages } from "./integration.ts";
|
|
3
|
-
import type { IntegrationInput as _IntegrationInput, IntegrationDefaults as _IntegrationDefaults, PartialIntegrationOptions as _PartialIntegrationOptions, IntegrationOptions as _IntegrationOptions, Page as _Page, AstroBuildDoneHookInput as _AstroBuildDoneHookInput, RenderFunctionInput as _RenderFunctionInput, RenderFunction as _RenderFunction, PageDetails as _PageDetails, SatoriWeight as _SatoriWeight, SatoriFontStyle as _SatoriFontStyle, SatoriFontOptions as _SatoriFontOptions, SatoriOptions as _SatoriOptions } from "./types.ts";
|
|
3
|
+
import type { IntegrationInput as _IntegrationInput, IntegrationDefaults as _IntegrationDefaults, PartialIntegrationOptions as _PartialIntegrationOptions, IntegrationOptions as _IntegrationOptions, Page as _Page, AstroBuildDoneHookInput as _AstroBuildDoneHookInput, RenderFunctionInput as _RenderFunctionInput, RenderFunction as _RenderFunction, FilterFunction as _FilterFunction, PageDetails as _PageDetails, SatoriWeight as _SatoriWeight, SatoriFontStyle as _SatoriFontStyle, SatoriFontOptions as _SatoriFontOptions, SatoriOptions as _SatoriOptions } from "./types.ts";
|
|
4
4
|
export declare const presets: {
|
|
5
5
|
blackAndWhite: typeof import("./presets/black-and-white.tsx").blackAndWhite;
|
|
6
6
|
gradients: typeof import("./presets/gradients.tsx").gradients;
|
|
@@ -24,6 +24,7 @@ export type Page = _Page;
|
|
|
24
24
|
export type AstroBuildDoneHookInput = _AstroBuildDoneHookInput;
|
|
25
25
|
export type RenderFunctionInput = _RenderFunctionInput;
|
|
26
26
|
export type RenderFunction = _RenderFunction;
|
|
27
|
+
export type FilterFunction = _FilterFunction;
|
|
27
28
|
export type PageDetails = _PageDetails;
|
|
28
29
|
export type SatoriWeight = _SatoriWeight;
|
|
29
30
|
export type SatoriFontStyle = _SatoriFontStyle;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,IAAI,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EACV,gBAAgB,IAAI,iBAAiB,EACrC,mBAAmB,IAAI,oBAAoB,EAC3C,yBAAyB,IAAI,0BAA0B,EACvD,kBAAkB,IAAI,mBAAmB,EACzC,IAAI,IAAI,KAAK,EACb,uBAAuB,IAAI,wBAAwB,EACnD,mBAAmB,IAAI,oBAAoB,EAC3C,cAAc,IAAI,eAAe,EACjC,WAAW,IAAI,YAAY,EAC3B,YAAY,IAAI,aAAa,EAC7B,eAAe,IAAI,gBAAgB,EACnC,iBAAiB,IAAI,kBAAkB,EACvC,aAAa,IAAI,cAAc,EAChC,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,OAAO;;;;;;;;;;;;CAAkB,CAAC;AACvC,eAAO,MAAM,YAAY,6BAAuB,CAAC;AACjD,eAAe,oBAAoB,CAAC;AAEpC,MAAM,MAAM,gBAAgB,GAAG,iBAAiB,CAAC;AACjD,MAAM,MAAM,mBAAmB,GAAG,oBAAoB,CAAC;AACvD,MAAM,MAAM,yBAAyB,GAAG,0BAA0B,CAAC;AACnE,MAAM,MAAM,kBAAkB,GAAG,mBAAmB,CAAC;AACrD,MAAM,MAAM,IAAI,GAAG,KAAK,CAAC;AACzB,MAAM,MAAM,uBAAuB,GAAG,wBAAwB,CAAC;AAC/D,MAAM,MAAM,mBAAmB,GAAG,oBAAoB,CAAC;AACvD,MAAM,MAAM,cAAc,GAAG,eAAe,CAAC;AAC7C,MAAM,MAAM,WAAW,GAAG,YAAY,CAAC;AACvC,MAAM,MAAM,YAAY,GAAG,aAAa,CAAC;AACzC,MAAM,MAAM,eAAe,GAAG,gBAAgB,CAAC;AAC/C,MAAM,MAAM,iBAAiB,GAAG,kBAAkB,CAAC;AACnD,MAAM,MAAM,aAAa,GAAG,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,IAAI,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EACV,gBAAgB,IAAI,iBAAiB,EACrC,mBAAmB,IAAI,oBAAoB,EAC3C,yBAAyB,IAAI,0BAA0B,EACvD,kBAAkB,IAAI,mBAAmB,EACzC,IAAI,IAAI,KAAK,EACb,uBAAuB,IAAI,wBAAwB,EACnD,mBAAmB,IAAI,oBAAoB,EAC3C,cAAc,IAAI,eAAe,EACjC,cAAc,IAAI,eAAe,EACjC,WAAW,IAAI,YAAY,EAC3B,YAAY,IAAI,aAAa,EAC7B,eAAe,IAAI,gBAAgB,EACnC,iBAAiB,IAAI,kBAAkB,EACvC,aAAa,IAAI,cAAc,EAChC,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,OAAO;;;;;;;;;;;;CAAkB,CAAC;AACvC,eAAO,MAAM,YAAY,6BAAuB,CAAC;AACjD,eAAe,oBAAoB,CAAC;AAEpC,MAAM,MAAM,gBAAgB,GAAG,iBAAiB,CAAC;AACjD,MAAM,MAAM,mBAAmB,GAAG,oBAAoB,CAAC;AACvD,MAAM,MAAM,yBAAyB,GAAG,0BAA0B,CAAC;AACnE,MAAM,MAAM,kBAAkB,GAAG,mBAAmB,CAAC;AACrD,MAAM,MAAM,IAAI,GAAG,KAAK,CAAC;AACzB,MAAM,MAAM,uBAAuB,GAAG,wBAAwB,CAAC;AAC/D,MAAM,MAAM,mBAAmB,GAAG,oBAAoB,CAAC;AACvD,MAAM,MAAM,cAAc,GAAG,eAAe,CAAC;AAC7C,MAAM,MAAM,cAAc,GAAG,eAAe,CAAC;AAC7C,MAAM,MAAM,WAAW,GAAG,YAAY,CAAC;AACvC,MAAM,MAAM,YAAY,GAAG,aAAa,CAAC;AACzC,MAAM,MAAM,eAAe,GAAG,gBAAgB,CAAC;AAC/C,MAAM,MAAM,iBAAiB,GAAG,kBAAkB,CAAC;AACnD,MAAM,MAAM,aAAa,GAAG,cAAc,CAAC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,YAAY,IAAI,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,YAAY,IAAI,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAkBxD,MAAM,CAAC,MAAM,OAAO,GAAG,eAAe,CAAC;AACvC,MAAM,CAAC,MAAM,YAAY,GAAG,oBAAoB,CAAC;AACjD,eAAe,oBAAoB,CAAC"}
|
package/dist/integration.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { AstroIntegration } from "astro";
|
|
2
2
|
import type { IntegrationInput } from "./types.ts";
|
|
3
|
-
export declare function astroOpenGraphImages({ options, render, }: IntegrationInput): AstroIntegration;
|
|
3
|
+
export declare function astroOpenGraphImages({ options, render, filter, }: IntegrationInput): AstroIntegration;
|
|
4
4
|
//# sourceMappingURL=integration.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../src/integration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAC9C,OAAO,KAAK,EAGV,gBAAgB,EAEjB,MAAM,YAAY,CAAC;AASpB,wBAAgB,oBAAoB,CAAC,EACnC,OAAO,EACP,MAAM,GACP,EAAE,gBAAgB,GAAG,gBAAgB,
|
|
1
|
+
{"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../src/integration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAC9C,OAAO,KAAK,EAGV,gBAAgB,EAEjB,MAAM,YAAY,CAAC;AASpB,wBAAgB,oBAAoB,CAAC,EACnC,OAAO,EACP,MAAM,EACN,MAAM,GACP,EAAE,gBAAgB,GAAG,gBAAgB,CAgBrC"}
|
package/dist/integration.js
CHANGED
|
@@ -4,7 +4,7 @@ const defaults = {
|
|
|
4
4
|
height: 630,
|
|
5
5
|
verbose: false,
|
|
6
6
|
};
|
|
7
|
-
export function astroOpenGraphImages({ options, render, }) {
|
|
7
|
+
export function astroOpenGraphImages({ options, render, filter, }) {
|
|
8
8
|
const optionsWithDefaults = { ...defaults, ...options };
|
|
9
9
|
return {
|
|
10
10
|
name: "astro-opengraph-images",
|
|
@@ -14,6 +14,7 @@ export function astroOpenGraphImages({ options, render, }) {
|
|
|
14
14
|
...entry,
|
|
15
15
|
options: optionsWithDefaults,
|
|
16
16
|
render,
|
|
17
|
+
filter,
|
|
17
18
|
});
|
|
18
19
|
},
|
|
19
20
|
},
|
package/dist/integration.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration.js","sourceRoot":"","sources":["../src/integration.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,QAAQ,GAAwB;IACpC,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,GAAG;IACX,OAAO,EAAE,KAAK;CACf,CAAC;AAEF,MAAM,UAAU,oBAAoB,CAAC,EACnC,OAAO,EACP,MAAM,GACW;IACjB,MAAM,mBAAmB,GAAuB,EAAE,GAAG,QAAQ,EAAE,GAAG,OAAO,EAAE,CAAC;IAE5E,OAAO;QACL,IAAI,EAAE,wBAAwB;QAC9B,KAAK,EAAE;YACL,kBAAkB,EAAE,KAAK,EAAE,KAA8B,EAAE,EAAE;gBAC3D,OAAO,aAAa,CAAC;oBACnB,GAAG,KAAK;oBACR,OAAO,EAAE,mBAAmB;oBAC5B,MAAM;iBACP,CAAC,CAAC;YACL,CAAC;SACF;KACF,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"integration.js","sourceRoot":"","sources":["../src/integration.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,QAAQ,GAAwB;IACpC,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,GAAG;IACX,OAAO,EAAE,KAAK;CACf,CAAC;AAEF,MAAM,UAAU,oBAAoB,CAAC,EACnC,OAAO,EACP,MAAM,EACN,MAAM,GACW;IACjB,MAAM,mBAAmB,GAAuB,EAAE,GAAG,QAAQ,EAAE,GAAG,OAAO,EAAE,CAAC;IAE5E,OAAO;QACL,IAAI,EAAE,wBAAwB;QAC9B,KAAK,EAAE;YACL,kBAAkB,EAAE,KAAK,EAAE,KAA8B,EAAE,EAAE;gBAC3D,OAAO,aAAa,CAAC;oBACnB,GAAG,KAAK;oBACR,OAAO,EAAE,mBAAmB;oBAC5B,MAAM;oBACN,MAAM;iBACP,CAAC,CAAC;YACL,CAAC;SACF;KACF,CAAC;AACJ,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { ReactNode } from "react";
|
|
|
3
3
|
export type IntegrationInput = {
|
|
4
4
|
options: PartialIntegrationOptions;
|
|
5
5
|
render: RenderFunction;
|
|
6
|
+
filter?: FilterFunction;
|
|
6
7
|
};
|
|
7
8
|
/** When applied to PartialIntegrationOptions this type equals IntegrationOptions */
|
|
8
9
|
export type IntegrationDefaults = {
|
|
@@ -32,6 +33,8 @@ export type RenderFunctionInput = {
|
|
|
32
33
|
dir: URL;
|
|
33
34
|
document: Document;
|
|
34
35
|
} & PageDetails;
|
|
36
|
+
/** A function that filters which pages should have Open Graph images generated for them **/
|
|
37
|
+
export type FilterFunction = (input: RenderFunctionInput) => Promise<boolean> | boolean;
|
|
35
38
|
/** A function that renders some page input to React */
|
|
36
39
|
export type RenderFunction = (input: RenderFunctionInput) => ReactNode | Promise<ReactNode>;
|
|
37
40
|
/** Basic information about a page */
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,yBAAyB,CAAC;IACnC,MAAM,EAAE,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,yBAAyB,CAAC;IACnC,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB,CAAC;AAEF,oFAAoF;AACpF,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAC1C,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,EAC5B,QAAQ,CACT,GACC,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAE/B;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,yBAAyB,GACxD,mBAAmB,CAAC;AAEtB,+CAA+C;AAC/C,MAAM,MAAM,IAAI,GAAG;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,oDAAoD;AACpD,MAAM,MAAM,uBAAuB,GAAG,UAAU,CAC9C,oBAAoB,CAAC,kBAAkB,CAAC,CACzC,CAAC,CAAC,CAAC,CAAC;AAEL,gDAAgD;AAChD,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,GAAG,CAAC;IACT,QAAQ,EAAE,QAAQ,CAAC;CACpB,GAAG,WAAW,CAAC;AAEhB,4FAA4F;AAC5F,MAAM,MAAM,cAAc,GAAG,CAC3B,KAAK,EAAE,mBAAmB,KACvB,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;AAEhC,uDAAuD;AACvD,MAAM,MAAM,cAAc,GAAG,CAC3B,KAAK,EAAE,mBAAmB,KACvB,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;AAEpC,qCAAqC;AACrC,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,KAAK,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;AAEpC,+BAA+B;AAC/B,MAAM,MAAM,YAAY,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAC/E,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAClD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AACF,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;IACxC,6EAA6E;IAC7E,mBAAmB,CAAC,EAAE,CACpB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC,MAAM,GAAG,iBAAiB,EAAE,CAAC,CAAC;CAC5C,CAAC"}
|
package/dist/util.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAeA,wBAAsB,WAAW,CAAC,EAChC,GAAG,EACH,IAAI,GACL,EAAE;IACD,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd,
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAeA,wBAAsB,WAAW,CAAC,EAChC,GAAG,EACH,IAAI,GACL,EAAE;IACD,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd,mBAWA;AAED,wBAAgB,YAAY,CAAC,EAC3B,GAAG,EACH,IAAI,GACL,EAAE;IACD,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,GAAG,GAAG,SAAS,CAAC;CACvB,GAAG,MAAM,CA0BT"}
|
package/dist/util.js
CHANGED
|
@@ -15,7 +15,7 @@ async function fileExists(filePath) {
|
|
|
15
15
|
export async function getFilePath({ dir, page, }) {
|
|
16
16
|
let target = path.join(dir, page, "index.html");
|
|
17
17
|
if (!(await fileExists(target))) {
|
|
18
|
-
target = path.join(dir, page.slice(0, -1) + ".html");
|
|
18
|
+
target = path.join(dir, (page.endsWith("/") ? page.slice(0, -1) : page) + ".html");
|
|
19
19
|
}
|
|
20
20
|
return target;
|
|
21
21
|
}
|
package/dist/util.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,KAAK,UAAU,UAAU,CAAC,QAAgB;IACxC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,mEAAmE;AACnE,yDAAyD;AACzD,uDAAuD;AACvD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,EAChC,GAAG,EACH,IAAI,GAIL;IACC,IAAI,MAAM,GAAW,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;IAExD,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QAChC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,KAAK,UAAU,UAAU,CAAC,QAAgB;IACxC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,mEAAmE;AACnE,yDAAyD;AACzD,uDAAuD;AACvD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,EAChC,GAAG,EACH,IAAI,GAIL;IACC,IAAI,MAAM,GAAW,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;IAExD,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QAChC,MAAM,GAAG,IAAI,CAAC,IAAI,CAChB,GAAG,EACH,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAC1D,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,EAC3B,GAAG,EACH,IAAI,GAIL;IACC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,qHAAqH,CACtH,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC;IAE1B,6CAA6C;IAC7C,2BAA2B;IAC3B,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC;IAEvE,iEAAiE;IACjE,IAAI,MAAM,KAAK,gBAAgB,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC,QAAQ,EAAE,GAAG,SAAS,CAAC;IACrC,CAAC;SAAM,IAAI,MAAM,KAAK,gBAAgB,EAAE,CAAC;QACvC,OAAO,IAAI,CAAC,QAAQ,EAAE,GAAG,SAAS,CAAC;IACrC,CAAC;IAED,uBAAuB;IACvB,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,eAAe;IACf,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,MAAM,CAAC;IAElC,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/util.test.js
CHANGED
|
@@ -37,6 +37,17 @@ test("getFilePath blog", async () => {
|
|
|
37
37
|
process.chdir(import.meta.dirname);
|
|
38
38
|
expect(path.normalize(result)).toBe(path.normalize("blog/index.html"));
|
|
39
39
|
});
|
|
40
|
+
test("getFilePath without trailing slash falls back to .html sibling", async () => {
|
|
41
|
+
// some callers may pass a pathname without a trailing slash (e.g. "404");
|
|
42
|
+
// getFilePath must still locate the corresponding .html file instead of
|
|
43
|
+
// slicing off the last character of the name.
|
|
44
|
+
const tmpDir = await createTempDir();
|
|
45
|
+
process.chdir(tmpDir);
|
|
46
|
+
await writeFile(path.join(tmpDir, "404.html"), "");
|
|
47
|
+
const result = await getFilePath({ dir: "", page: "404" });
|
|
48
|
+
process.chdir(import.meta.dirname);
|
|
49
|
+
expect(path.normalize(result)).toBe(path.normalize("404.html"));
|
|
50
|
+
});
|
|
40
51
|
// https://sdorra.dev/posts/2024-02-12-vitest-tmpdir
|
|
41
52
|
async function createTempDir() {
|
|
42
53
|
const ostmpdir = tmpdir();
|
package/dist/util.test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.test.js","sourceRoot":"","sources":["../src/util.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"util.test.js","sourceRoot":"","sources":["../src/util.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7D,IAAI,CAAC,mBAAmB,EAAE,KAAK,IAAI,EAAE;IACnC,MAAM,MAAM,GAAG,MAAM,aAAa,EAAE,CAAC;IAErC,uDAAuD;IACvD,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAEtB,iDAAiD;IACjD,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,EAAE,CAAC,CAAC;IAErD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;IAE9D,4DAA4D;IAC5D,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAEnC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;AACpE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,iBAAiB,EAAE,KAAK,IAAI,EAAE;IACjC,MAAM,MAAM,GAAG,MAAM,aAAa,EAAE,CAAC;IAErC,uDAAuD;IACvD,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAEtB,iDAAiD;IACjD,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;IAEnD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IAE5D,4DAA4D;IAC5D,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAEnC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC;AAClE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kBAAkB,EAAE,KAAK,IAAI,EAAE;IAClC,MAAM,MAAM,GAAG,MAAM,aAAa,EAAE,CAAC;IAErC,uDAAuD;IACvD,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAEtB,iDAAiD;IACjD,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACvC,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,EAAE,CAAC,CAAC;IAE7D,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IAE7D,4DAA4D;IAC5D,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAEnC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC;AACzE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;IAChF,0EAA0E;IAC1E,wEAAwE;IACxE,8CAA8C;IAC9C,MAAM,MAAM,GAAG,MAAM,aAAa,EAAE,CAAC;IAErC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAEtB,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;IAEnD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAE3D,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAEnC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC;AAClE,CAAC,CAAC,CAAC;AAEH,oDAAoD;AACpD,KAAK,UAAU,aAAa;IAC1B,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC;IAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAC9C,OAAO,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;AAC5B,CAAC"}
|
package/package.json
CHANGED
package/src/hook.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { Resvg } from "@resvg/resvg-js";
|
|
|
2
2
|
import satori from "satori";
|
|
3
3
|
import type {
|
|
4
4
|
AstroBuildDoneHookInput,
|
|
5
|
+
FilterFunction,
|
|
5
6
|
IntegrationOptions,
|
|
6
7
|
Page,
|
|
7
8
|
RenderFunction,
|
|
@@ -20,13 +21,15 @@ export async function buildDoneHook({
|
|
|
20
21
|
options,
|
|
21
22
|
dir,
|
|
22
23
|
render,
|
|
24
|
+
filter,
|
|
23
25
|
}: AstroBuildDoneHookInput & {
|
|
24
26
|
options: IntegrationOptions;
|
|
25
27
|
render: RenderFunction;
|
|
28
|
+
filter: FilterFunction | undefined;
|
|
26
29
|
}) {
|
|
27
30
|
logger.info("Generating Open Graph images");
|
|
28
31
|
const promises = pages.map((page) =>
|
|
29
|
-
handlePage({ page, options, render, dir, logger }),
|
|
32
|
+
handlePage({ page, options, render, dir, logger, filter }),
|
|
30
33
|
);
|
|
31
34
|
await Promise.all(promises);
|
|
32
35
|
}
|
|
@@ -37,6 +40,7 @@ type HandlePageInput = {
|
|
|
37
40
|
render: RenderFunction;
|
|
38
41
|
dir: URL;
|
|
39
42
|
logger: AstroIntegrationLogger;
|
|
43
|
+
filter: FilterFunction | undefined;
|
|
40
44
|
};
|
|
41
45
|
|
|
42
46
|
async function handlePage({
|
|
@@ -45,6 +49,7 @@ async function handlePage({
|
|
|
45
49
|
render,
|
|
46
50
|
dir,
|
|
47
51
|
logger,
|
|
52
|
+
filter,
|
|
48
53
|
}: HandlePageInput) {
|
|
49
54
|
// gets the absolute path to the HTML file. E.g. /home/user/project/dist/blog/index.html
|
|
50
55
|
// fileURLToPath() converts the URL to a file path. Without it, the path would start with a leading slash on Windows
|
|
@@ -61,9 +66,21 @@ async function handlePage({
|
|
|
61
66
|
|
|
62
67
|
// extract the OpenGraph properties from the HTML file
|
|
63
68
|
const pageDetails = extract(document);
|
|
69
|
+
const renderInput = { ...page, ...pageDetails, dir, document };
|
|
70
|
+
|
|
71
|
+
if (filter) {
|
|
72
|
+
const shouldRender = await filter(renderInput);
|
|
73
|
+
|
|
74
|
+
if (!shouldRender) {
|
|
75
|
+
if (options.verbose) {
|
|
76
|
+
logger.info(`Skipping page ${page.pathname}.`);
|
|
77
|
+
}
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
64
81
|
|
|
65
82
|
// render the image using Satori and Resvg
|
|
66
|
-
const reactNode = await render(
|
|
83
|
+
const reactNode = await render(renderInput);
|
|
67
84
|
const svg = await satori(reactNode, options);
|
|
68
85
|
const resvg = new Resvg(svg, {
|
|
69
86
|
font: {
|
package/src/index.ts
CHANGED
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
AstroBuildDoneHookInput as _AstroBuildDoneHookInput,
|
|
11
11
|
RenderFunctionInput as _RenderFunctionInput,
|
|
12
12
|
RenderFunction as _RenderFunction,
|
|
13
|
+
FilterFunction as _FilterFunction,
|
|
13
14
|
PageDetails as _PageDetails,
|
|
14
15
|
SatoriWeight as _SatoriWeight,
|
|
15
16
|
SatoriFontStyle as _SatoriFontStyle,
|
|
@@ -29,6 +30,7 @@ export type Page = _Page;
|
|
|
29
30
|
export type AstroBuildDoneHookInput = _AstroBuildDoneHookInput;
|
|
30
31
|
export type RenderFunctionInput = _RenderFunctionInput;
|
|
31
32
|
export type RenderFunction = _RenderFunction;
|
|
33
|
+
export type FilterFunction = _FilterFunction;
|
|
32
34
|
export type PageDetails = _PageDetails;
|
|
33
35
|
export type SatoriWeight = _SatoriWeight;
|
|
34
36
|
export type SatoriFontStyle = _SatoriFontStyle;
|
package/src/integration.ts
CHANGED
|
@@ -16,6 +16,7 @@ const defaults: IntegrationDefaults = {
|
|
|
16
16
|
export function astroOpenGraphImages({
|
|
17
17
|
options,
|
|
18
18
|
render,
|
|
19
|
+
filter,
|
|
19
20
|
}: IntegrationInput): AstroIntegration {
|
|
20
21
|
const optionsWithDefaults: IntegrationOptions = { ...defaults, ...options };
|
|
21
22
|
|
|
@@ -27,6 +28,7 @@ export function astroOpenGraphImages({
|
|
|
27
28
|
...entry,
|
|
28
29
|
options: optionsWithDefaults,
|
|
29
30
|
render,
|
|
31
|
+
filter,
|
|
30
32
|
});
|
|
31
33
|
},
|
|
32
34
|
},
|
package/src/types.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { ReactNode } from "react";
|
|
|
4
4
|
export type IntegrationInput = {
|
|
5
5
|
options: PartialIntegrationOptions;
|
|
6
6
|
render: RenderFunction;
|
|
7
|
+
filter?: FilterFunction;
|
|
7
8
|
};
|
|
8
9
|
|
|
9
10
|
/** When applied to PartialIntegrationOptions this type equals IntegrationOptions */
|
|
@@ -47,6 +48,11 @@ export type RenderFunctionInput = {
|
|
|
47
48
|
document: Document;
|
|
48
49
|
} & PageDetails;
|
|
49
50
|
|
|
51
|
+
/** A function that filters which pages should have Open Graph images generated for them **/
|
|
52
|
+
export type FilterFunction = (
|
|
53
|
+
input: RenderFunctionInput,
|
|
54
|
+
) => Promise<boolean> | boolean;
|
|
55
|
+
|
|
50
56
|
/** A function that renders some page input to React */
|
|
51
57
|
export type RenderFunction = (
|
|
52
58
|
input: RenderFunctionInput,
|
package/src/util.test.ts
CHANGED
|
@@ -56,6 +56,23 @@ test("getFilePath blog", async () => {
|
|
|
56
56
|
expect(path.normalize(result)).toBe(path.normalize("blog/index.html"));
|
|
57
57
|
});
|
|
58
58
|
|
|
59
|
+
test("getFilePath without trailing slash falls back to .html sibling", async () => {
|
|
60
|
+
// some callers may pass a pathname without a trailing slash (e.g. "404");
|
|
61
|
+
// getFilePath must still locate the corresponding .html file instead of
|
|
62
|
+
// slicing off the last character of the name.
|
|
63
|
+
const tmpDir = await createTempDir();
|
|
64
|
+
|
|
65
|
+
process.chdir(tmpDir);
|
|
66
|
+
|
|
67
|
+
await writeFile(path.join(tmpDir, "404.html"), "");
|
|
68
|
+
|
|
69
|
+
const result = await getFilePath({ dir: "", page: "404" });
|
|
70
|
+
|
|
71
|
+
process.chdir(import.meta.dirname);
|
|
72
|
+
|
|
73
|
+
expect(path.normalize(result)).toBe(path.normalize("404.html"));
|
|
74
|
+
});
|
|
75
|
+
|
|
59
76
|
// https://sdorra.dev/posts/2024-02-12-vitest-tmpdir
|
|
60
77
|
async function createTempDir() {
|
|
61
78
|
const ostmpdir = tmpdir();
|
package/src/util.ts
CHANGED
|
@@ -23,7 +23,10 @@ export async function getFilePath({
|
|
|
23
23
|
let target: string = path.join(dir, page, "index.html");
|
|
24
24
|
|
|
25
25
|
if (!(await fileExists(target))) {
|
|
26
|
-
target = path.join(
|
|
26
|
+
target = path.join(
|
|
27
|
+
dir,
|
|
28
|
+
(page.endsWith("/") ? page.slice(0, -1) : page) + ".html"
|
|
29
|
+
);
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
return target;
|