nuxt-og-image 6.6.0 → 6.7.1
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 +2 -0
- package/dist/chunks/tw4.cjs +7 -7
- package/dist/chunks/tw4.mjs +7 -7
- package/dist/chunks/uno.cjs +6 -6
- package/dist/chunks/uno.mjs +6 -6
- package/dist/cli.cjs +12 -5
- package/dist/cli.mjs +10 -3
- package/dist/module.cjs +5 -5
- package/dist/module.d.cts +5 -3
- package/dist/module.d.mts +5 -3
- package/dist/module.d.ts +5 -3
- package/dist/module.json +1 -1
- package/dist/module.mjs +5 -5
- package/dist/runtime/server/og-image/bindings/font-assets/cloudflare.d.ts +1 -1
- package/dist/runtime/server/og-image/bindings/font-assets/cloudflare.js +6 -1
- package/dist/runtime/server/og-image/bindings/font-assets/dev-prerender.js +13 -6
- package/dist/runtime/server/og-image/bindings/font-assets/external-url.d.ts +36 -0
- package/dist/runtime/server/og-image/bindings/font-assets/external-url.js +47 -0
- package/dist/runtime/server/og-image/bindings/font-assets/node.d.ts +1 -1
- package/dist/runtime/server/og-image/bindings/font-assets/node.js +14 -7
- package/dist/runtime/server/og-image/bindings/takumi/node-dev.d.ts +2 -1
- package/dist/runtime/server/og-image/bindings/takumi/node-dev.js +10 -8
- package/dist/runtime/server/og-image/bindings/takumi/node.d.ts +2 -1
- package/dist/runtime/server/og-image/bindings/takumi/node.js +2 -1
- package/dist/runtime/server/og-image/bindings/takumi/resource-urls.d.ts +2 -0
- package/dist/runtime/server/og-image/bindings/takumi/resource-urls.js +91 -0
- package/dist/runtime/server/og-image/bindings/takumi/wasm.d.ts +2 -1
- package/dist/runtime/server/og-image/bindings/takumi/wasm.js +2 -1
- package/dist/runtime/server/og-image/fonts.d.ts +4 -0
- package/dist/runtime/server/og-image/fonts.js +21 -5
- package/dist/runtime/server/og-image/satori/instances.d.ts +1 -2
- package/dist/runtime/server/og-image/takumi/renderer.js +61 -19
- package/dist/runtime/server/util/ssrf.d.ts +10 -0
- package/dist/runtime/server/util/ssrf.js +9 -1
- package/dist/runtime/types.d.ts +13 -0
- package/dist/shared/{nuxt-og-image.CfTPCtaS.cjs → nuxt-og-image.BCK8Adm4.cjs} +181 -555
- package/dist/shared/nuxt-og-image.DQkJQHaN.cjs +689 -0
- package/dist/shared/nuxt-og-image.LgUGeaz-.mjs +660 -0
- package/dist/shared/{nuxt-og-image.DdbTs-xp.mjs → nuxt-og-image.Pfj5JkJd.mjs} +122 -496
- package/package.json +46 -42
- package/dist/shared/nuxt-og-image.CJa2KCie.mjs +0 -189
- package/dist/shared/nuxt-og-image.CMYbz66P.cjs +0 -193
package/README.md
CHANGED
|
@@ -47,6 +47,8 @@ npx nuxi@latest module add og-image
|
|
|
47
47
|
> npx skilld add nuxt-og-image
|
|
48
48
|
> ```
|
|
49
49
|
|
|
50
|
+
💡 Built your OG images? Check how they render across Twitter, Facebook, LinkedIn and Slack with the free [Social Share Debugger](https://nuxtseo.com/tools/social-share-debugger), or monitor them site-wide with [Nuxt SEO Pro](https://nuxtseo.com/pro).
|
|
51
|
+
|
|
50
52
|
## Documentation
|
|
51
53
|
|
|
52
54
|
[📖 Read the full documentation](https://nuxtseo.com/og-image/getting-started/installation) for more information.
|
package/dist/chunks/tw4.cjs
CHANGED
|
@@ -4,7 +4,8 @@ const promises = require('node:fs/promises');
|
|
|
4
4
|
const node_url = require('node:url');
|
|
5
5
|
const exsolve = require('exsolve');
|
|
6
6
|
const pathe = require('pathe');
|
|
7
|
-
const module$1 = require('../shared/nuxt-og-image.
|
|
7
|
+
const module$1 = require('../shared/nuxt-og-image.BCK8Adm4.cjs');
|
|
8
|
+
require('node:crypto');
|
|
8
9
|
require('node:fs');
|
|
9
10
|
require('@nuxt/kit');
|
|
10
11
|
require('defu');
|
|
@@ -12,12 +13,14 @@ require('nuxt-site-config/kit');
|
|
|
12
13
|
require('ohash');
|
|
13
14
|
require('pkg-types');
|
|
14
15
|
require('std-env');
|
|
15
|
-
require('node:crypto');
|
|
16
16
|
require('oxc-walker');
|
|
17
|
-
require('
|
|
17
|
+
require('../shared/nuxt-og-image.DQkJQHaN.cjs');
|
|
18
|
+
require('magicast');
|
|
19
|
+
require('magicast/helpers');
|
|
18
20
|
require('../../dist/runtime/logger.js');
|
|
19
|
-
require('chrome-launcher');
|
|
20
21
|
require('nypm');
|
|
22
|
+
require('nuxtseo-shared/kit');
|
|
23
|
+
require('chrome-launcher');
|
|
21
24
|
require('nuxtseo-shared/devtools');
|
|
22
25
|
require('unstorage');
|
|
23
26
|
require('unstorage/drivers/fs-lite');
|
|
@@ -30,9 +33,6 @@ require('@vue/compiler-sfc');
|
|
|
30
33
|
require('ofetch');
|
|
31
34
|
require('ultrahtml');
|
|
32
35
|
require('../../dist/runtime/server/og-image/core/transforms/emojis/emoji-utils.js');
|
|
33
|
-
require('../shared/nuxt-og-image.CMYbz66P.cjs');
|
|
34
|
-
require('magicast');
|
|
35
|
-
require('magicast/helpers');
|
|
36
36
|
|
|
37
37
|
const RE_GRADIENT_STOP_PREFIX = /^(from|via|to)-/;
|
|
38
38
|
const RE_COLOR_SHADE = /^(.+)-(\d+)$/;
|
package/dist/chunks/tw4.mjs
CHANGED
|
@@ -2,7 +2,8 @@ import { readFile } from 'node:fs/promises';
|
|
|
2
2
|
import { pathToFileURL } from 'node:url';
|
|
3
3
|
import { resolveModulePath } from 'exsolve';
|
|
4
4
|
import { dirname, join } from 'pathe';
|
|
5
|
-
import { e as extractVariantBaseClasses, r as resolveVariantPrefixes, h as resolveExtractedVars, i as resolveVarsDeep, s as simplifyCss, p as postProcessStyles, l as loadLightningCss, a as extractCssVars, c as extractUniversalVars, d as extractPerClassVars, g as extractVarsFromCss, f as extractClassStyles } from '../shared/nuxt-og-image.
|
|
5
|
+
import { e as extractVariantBaseClasses, r as resolveVariantPrefixes, h as resolveExtractedVars, i as resolveVarsDeep, s as simplifyCss, p as postProcessStyles, l as loadLightningCss, a as extractCssVars, c as extractUniversalVars, d as extractPerClassVars, g as extractVarsFromCss, f as extractClassStyles } from '../shared/nuxt-og-image.Pfj5JkJd.mjs';
|
|
6
|
+
import 'node:crypto';
|
|
6
7
|
import 'node:fs';
|
|
7
8
|
import '@nuxt/kit';
|
|
8
9
|
import 'defu';
|
|
@@ -10,12 +11,14 @@ import 'nuxt-site-config/kit';
|
|
|
10
11
|
import 'ohash';
|
|
11
12
|
import 'pkg-types';
|
|
12
13
|
import 'std-env';
|
|
13
|
-
import 'node:crypto';
|
|
14
14
|
import 'oxc-walker';
|
|
15
|
-
import '
|
|
15
|
+
import '../shared/nuxt-og-image.LgUGeaz-.mjs';
|
|
16
|
+
import 'magicast';
|
|
17
|
+
import 'magicast/helpers';
|
|
16
18
|
import '../../dist/runtime/logger.js';
|
|
17
|
-
import 'chrome-launcher';
|
|
18
19
|
import 'nypm';
|
|
20
|
+
import 'nuxtseo-shared/kit';
|
|
21
|
+
import 'chrome-launcher';
|
|
19
22
|
import 'nuxtseo-shared/devtools';
|
|
20
23
|
import 'unstorage';
|
|
21
24
|
import 'unstorage/drivers/fs-lite';
|
|
@@ -28,9 +31,6 @@ import '@vue/compiler-sfc';
|
|
|
28
31
|
import 'ofetch';
|
|
29
32
|
import 'ultrahtml';
|
|
30
33
|
import '../../dist/runtime/server/og-image/core/transforms/emojis/emoji-utils.js';
|
|
31
|
-
import '../shared/nuxt-og-image.CJa2KCie.mjs';
|
|
32
|
-
import 'magicast';
|
|
33
|
-
import 'magicast/helpers';
|
|
34
34
|
|
|
35
35
|
const RE_GRADIENT_STOP_PREFIX = /^(from|via|to)-/;
|
|
36
36
|
const RE_COLOR_SHADE = /^(.+)-(\d+)$/;
|
package/dist/chunks/uno.cjs
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
const promises = require('node:fs/promises');
|
|
4
4
|
const defu = require('defu');
|
|
5
5
|
const logger_js = require('../../dist/runtime/logger.js');
|
|
6
|
-
const module$1 = require('../shared/nuxt-og-image.
|
|
6
|
+
const module$1 = require('../shared/nuxt-og-image.BCK8Adm4.cjs');
|
|
7
|
+
require('node:crypto');
|
|
7
8
|
require('node:fs');
|
|
8
9
|
require('node:url');
|
|
9
10
|
require('@nuxt/kit');
|
|
@@ -12,11 +13,13 @@ require('ohash');
|
|
|
12
13
|
require('pathe');
|
|
13
14
|
require('pkg-types');
|
|
14
15
|
require('std-env');
|
|
15
|
-
require('node:crypto');
|
|
16
16
|
require('oxc-walker');
|
|
17
|
+
require('../shared/nuxt-og-image.DQkJQHaN.cjs');
|
|
18
|
+
require('magicast');
|
|
19
|
+
require('magicast/helpers');
|
|
20
|
+
require('nypm');
|
|
17
21
|
require('nuxtseo-shared/kit');
|
|
18
22
|
require('chrome-launcher');
|
|
19
|
-
require('nypm');
|
|
20
23
|
require('nuxtseo-shared/devtools');
|
|
21
24
|
require('unstorage');
|
|
22
25
|
require('unstorage/drivers/fs-lite');
|
|
@@ -30,9 +33,6 @@ require('ofetch');
|
|
|
30
33
|
require('ultrahtml');
|
|
31
34
|
require('../../dist/runtime/server/og-image/core/transforms/emojis/emoji-utils.js');
|
|
32
35
|
require('exsolve');
|
|
33
|
-
require('../shared/nuxt-og-image.CMYbz66P.cjs');
|
|
34
|
-
require('magicast');
|
|
35
|
-
require('magicast/helpers');
|
|
36
36
|
|
|
37
37
|
const RE_SVG_DATA_URL = /url\("data:image\/svg\+xml[;,]([^"]+)"\)/;
|
|
38
38
|
const RE_UTF8_PREFIX = /^utf8,/;
|
package/dist/chunks/uno.mjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
2
|
import { defu } from 'defu';
|
|
3
3
|
import { logger } from '../../dist/runtime/logger.js';
|
|
4
|
-
import { e as extractVariantBaseClasses, s as simplifyCss, a as extractCssVars, b as extractPropertyInitialValues, c as extractUniversalVars, d as extractPerClassVars, f as extractClassStyles, p as postProcessStyles, r as resolveVariantPrefixes, g as extractVarsFromCss, h as resolveExtractedVars } from '../shared/nuxt-og-image.
|
|
4
|
+
import { e as extractVariantBaseClasses, s as simplifyCss, a as extractCssVars, b as extractPropertyInitialValues, c as extractUniversalVars, d as extractPerClassVars, f as extractClassStyles, p as postProcessStyles, r as resolveVariantPrefixes, g as extractVarsFromCss, h as resolveExtractedVars } from '../shared/nuxt-og-image.Pfj5JkJd.mjs';
|
|
5
|
+
import 'node:crypto';
|
|
5
6
|
import 'node:fs';
|
|
6
7
|
import 'node:url';
|
|
7
8
|
import '@nuxt/kit';
|
|
@@ -10,11 +11,13 @@ import 'ohash';
|
|
|
10
11
|
import 'pathe';
|
|
11
12
|
import 'pkg-types';
|
|
12
13
|
import 'std-env';
|
|
13
|
-
import 'node:crypto';
|
|
14
14
|
import 'oxc-walker';
|
|
15
|
+
import '../shared/nuxt-og-image.LgUGeaz-.mjs';
|
|
16
|
+
import 'magicast';
|
|
17
|
+
import 'magicast/helpers';
|
|
18
|
+
import 'nypm';
|
|
15
19
|
import 'nuxtseo-shared/kit';
|
|
16
20
|
import 'chrome-launcher';
|
|
17
|
-
import 'nypm';
|
|
18
21
|
import 'nuxtseo-shared/devtools';
|
|
19
22
|
import 'unstorage';
|
|
20
23
|
import 'unstorage/drivers/fs-lite';
|
|
@@ -28,9 +31,6 @@ import 'ofetch';
|
|
|
28
31
|
import 'ultrahtml';
|
|
29
32
|
import '../../dist/runtime/server/og-image/core/transforms/emojis/emoji-utils.js';
|
|
30
33
|
import 'exsolve';
|
|
31
|
-
import '../shared/nuxt-og-image.CJa2KCie.mjs';
|
|
32
|
-
import 'magicast';
|
|
33
|
-
import 'magicast/helpers';
|
|
34
34
|
|
|
35
35
|
const RE_SVG_DATA_URL = /url\("data:image\/svg\+xml[;,]([^"]+)"\)/;
|
|
36
36
|
const RE_UTF8_PREFIX = /^utf8,/;
|
package/dist/cli.cjs
CHANGED
|
@@ -10,10 +10,14 @@ const nypm = require('nypm');
|
|
|
10
10
|
const oxcWalker = require('oxc-walker');
|
|
11
11
|
const pathe = require('pathe');
|
|
12
12
|
const ultrahtml = require('ultrahtml');
|
|
13
|
-
const
|
|
13
|
+
const dependencies = require('./shared/nuxt-og-image.DQkJQHaN.cjs');
|
|
14
14
|
require('magicast');
|
|
15
15
|
require('magicast/helpers');
|
|
16
16
|
require('../dist/runtime/logger.js');
|
|
17
|
+
require('std-env');
|
|
18
|
+
require('defu');
|
|
19
|
+
require('nuxtseo-shared/kit');
|
|
20
|
+
require('chrome-launcher');
|
|
17
21
|
|
|
18
22
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
19
23
|
function _interopNamespaceCompat(e) {
|
|
@@ -189,11 +193,14 @@ const RENDERERS = [
|
|
|
189
193
|
}
|
|
190
194
|
];
|
|
191
195
|
const EDGE_PRESETS = ["cloudflare", "cloudflare-pages", "cloudflare-module", "vercel-edge", "netlify-edge"];
|
|
192
|
-
function getRendererDeps(renderer, isEdge) {
|
|
196
|
+
function getRendererDeps(renderer, isEdge, options = {}) {
|
|
193
197
|
switch (renderer) {
|
|
194
198
|
case "satori":
|
|
195
199
|
return isEdge ? ["satori", "@resvg/resvg-js", "@resvg/resvg-wasm"] : ["satori", "@resvg/resvg-js"];
|
|
196
200
|
case "takumi":
|
|
201
|
+
if (options.installSpec) {
|
|
202
|
+
return isEdge ? [dependencies.TAKUMI_CORE_INSTALL_SPEC, dependencies.TAKUMI_WASM_INSTALL_SPEC] : [dependencies.TAKUMI_CORE_INSTALL_SPEC];
|
|
203
|
+
}
|
|
197
204
|
return isEdge ? ["@takumi-rs/core", "@takumi-rs/wasm"] : ["@takumi-rs/core"];
|
|
198
205
|
case "browser":
|
|
199
206
|
return isEdge ? [] : ["playwright-core"];
|
|
@@ -554,7 +561,7 @@ async function installRendererDeps(renderers, isEdge) {
|
|
|
554
561
|
const pmName = pm?.name || "npm";
|
|
555
562
|
const allDeps = [];
|
|
556
563
|
for (const renderer of renderers) {
|
|
557
|
-
allDeps.push(...getRendererDeps(renderer, isEdge));
|
|
564
|
+
allDeps.push(...getRendererDeps(renderer, isEdge, { installSpec: true }));
|
|
558
565
|
}
|
|
559
566
|
const uniqueDeps = [...new Set(allDeps)];
|
|
560
567
|
if (uniqueDeps.length === 0)
|
|
@@ -706,7 +713,7 @@ async function runMigrate(args2) {
|
|
|
706
713
|
if (dryRun) {
|
|
707
714
|
p__namespace.log.info(`Would remove defaults.component: '${migrationCheck.defaultComponentName}'`);
|
|
708
715
|
} else {
|
|
709
|
-
const result = await
|
|
716
|
+
const result = await dependencies.migrateDefaultsComponent(cwd).catch((err) => {
|
|
710
717
|
p__namespace.log.warn(`Failed to migrate defaults.component: ${err.message}`);
|
|
711
718
|
return { migrated: false, componentName: null, message: err.message };
|
|
712
719
|
});
|
|
@@ -720,7 +727,7 @@ async function runMigrate(args2) {
|
|
|
720
727
|
if (dryRun) {
|
|
721
728
|
p__namespace.log.info("Would migrate ogImage.fonts to @nuxt/fonts config");
|
|
722
729
|
} else {
|
|
723
|
-
const result = await
|
|
730
|
+
const result = await dependencies.migrateFontsConfig(cwd).catch((err) => {
|
|
724
731
|
p__namespace.log.warn(`Failed to migrate fonts config: ${err.message}`);
|
|
725
732
|
return { migrated: false, message: err.message };
|
|
726
733
|
});
|
package/dist/cli.mjs
CHANGED
|
@@ -8,10 +8,14 @@ import { detectPackageManager, removeDependency, addDependency } from 'nypm';
|
|
|
8
8
|
import { parseAndWalk } from 'oxc-walker';
|
|
9
9
|
import { dirname, resolve, join, relative, basename } from 'pathe';
|
|
10
10
|
import { parse, walkSync, ELEMENT_NODE } from 'ultrahtml';
|
|
11
|
-
import { m as migrateDefaultsComponent, a as migrateFontsConfig } from './shared/nuxt-og-image.
|
|
11
|
+
import { m as migrateDefaultsComponent, a as migrateFontsConfig, T as TAKUMI_CORE_INSTALL_SPEC, b as TAKUMI_WASM_INSTALL_SPEC } from './shared/nuxt-og-image.LgUGeaz-.mjs';
|
|
12
12
|
import 'magicast';
|
|
13
13
|
import 'magicast/helpers';
|
|
14
14
|
import '../dist/runtime/logger.js';
|
|
15
|
+
import 'std-env';
|
|
16
|
+
import 'defu';
|
|
17
|
+
import 'nuxtseo-shared/kit';
|
|
18
|
+
import 'chrome-launcher';
|
|
15
19
|
|
|
16
20
|
const __dirname$1 = dirname(fileURLToPath(import.meta.url));
|
|
17
21
|
const communityDir = resolve(__dirname$1, "runtime/app/components/Templates/Community");
|
|
@@ -172,11 +176,14 @@ const RENDERERS = [
|
|
|
172
176
|
}
|
|
173
177
|
];
|
|
174
178
|
const EDGE_PRESETS = ["cloudflare", "cloudflare-pages", "cloudflare-module", "vercel-edge", "netlify-edge"];
|
|
175
|
-
function getRendererDeps(renderer, isEdge) {
|
|
179
|
+
function getRendererDeps(renderer, isEdge, options = {}) {
|
|
176
180
|
switch (renderer) {
|
|
177
181
|
case "satori":
|
|
178
182
|
return isEdge ? ["satori", "@resvg/resvg-js", "@resvg/resvg-wasm"] : ["satori", "@resvg/resvg-js"];
|
|
179
183
|
case "takumi":
|
|
184
|
+
if (options.installSpec) {
|
|
185
|
+
return isEdge ? [TAKUMI_CORE_INSTALL_SPEC, TAKUMI_WASM_INSTALL_SPEC] : [TAKUMI_CORE_INSTALL_SPEC];
|
|
186
|
+
}
|
|
180
187
|
return isEdge ? ["@takumi-rs/core", "@takumi-rs/wasm"] : ["@takumi-rs/core"];
|
|
181
188
|
case "browser":
|
|
182
189
|
return isEdge ? [] : ["playwright-core"];
|
|
@@ -537,7 +544,7 @@ async function installRendererDeps(renderers, isEdge) {
|
|
|
537
544
|
const pmName = pm?.name || "npm";
|
|
538
545
|
const allDeps = [];
|
|
539
546
|
for (const renderer of renderers) {
|
|
540
|
-
allDeps.push(...getRendererDeps(renderer, isEdge));
|
|
547
|
+
allDeps.push(...getRendererDeps(renderer, isEdge, { installSpec: true }));
|
|
541
548
|
}
|
|
542
549
|
const uniqueDeps = [...new Set(allDeps)];
|
|
543
550
|
if (uniqueDeps.length === 0)
|
package/dist/module.cjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
require('node:crypto');
|
|
3
4
|
require('node:fs');
|
|
4
5
|
require('node:fs/promises');
|
|
5
6
|
require('node:url');
|
|
@@ -10,13 +11,11 @@ require('ohash');
|
|
|
10
11
|
require('pathe');
|
|
11
12
|
require('pkg-types');
|
|
12
13
|
require('std-env');
|
|
13
|
-
const module$1 = require('./shared/nuxt-og-image.
|
|
14
|
+
const module$1 = require('./shared/nuxt-og-image.BCK8Adm4.cjs');
|
|
15
|
+
require('./shared/nuxt-og-image.DQkJQHaN.cjs');
|
|
14
16
|
require('nuxtseo-shared/kit');
|
|
15
17
|
require('../dist/runtime/logger.js');
|
|
16
|
-
require('node:crypto');
|
|
17
18
|
require('oxc-walker');
|
|
18
|
-
require('chrome-launcher');
|
|
19
|
-
require('nypm');
|
|
20
19
|
require('nuxtseo-shared/devtools');
|
|
21
20
|
require('unstorage');
|
|
22
21
|
require('unstorage/drivers/fs-lite');
|
|
@@ -30,9 +29,10 @@ require('ofetch');
|
|
|
30
29
|
require('ultrahtml');
|
|
31
30
|
require('../dist/runtime/server/og-image/core/transforms/emojis/emoji-utils.js');
|
|
32
31
|
require('exsolve');
|
|
33
|
-
require('./shared/nuxt-og-image.CMYbz66P.cjs');
|
|
34
32
|
require('magicast');
|
|
35
33
|
require('magicast/helpers');
|
|
34
|
+
require('nypm');
|
|
35
|
+
require('chrome-launcher');
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
|
package/dist/module.d.cts
CHANGED
|
@@ -186,12 +186,14 @@ interface ModuleOptions {
|
|
|
186
186
|
* keyed hash signature and the handler rejects requests with missing or
|
|
187
187
|
* invalid signatures.
|
|
188
188
|
*
|
|
189
|
-
*
|
|
189
|
+
* Leave unset to auto-generate a per-build secret (signing on by default).
|
|
190
|
+
* Set an explicit, stable string for rolling or multi-instance deploys, or
|
|
191
|
+
* `false` to disable signing entirely. Generate one with:
|
|
190
192
|
* `npx nuxt-og-image generate-secret`
|
|
191
193
|
*
|
|
192
|
-
* Required when `strict` is enabled.
|
|
194
|
+
* Required (explicitly) when `strict` is enabled.
|
|
193
195
|
*/
|
|
194
|
-
secret?: string;
|
|
196
|
+
secret?: string | false;
|
|
195
197
|
/**
|
|
196
198
|
* Enable strict security mode. When enabled:
|
|
197
199
|
* - `secret` is required (URL signing)
|
package/dist/module.d.mts
CHANGED
|
@@ -186,12 +186,14 @@ interface ModuleOptions {
|
|
|
186
186
|
* keyed hash signature and the handler rejects requests with missing or
|
|
187
187
|
* invalid signatures.
|
|
188
188
|
*
|
|
189
|
-
*
|
|
189
|
+
* Leave unset to auto-generate a per-build secret (signing on by default).
|
|
190
|
+
* Set an explicit, stable string for rolling or multi-instance deploys, or
|
|
191
|
+
* `false` to disable signing entirely. Generate one with:
|
|
190
192
|
* `npx nuxt-og-image generate-secret`
|
|
191
193
|
*
|
|
192
|
-
* Required when `strict` is enabled.
|
|
194
|
+
* Required (explicitly) when `strict` is enabled.
|
|
193
195
|
*/
|
|
194
|
-
secret?: string;
|
|
196
|
+
secret?: string | false;
|
|
195
197
|
/**
|
|
196
198
|
* Enable strict security mode. When enabled:
|
|
197
199
|
* - `secret` is required (URL signing)
|
package/dist/module.d.ts
CHANGED
|
@@ -186,12 +186,14 @@ interface ModuleOptions {
|
|
|
186
186
|
* keyed hash signature and the handler rejects requests with missing or
|
|
187
187
|
* invalid signatures.
|
|
188
188
|
*
|
|
189
|
-
*
|
|
189
|
+
* Leave unset to auto-generate a per-build secret (signing on by default).
|
|
190
|
+
* Set an explicit, stable string for rolling or multi-instance deploys, or
|
|
191
|
+
* `false` to disable signing entirely. Generate one with:
|
|
190
192
|
* `npx nuxt-og-image generate-secret`
|
|
191
193
|
*
|
|
192
|
-
* Required when `strict` is enabled.
|
|
194
|
+
* Required (explicitly) when `strict` is enabled.
|
|
193
195
|
*/
|
|
194
|
-
secret?: string;
|
|
196
|
+
secret?: string | false;
|
|
195
197
|
/**
|
|
196
198
|
* Enable strict security mode. When enabled:
|
|
197
199
|
* - `secret` is required (URL signing)
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import 'node:crypto';
|
|
1
2
|
import 'node:fs';
|
|
2
3
|
import 'node:fs/promises';
|
|
3
4
|
import 'node:url';
|
|
@@ -8,13 +9,11 @@ import 'ohash';
|
|
|
8
9
|
import 'pathe';
|
|
9
10
|
import 'pkg-types';
|
|
10
11
|
import 'std-env';
|
|
11
|
-
export { m as default } from './shared/nuxt-og-image.
|
|
12
|
+
export { m as default } from './shared/nuxt-og-image.Pfj5JkJd.mjs';
|
|
13
|
+
import './shared/nuxt-og-image.LgUGeaz-.mjs';
|
|
12
14
|
import 'nuxtseo-shared/kit';
|
|
13
15
|
import '../dist/runtime/logger.js';
|
|
14
|
-
import 'node:crypto';
|
|
15
16
|
import 'oxc-walker';
|
|
16
|
-
import 'chrome-launcher';
|
|
17
|
-
import 'nypm';
|
|
18
17
|
import 'nuxtseo-shared/devtools';
|
|
19
18
|
import 'unstorage';
|
|
20
19
|
import 'unstorage/drivers/fs-lite';
|
|
@@ -28,6 +27,7 @@ import 'ofetch';
|
|
|
28
27
|
import 'ultrahtml';
|
|
29
28
|
import '../dist/runtime/server/og-image/core/transforms/emojis/emoji-utils.js';
|
|
30
29
|
import 'exsolve';
|
|
31
|
-
import './shared/nuxt-og-image.CJa2KCie.mjs';
|
|
32
30
|
import 'magicast';
|
|
33
31
|
import 'magicast/helpers';
|
|
32
|
+
import 'nypm';
|
|
33
|
+
import 'chrome-launcher';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { H3Event } from 'h3';
|
|
2
2
|
import type { FontConfig } from '../../../../types.js';
|
|
3
|
-
export declare function resolve(event: H3Event, font: FontConfig): Promise<Buffer<
|
|
3
|
+
export declare function resolve(event: H3Event, font: FontConfig): Promise<Buffer<ArrayBufferLike>>;
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { useRuntimeConfig } from "nitropack/runtime";
|
|
2
2
|
import { withBase } from "ufo";
|
|
3
|
+
import { getSiteConfig } from "#site-config/server/composables";
|
|
3
4
|
import { getCloudflareAssets } from "../../../util/cloudflareAssets.js";
|
|
4
5
|
import { fetchLocalAsset } from "../../../util/fetchLocalAsset.js";
|
|
5
6
|
import { getFetchTimeout } from "../../../util/fetchTimeout.js";
|
|
6
7
|
import { useOgImageRuntimeConfig } from "../../../utils.js";
|
|
8
|
+
import { fetchSpecialFontUrl, isDataFontUrl, isExternalFontUrl } from "./external-url.js";
|
|
7
9
|
export async function resolve(event, font) {
|
|
8
10
|
const path = font.src || font.localPath;
|
|
11
|
+
const runtimeConfig = useOgImageRuntimeConfig();
|
|
12
|
+
const timeout = getFetchTimeout(runtimeConfig);
|
|
9
13
|
const { app } = useRuntimeConfig();
|
|
10
14
|
const fullPath = withBase(path, app.baseURL);
|
|
11
|
-
|
|
15
|
+
if (path && (isDataFontUrl(path) || isExternalFontUrl(path)))
|
|
16
|
+
return fetchSpecialFontUrl(path, getSiteConfig(event).url, timeout);
|
|
12
17
|
const ab = await fetchLocalAsset(event, fullPath, { fetchTimeout: timeout });
|
|
13
18
|
if (ab)
|
|
14
19
|
return Buffer.from(ab);
|
|
@@ -4,8 +4,11 @@ import { useRuntimeConfig } from "nitropack/runtime";
|
|
|
4
4
|
import { join } from "pathe";
|
|
5
5
|
import { withBase } from "ufo";
|
|
6
6
|
import { buildDir, rootDir } from "#og-image-virtual/build-dir.mjs";
|
|
7
|
+
import { getSiteConfig } from "#site-config/server/composables";
|
|
7
8
|
import { getFetchTimeout } from "../../../util/fetchTimeout.js";
|
|
9
|
+
import { fetchWithRedirectValidation } from "../../../util/ssrf.js";
|
|
8
10
|
import { useOgImageRuntimeConfig } from "../../../utils.js";
|
|
11
|
+
import { fetchSpecialFontUrl, isDataFontUrl, isExternalFontUrl } from "./external-url.js";
|
|
9
12
|
let fontUrlMapping;
|
|
10
13
|
async function loadFontUrlMapping() {
|
|
11
14
|
if (fontUrlMapping)
|
|
@@ -16,12 +19,15 @@ async function loadFontUrlMapping() {
|
|
|
16
19
|
}
|
|
17
20
|
export async function resolve(event, font) {
|
|
18
21
|
const path = font.src || font.localPath;
|
|
19
|
-
const
|
|
22
|
+
const runtimeConfig = useOgImageRuntimeConfig();
|
|
23
|
+
const timeout = getFetchTimeout(runtimeConfig);
|
|
20
24
|
if (font.absolutePath) {
|
|
21
25
|
const data = await readFile(font.absolutePath).catch(() => null);
|
|
22
26
|
if (data?.length)
|
|
23
27
|
return data;
|
|
24
28
|
}
|
|
29
|
+
if (path && (isDataFontUrl(path) || isExternalFontUrl(path)))
|
|
30
|
+
return fetchSpecialFontUrl(path, getSiteConfig(event).url, timeout);
|
|
25
31
|
if (import.meta.prerender) {
|
|
26
32
|
if (path.startsWith("/_og-static-fonts/")) {
|
|
27
33
|
const filename2 = path.slice("/_og-static-fonts/".length);
|
|
@@ -72,14 +78,15 @@ export async function resolve(event, font) {
|
|
|
72
78
|
if (import.meta.dev) {
|
|
73
79
|
const reqUrl = getRequestURL(event);
|
|
74
80
|
const origin = `${reqUrl.protocol}//${reqUrl.host}`;
|
|
75
|
-
const
|
|
76
|
-
const
|
|
77
|
-
if (
|
|
78
|
-
return Buffer.from(
|
|
81
|
+
const target = new URL(withBase(path, app.baseURL), origin);
|
|
82
|
+
const ab = await fetchWithRedirectValidation(target.href, { timeout, trustedHost: target.host }).catch(() => null);
|
|
83
|
+
if (ab) {
|
|
84
|
+
return Buffer.from(ab);
|
|
79
85
|
}
|
|
80
86
|
}
|
|
81
87
|
const fullPath = withBase(path, app.baseURL);
|
|
82
|
-
const
|
|
88
|
+
const fetchArrayBuffer = event.$fetch;
|
|
89
|
+
const arrayBuffer = await fetchArrayBuffer(fullPath, {
|
|
83
90
|
responseType: "arrayBuffer",
|
|
84
91
|
timeout
|
|
85
92
|
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/** True for an inline `data:` font URI (no network — safe to decode directly). */
|
|
2
|
+
export declare function isDataFontUrl(path: string): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* True when a font path carries its own authority (`//host`, `http://host`,
|
|
5
|
+
* `\\host`) or a non-http scheme — i.e. it would not resolve same-origin.
|
|
6
|
+
*
|
|
7
|
+
* Classification resolves the path against a sentinel origin through the WHATWG
|
|
8
|
+
* URL parser, so it sees exactly what `fetch` will: leading C0 controls/spaces,
|
|
9
|
+
* embedded tab/CR/LF, and backslash folding are all normalized first. This
|
|
10
|
+
* closes the bypass class where " //127.0.0.1" or " //169.254.169.254" looks
|
|
11
|
+
* relative to a naive scheme check yet resolves cross-origin (GHSA-q8hw-4fvp-9rwv).
|
|
12
|
+
* Check `isDataFontUrl` first — `data:` is non-http and would report true here.
|
|
13
|
+
*/
|
|
14
|
+
export declare function isExternalFontUrl(path: string): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Resolve an authority-bearing font URL to the href to fetch, but only when it
|
|
17
|
+
* is same-origin with the configured site URL. Returns null otherwise.
|
|
18
|
+
*
|
|
19
|
+
* Runtime external font URLs are unsupported — `@nuxt/fonts` is the only
|
|
20
|
+
* supported way to load custom fonts, and it serves them same-origin. The single
|
|
21
|
+
* allowed exception is the site's own origin, gated on an explicitly configured
|
|
22
|
+
* site URL. Resolving against that origin also collapses canonicalization
|
|
23
|
+
* bypasses (a crafted " //127.0.0.1" resolves cross-origin → rejected).
|
|
24
|
+
*/
|
|
25
|
+
export declare function resolveSameOriginFontUrl(path: string, siteUrl: string | undefined): string | null;
|
|
26
|
+
/**
|
|
27
|
+
* Fetch a `data:` or authority-bearing font URL. `data:` is decoded directly
|
|
28
|
+
* (no network). An external URL is fetched only when same-origin with the site
|
|
29
|
+
* URL, and always through the SSRF guard (scheme allowlist, private-network
|
|
30
|
+
* block, per-hop redirect re-validation) so the site's own host can't be used
|
|
31
|
+
* to relay into its internal network via an open redirect.
|
|
32
|
+
*
|
|
33
|
+
* Throws on an unsupported/blocked/unreachable URL so the caller falls back to a
|
|
34
|
+
* bundled font; blocked targets stay indistinguishable from missing fonts.
|
|
35
|
+
*/
|
|
36
|
+
export declare function fetchSpecialFontUrl(path: string, siteUrl: string | undefined, timeout: number): Promise<Buffer>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { fetchWithRedirectValidation } from "../../../util/ssrf.js";
|
|
2
|
+
const SENTINEL_ORIGIN = "http://font-asset.invalid/";
|
|
3
|
+
const SENTINEL_HOST = "font-asset.invalid";
|
|
4
|
+
export function isDataFontUrl(path) {
|
|
5
|
+
return path.trimStart().toLowerCase().startsWith("data:");
|
|
6
|
+
}
|
|
7
|
+
export function isExternalFontUrl(path) {
|
|
8
|
+
let resolved;
|
|
9
|
+
try {
|
|
10
|
+
resolved = new URL(path, SENTINEL_ORIGIN);
|
|
11
|
+
} catch {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
return resolved.protocol !== "http:" || resolved.host !== SENTINEL_HOST;
|
|
15
|
+
}
|
|
16
|
+
export function resolveSameOriginFontUrl(path, siteUrl) {
|
|
17
|
+
if (!siteUrl)
|
|
18
|
+
return null;
|
|
19
|
+
let siteOrigin;
|
|
20
|
+
try {
|
|
21
|
+
siteOrigin = new URL(siteUrl).origin;
|
|
22
|
+
} catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
let target;
|
|
26
|
+
try {
|
|
27
|
+
target = new URL(path, siteOrigin);
|
|
28
|
+
} catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
return target.origin === siteOrigin ? target.href : null;
|
|
32
|
+
}
|
|
33
|
+
export async function fetchSpecialFontUrl(path, siteUrl, timeout) {
|
|
34
|
+
if (isDataFontUrl(path)) {
|
|
35
|
+
const res = await fetch(path.trimStart(), { signal: AbortSignal.timeout(timeout) }).catch(() => null);
|
|
36
|
+
if (res?.ok)
|
|
37
|
+
return Buffer.from(await res.arrayBuffer());
|
|
38
|
+
throw new Error("[Nuxt OG Image] Invalid data: font URL.");
|
|
39
|
+
}
|
|
40
|
+
const href = resolveSameOriginFontUrl(path, siteUrl);
|
|
41
|
+
if (!href)
|
|
42
|
+
throw new Error("[Nuxt OG Image] External font URLs are not supported. Load custom fonts via @nuxt/fonts.");
|
|
43
|
+
const ab = await fetchWithRedirectValidation(href, { timeout });
|
|
44
|
+
if (!ab)
|
|
45
|
+
throw new Error("[Nuxt OG Image] Font URL blocked or unreachable.");
|
|
46
|
+
return Buffer.from(ab);
|
|
47
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { H3Event } from 'h3';
|
|
2
2
|
import type { FontConfig } from '../../../../types.js';
|
|
3
|
-
export declare function resolve(event: H3Event, font: FontConfig): Promise<Buffer<
|
|
3
|
+
export declare function resolve(event: H3Event, font: FontConfig): Promise<Buffer<ArrayBufferLike>>;
|
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
import { useRuntimeConfig } from "nitropack/runtime";
|
|
2
2
|
import { withBase } from "ufo";
|
|
3
|
-
import { getNitroOrigin } from "#site-config/server/composables";
|
|
3
|
+
import { getNitroOrigin, getSiteConfig } from "#site-config/server/composables";
|
|
4
4
|
import { getFetchTimeout } from "../../../util/fetchTimeout.js";
|
|
5
|
+
import { fetchWithRedirectValidation } from "../../../util/ssrf.js";
|
|
5
6
|
import { useOgImageRuntimeConfig } from "../../../utils.js";
|
|
7
|
+
import { fetchSpecialFontUrl, isDataFontUrl, isExternalFontUrl } from "./external-url.js";
|
|
6
8
|
export async function resolve(event, font) {
|
|
7
9
|
const path = font.src || font.localPath;
|
|
10
|
+
const runtimeConfig = useOgImageRuntimeConfig();
|
|
11
|
+
const timeout = getFetchTimeout(runtimeConfig);
|
|
8
12
|
const { app } = useRuntimeConfig();
|
|
9
|
-
const fullPath = withBase(path, app.baseURL);
|
|
10
13
|
const origin = getNitroOrigin(event);
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
const fullPath = withBase(path, app.baseURL);
|
|
15
|
+
if (path && (isDataFontUrl(path) || isExternalFontUrl(path)))
|
|
16
|
+
return fetchSpecialFontUrl(path, getSiteConfig(event).url, timeout);
|
|
17
|
+
const target = new URL(fullPath, origin);
|
|
18
|
+
const ab = await fetchWithRedirectValidation(target.href, { timeout, trustedHost: target.host }).catch(() => null);
|
|
19
|
+
if (ab) {
|
|
20
|
+
return Buffer.from(ab);
|
|
15
21
|
}
|
|
16
|
-
const
|
|
22
|
+
const fetchArrayBuffer = event.$fetch;
|
|
23
|
+
const arrayBuffer = await fetchArrayBuffer(fullPath, {
|
|
17
24
|
responseType: "arrayBuffer",
|
|
18
25
|
timeout
|
|
19
26
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
declare function extractResourceUrls(nodes: any): Promise<string[]>;
|
|
1
2
|
declare const _default: {
|
|
2
3
|
initWasmPromise: Promise<void>;
|
|
3
4
|
Renderer: typeof import("@takumi-rs/core").Renderer;
|
|
4
|
-
extractResourceUrls: typeof
|
|
5
|
+
extractResourceUrls: typeof extractResourceUrls;
|
|
5
6
|
};
|
|
6
7
|
export default _default;
|