.
This commit is contained in:
+11
@@ -0,0 +1,11 @@
|
||||
import type { CollectingMetadata } from './types';
|
||||
import type { MetadataResolver } from '../next-app-loader';
|
||||
import type { PageExtensions } from '../../../page-extensions-type';
|
||||
export declare function createStaticMetadataFromRoute(resolvedDir: string, { segment, metadataResolver, isRootLayoutOrRootPage, pageExtensions, basePath, }: {
|
||||
segment: string;
|
||||
metadataResolver: MetadataResolver;
|
||||
isRootLayoutOrRootPage: boolean;
|
||||
pageExtensions: PageExtensions;
|
||||
basePath: string;
|
||||
}): Promise<CollectingMetadata | null>;
|
||||
export declare function createMetadataExportsCode(metadata: Awaited<ReturnType<typeof createStaticMetadataFromRoute>>): string;
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
0 && (module.exports = {
|
||||
createMetadataExportsCode: null,
|
||||
createStaticMetadataFromRoute: null
|
||||
});
|
||||
function _export(target, all) {
|
||||
for(var name in all)Object.defineProperty(target, name, {
|
||||
enumerable: true,
|
||||
get: all[name]
|
||||
});
|
||||
}
|
||||
_export(exports, {
|
||||
createMetadataExportsCode: function() {
|
||||
return createMetadataExportsCode;
|
||||
},
|
||||
createStaticMetadataFromRoute: function() {
|
||||
return createStaticMetadataFromRoute;
|
||||
}
|
||||
});
|
||||
const _path = /*#__PURE__*/ _interop_require_default(require("path"));
|
||||
const _querystring = require("querystring");
|
||||
const _ismetadataroute = require("../../../../lib/metadata/is-metadata-route");
|
||||
const _constants = require("../../../../lib/constants");
|
||||
function _interop_require_default(obj) {
|
||||
return obj && obj.__esModule ? obj : {
|
||||
default: obj
|
||||
};
|
||||
}
|
||||
const METADATA_TYPE = 'metadata';
|
||||
const NUMERIC_SUFFIX_ARRAY = Array(10).fill(0);
|
||||
// Produce all compositions with filename (icon, apple-icon, etc.) with extensions (png, jpg, etc.)
|
||||
async function enumMetadataFiles(dir, filename, extensions, { metadataResolver, // When set to true, possible filename without extension could: icon, icon0, ..., icon9
|
||||
numericSuffix }) {
|
||||
const collectedFiles = [];
|
||||
// Collect <filename>.<ext>, <filename>[].<ext>
|
||||
const possibleFileNames = [
|
||||
filename
|
||||
].concat(numericSuffix ? NUMERIC_SUFFIX_ARRAY.map((_, index)=>filename + index) : []);
|
||||
for (const name of possibleFileNames){
|
||||
const resolved = await metadataResolver(dir, name, extensions);
|
||||
collectedFiles.push(...resolved);
|
||||
}
|
||||
return collectedFiles;
|
||||
}
|
||||
async function createStaticMetadataFromRoute(resolvedDir, { segment, metadataResolver, isRootLayoutOrRootPage, pageExtensions, basePath }) {
|
||||
let hasStaticMetadataFiles = false;
|
||||
const staticImagesMetadata = {
|
||||
icon: [],
|
||||
apple: [],
|
||||
twitter: [],
|
||||
openGraph: [],
|
||||
manifest: undefined
|
||||
};
|
||||
async function collectIconModuleIfExists(type) {
|
||||
if (type === 'manifest') {
|
||||
const staticManifestExtension = [
|
||||
'webmanifest',
|
||||
'json'
|
||||
];
|
||||
const manifestFile = await enumMetadataFiles(resolvedDir, 'manifest', staticManifestExtension.concat(pageExtensions), {
|
||||
metadataResolver,
|
||||
numericSuffix: false
|
||||
});
|
||||
if (manifestFile.length > 0) {
|
||||
hasStaticMetadataFiles = true;
|
||||
const { name, ext } = _path.default.parse(manifestFile[0]);
|
||||
const extension = staticManifestExtension.includes(ext.slice(1)) ? ext.slice(1) : 'webmanifest';
|
||||
staticImagesMetadata.manifest = JSON.stringify(`${basePath}/${name}.${extension}`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const isFavicon = type === 'favicon';
|
||||
const resolvedMetadataFiles = await enumMetadataFiles(resolvedDir, _ismetadataroute.STATIC_METADATA_IMAGES[type].filename, [
|
||||
..._ismetadataroute.STATIC_METADATA_IMAGES[type].extensions,
|
||||
...isFavicon ? [] : pageExtensions
|
||||
], {
|
||||
metadataResolver,
|
||||
numericSuffix: !isFavicon
|
||||
});
|
||||
resolvedMetadataFiles.sort((a, b)=>a.localeCompare(b)).forEach((filepath)=>{
|
||||
const imageModuleImportSource = `next-metadata-image-loader?${(0, _querystring.stringify)({
|
||||
type,
|
||||
segment,
|
||||
basePath,
|
||||
pageExtensions
|
||||
})}!${filepath}?${_constants.WEBPACK_RESOURCE_QUERIES.metadata}`;
|
||||
const imageModule = `(async (props) => (await import(/* webpackMode: "eager" */ ${JSON.stringify(imageModuleImportSource)})).default(props))`;
|
||||
hasStaticMetadataFiles = true;
|
||||
if (type === 'favicon') {
|
||||
staticImagesMetadata.icon.unshift(imageModule);
|
||||
} else {
|
||||
staticImagesMetadata[type].push(imageModule);
|
||||
}
|
||||
});
|
||||
}
|
||||
// Intentionally make these serial to reuse directory access cache.
|
||||
await collectIconModuleIfExists('icon');
|
||||
await collectIconModuleIfExists('apple');
|
||||
await collectIconModuleIfExists('openGraph');
|
||||
await collectIconModuleIfExists('twitter');
|
||||
if (isRootLayoutOrRootPage) {
|
||||
await collectIconModuleIfExists('favicon');
|
||||
await collectIconModuleIfExists('manifest');
|
||||
}
|
||||
return hasStaticMetadataFiles ? staticImagesMetadata : null;
|
||||
}
|
||||
function createMetadataExportsCode(metadata) {
|
||||
return metadata ? `${METADATA_TYPE}: {
|
||||
icon: [${metadata.icon.join(',')}],
|
||||
apple: [${metadata.apple.join(',')}],
|
||||
openGraph: [${metadata.openGraph.join(',')}],
|
||||
twitter: [${metadata.twitter.join(',')}],
|
||||
manifest: ${metadata.manifest ? metadata.manifest : 'undefined'}
|
||||
}` : '';
|
||||
}
|
||||
|
||||
//# sourceMappingURL=discover.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+5
@@ -0,0 +1,5 @@
|
||||
import type { MetadataRoute } from '../../../../lib/metadata/types/metadata-interface';
|
||||
export declare function resolveRobots(data: MetadataRoute.Robots): string;
|
||||
export declare function resolveSitemap(data: MetadataRoute.Sitemap): string;
|
||||
export declare function resolveManifest(data: MetadataRoute.Manifest): string;
|
||||
export declare function resolveRouteData(data: MetadataRoute.Robots | MetadataRoute.Sitemap | MetadataRoute.Manifest, fileType: 'robots' | 'sitemap' | 'manifest'): string;
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
0 && (module.exports = {
|
||||
resolveManifest: null,
|
||||
resolveRobots: null,
|
||||
resolveRouteData: null,
|
||||
resolveSitemap: null
|
||||
});
|
||||
function _export(target, all) {
|
||||
for(var name in all)Object.defineProperty(target, name, {
|
||||
enumerable: true,
|
||||
get: all[name]
|
||||
});
|
||||
}
|
||||
_export(exports, {
|
||||
resolveManifest: function() {
|
||||
return resolveManifest;
|
||||
},
|
||||
resolveRobots: function() {
|
||||
return resolveRobots;
|
||||
},
|
||||
resolveRouteData: function() {
|
||||
return resolveRouteData;
|
||||
},
|
||||
resolveSitemap: function() {
|
||||
return resolveSitemap;
|
||||
}
|
||||
});
|
||||
const _utils = require("../../../../lib/metadata/generate/utils");
|
||||
function resolveRobots(data) {
|
||||
let content = '';
|
||||
const rules = Array.isArray(data.rules) ? data.rules : [
|
||||
data.rules
|
||||
];
|
||||
for (const rule of rules){
|
||||
const userAgent = (0, _utils.resolveArray)(rule.userAgent || [
|
||||
'*'
|
||||
]);
|
||||
for (const agent of userAgent){
|
||||
content += `User-Agent: ${agent}\n`;
|
||||
}
|
||||
if (rule.allow) {
|
||||
const allow = (0, _utils.resolveArray)(rule.allow);
|
||||
for (const item of allow){
|
||||
content += `Allow: ${item}\n`;
|
||||
}
|
||||
}
|
||||
if (rule.disallow) {
|
||||
const disallow = (0, _utils.resolveArray)(rule.disallow);
|
||||
for (const item of disallow){
|
||||
content += `Disallow: ${item}\n`;
|
||||
}
|
||||
}
|
||||
if (rule.crawlDelay) {
|
||||
content += `Crawl-delay: ${rule.crawlDelay}\n`;
|
||||
}
|
||||
content += '\n';
|
||||
}
|
||||
if (data.host) {
|
||||
content += `Host: ${data.host}\n`;
|
||||
}
|
||||
if (data.sitemap) {
|
||||
const sitemap = (0, _utils.resolveArray)(data.sitemap);
|
||||
// TODO-METADATA: support injecting sitemap url into robots.txt
|
||||
sitemap.forEach((item)=>{
|
||||
content += `Sitemap: ${item}\n`;
|
||||
});
|
||||
}
|
||||
return content;
|
||||
}
|
||||
function resolveSitemap(data) {
|
||||
const hasAlternates = data.some((item)=>Object.keys(item.alternates ?? {}).length > 0);
|
||||
const hasImages = data.some((item)=>{
|
||||
var _item_images;
|
||||
return Boolean((_item_images = item.images) == null ? void 0 : _item_images.length);
|
||||
});
|
||||
const hasVideos = data.some((item)=>{
|
||||
var _item_videos;
|
||||
return Boolean((_item_videos = item.videos) == null ? void 0 : _item_videos.length);
|
||||
});
|
||||
let content = '';
|
||||
content += '<?xml version="1.0" encoding="UTF-8"?>\n';
|
||||
content += '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"';
|
||||
if (hasImages) {
|
||||
content += ' xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"';
|
||||
}
|
||||
if (hasVideos) {
|
||||
content += ' xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"';
|
||||
}
|
||||
if (hasAlternates) {
|
||||
content += ' xmlns:xhtml="http://www.w3.org/1999/xhtml">\n';
|
||||
} else {
|
||||
content += '>\n';
|
||||
}
|
||||
for (const item of data){
|
||||
var _item_alternates, _item_images, _item_videos;
|
||||
content += '<url>\n';
|
||||
content += `<loc>${item.url}</loc>\n`;
|
||||
const languages = (_item_alternates = item.alternates) == null ? void 0 : _item_alternates.languages;
|
||||
if (languages && Object.keys(languages).length) {
|
||||
// Since sitemap is separated from the page rendering, there's not metadataBase accessible yet.
|
||||
// we give the default setting that won't effect the languages resolving.
|
||||
for(const language in languages){
|
||||
content += `<xhtml:link rel="alternate" hreflang="${language}" href="${languages[language]}" />\n`;
|
||||
}
|
||||
}
|
||||
if ((_item_images = item.images) == null ? void 0 : _item_images.length) {
|
||||
for (const image of item.images){
|
||||
content += `<image:image>\n<image:loc>${image}</image:loc>\n</image:image>\n`;
|
||||
}
|
||||
}
|
||||
if ((_item_videos = item.videos) == null ? void 0 : _item_videos.length) {
|
||||
for (const video of item.videos){
|
||||
let videoFields = [
|
||||
`<video:video>`,
|
||||
`<video:title>${video.title}</video:title>`,
|
||||
`<video:thumbnail_loc>${video.thumbnail_loc}</video:thumbnail_loc>`,
|
||||
`<video:description>${video.description}</video:description>`,
|
||||
video.content_loc && `<video:content_loc>${video.content_loc}</video:content_loc>`,
|
||||
video.player_loc && `<video:player_loc>${video.player_loc}</video:player_loc>`,
|
||||
video.duration && `<video:duration>${video.duration}</video:duration>`,
|
||||
video.view_count && `<video:view_count>${video.view_count}</video:view_count>`,
|
||||
video.tag && `<video:tag>${video.tag}</video:tag>`,
|
||||
video.rating && `<video:rating>${video.rating}</video:rating>`,
|
||||
video.expiration_date && `<video:expiration_date>${video.expiration_date}</video:expiration_date>`,
|
||||
video.publication_date && `<video:publication_date>${video.publication_date}</video:publication_date>`,
|
||||
video.family_friendly && `<video:family_friendly>${video.family_friendly}</video:family_friendly>`,
|
||||
video.requires_subscription && `<video:requires_subscription>${video.requires_subscription}</video:requires_subscription>`,
|
||||
video.live && `<video:live>${video.live}</video:live>`,
|
||||
video.restriction && `<video:restriction relationship="${video.restriction.relationship}">${video.restriction.content}</video:restriction>`,
|
||||
video.platform && `<video:platform relationship="${video.platform.relationship}">${video.platform.content}</video:platform>`,
|
||||
video.uploader && `<video:uploader${video.uploader.info && ` info="${video.uploader.info}"`}>${video.uploader.content}</video:uploader>`,
|
||||
`</video:video>\n`
|
||||
].filter(Boolean);
|
||||
content += videoFields.join('\n');
|
||||
}
|
||||
}
|
||||
if (item.lastModified) {
|
||||
const serializedDate = item.lastModified instanceof Date ? item.lastModified.toISOString() : item.lastModified;
|
||||
content += `<lastmod>${serializedDate}</lastmod>\n`;
|
||||
}
|
||||
if (item.changeFrequency) {
|
||||
content += `<changefreq>${item.changeFrequency}</changefreq>\n`;
|
||||
}
|
||||
if (typeof item.priority === 'number') {
|
||||
content += `<priority>${item.priority}</priority>\n`;
|
||||
}
|
||||
content += '</url>\n';
|
||||
}
|
||||
content += '</urlset>\n';
|
||||
return content;
|
||||
}
|
||||
function resolveManifest(data) {
|
||||
return JSON.stringify(data);
|
||||
}
|
||||
function resolveRouteData(data, fileType) {
|
||||
if (fileType === 'robots') {
|
||||
return resolveRobots(data);
|
||||
}
|
||||
if (fileType === 'sitemap') {
|
||||
return resolveSitemap(data);
|
||||
}
|
||||
if (fileType === 'manifest') {
|
||||
return resolveManifest(data);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
//# sourceMappingURL=resolve-route-data.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+28
@@ -0,0 +1,28 @@
|
||||
export type ModuleGetter = () => any;
|
||||
export type ModuleTuple = [getModule: ModuleGetter, filePath: string];
|
||||
export type CollectingMetadata = {
|
||||
icon: string[];
|
||||
apple: string[];
|
||||
twitter: string[];
|
||||
openGraph: string[];
|
||||
manifest?: string;
|
||||
};
|
||||
export type CollectedMetadata = {
|
||||
icon: ModuleGetter[];
|
||||
apple: ModuleGetter[];
|
||||
twitter: ModuleGetter[] | null;
|
||||
openGraph: ModuleGetter[] | null;
|
||||
manifest?: string;
|
||||
};
|
||||
export type MetadataImageModule = {
|
||||
url: string;
|
||||
type?: string;
|
||||
alt?: string;
|
||||
} & ({
|
||||
sizes?: string;
|
||||
} | {
|
||||
width?: number;
|
||||
height?: number;
|
||||
});
|
||||
export type PossibleImageFileNameConvention = 'icon' | 'apple' | 'favicon' | 'twitter' | 'openGraph';
|
||||
export type PossibleStaticMetadataFileNameConvention = PossibleImageFileNameConvention | 'manifest';
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// TODO-APP: check if this can be narrowed.
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
//# sourceMappingURL=types.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../../../../src/build/webpack/loaders/metadata/types.ts"],"sourcesContent":["// TODO-APP: check if this can be narrowed.\nexport type ModuleGetter = () => any\n\nexport type ModuleTuple = [getModule: ModuleGetter, filePath: string]\n\n// Contain the collecting image module paths\nexport type CollectingMetadata = {\n icon: string[]\n apple: string[]\n twitter: string[]\n openGraph: string[]\n manifest?: string\n}\n\n// Contain the collecting evaluated image module\nexport type CollectedMetadata = {\n icon: ModuleGetter[]\n apple: ModuleGetter[]\n twitter: ModuleGetter[] | null\n openGraph: ModuleGetter[] | null\n manifest?: string\n}\n\nexport type MetadataImageModule = {\n url: string\n type?: string\n alt?: string\n} & (\n | { sizes?: string }\n | {\n width?: number\n height?: number\n }\n)\n\nexport type PossibleImageFileNameConvention =\n | 'icon'\n | 'apple'\n | 'favicon'\n | 'twitter'\n | 'openGraph'\n\nexport type PossibleStaticMetadataFileNameConvention =\n | PossibleImageFileNameConvention\n | 'manifest'\n"],"names":[],"mappings":"AAAA,2CAA2C","ignoreList":[0]}
|
||||
Reference in New Issue
Block a user