@altano/astro-opengraph 0.1.0-alpha.3 → 0.1.0

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.
Files changed (34) hide show
  1. package/README.md +9 -0
  2. package/components/meta.astro +1 -1
  3. package/dist/config-CzK0JuaO.js +45 -0
  4. package/dist/config.d.ts +8 -3
  5. package/dist/config.js +3 -0
  6. package/dist/endpoint.d.ts +25 -11
  7. package/dist/endpoint.js +62 -126
  8. package/dist/index.d.ts +8 -2
  9. package/dist/index.js +41 -58
  10. package/dist/toolbar/index.d.ts +7 -2
  11. package/dist/toolbar/index.js +364 -396
  12. package/dist/types-Lk5HqHkQ.d.ts +71 -0
  13. package/package.json +28 -26
  14. package/dist/image.d.ts +0 -7
  15. package/dist/integration.d.ts +0 -5
  16. package/dist/toolbar/components/CopyImageUrlButton.d.ts +0 -3
  17. package/dist/toolbar/components/ExternalLinkicon.d.ts +0 -7
  18. package/dist/toolbar/components/Image.d.ts +0 -5
  19. package/dist/toolbar/components/ImageSection.d.ts +0 -4
  20. package/dist/toolbar/components/ImageZoomToolbar.d.ts +0 -7
  21. package/dist/toolbar/components/LinkOrText.d.ts +0 -7
  22. package/dist/toolbar/components/MetaTags.d.ts +0 -3
  23. package/dist/toolbar/components/Summary.d.ts +0 -5
  24. package/dist/toolbar/components/ToolbarApp.d.ts +0 -3
  25. package/dist/toolbar/components/ToolbarAppWindow.d.ts +0 -3
  26. package/dist/toolbar/components/ToolbarSection.d.ts +0 -6
  27. package/dist/toolbar/components/ZoomButton.d.ts +0 -7
  28. package/dist/toolbar/components/ZoomLabel.d.ts +0 -4
  29. package/dist/toolbar/hooks/useHoverState.d.ts +0 -3
  30. package/dist/toolbar/hooks/useImageURL.d.ts +0 -3
  31. package/dist/toolbar/hooks/useMetaTagInfo.d.ts +0 -3
  32. package/dist/toolbar/styles.d.ts +0 -2
  33. package/dist/types.d.ts +0 -67
  34. package/dist/virtual-user-config.d.ts +0 -8
package/README.md CHANGED
@@ -419,6 +419,15 @@ export const GET: APIRoute = makeOpengraphDevEndpoint({
419
419
  });
