@vistagenic/vista 0.3.6 → 0.3.9
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/bin/flashpack-agent-playground.mjs +134 -0
- package/bin/flashpack-boot.mjs +506 -0
- package/bin/flashpack-ssr-loader.mjs +42 -0
- package/bin/flashpack-ssr.mjs +202 -0
- package/bin/flashpack-vendor.mjs +97 -0
- package/bin/vista.js +56 -42
- package/dist/ai/providers/base.js +7 -1
- package/dist/bin/build-rsc.js +16 -0
- package/dist/bin/build.js +17 -11
- package/dist/bin/deploy.js +7 -0
- package/dist/bin/dev-client-runtime.d.ts +6 -0
- package/dist/bin/dev-client-runtime.js +99 -0
- package/dist/bin/dev-error-overlay-snippet.js +79 -21
- package/dist/bin/dev-error-overlay-snippet.ts +840 -0
- package/dist/bin/devtools-indicator-snippet.js +29 -13
- package/dist/bin/file-scanner.js +7 -24
- package/dist/bin/generate.js +94 -2
- package/dist/bin/webpack.config.js +3 -1
- package/dist/build/rsc/compiler.d.ts +14 -0
- package/dist/build/rsc/compiler.js +66 -6
- package/dist/build/rsc/server-manifest.js +5 -4
- package/dist/config.d.ts +5 -0
- package/dist/config.js +15 -1
- package/dist/deploy/adapters/render.js +2 -2
- package/dist/deploy/index.d.ts +1 -0
- package/dist/deploy/index.js +3 -0
- package/dist/deploy/runtime-pack.js +22 -1
- package/dist/deploy/utils.js +16 -6
- package/dist/flashpack/command.d.ts +1 -0
- package/dist/flashpack/command.js +42 -76
- package/dist/flashpack/runtime.d.ts +12 -0
- package/dist/flashpack/runtime.js +124 -22
- package/dist/metadata/generate.d.ts +1 -0
- package/dist/metadata/generate.js +117 -21
- package/dist/metadata/index.d.ts +5 -0
- package/dist/metadata/index.js +15 -1
- package/dist/metadata/json-ld.d.ts +15 -0
- package/dist/metadata/json-ld.js +19 -0
- package/dist/metadata/merge.d.ts +17 -0
- package/dist/metadata/merge.js +161 -0
- package/dist/metadata/routes.d.ts +66 -0
- package/dist/metadata/routes.js +143 -0
- package/dist/metadata/types.d.ts +1 -1
- package/dist/metadata/types.js +3 -1
- package/dist/og/image-response.d.ts +38 -0
- package/dist/og/image-response.js +88 -0
- package/dist/og/index.d.ts +2 -0
- package/dist/og/index.js +5 -0
- package/dist/rust/index.d.ts +13 -0
- package/dist/rust/index.js +132 -0
- package/dist/server/engine.js +13 -3
- package/dist/server/logger.js +2 -1
- package/dist/server/project-alias-resolver.d.ts +7 -0
- package/dist/server/project-alias-resolver.js +70 -0
- package/dist/server/rsc-engine.js +93 -16
- package/dist/server/static-generator.js +4 -3
- package/dist/server/typed-api-runtime.js +92 -0
- package/docs/ai.md +69 -0
- package/docs/app.md +30 -0
- package/docs/cli.md +29 -0
- package/docs/index.md +18 -0
- package/docs/rag.md +54 -0
- package/native/win32-x64/flashpack-cli.exe +0 -0
- package/package.json +196 -178
- package/skills/README.md +9 -0
- package/skills/vista-agent/SKILL.md +28 -0
- package/skills/vista-dev-loop/SKILL.md +25 -0
- package/skills/vista-rag/SKILL.md +26 -0
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.MetadataRenderer = MetadataRenderer;
|
|
4
4
|
exports.generateMetadataHtml = generateMetadataHtml;
|
|
5
5
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
const merge_1 = require("./merge");
|
|
6
7
|
// ============================================================================
|
|
7
8
|
// Helper Functions
|
|
8
9
|
// ============================================================================
|
|
@@ -19,9 +20,10 @@ function resolveTitle(title, template) {
|
|
|
19
20
|
if (title.absolute) {
|
|
20
21
|
return title.absolute;
|
|
21
22
|
}
|
|
22
|
-
const baseTitle = title.default;
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
const baseTitle = title.default ?? '';
|
|
24
|
+
const activeTemplate = title.template || template;
|
|
25
|
+
if (activeTemplate && baseTitle) {
|
|
26
|
+
return activeTemplate.replace('%s', baseTitle);
|
|
25
27
|
}
|
|
26
28
|
return baseTitle;
|
|
27
29
|
}
|
|
@@ -98,12 +100,7 @@ function generateAuthorMeta(authors) {
|
|
|
98
100
|
});
|
|
99
101
|
return elements;
|
|
100
102
|
}
|
|
101
|
-
function
|
|
102
|
-
if (!robots)
|
|
103
|
-
return [];
|
|
104
|
-
if (typeof robots === 'string') {
|
|
105
|
-
return [(0, jsx_runtime_1.jsx)("meta", { name: "robots", content: robots }, "robots")];
|
|
106
|
-
}
|
|
103
|
+
function robotsDirectives(robots) {
|
|
107
104
|
const directives = [];
|
|
108
105
|
if (robots.index !== undefined)
|
|
109
106
|
directives.push(robots.index ? 'index' : 'noindex');
|
|
@@ -117,21 +114,37 @@ function generateRobotsMeta(robots) {
|
|
|
117
114
|
directives.push('noimageindex');
|
|
118
115
|
if (robots.nocache)
|
|
119
116
|
directives.push('nocache');
|
|
117
|
+
if (robots.notranslate)
|
|
118
|
+
directives.push('notranslate');
|
|
120
119
|
if (robots['max-snippet'] !== undefined)
|
|
121
120
|
directives.push(`max-snippet:${robots['max-snippet']}`);
|
|
122
121
|
if (robots['max-image-preview'])
|
|
123
122
|
directives.push(`max-image-preview:${robots['max-image-preview']}`);
|
|
124
123
|
if (robots['max-video-preview'] !== undefined)
|
|
125
124
|
directives.push(`max-video-preview:${robots['max-video-preview']}`);
|
|
125
|
+
return directives;
|
|
126
|
+
}
|
|
127
|
+
function generateRobotsMeta(robots) {
|
|
128
|
+
if (!robots)
|
|
129
|
+
return [];
|
|
130
|
+
if (typeof robots === 'string') {
|
|
131
|
+
return [(0, jsx_runtime_1.jsx)("meta", { name: "robots", content: robots }, "robots")];
|
|
132
|
+
}
|
|
126
133
|
const elements = [];
|
|
134
|
+
const directives = robotsDirectives(robots);
|
|
127
135
|
if (directives.length > 0) {
|
|
128
136
|
elements.push((0, jsx_runtime_1.jsx)("meta", { name: "robots", content: directives.join(', ') }, "robots"));
|
|
129
137
|
}
|
|
130
|
-
// GoogleBot specific
|
|
131
138
|
if (robots.googleBot) {
|
|
132
139
|
if (typeof robots.googleBot === 'string') {
|
|
133
140
|
elements.push((0, jsx_runtime_1.jsx)("meta", { name: "googlebot", content: robots.googleBot }, "googlebot"));
|
|
134
141
|
}
|
|
142
|
+
else {
|
|
143
|
+
const googleDirectives = robotsDirectives(robots.googleBot);
|
|
144
|
+
if (googleDirectives.length > 0) {
|
|
145
|
+
elements.push((0, jsx_runtime_1.jsx)("meta", { name: "googlebot", content: googleDirectives.join(', ') }, "googlebot"));
|
|
146
|
+
}
|
|
147
|
+
}
|
|
135
148
|
}
|
|
136
149
|
return elements;
|
|
137
150
|
}
|
|
@@ -184,44 +197,108 @@ function generateOpenGraphMeta(og, base) {
|
|
|
184
197
|
if (image.alt) {
|
|
185
198
|
elements.push((0, jsx_runtime_1.jsx)("meta", { property: "og:image:alt", content: image.alt }, `og:image:alt:${index}`));
|
|
186
199
|
}
|
|
200
|
+
if (image.type) {
|
|
201
|
+
elements.push((0, jsx_runtime_1.jsx)("meta", { property: "og:image:type", content: image.type }, `og:image:type:${index}`));
|
|
202
|
+
}
|
|
187
203
|
}
|
|
188
204
|
});
|
|
189
205
|
}
|
|
206
|
+
if ('article' in og && og.article) {
|
|
207
|
+
const article = og.article;
|
|
208
|
+
if (article.publishedTime) {
|
|
209
|
+
elements.push((0, jsx_runtime_1.jsx)("meta", { property: "article:published_time", content: article.publishedTime }, "og:article:published_time"));
|
|
210
|
+
}
|
|
211
|
+
if (article.modifiedTime) {
|
|
212
|
+
elements.push((0, jsx_runtime_1.jsx)("meta", { property: "article:modified_time", content: article.modifiedTime }, "og:article:modified_time"));
|
|
213
|
+
}
|
|
214
|
+
if (article.section) {
|
|
215
|
+
elements.push((0, jsx_runtime_1.jsx)("meta", { property: "article:section", content: article.section }, "og:article:section"));
|
|
216
|
+
}
|
|
217
|
+
if (article.tags) {
|
|
218
|
+
const tags = Array.isArray(article.tags) ? article.tags : [article.tags];
|
|
219
|
+
tags.forEach((tag, index) => {
|
|
220
|
+
elements.push((0, jsx_runtime_1.jsx)("meta", { property: "article:tag", content: tag }, `og:article:tag:${index}`));
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
}
|
|
190
224
|
return elements;
|
|
191
225
|
}
|
|
192
|
-
function generateTwitterMeta(twitter) {
|
|
226
|
+
function generateTwitterMeta(twitter, base) {
|
|
193
227
|
if (!twitter)
|
|
194
228
|
return [];
|
|
195
229
|
const elements = [];
|
|
196
|
-
// Card type
|
|
197
230
|
if (twitter.card) {
|
|
198
231
|
elements.push((0, jsx_runtime_1.jsx)("meta", { name: "twitter:card", content: twitter.card }, "twitter:card"));
|
|
199
232
|
}
|
|
200
|
-
// Site
|
|
201
233
|
if (twitter.site) {
|
|
202
234
|
elements.push((0, jsx_runtime_1.jsx)("meta", { name: "twitter:site", content: twitter.site }, "twitter:site"));
|
|
203
235
|
}
|
|
204
|
-
// Creator
|
|
205
236
|
if (twitter.creator) {
|
|
206
237
|
elements.push((0, jsx_runtime_1.jsx)("meta", { name: "twitter:creator", content: twitter.creator }, "twitter:creator"));
|
|
207
238
|
}
|
|
208
|
-
// Title
|
|
209
239
|
if (twitter.title) {
|
|
210
240
|
elements.push((0, jsx_runtime_1.jsx)("meta", { name: "twitter:title", content: twitter.title }, "twitter:title"));
|
|
211
241
|
}
|
|
212
|
-
// Description
|
|
213
242
|
if (twitter.description) {
|
|
214
243
|
elements.push((0, jsx_runtime_1.jsx)("meta", { name: "twitter:description", content: twitter.description }, "twitter:description"));
|
|
215
244
|
}
|
|
216
|
-
// Images
|
|
217
245
|
if (twitter.images) {
|
|
218
246
|
const images = Array.isArray(twitter.images) ? twitter.images : [twitter.images];
|
|
219
247
|
images.forEach((image, index) => {
|
|
220
|
-
elements.push((0, jsx_runtime_1.jsx)("meta", { name: "twitter:image", content: image.toString() }, `twitter:image:${index}`));
|
|
248
|
+
elements.push((0, jsx_runtime_1.jsx)("meta", { name: "twitter:image", content: resolveUrl(image, base) || image.toString() }, `twitter:image:${index}`));
|
|
221
249
|
});
|
|
222
250
|
}
|
|
223
251
|
return elements;
|
|
224
252
|
}
|
|
253
|
+
function generateOtherMeta(other) {
|
|
254
|
+
if (!other)
|
|
255
|
+
return [];
|
|
256
|
+
const elements = [];
|
|
257
|
+
Object.entries(other).forEach(([name, value]) => {
|
|
258
|
+
const values = Array.isArray(value) ? value : [value];
|
|
259
|
+
values.forEach((entry, index) => {
|
|
260
|
+
elements.push((0, jsx_runtime_1.jsx)("meta", { name: name, content: String(entry) }, `other-${name}-${index}`));
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
return elements;
|
|
264
|
+
}
|
|
265
|
+
function generateAppleWebAppMeta(appleWebApp) {
|
|
266
|
+
if (appleWebApp === null || appleWebApp === undefined)
|
|
267
|
+
return [];
|
|
268
|
+
const elements = [];
|
|
269
|
+
if (appleWebApp === true) {
|
|
270
|
+
elements.push((0, jsx_runtime_1.jsx)("meta", { name: "apple-mobile-web-app-capable", content: "yes" }, "apple-mobile-web-app-capable"));
|
|
271
|
+
return elements;
|
|
272
|
+
}
|
|
273
|
+
if (appleWebApp === false)
|
|
274
|
+
return elements;
|
|
275
|
+
if (appleWebApp.capable !== undefined) {
|
|
276
|
+
elements.push((0, jsx_runtime_1.jsx)("meta", { name: "apple-mobile-web-app-capable", content: appleWebApp.capable ? 'yes' : 'no' }, "apple-mobile-web-app-capable"));
|
|
277
|
+
}
|
|
278
|
+
if (appleWebApp.title) {
|
|
279
|
+
elements.push((0, jsx_runtime_1.jsx)("meta", { name: "apple-mobile-web-app-title", content: appleWebApp.title }, "apple-mobile-web-app-title"));
|
|
280
|
+
}
|
|
281
|
+
if (appleWebApp.statusBarStyle) {
|
|
282
|
+
elements.push((0, jsx_runtime_1.jsx)("meta", { name: "apple-mobile-web-app-status-bar-style", content: appleWebApp.statusBarStyle }, "apple-mobile-web-app-status-bar-style"));
|
|
283
|
+
}
|
|
284
|
+
return elements;
|
|
285
|
+
}
|
|
286
|
+
function generateFormatDetectionMeta(formatDetection) {
|
|
287
|
+
if (!formatDetection)
|
|
288
|
+
return [];
|
|
289
|
+
const parts = [];
|
|
290
|
+
['telephone', 'date', 'address', 'email', 'url'].forEach((key) => {
|
|
291
|
+
if (formatDetection[key] === false)
|
|
292
|
+
parts.push(`${key}=no`);
|
|
293
|
+
if (formatDetection[key] === true)
|
|
294
|
+
parts.push(`${key}=yes`);
|
|
295
|
+
});
|
|
296
|
+
if (parts.length === 0)
|
|
297
|
+
return [];
|
|
298
|
+
return [
|
|
299
|
+
(0, jsx_runtime_1.jsx)("meta", { name: "format-detection", content: parts.join(', ') }, "format-detection"),
|
|
300
|
+
];
|
|
301
|
+
}
|
|
225
302
|
function generateIconLinks(icons) {
|
|
226
303
|
if (!icons)
|
|
227
304
|
return [];
|
|
@@ -305,6 +382,22 @@ function generateAlternateLinks(alternates, base) {
|
|
|
305
382
|
});
|
|
306
383
|
});
|
|
307
384
|
}
|
|
385
|
+
if (alternates.media) {
|
|
386
|
+
Object.entries(alternates.media).forEach(([media, url]) => {
|
|
387
|
+
const urls = Array.isArray(url) ? url : [url];
|
|
388
|
+
urls.forEach((u, index) => {
|
|
389
|
+
elements.push((0, jsx_runtime_1.jsx)("link", { rel: "alternate", media: media, href: resolveUrl(u, base) || '' }, `alternate-media-${media}-${index}`));
|
|
390
|
+
});
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
if (alternates.types) {
|
|
394
|
+
Object.entries(alternates.types).forEach(([type, url]) => {
|
|
395
|
+
const urls = Array.isArray(url) ? url : [url];
|
|
396
|
+
urls.forEach((u, index) => {
|
|
397
|
+
elements.push((0, jsx_runtime_1.jsx)("link", { rel: "alternate", type: type, href: resolveUrl(u, base) || '' }, `alternate-type-${type}-${index}`));
|
|
398
|
+
});
|
|
399
|
+
});
|
|
400
|
+
}
|
|
308
401
|
return elements;
|
|
309
402
|
}
|
|
310
403
|
/**
|
|
@@ -313,16 +406,19 @@ function generateAlternateLinks(alternates, base) {
|
|
|
313
406
|
*/
|
|
314
407
|
function MetadataRenderer({ metadata, parentTemplate, }) {
|
|
315
408
|
const base = metadata.metadataBase;
|
|
316
|
-
const
|
|
317
|
-
|
|
409
|
+
const inheritedTemplate = parentTemplate ?? (0, merge_1.resolveParentTitleTemplate)(metadata);
|
|
410
|
+
const title = resolveTitle(metadata.title, inheritedTemplate);
|
|
411
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [title && (0, jsx_runtime_1.jsx)("title", { children: title }), generateBasicMeta(metadata), generateAuthorMeta(metadata.authors), generateRobotsMeta(metadata.robots), generateOpenGraphMeta(metadata.openGraph, base), generateTwitterMeta(metadata.twitter, base), generateIconLinks(metadata.icons), generateVerificationMeta(metadata.verification), generateAlternateLinks(metadata.alternates, base), generateAppleWebAppMeta(metadata.appleWebApp), generateFormatDetectionMeta(metadata.formatDetection), generateOtherMeta(metadata.other), metadata.manifest && ((0, jsx_runtime_1.jsx)("link", { rel: "manifest", href: resolveUrl(metadata.manifest, base) || '' })), metadata.classification && ((0, jsx_runtime_1.jsx)("meta", { name: "classification", content: metadata.classification }))] }));
|
|
318
412
|
}
|
|
319
413
|
/**
|
|
320
414
|
* Converts metadata to HTML string for SSR injection.
|
|
415
|
+
* Applies title template from merged metadata when parentTemplate is omitted.
|
|
321
416
|
*/
|
|
322
417
|
function generateMetadataHtml(metadata, parentTemplate) {
|
|
323
418
|
if (!metadata || typeof metadata !== 'object')
|
|
324
419
|
return '';
|
|
325
420
|
const { renderToStaticMarkup } = require('react-dom/server');
|
|
326
|
-
|
|
421
|
+
const template = parentTemplate ?? (0, merge_1.resolveParentTitleTemplate)(metadata);
|
|
422
|
+
return renderToStaticMarkup((0, jsx_runtime_1.jsx)(MetadataRenderer, { metadata: metadata, parentTemplate: template }));
|
|
327
423
|
}
|
|
328
424
|
exports.default = MetadataRenderer;
|
package/dist/metadata/index.d.ts
CHANGED
|
@@ -5,3 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export * from './types';
|
|
7
7
|
export { MetadataRenderer, generateMetadataHtml } from './generate';
|
|
8
|
+
export { deepMergeMetadata, mergeMetadataChain, resolveParentTitleTemplate } from './merge';
|
|
9
|
+
export { robots, sitemap, manifest, serializeRobots, serializeSitemap, metadataRouteToResponse, MetadataRoute, } from './routes';
|
|
10
|
+
export type { RobotsFile, RobotsRule, SitemapFile, SitemapEntry, ManifestFile, ManifestIcon, } from './routes';
|
|
11
|
+
export { jsonLd, JsonLd } from './json-ld';
|
|
12
|
+
export type { JsonLdProps } from './json-ld';
|
package/dist/metadata/index.js
CHANGED
|
@@ -19,8 +19,22 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
19
19
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
20
20
|
};
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
exports.generateMetadataHtml = exports.MetadataRenderer = void 0;
|
|
22
|
+
exports.JsonLd = exports.jsonLd = exports.metadataRouteToResponse = exports.serializeSitemap = exports.serializeRobots = exports.manifest = exports.sitemap = exports.robots = exports.resolveParentTitleTemplate = exports.mergeMetadataChain = exports.deepMergeMetadata = exports.generateMetadataHtml = exports.MetadataRenderer = void 0;
|
|
23
23
|
__exportStar(require("./types"), exports);
|
|
24
24
|
var generate_1 = require("./generate");
|
|
25
25
|
Object.defineProperty(exports, "MetadataRenderer", { enumerable: true, get: function () { return generate_1.MetadataRenderer; } });
|
|
26
26
|
Object.defineProperty(exports, "generateMetadataHtml", { enumerable: true, get: function () { return generate_1.generateMetadataHtml; } });
|
|
27
|
+
var merge_1 = require("./merge");
|
|
28
|
+
Object.defineProperty(exports, "deepMergeMetadata", { enumerable: true, get: function () { return merge_1.deepMergeMetadata; } });
|
|
29
|
+
Object.defineProperty(exports, "mergeMetadataChain", { enumerable: true, get: function () { return merge_1.mergeMetadataChain; } });
|
|
30
|
+
Object.defineProperty(exports, "resolveParentTitleTemplate", { enumerable: true, get: function () { return merge_1.resolveParentTitleTemplate; } });
|
|
31
|
+
var routes_1 = require("./routes");
|
|
32
|
+
Object.defineProperty(exports, "robots", { enumerable: true, get: function () { return routes_1.robots; } });
|
|
33
|
+
Object.defineProperty(exports, "sitemap", { enumerable: true, get: function () { return routes_1.sitemap; } });
|
|
34
|
+
Object.defineProperty(exports, "manifest", { enumerable: true, get: function () { return routes_1.manifest; } });
|
|
35
|
+
Object.defineProperty(exports, "serializeRobots", { enumerable: true, get: function () { return routes_1.serializeRobots; } });
|
|
36
|
+
Object.defineProperty(exports, "serializeSitemap", { enumerable: true, get: function () { return routes_1.serializeSitemap; } });
|
|
37
|
+
Object.defineProperty(exports, "metadataRouteToResponse", { enumerable: true, get: function () { return routes_1.metadataRouteToResponse; } });
|
|
38
|
+
var json_ld_1 = require("./json-ld");
|
|
39
|
+
Object.defineProperty(exports, "jsonLd", { enumerable: true, get: function () { return json_ld_1.jsonLd; } });
|
|
40
|
+
Object.defineProperty(exports, "JsonLd", { enumerable: true, get: function () { return json_ld_1.JsonLd; } });
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSR-safe JSON-LD helpers for structured data.
|
|
3
|
+
*/
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
/** Serialize structured data for embedding in a script tag. */
|
|
6
|
+
export declare function jsonLd(data: unknown): string;
|
|
7
|
+
export interface JsonLdProps {
|
|
8
|
+
data: unknown;
|
|
9
|
+
id?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Renders `<script type="application/ld+json">` with XSS-safe serialization.
|
|
13
|
+
* Prefer this over hand-rolling dangerouslySetInnerHTML.
|
|
14
|
+
*/
|
|
15
|
+
export declare function JsonLd({ data, id }: JsonLdProps): React.ReactElement;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.jsonLd = jsonLd;
|
|
4
|
+
exports.JsonLd = JsonLd;
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
function serializeJsonLd(data) {
|
|
7
|
+
return JSON.stringify(data).replace(/</g, '\\u003c');
|
|
8
|
+
}
|
|
9
|
+
/** Serialize structured data for embedding in a script tag. */
|
|
10
|
+
function jsonLd(data) {
|
|
11
|
+
return serializeJsonLd(data);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Renders `<script type="application/ld+json">` with XSS-safe serialization.
|
|
15
|
+
* Prefer this over hand-rolling dangerouslySetInnerHTML.
|
|
16
|
+
*/
|
|
17
|
+
function JsonLd({ data, id }) {
|
|
18
|
+
return ((0, jsx_runtime_1.jsx)("script", { id: id, type: "application/ld+json", dangerouslySetInnerHTML: { __html: serializeJsonLd(data) } }));
|
|
19
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Next.js-compatible deep merge for Metadata objects.
|
|
3
|
+
* Nested openGraph / twitter / robots / alternates / icons merge instead of replace.
|
|
4
|
+
* Title templates inherit from parent layouts.
|
|
5
|
+
*/
|
|
6
|
+
import type { Metadata } from './types';
|
|
7
|
+
/**
|
|
8
|
+
* Deep-merge parent layout metadata with child page/layout metadata.
|
|
9
|
+
* Child wins on scalar fields; nested objects merge.
|
|
10
|
+
*/
|
|
11
|
+
export declare function deepMergeMetadata(parent: Metadata | null | undefined, child: Metadata | null | undefined): Metadata;
|
|
12
|
+
/** Fold a chain of metadata objects (root → … → page). */
|
|
13
|
+
export declare function mergeMetadataChain(chain: Array<Metadata | null | undefined>): Metadata;
|
|
14
|
+
/**
|
|
15
|
+
* Resolve the active title template string from merged metadata (for generateMetadataHtml).
|
|
16
|
+
*/
|
|
17
|
+
export declare function resolveParentTitleTemplate(metadata: Metadata | null | undefined): string | undefined;
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Next.js-compatible deep merge for Metadata objects.
|
|
4
|
+
* Nested openGraph / twitter / robots / alternates / icons merge instead of replace.
|
|
5
|
+
* Title templates inherit from parent layouts.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.deepMergeMetadata = deepMergeMetadata;
|
|
9
|
+
exports.mergeMetadataChain = mergeMetadataChain;
|
|
10
|
+
exports.resolveParentTitleTemplate = resolveParentTitleTemplate;
|
|
11
|
+
const types_1 = require("./types");
|
|
12
|
+
function isPlainObject(value) {
|
|
13
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value) && !(value instanceof URL);
|
|
14
|
+
}
|
|
15
|
+
function mergeTitle(parent, child) {
|
|
16
|
+
if (child === null)
|
|
17
|
+
return null;
|
|
18
|
+
if (child === undefined)
|
|
19
|
+
return parent;
|
|
20
|
+
const parentTemplate = (0, types_1.isTemplateString)(parent) && parent.template
|
|
21
|
+
? parent.template
|
|
22
|
+
: typeof parent === 'object' && parent && 'template' in parent
|
|
23
|
+
? parent.template
|
|
24
|
+
: undefined;
|
|
25
|
+
if (typeof child === 'string') {
|
|
26
|
+
if (parentTemplate) {
|
|
27
|
+
return { default: child, template: parentTemplate };
|
|
28
|
+
}
|
|
29
|
+
return child;
|
|
30
|
+
}
|
|
31
|
+
if ((0, types_1.isTemplateString)(child)) {
|
|
32
|
+
if (child.absolute) {
|
|
33
|
+
return {
|
|
34
|
+
absolute: child.absolute,
|
|
35
|
+
default: child.default ?? child.absolute,
|
|
36
|
+
template: child.template ?? parentTemplate,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
default: child.default ?? '',
|
|
41
|
+
absolute: child.absolute,
|
|
42
|
+
template: child.template ?? parentTemplate,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return child;
|
|
46
|
+
}
|
|
47
|
+
function mergeRobots(parent, child) {
|
|
48
|
+
if (child === null)
|
|
49
|
+
return null;
|
|
50
|
+
if (child === undefined)
|
|
51
|
+
return parent;
|
|
52
|
+
if (typeof child === 'string' || typeof parent === 'string')
|
|
53
|
+
return child;
|
|
54
|
+
if (!parent || typeof parent !== 'object')
|
|
55
|
+
return child;
|
|
56
|
+
const merged = { ...parent, ...child };
|
|
57
|
+
if (isPlainObject(parent.googleBot) && isPlainObject(child.googleBot)) {
|
|
58
|
+
merged.googleBot = { ...parent.googleBot, ...child.googleBot };
|
|
59
|
+
}
|
|
60
|
+
return merged;
|
|
61
|
+
}
|
|
62
|
+
function mergeOpenGraph(parent, child) {
|
|
63
|
+
if (child === null)
|
|
64
|
+
return null;
|
|
65
|
+
if (child === undefined)
|
|
66
|
+
return parent;
|
|
67
|
+
if (!parent)
|
|
68
|
+
return child;
|
|
69
|
+
return { ...parent, ...child };
|
|
70
|
+
}
|
|
71
|
+
function mergeTwitter(parent, child) {
|
|
72
|
+
if (child === null)
|
|
73
|
+
return null;
|
|
74
|
+
if (child === undefined)
|
|
75
|
+
return parent;
|
|
76
|
+
if (!parent)
|
|
77
|
+
return child;
|
|
78
|
+
return { ...parent, ...child };
|
|
79
|
+
}
|
|
80
|
+
function mergeIcons(parent, child) {
|
|
81
|
+
if (child === null)
|
|
82
|
+
return null;
|
|
83
|
+
if (child === undefined)
|
|
84
|
+
return parent;
|
|
85
|
+
if (!parent || typeof parent !== 'object' || Array.isArray(parent) || parent instanceof URL) {
|
|
86
|
+
return child;
|
|
87
|
+
}
|
|
88
|
+
if (!child || typeof child !== 'object' || Array.isArray(child) || child instanceof URL) {
|
|
89
|
+
return child;
|
|
90
|
+
}
|
|
91
|
+
if ('url' in child)
|
|
92
|
+
return child;
|
|
93
|
+
return { ...parent, ...child };
|
|
94
|
+
}
|
|
95
|
+
function mergeAlternates(parent, child) {
|
|
96
|
+
if (child === null)
|
|
97
|
+
return null;
|
|
98
|
+
if (child === undefined)
|
|
99
|
+
return parent;
|
|
100
|
+
if (!parent)
|
|
101
|
+
return child;
|
|
102
|
+
return {
|
|
103
|
+
...parent,
|
|
104
|
+
...child,
|
|
105
|
+
languages: { ...(parent.languages || {}), ...(child.languages || {}) },
|
|
106
|
+
media: { ...(parent.media || {}), ...(child.media || {}) },
|
|
107
|
+
types: { ...(parent.types || {}), ...(child.types || {}) },
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Deep-merge parent layout metadata with child page/layout metadata.
|
|
112
|
+
* Child wins on scalar fields; nested objects merge.
|
|
113
|
+
*/
|
|
114
|
+
function deepMergeMetadata(parent, child) {
|
|
115
|
+
const base = parent && typeof parent === 'object' ? { ...parent } : {};
|
|
116
|
+
if (!child || typeof child !== 'object')
|
|
117
|
+
return base;
|
|
118
|
+
const next = { ...base, ...child };
|
|
119
|
+
next.title = mergeTitle(base.title, child.title);
|
|
120
|
+
next.robots = mergeRobots(base.robots, child.robots);
|
|
121
|
+
next.openGraph = mergeOpenGraph(base.openGraph, child.openGraph);
|
|
122
|
+
next.twitter = mergeTwitter(base.twitter, child.twitter);
|
|
123
|
+
next.icons = mergeIcons(base.icons, child.icons);
|
|
124
|
+
next.alternates = mergeAlternates(base.alternates, child.alternates);
|
|
125
|
+
if (isPlainObject(base.other) || isPlainObject(child.other)) {
|
|
126
|
+
next.other = { ...(base.other || {}), ...(child.other || {}) };
|
|
127
|
+
}
|
|
128
|
+
if (isPlainObject(base.verification) || isPlainObject(child.verification)) {
|
|
129
|
+
next.verification = { ...(base.verification || {}), ...(child.verification || {}) };
|
|
130
|
+
}
|
|
131
|
+
if (isPlainObject(base.formatDetection) || isPlainObject(child.formatDetection)) {
|
|
132
|
+
next.formatDetection = { ...(base.formatDetection || {}), ...(child.formatDetection || {}) };
|
|
133
|
+
}
|
|
134
|
+
if ((isPlainObject(base.appleWebApp) || typeof base.appleWebApp === 'boolean') &&
|
|
135
|
+
(isPlainObject(child.appleWebApp) || typeof child.appleWebApp === 'boolean')) {
|
|
136
|
+
if (typeof child.appleWebApp === 'boolean' || typeof base.appleWebApp === 'boolean') {
|
|
137
|
+
next.appleWebApp = child.appleWebApp !== undefined ? child.appleWebApp : base.appleWebApp;
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
next.appleWebApp = { ...base.appleWebApp, ...child.appleWebApp };
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (base.metadataBase && child.metadataBase === undefined) {
|
|
144
|
+
next.metadataBase = base.metadataBase;
|
|
145
|
+
}
|
|
146
|
+
return next;
|
|
147
|
+
}
|
|
148
|
+
/** Fold a chain of metadata objects (root → … → page). */
|
|
149
|
+
function mergeMetadataChain(chain) {
|
|
150
|
+
return chain.reduce((acc, item) => deepMergeMetadata(acc, item), {});
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Resolve the active title template string from merged metadata (for generateMetadataHtml).
|
|
154
|
+
*/
|
|
155
|
+
function resolveParentTitleTemplate(metadata) {
|
|
156
|
+
if (!metadata?.title)
|
|
157
|
+
return undefined;
|
|
158
|
+
if ((0, types_1.isTemplateString)(metadata.title))
|
|
159
|
+
return metadata.title.template;
|
|
160
|
+
return undefined;
|
|
161
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Next-compatible MetadataRoute helpers for robots.txt, sitemap.xml, and web manifests.
|
|
3
|
+
*/
|
|
4
|
+
export type RobotsRule = {
|
|
5
|
+
userAgent?: string | string[];
|
|
6
|
+
allow?: string | string[];
|
|
7
|
+
disallow?: string | string[];
|
|
8
|
+
crawlDelay?: number;
|
|
9
|
+
other?: Record<string, string | number | Array<string | number>>;
|
|
10
|
+
};
|
|
11
|
+
export type RobotsFile = {
|
|
12
|
+
rules: RobotsRule | RobotsRule[];
|
|
13
|
+
sitemap?: string | string[];
|
|
14
|
+
host?: string;
|
|
15
|
+
};
|
|
16
|
+
export type SitemapEntry = {
|
|
17
|
+
url: string;
|
|
18
|
+
lastModified?: string | Date;
|
|
19
|
+
changeFrequency?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
|
|
20
|
+
priority?: number;
|
|
21
|
+
alternates?: {
|
|
22
|
+
languages?: Record<string, string>;
|
|
23
|
+
};
|
|
24
|
+
images?: string[];
|
|
25
|
+
videos?: Array<{
|
|
26
|
+
title: string;
|
|
27
|
+
thumbnail_loc: string;
|
|
28
|
+
description: string;
|
|
29
|
+
}>;
|
|
30
|
+
};
|
|
31
|
+
export type SitemapFile = SitemapEntry[];
|
|
32
|
+
export type ManifestIcon = {
|
|
33
|
+
src: string;
|
|
34
|
+
sizes?: string;
|
|
35
|
+
type?: string;
|
|
36
|
+
purpose?: string;
|
|
37
|
+
};
|
|
38
|
+
export type ManifestFile = {
|
|
39
|
+
name?: string;
|
|
40
|
+
short_name?: string;
|
|
41
|
+
description?: string;
|
|
42
|
+
start_url?: string;
|
|
43
|
+
display?: 'fullscreen' | 'standalone' | 'minimal-ui' | 'browser';
|
|
44
|
+
background_color?: string;
|
|
45
|
+
theme_color?: string;
|
|
46
|
+
icons?: ManifestIcon[];
|
|
47
|
+
[key: string]: unknown;
|
|
48
|
+
};
|
|
49
|
+
/** Namespace mirroring Next.js `MetadataRoute`. */
|
|
50
|
+
export declare namespace MetadataRoute {
|
|
51
|
+
type Robots = RobotsFile;
|
|
52
|
+
type Sitemap = SitemapFile;
|
|
53
|
+
type Manifest = ManifestFile;
|
|
54
|
+
}
|
|
55
|
+
/** Serialize a Robots object to robots.txt body text. */
|
|
56
|
+
export declare function serializeRobots(data: RobotsFile): string;
|
|
57
|
+
/** Serialize sitemap entries to XML. */
|
|
58
|
+
export declare function serializeSitemap(entries: SitemapFile): string;
|
|
59
|
+
/** Build a robots.txt Response. */
|
|
60
|
+
export declare function robots(data: RobotsFile): Response;
|
|
61
|
+
/** Build a sitemap.xml Response. */
|
|
62
|
+
export declare function sitemap(entries: SitemapFile): Response;
|
|
63
|
+
/** Build a webmanifest JSON Response. */
|
|
64
|
+
export declare function manifest(data: ManifestFile): Response;
|
|
65
|
+
/** Convert a MetadataRoute default-export payload into a Response. */
|
|
66
|
+
export declare function metadataRouteToResponse(stem: 'robots' | 'sitemap' | 'manifest', payload: unknown): Response | null;
|