@soonit/rspress-plugin-og 0.0.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 - Estéban Soubiran <esteban@soubiran.dev> (https://soubiran.dev)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,107 @@
1
+ # rspress-plugin-og
2
+
3
+ [![npm version][npm-version-src]][npm-version-href]
4
+ [![npm downloads][npm-downloads-src]][npm-downloads-href]
5
+ [![License][license-src]][license-href]
6
+ [![pkg.pr.new](https://pkg.pr.new/badge/Barbapapazes/vitepress-plugin-og)](https://pkg.pr.new/~/Barbapapazes/vitepress-plugin-og)
7
+
8
+ Automatically generate Open Graph images for your Rspress pages.
9
+
10
+ - 🖼️ Generates OG images from an SVG template
11
+ - 🚀 Integrates with Rspress
12
+ - 🧩 Bring your own SVG template
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ pnpm add -D rspress-plugin-og
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ Add the plugin to your Rspress configuration file (`rspress.config.ts`):
23
+
24
+ For Rspress v2:
25
+
26
+ ```ts
27
+ import { defineConfig } from '@rspress/core'
28
+ import pluginOg from 'rspress-plugin-og'
29
+
30
+ export default defineConfig({
31
+ plugins: [
32
+ pluginOg({
33
+ domain: 'https://example.com',
34
+ // ...other options
35
+ }),
36
+ ],
37
+ })
38
+ ```
39
+
40
+ For Rspress v1:
41
+
42
+ This is a plugin that is compatible with both V2 and V1, but when used in V1, there may be type errors.
43
+
44
+ ```ts
45
+ import pluginOg from 'rspress-plugin-og'
46
+ import { defineConfig } from 'rspress/config'
47
+
48
+ export default defineConfig({
49
+ plugins: [
50
+ pluginOg({
51
+ domain: 'https://example.com',
52
+ // ...other options
53
+ }) as any,
54
+ ],
55
+ })
56
+ ```
57
+
58
+ ## Configuration
59
+
60
+ | Option | Type | Default | Description |
61
+ | :--- | :--- | :--- | :--- |
62
+ | `domain` | `string` | **Required** | The domain to use for the generated OG image URLs. |
63
+ | `outDir` | `string` | `'og'` | Output directory for the generated OG images (inside `public`). |
64
+ | `ogTemplate` | `string` | `'og-template.svg'` | The path to the OG image template file. |
65
+ | `maxTitleSizePerLine` | `number` | `30` | Maximum number of characters per line in the title. |
66
+
67
+ ## Template
68
+
69
+ Create an SVG template at `og-template.svg` (or your configured path). Use `{{line1}}`, `{{line2}}`, and `{{line3}}` placeholders for the title lines.
70
+
71
+ Example:
72
+
73
+ ```xml
74
+ <svg width="1200" height="630" viewBox="0 0 1200 630" xmlns="http://www.w3.org/2000/svg">
75
+ <!-- Background -->
76
+ <rect width="1200" height="630" fill="#1e1e1e" />
77
+
78
+ <!-- Title -->
79
+ <text x="60" y="200" font-family="Arial" font-size="80" fill="#ffffff">
80
+ <tspan x="60" dy="0">{{line1}}</tspan>
81
+ <tspan x="60" dy="100">{{line2}}</tspan>
82
+ <tspan x="60" dy="100">{{line3}}</tspan>
83
+ </text>
84
+ </svg>
85
+ ```
86
+
87
+ ## Sponsors
88
+
89
+ <p align="center">
90
+ <a href="https://github.com/sponsors/barbapapazes">
91
+ <img src='https://cdn.jsdelivr.net/gh/barbapapazes/static/sponsors.svg'/>
92
+ </a>
93
+ </p>
94
+
95
+ ## License
96
+
97
+ [MIT](../../LICENSE) License © 2025-PRESENT [Estéban Soubiran](https://github.com/barbapapazes)
98
+
99
+ <!-- Badges -->
100
+ [npm-version-src]: https://img.shields.io/npm/v/rspress-plugin-og/latest.svg?style=flat&colorA=000&colorB=171717
101
+ [npm-version-href]: https://npmjs.com/package/rspress-plugin-og
102
+
103
+ [npm-downloads-src]: https://img.shields.io/npm/dm/rspress-plugin-og.svg?style=flat&colorA=000&colorB=171717
104
+ [npm-downloads-href]: https://npmjs.com/package/rspress-plugin-og
105
+
106
+ [license-src]: https://img.shields.io/npm/l/rspress-plugin-og.svg?style=flat&colorA=000&colorB=171717
107
+ [license-href]: https://npmjs.com/package/rspress-plugin-og
@@ -0,0 +1,13 @@
1
+ import { t as Options } from "./types-d5VtTQ1o.mjs";
2
+ import * as _rspress_core0 from "@rspress/core";
3
+ import { PageIndexInfo } from "@rspress/core";
4
+
5
+ //#region src/index.d.ts
6
+ declare function export_default(userOptions: Options): {
7
+ name: string;
8
+ config(config: _rspress_core0.UserConfig): _rspress_core0.UserConfig;
9
+ extendPageData: (pageData: PageIndexInfo) => void;
10
+ afterBuild(config: _rspress_core0.UserConfig): Promise<void>;
11
+ };
12
+ //#endregion
13
+ export { export_default as default };
package/dist/index.mjs ADDED
@@ -0,0 +1,382 @@
1
+ import { dirname, join, relative } from "node:path";
2
+ import node_process, { cwd } from "node:process";
3
+ import { Buffer } from "node:buffer";
4
+ import { existsSync, mkdirSync, readFileSync } from "node:fs";
5
+ import sharp from "sharp";
6
+ import node_os from "node:os";
7
+ import node_tty from "node:tty";
8
+ import { joinURL } from "ufo";
9
+
10
+ //#region ../core/src/head.ts
11
+ function createTwitterImageHead(imageUrl) {
12
+ return ["meta", {
13
+ name: "twitter:image",
14
+ content: imageUrl
15
+ }];
16
+ }
17
+ function createTwitterCardHead() {
18
+ return ["meta", {
19
+ name: "twitter:card",
20
+ content: "summary_large_image"
21
+ }];
22
+ }
23
+ function createOgImageHead(imageUrl) {
24
+ return ["meta", {
25
+ property: "og:image",
26
+ content: imageUrl
27
+ }];
28
+ }
29
+ function createOgImageWidthHead() {
30
+ return ["meta", {
31
+ property: "og:image:width",
32
+ content: "1200"
33
+ }];
34
+ }
35
+ function createOgImageHeightHead() {
36
+ return ["meta", {
37
+ property: "og:image:height",
38
+ content: "630"
39
+ }];
40
+ }
41
+ function createOgImageTypeHead() {
42
+ return ["meta", {
43
+ property: "og:image:type",
44
+ content: "image/png"
45
+ }];
46
+ }
47
+
48
+ //#endregion
49
+ //#region ../core/src/og.ts
50
+ const templates = /* @__PURE__ */ new Map();
51
+ function escapeHtml(unsafe) {
52
+ return unsafe.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
53
+ }
54
+ async function generateOgImage({ title }, output, options) {
55
+ if (existsSync(output)) return;
56
+ if (!templates.has(options.ogTemplate)) templates.set(options.ogTemplate, readFileSync(options.ogTemplate, "utf-8"));
57
+ const ogTemplate = templates.get(options.ogTemplate);
58
+ mkdirSync(dirname(output), { recursive: true });
59
+ const lines = title.trim().split(new RegExp(`(.{0,${options.maxTitleSizePerLine}})(?:\\s|$)`, "g")).filter(Boolean);
60
+ const data = {
61
+ line1: lines[0] ? escapeHtml(lines[0]) : "",
62
+ line2: lines[1] ? escapeHtml(lines[1]) : "",
63
+ line3: lines[2] ? escapeHtml(lines[2]) : ""
64
+ };
65
+ const svg = ogTemplate.replace(/\{\{([^}]+)\}\}/g, (_, name) => data[name] || "");
66
+ await sharp(Buffer.from(svg)).resize(1200, 630).png().toFile(output);
67
+ }
68
+
69
+ //#endregion
70
+ //#region ../core/src/utils.ts
71
+ function slugifyPath(path) {
72
+ return `${path.replace(/\//g, "-").replace(/\.mdx?$/, "")}.png`;
73
+ }
74
+
75
+ //#endregion
76
+ //#region ../../node_modules/.pnpm/rslog@1.3.2/node_modules/rslog/dist/index.js
77
+ function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : node_process.argv) {
78
+ const prefix = flag.startsWith("-") ? "" : 1 === flag.length ? "-" : "--";
79
+ const position = argv.indexOf(prefix + flag);
80
+ const terminatorPosition = argv.indexOf("--");
81
+ return -1 !== position && (-1 === terminatorPosition || position < terminatorPosition);
82
+ }
83
+ const { env } = node_process;
84
+ let flagForceColor;
85
+ if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) flagForceColor = 0;
86
+ else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) flagForceColor = 1;
87
+ function envForceColor() {
88
+ if (!("FORCE_COLOR" in env)) return;
89
+ if ("true" === env.FORCE_COLOR) return 1;
90
+ if ("false" === env.FORCE_COLOR) return 0;
91
+ if (0 === env.FORCE_COLOR.length) return 1;
92
+ const level = Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
93
+ if (![
94
+ 0,
95
+ 1,
96
+ 2,
97
+ 3
98
+ ].includes(level)) return;
99
+ return level;
100
+ }
101
+ function translateLevel(level) {
102
+ if (0 === level) return false;
103
+ return {
104
+ level,
105
+ hasBasic: true,
106
+ has256: level >= 2,
107
+ has16m: level >= 3
108
+ };
109
+ }
110
+ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
111
+ const noFlagForceColor = envForceColor();
112
+ if (void 0 !== noFlagForceColor) flagForceColor = noFlagForceColor;
113
+ const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
114
+ if (0 === forceColor) return 0;
115
+ if (sniffFlags) {
116
+ if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) return 3;
117
+ if (hasFlag("color=256")) return 2;
118
+ }
119
+ if ("TF_BUILD" in env && "AGENT_NAME" in env) return 1;
120
+ if (haveStream && !streamIsTTY && void 0 === forceColor) return 0;
121
+ const min = forceColor || 0;
122
+ if ("dumb" === env.TERM) return min;
123
+ if ("win32" === node_process.platform) {
124
+ const osRelease = node_os.release().split(".");
125
+ if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) return Number(osRelease[2]) >= 14931 ? 3 : 2;
126
+ return 1;
127
+ }
128
+ if ("CI" in env) {
129
+ if ([
130
+ "GITHUB_ACTIONS",
131
+ "GITEA_ACTIONS",
132
+ "CIRCLECI"
133
+ ].some((key) => key in env)) return 3;
134
+ if ([
135
+ "TRAVIS",
136
+ "APPVEYOR",
137
+ "GITLAB_CI",
138
+ "BUILDKITE",
139
+ "DRONE"
140
+ ].some((sign) => sign in env) || "codeship" === env.CI_NAME) return 1;
141
+ return min;
142
+ }
143
+ if ("TEAMCITY_VERSION" in env) return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
144
+ if ("truecolor" === env.COLORTERM) return 3;
145
+ if ("xterm-kitty" === env.TERM) return 3;
146
+ if ("xterm-ghostty" === env.TERM) return 3;
147
+ if ("wezterm" === env.TERM) return 3;
148
+ if ("TERM_PROGRAM" in env) {
149
+ const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
150
+ switch (env.TERM_PROGRAM) {
151
+ case "iTerm.app": return version >= 3 ? 3 : 2;
152
+ case "Apple_Terminal": return 2;
153
+ }
154
+ }
155
+ if (/-256(color)?$/i.test(env.TERM)) return 2;
156
+ if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) return 1;
157
+ if ("COLORTERM" in env) return 1;
158
+ return min;
159
+ }
160
+ function createSupportsColor(stream, options = {}) {
161
+ return translateLevel(_supportsColor(stream, {
162
+ streamIsTTY: stream && stream.isTTY,
163
+ ...options
164
+ }));
165
+ }
166
+ const supports_color = {
167
+ stdout: createSupportsColor({ isTTY: node_tty.isatty(1) }),
168
+ stderr: createSupportsColor({ isTTY: node_tty.isatty(2) })
169
+ };
170
+ const colorLevel = supports_color.stdout ? supports_color.stdout.level : 0;
171
+ let errorStackRegExp = /at [^\r\n]{0,200}:\d+:\d+[\s\)]*$/;
172
+ let anonymousErrorStackRegExp = /at [^\r\n]{0,200}\(<anonymous>\)$/;
173
+ let indexErrorStackRegExp = /at [^\r\n]{0,200}\(index\s\d+\)$/;
174
+ let isErrorStackMessage = (message) => errorStackRegExp.test(message) || anonymousErrorStackRegExp.test(message) || indexErrorStackRegExp.test(message);
175
+ let formatter = (open, close, replace = open) => colorLevel >= 2 ? (input) => {
176
+ let string = "" + input;
177
+ let index = string.indexOf(close, open.length);
178
+ return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
179
+ } : String;
180
+ let replaceClose = (string, close, replace, index) => {
181
+ let start = string.substring(0, index) + replace;
182
+ let end = string.substring(index + close.length);
183
+ let nextIndex = end.indexOf(close);
184
+ return ~nextIndex ? start + replaceClose(end, close, replace, nextIndex) : start + end;
185
+ };
186
+ const bold = formatter("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m");
187
+ const red = formatter("\x1B[31m", "\x1B[39m");
188
+ const green = formatter("\x1B[32m", "\x1B[39m");
189
+ const yellow = formatter("\x1B[33m", "\x1B[39m");
190
+ const magenta = formatter("\x1B[35m", "\x1B[39m");
191
+ const cyan = formatter("\x1B[36m", "\x1B[39m");
192
+ const gray = formatter("\x1B[90m", "\x1B[39m");
193
+ let startColor = [
194
+ 189,
195
+ 255,
196
+ 243
197
+ ];
198
+ let endColor = [
199
+ 74,
200
+ 194,
201
+ 154
202
+ ];
203
+ let isWord = (char) => !/[\s\n]/.test(char);
204
+ let gradient = (message) => {
205
+ if (colorLevel < 3) return 2 === colorLevel ? bold(cyan(message)) : message;
206
+ let chars = [...message];
207
+ let steps = chars.filter(isWord).length;
208
+ let r = startColor[0];
209
+ let g = startColor[1];
210
+ let b = startColor[2];
211
+ let rStep = (endColor[0] - r) / steps;
212
+ let gStep = (endColor[1] - g) / steps;
213
+ let bStep = (endColor[2] - b) / steps;
214
+ let output = "";
215
+ for (let char of chars) {
216
+ if (isWord(char)) {
217
+ r += rStep;
218
+ g += gStep;
219
+ b += bStep;
220
+ }
221
+ output += `\x1b[38;2;${Math.round(r)};${Math.round(g)};${Math.round(b)}m${char}\x1b[39m`;
222
+ }
223
+ return bold(output);
224
+ };
225
+ let LOG_LEVEL = {
226
+ silent: -1,
227
+ error: 0,
228
+ warn: 1,
229
+ info: 2,
230
+ log: 2,
231
+ verbose: 3
232
+ };
233
+ let LOG_TYPES = {
234
+ error: {
235
+ label: "error",
236
+ level: "error",
237
+ color: red
238
+ },
239
+ warn: {
240
+ label: "warn",
241
+ level: "warn",
242
+ color: yellow
243
+ },
244
+ info: {
245
+ label: "info",
246
+ level: "info",
247
+ color: cyan
248
+ },
249
+ start: {
250
+ label: "start",
251
+ level: "info",
252
+ color: cyan
253
+ },
254
+ ready: {
255
+ label: "ready",
256
+ level: "info",
257
+ color: green
258
+ },
259
+ success: {
260
+ label: "success",
261
+ level: "info",
262
+ color: green
263
+ },
264
+ log: { level: "info" },
265
+ debug: {
266
+ label: "debug",
267
+ level: "verbose",
268
+ color: magenta
269
+ }
270
+ };
271
+ const normalizeErrorMessage = (err) => {
272
+ if (err.stack) {
273
+ let [name, ...rest] = err.stack.split("\n");
274
+ if (name.startsWith("Error: ")) name = name.slice(7);
275
+ return `${name}\n${gray(rest.join("\n"))}`;
276
+ }
277
+ return err.message;
278
+ };
279
+ let createLogger = (options = {}) => {
280
+ let maxLevel = options.level || "info";
281
+ let log = (type, message, ...args) => {
282
+ let logType = LOG_TYPES[type];
283
+ const { level } = logType;
284
+ if (LOG_LEVEL[level] > LOG_LEVEL[maxLevel]) return;
285
+ if (null == message) return console.log();
286
+ let label = "";
287
+ let text = "";
288
+ if ("label" in logType) {
289
+ label = (logType.label || "").padEnd(7);
290
+ label = bold(logType.color ? logType.color(label) : label);
291
+ }
292
+ if (message instanceof Error) {
293
+ text += normalizeErrorMessage(message);
294
+ const { cause } = message;
295
+ if (cause) {
296
+ text += yellow("\n [cause]: ");
297
+ text += cause instanceof Error ? normalizeErrorMessage(cause) : String(cause);
298
+ }
299
+ } else if ("error" === level && "string" == typeof message) text = message.split("\n").map((line) => isErrorStackMessage(line) ? gray(line) : line).join("\n");
300
+ else text = `${message}`;
301
+ const method = "error" === level || "warn" === level ? level : "log";
302
+ console[method](label.length ? `${label} ${text}` : text, ...args);
303
+ };
304
+ let logger = { greet: (message) => log("log", gradient(message)) };
305
+ Object.keys(LOG_TYPES).forEach((key) => {
306
+ logger[key] = (...args) => log(key, ...args);
307
+ });
308
+ Object.defineProperty(logger, "level", {
309
+ get: () => maxLevel,
310
+ set(val) {
311
+ maxLevel = val;
312
+ }
313
+ });
314
+ logger.override = (customLogger) => {
315
+ Object.assign(logger, customLogger);
316
+ };
317
+ return logger;
318
+ };
319
+ let src_logger = createLogger();
320
+
321
+ //#endregion
322
+ //#region src/options.ts
323
+ function resolveOptions(userOptions) {
324
+ return {
325
+ domain: "",
326
+ outDir: "og",
327
+ ogTemplate: "og-template.svg",
328
+ maxTitleSizePerLine: 30,
329
+ ...userOptions
330
+ };
331
+ }
332
+
333
+ //#endregion
334
+ //#region src/index.ts
335
+ const NAME = "rspress-plugin-og";
336
+ const LOG_PREFIX = `[${NAME}]`;
337
+ function src_default(userOptions) {
338
+ const options = resolveOptions(userOptions);
339
+ const images = /* @__PURE__ */ new Map();
340
+ const headCreators = [
341
+ (url) => createTwitterImageHead(url),
342
+ () => createTwitterCardHead(),
343
+ (url) => createOgImageHead(url),
344
+ () => createOgImageWidthHead(),
345
+ () => createOgImageHeightHead(),
346
+ () => createOgImageTypeHead()
347
+ ];
348
+ return {
349
+ name: NAME,
350
+ config(config) {
351
+ config.head = [...config.head || [], ...headCreators.map((creator) => (route) => {
352
+ const imageInfo = images.get(route.routePath);
353
+ if (!imageInfo) return;
354
+ return creator(imageInfo.imageUrl);
355
+ })];
356
+ return config;
357
+ },
358
+ extendPageData: (pageData) => {
359
+ if (!(pageData.frontmatter.title || pageData.title)) {
360
+ src_logger.warn(`${LOG_PREFIX} Cannot generate OG image for page without title: ${pageData._relativePath}`);
361
+ return;
362
+ }
363
+ const imageName = slugifyPath(pageData._relativePath);
364
+ images.set(pageData.routePath, {
365
+ title: pageData.frontmatter.title || pageData.title,
366
+ imageName,
367
+ imageUrl: joinURL(options.domain, options.outDir, imageName)
368
+ });
369
+ },
370
+ async afterBuild(config) {
371
+ const outputFolder = join(cwd(), config.outDir ?? "doc_build", options.outDir);
372
+ src_logger.info(`${LOG_PREFIX} Generating OG images to ${relative(cwd(), outputFolder)} ...`);
373
+ await Promise.all(Array.from(images.entries()).map(([_, { title, imageName }]) => {
374
+ return generateOgImage({ title }, join(outputFolder, imageName), options);
375
+ }));
376
+ src_logger.success(`${LOG_PREFIX} ${images.size} OG images generated.`);
377
+ }
378
+ };
379
+ }
380
+
381
+ //#endregion
382
+ export { src_default as default };
@@ -0,0 +1,33 @@
1
+ //#region ../core/src/types.d.ts
2
+ interface Options {
3
+ /**
4
+ * The domain to use for the generated OG image URLs.
5
+ */
6
+ domain: string;
7
+ /**
8
+ * Output directory for the generated OG images.
9
+ *
10
+ * @default 'og'
11
+ */
12
+ outDir?: string;
13
+ /**
14
+ * Maximum number of characters per line in the title.
15
+ *
16
+ * @default 30
17
+ */
18
+ maxTitleSizePerLine?: number;
19
+ /**
20
+ * The path to the OG image template file.
21
+ *
22
+ * @default '.vitepress/og-template.svg' for VitePress
23
+ * @default 'og-template.svg' for Rspress
24
+ */
25
+ ogTemplate?: string;
26
+ }
27
+ interface ResolvedOptions extends Required<Options> {}
28
+ //#endregion
29
+ //#region src/types.d.ts
30
+ interface Options$1 extends Options {}
31
+ interface ResolvedOptions$1 extends ResolvedOptions {}
32
+ //#endregion
33
+ export { ResolvedOptions$1 as n, Options$1 as t };
@@ -0,0 +1,2 @@
1
+ import { n as ResolvedOptions, t as Options } from "./types-d5VtTQ1o.mjs";
2
+ export { Options, ResolvedOptions };
package/dist/types.mjs ADDED
@@ -0,0 +1 @@
1
+ export { };
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@soonit/rspress-plugin-og",
3
+ "type": "module",
4
+ "version": "0.0.0",
5
+ "description": "Automatically generate Open Graph images for your Rspress pages.",
6
+ "author": "Estéban Soubiran <esteban@soubiran.dev>",
7
+ "license": "MIT",
8
+ "funding": "https://github.com/sponsors/Barbapapazes",
9
+ "homepage": "https://github.com/Barbapapazes/vitepress-plugin-og",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/Barbapapazes/vitepress-plugin-og"
13
+ },
14
+ "bugs": "https://github.com/Barbapapazes/vitepress-plugin-og/issues",
15
+ "publishConfig": {
16
+ "access": "public",
17
+ "registry": "https://registry.npmjs.org/"
18
+ },
19
+ "exports": {
20
+ ".": {
21
+ "types": "./dist/index.d.mts",
22
+ "import": "./dist/index.mjs"
23
+ },
24
+ "./types": {
25
+ "types": "./dist/types.d.mts",
26
+ "import": "./dist/types.mjs"
27
+ },
28
+ "./*": "./*"
29
+ },
30
+ "main": "dist/index.mjs",
31
+ "types": "dist/index.d.mts",
32
+ "files": [
33
+ "dist"
34
+ ],
35
+ "engines": {
36
+ "node": ">=20"
37
+ },
38
+ "peerDependencies": {
39
+ "@rspress/core": "^2.0.0-rc.1 || ^2.0.0"
40
+ },
41
+ "dependencies": {
42
+ "sharp": "^0.34.5",
43
+ "ufo": "^1.6.1"
44
+ },
45
+ "devDependencies": {
46
+ "rslog": "^1.3.2",
47
+ "tsdown": "^0.16.6",
48
+ "vitest": "^4.0.12"
49
+ },
50
+ "scripts": {
51
+ "build": "tsdown",
52
+ "test": "vitest"
53
+ }
54
+ }