420
420
  ```
421
421
 
422
+ You'll probably want to include a remote stylesheet that has your font face so that it renders correctly in HTML, since the integration's font configuration doesn't affect the HTML rendered version. For example, you might include this in your `./_opengraph.astro`:
423
+
424
+ ```
425
+ <link
426
+ href=" https://cdn.jsdelivr.net/npm/@fontsource-variable/inter@5.2.5/index.min.css "
427
+ rel="stylesheet"
428
+ />
429
+ ```
430
+
422
431
  # FAQ
423
432
 
424
433
  ## Question: How does this work?
@@ -1,5 +1,5 @@
1
1
  ---
2
- import { getResolvedConfig } from "../src/config";
2
+ import { getResolvedConfig } from "@altano/astro-opengraph/config";
3
3
 
4
4
  export type Props = {
5
5
  /**
@@ -0,0 +1,45 @@
1
+ import { readFile } from "node:fs/promises";
2
+
3
+ //#region src/config.ts
4
+ async function deserializeVirtualConfig(configMaybeMocked) {
5
+ const config = typeof configMaybeMocked === "function" ? configMaybeMocked() : configMaybeMocked;
6
+ const fontsWithBuffers = await Promise.all(config.imageOptions.fonts.map(async (font) => {
7
+ const data = await readFile(font.path);
8
+ return {
9
+ ...font,
10
+ data
11
+ };
12
+ }));
13
+ return {
14
+ ...config,
15
+ imageOptions: {
16
+ ...config.imageOptions,
17
+ fonts: fontsWithBuffers
18
+ }
19
+ };
20
+ }
21
+ const imageOptionDefaults = {
22
+ width: 1200,
23
+ height: 630
24
+ };
25
+ const metaTagDefaults = { "og:image": `/opengraph.png` };
26
+ async function getResolvedConfig() {
27
+ const module = await import("virtual:astro-opengraph/user-config");
28
+ const lazyConfig = module.default;
29
+ const deserialized = await deserializeVirtualConfig(lazyConfig);
30
+ return {
31
+ ...deserialized,
32
+ imageOptions: {
33
+ ...imageOptionDefaults,
34
+ ...deserialized.imageOptions
35
+ },
36
+ componentMetaTagFallbacks: {
37
+ ...deserialized.componentMetaTagFallbacks,
38
+ ...metaTagDefaults
39
+ }
40
+ };
41
+ }
42
+
43
+ //#endregion
44
+ export { deserializeVirtualConfig, getResolvedConfig };
45
+ //# sourceMappingURL=config-CzK0JuaO.js.map
package/dist/config.d.ts CHANGED
@@ -1,4 +1,9 @@
1
- import type { OpengraphImageConfigDeserialized, OpengraphImageConfigResolved, OpengraphImageConfigSerializableMaybeMocked } from "./types.js";
2
- export declare function deserializeVirtualConfig(configMaybeMocked: OpengraphImageConfigSerializableMaybeMocked): Promise<OpengraphImageConfigDeserialized>;
3
- export declare function getResolvedConfig(): Promise<OpengraphImageConfigResolved>;
1
+ import { OpengraphImageConfigDeserialized, OpengraphImageConfigResolved, OpengraphImageConfigSerializableMaybeMocked } from "./types-Lk5HqHkQ.js";
2
+
3
+ //#region src/config.d.ts
4
+ declare function deserializeVirtualConfig(configMaybeMocked: OpengraphImageConfigSerializableMaybeMocked): Promise<OpengraphImageConfigDeserialized>;
5
+ declare function getResolvedConfig(): Promise<OpengraphImageConfigResolved>;
6
+
7
+ //#endregion
8
+ export { deserializeVirtualConfig, getResolvedConfig };
4
9
  //# sourceMappingURL=config.d.ts.map
package/dist/config.js ADDED
@@ -0,0 +1,3 @@
1
+ import { deserializeVirtualConfig, getResolvedConfig } from "./config-CzK0JuaO.js";
2
+
3
+ export { deserializeVirtualConfig, getResolvedConfig };
@@ -1,14 +1,28 @@
1
- import type { APIRoute } from "astro";
2
- import type { ImageOptions } from "./types.js";
1
+ import { ImageOptions } from "./types-Lk5HqHkQ.js";
2
+ import { APIRoute } from "astro";
3
+
4
+ //#region src/endpoint.d.ts
3
5
  type Options = {
4
- template: unknown;
5
- /**
6
- * Custom "Content-Type" header, only used in SSR. Defaults to "image/png"
7
- */
8
- contentType?: string;
9
- imageOptionOverrides?: Partial<ImageOptions>;
6
+ // We don't just type this as `AstroComponentFactory` because astro typing is
7
+ // hard to get right and simply importing a .astro file doesn't give you
8
+ // something typed as a factory.
9
+ template: unknown;
10
+ /**
11
+ * Custom "Content-Type" header, only used in SSR. Defaults to "image/png"
12
+ */
13
+ contentType?: string;
14
+ imageOptionOverrides?: Partial<ImageOptions>;
10
15
  };
11
- export declare function makeOpengraphDevEndpoint({ template, contentType, }: Options): APIRoute;
12
- export declare function makeOpengraphEndpoint({ template, imageOptionOverrides, contentType, }: Options): APIRoute;
13
- export {};
16
+ declare function makeOpengraphDevEndpoint({
17
+ template,
18
+ contentType
19
+ }: Options): APIRoute;
20
+ declare function makeOpengraphEndpoint({
21
+ template,
22
+ imageOptionOverrides,
23
+ contentType
24
+ }: Options): APIRoute;
25
+
26
+ //#endregion
27
+ export { makeOpengraphDevEndpoint, makeOpengraphEndpoint };
14
28
  //# sourceMappingURL=endpoint.d.ts.map
package/dist/endpoint.js CHANGED
@@ -1,137 +1,73 @@
1
- // src/endpoint.ts
1
+ import { getResolvedConfig } from "./config-CzK0JuaO.js";
2
2
  import { experimental_AstroContainer } from "astro/container";
3
3
  import { isAstroComponentFactory } from "astro/runtime/server/render/astro/factory.js";
4
-
5
- // src/config.ts
6
- import { readFile } from "node:fs/promises";
7
- async function deserializeVirtualConfig(configMaybeMocked) {
8
- const config = typeof configMaybeMocked === "function" ? configMaybeMocked() : configMaybeMocked;
9
- const fontsWithBuffers = await Promise.all(
10
- config.imageOptions.fonts.map(async (font) => {
11
- const data = await readFile(font.path);
12
- return {
13
- ...font,
14
- data
15
- };
16
- })
17
- );
18
- return {
19
- ...config,
20
- imageOptions: {
21
- ...config.imageOptions,
22
- fonts: fontsWithBuffers
23
- }
24
- };
25
- }
26
- var imageOptionDefaults = {
27
- width: 1200,
28
- height: 630
29
- };
30
- var metaTagDefaults = {
31
- "og:image": `/opengraph.png`
32
- };
33
- async function getResolvedConfig() {
34
- const module = await import("virtual:astro-opengraph/user-config");
35
- const lazyConfig = module.default;
36
- const deserialized = await deserializeVirtualConfig(lazyConfig);
37
- return {
38
- ...deserialized,
39
- imageOptions: {
40
- ...imageOptionDefaults,
41
- ...deserialized.imageOptions
42
- },
43
- componentMetaTagFallbacks: {
44
- ...deserialized.componentMetaTagFallbacks,
45
- ...metaTagDefaults
46
- }
47
- };
48
- }
49
-
50
- // src/image.ts
51
4
  import { getConfiguredImageService, imageConfig } from "astro:assets";
52
5
  import satori from "satori";
53
- import { html as htmlToVNode } from "satori-html";
6
+ import { html } from "satori-html";
54
7
  import he from "he";
55
- async function htmlToPNG(html, satoriOptions) {
56
- const responseTextWithDecodedHtmlEntities = he.decode(html);
57
- const vnode = htmlToVNode(responseTextWithDecodedHtmlEntities);
58
- const svg = await satori(vnode, satoriOptions);
59
- const fileBuffer = Buffer.from(svg, "utf-8");
60
- const uint8Array = new Uint8Array(
61
- fileBuffer.buffer,
62
- fileBuffer.byteOffset,
63
- fileBuffer.byteLength
64
- );
65
- return bufferToTransformedPNG(uint8Array);
8
+
9
+ //#region src/image.ts
10
+ /**
11
+ * Convert an html string to an image
12
+ */
13
+ async function htmlToPNG(html$1, satoriOptions) {
14
+ const responseTextWithDecodedHtmlEntities = he.decode(html$1);
15
+ const vnode = html(responseTextWithDecodedHtmlEntities);
16
+ const svg = await satori(vnode, satoriOptions);
17
+ const fileBuffer = Buffer.from(svg, "utf-8");
18
+ const uint8Array = new Uint8Array(fileBuffer.buffer, fileBuffer.byteOffset, fileBuffer.byteLength);
19
+ return bufferToTransformedPNG(uint8Array);
66
20
  }
21
+ /**
22
+ * Convert a buffer to an image using the astro local image service
23
+ */
67
24
  async function bufferToTransformedPNG(imageBuffer) {
68
- const imageService = await getConfiguredImageService();
69
- return imageService.transform(
70
- imageBuffer,
71
- { src: "", format: "png" },
72
- imageConfig
73
- );
25
+ const imageService = await getConfiguredImageService();
26
+ return imageService.transform(imageBuffer, {
27
+ src: "",
28
+ format: "png"
29
+ }, imageConfig);
74
30
  }
75
31
 
76
- // src/endpoint.ts
77
- function makeOpengraphDevEndpoint({
78
- template,
79
- contentType = "text/html"
80
- }) {
81
- return async ({ locals, params, props, request }) => {
82
- const config = await getResolvedConfig();
83
- if (config.command !== "dev") {
84
- return new Response(null, { status: 404 });
85
- }
86
- if (!isAstroComponentFactory(template)) {
87
- throw new Error(`Given is not an Astro template.`);
88
- }
89
- const container = await experimental_AstroContainer.create();
90
- const templateStr = await container.renderToString(template, {
91
- partial: false,
92
- request,
93
- params,
94
- locals,
95
- props
96
- });
97
- return new Response(templateStr, {
98
- headers: {
99
- "Content-Type": contentType
100
- }
101
- });
102
- };
32
+ //#endregion
33
+ //#region src/endpoint.ts
34
+ function makeOpengraphDevEndpoint({ template, contentType = "text/html" }) {
35
+ return async ({ locals, params, props, request }) => {
36
+ const config = await getResolvedConfig();
37
+ if (config.command !== "dev") return new Response(null, { status: 404 });
38
+ if (!isAstroComponentFactory(template)) throw new Error(`Given is not an Astro template.`);
39
+ const container = await experimental_AstroContainer.create();
40
+ const templateStr = await container.renderToString(template, {
41
+ partial: false,
42
+ request,
43
+ params,
44
+ locals,
45
+ props
46
+ });
47
+ return new Response(templateStr, { headers: { "Content-Type": contentType } });
48
+ };
103
49
  }
104
- function makeOpengraphEndpoint({
105
- template,
106
- imageOptionOverrides,
107
- contentType = "image/png"
108
- }) {
109
- return async ({ locals, params, props, request }) => {
110
- if (!isAstroComponentFactory(template)) {
111
- throw new Error(`Given is not an Astro template.`);
112
- }
113
- const container = await experimental_AstroContainer.create();
114
- const templateStr = await container.renderToString(template, {
115
- partial: false,
116
- request,
117
- params,
118
- locals,
119
- props
120
- });
121
- const config = await getResolvedConfig();
122
- const imageOptions = {
123
- ...config.imageOptions,
124
- ...imageOptionOverrides
125
- };
126
- const png = await htmlToPNG(templateStr, imageOptions);
127
- return new Response(png.data, {
128
- headers: {
129
- "Content-Type": contentType
130
- }
131
- });
132
- };
50
+ function makeOpengraphEndpoint({ template, imageOptionOverrides, contentType = "image/png" }) {
51
+ return async ({ locals, params, props, request }) => {
52
+ if (!isAstroComponentFactory(template)) throw new Error(`Given is not an Astro template.`);
53
+ const container = await experimental_AstroContainer.create();
54
+ const templateStr = await container.renderToString(template, {
55
+ partial: false,
56
+ request,
57
+ params,
58
+ locals,
59
+ props
60
+ });
61
+ const config = await getResolvedConfig();
62
+ const imageOptions = {
63
+ ...config.imageOptions,
64
+ ...imageOptionOverrides
65
+ };
66
+ const png = await htmlToPNG(templateStr, imageOptions);
67
+ return new Response(png.data, { headers: { "Content-Type": contentType } });
68
+ };
133
69
  }
134
- export {
135
- makeOpengraphDevEndpoint,
136
- makeOpengraphEndpoint
137
- };
70
+
71
+ //#endregion
72
+ export { makeOpengraphDevEndpoint, makeOpengraphEndpoint };
73
+ //# sourceMappingURL=endpoint.js.map
package/dist/index.d.ts CHANGED
@@ -1,3 +1,9 @@
1
- export { default } from "./integration.js";
2
- export type { OpengraphImageConfig, ImageOptionsWithFontPaths, ComponentMetaTagFallbacks, } from "./types.js";
1
+ import { ComponentMetaTagFallbacks, ImageOptionsWithFontPaths, OpengraphImageConfig } from "./types-Lk5HqHkQ.js";
2
+ import { AstroIntegration } from "astro";
3
+
4
+ //#region src/integration.d.ts
5
+ declare const _default: (config: OpengraphImageConfig) => AstroIntegration;
6
+
7
+ //#endregion
8
+ export { ComponentMetaTagFallbacks, ImageOptionsWithFontPaths, OpengraphImageConfig, _default as default };
3
9
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,65 +1,48 @@
1
- // src/virtual-user-config.ts
1
+ //#region src/virtual-user-config.ts
2
2
  function resolveVirtualModuleId(id) {
3
- return `\0${id}`;
3
+ return `\0${id}`;
4
4
  }
5
+ /**
6
+ * Vite plugin that exposes OpengraphImage user config and project context via
7
+ * virtual modules.
8
+ */
5
9
  function vitePluginOpengraphImageUserConfig(config) {
6
- const modules = {
7
- "virtual:astro-opengraph/user-config": `export default ${JSON.stringify(
8
- config
9
- )}`
10
- };
11
- const resolutionMap = Object.fromEntries(
12
- Object.keys(modules).map((key) => [
13
- resolveVirtualModuleId(key),
14
- key
15
- ])
16
- );
17
- return {
18
- name: "vite-plugin-astro-opengraph-user-config",
19
- resolveId(id) {
20
- if (id in modules) return resolveVirtualModuleId(id);
21
- },
22
- load(id) {
23
- const resolution = resolutionMap[id];
24
- if (resolution) return modules[resolution];
25
- }
26
- };
10
+ /** Map of virtual module names to their code contents as strings. */
11
+ const modules = { "virtual:astro-opengraph/user-config": `export default ${JSON.stringify(config)}` };
12
+ /** Mapping names prefixed with `\0` to their original form. */
13
+ const resolutionMap = Object.fromEntries(Object.keys(modules).map((key) => [resolveVirtualModuleId(key), key]));
14
+ return {
15
+ name: "vite-plugin-astro-opengraph-user-config",
16
+ resolveId(id) {
17
+ if (id in modules) return resolveVirtualModuleId(id);
18
+ },
19
+ load(id) {
20
+ const resolution = resolutionMap[id];
21
+ if (resolution) return modules[resolution];
22
+ }
23
+ };
27
24
  }
28
25
 
29
- // src/integration.ts
26
+ //#endregion
27
+ //#region src/integration.ts
30
28
  var integration_default = (config) => ({
31
- name: "@altano/astro-opengraph",
32
- hooks: {
33
- async "astro:config:setup"({
34
- updateConfig,
35
- command,
36
- addDevToolbarApp
37
- }) {
38
- const imageOptions = await config.getImageOptions();
39
- const configSerializable = {
40
- imageOptions,
41
- command
42
- };
43
- updateConfig({
44
- vite: {
45
- // Shove the serializable config into the virtual module for later
46
- // retrieval in the middleware
47
- plugins: [vitePluginOpengraphImageUserConfig(configSerializable)]
48
- }
49
- });
50
- addDevToolbarApp({
51
- id: "@altano/astro-opengraph",
52
- name: "Open Graph",
53
- // icon: "🌠",
54
- icon: "image",
55
- // We don't use `@altano/astro-opengraph/toolbar` because that won't
56
- // resolve when serving the test fixture for e2e runs (`pnpm
57
- // test:e2e:server`)
58
- entrypoint: new URL("./toolbar/index.js", import.meta.url)
59
- });
60
- }
61
- }
29
+ name: "@altano/astro-opengraph",
30
+ hooks: { async "astro:config:setup"({ updateConfig, command, addDevToolbarApp }) {
31
+ const imageOptions = await config.getImageOptions();
32
+ const configSerializable = {
33
+ imageOptions,
34
+ command
35
+ };
36
+ updateConfig({ vite: { plugins: [vitePluginOpengraphImageUserConfig(configSerializable)] } });
37
+ addDevToolbarApp({
38
+ id: "@altano/astro-opengraph",
39
+ name: "Open Graph",
40
+ icon: "image",
41
+ entrypoint: new URL("./toolbar/index.js", import.meta.url)
42
+ });
43
+ } }
62
44
  });
63
- export {
64
- integration_default as default
65
- };
45
+
46
+ //#endregion
47
+ export { integration_default as default };
48
+ //# sourceMappingURL=index.js.map
@@ -1,3 +1,8 @@
1
- declare const _default: import("astro").DevToolbarApp;
2
- export default _default;
1
+ import { DevToolbarApp } from "astro";
2
+
3
+ //#region src/toolbar/index.d.ts
4
+ declare const app: DevToolbarApp;
5
+
6
+ //#endregion
7
+ export { app as default };
3
8
  //# sourceMappingURL=index.d.ts.map