File size: 8,011 Bytes
c592d77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
0 && (module.exports = {
    resolveImages: null,
    resolveOpenGraph: null,
    resolveTwitter: null
});
function _export(target, all) {
    for(var name in all)Object.defineProperty(target, name, {
        enumerable: true,
        get: all[name]
    });
}
_export(exports, {
    resolveImages: function() {
        return resolveImages;
    },
    resolveOpenGraph: function() {
        return resolveOpenGraph;
    },
    resolveTwitter: function() {
        return resolveTwitter;
    }
});
const _utils = require("../generate/utils");
const _resolveurl = require("./resolve-url");
const _resolvetitle = require("./resolve-title");
const _url = require("../../url");
const _log = require("../../../build/output/log");
const OgTypeFields = {
    article: [
        'authors',
        'tags'
    ],
    song: [
        'albums',
        'musicians'
    ],
    playlist: [
        'albums',
        'musicians'
    ],
    radio: [
        'creators'
    ],
    video: [
        'actors',
        'directors',
        'writers',
        'tags'
    ],
    basic: [
        'emails',
        'phoneNumbers',
        'faxNumbers',
        'alternateLocale',
        'audio',
        'videos'
    ]
};
function resolveAndValidateImage(item, metadataBase, isStaticMetadataRouteFile) {
    if (!item) return undefined;
    const isItemUrl = (0, _resolveurl.isStringOrURL)(item);
    const inputUrl = isItemUrl ? item : item.url;
    if (!inputUrl) return undefined;
    // process.env.VERCEL is set to "1" when System Environment Variables are
    // exposed. When exposed, validation is not necessary since we are falling back to
    // process.env.VERCEL_PROJECT_PRODUCTION_URL, process.env.VERCEL_BRANCH_URL, or
    // process.env.VERCEL_URL for the `metadataBase`. process.env.VERCEL is undefined
    // when System Environment Variables are not exposed. When not exposed, we cannot
    // detect in the build environment if the deployment is a Vercel deployment or not.
    //
    // x-ref: https://vercel.com/docs/projects/environment-variables/system-environment-variables#system-environment-variables
    const isUsingVercelSystemEnvironmentVariables = Boolean(process.env.VERCEL);
    const isRelativeUrl = typeof inputUrl === 'string' && !(0, _url.isFullStringUrl)(inputUrl);
    // When no explicit metadataBase is specified by the user, we'll override it with the fallback metadata
    // under the following conditions:
    // - The provided URL is relative (ie ./og-image).
    // - The image is statically generated by Next.js (such as the special `opengraph-image` route)
    // In both cases, we want to ensure that across all environments, the ogImage is a fully qualified URL.
    // In the `opengraph-image` case, since the user isn't explicitly passing a relative path, this ensures
    // the ogImage will be properly discovered across different environments without the user needing to
    // have a bunch of `process.env` checks when defining their `metadataBase`.
    if (isRelativeUrl && (!metadataBase || isStaticMetadataRouteFile)) {
        const fallbackMetadataBase = (0, _resolveurl.getSocialImageMetadataBaseFallback)(metadataBase);
        // When not using Vercel environment variables for URL injection, we aren't able to determine
        // a fallback value for `metadataBase`. For self-hosted setups, we want to warn
        // about this since the only fallback we'll be able to generate is `localhost`.
        // In development, we'll only warn for relative metadata that isn't part of the static
        // metadata conventions (eg `opengraph-image`), as otherwise it's currently very noisy
        // for common cases. Eventually we should remove this warning all together in favor of
        // devtools.
        const shouldWarn = !isUsingVercelSystemEnvironmentVariables && !metadataBase && (process.env.NODE_ENV === 'production' || !isStaticMetadataRouteFile);
        if (shouldWarn) {
            (0, _log.warnOnce)(`metadataBase property in metadata export is not set for resolving social open graph or twitter images, using "${fallbackMetadataBase.origin}". See https://nextjs.org/docs/app/api-reference/functions/generate-metadata#metadatabase`);
        }
        metadataBase = fallbackMetadataBase;
    }
    return isItemUrl ? {
        url: (0, _resolveurl.resolveUrl)(inputUrl, metadataBase)
    } : {
        ...item,
        // Update image descriptor url
        url: (0, _resolveurl.resolveUrl)(inputUrl, metadataBase)
    };
}
function resolveImages(images, metadataBase, isStaticMetadataRouteFile) {
    const resolvedImages = (0, _utils.resolveAsArrayOrUndefined)(images);
    if (!resolvedImages) return resolvedImages;
    const nonNullableImages = [];
    for (const item of resolvedImages){
        const resolvedItem = resolveAndValidateImage(item, metadataBase, isStaticMetadataRouteFile);
        if (!resolvedItem) continue;
        nonNullableImages.push(resolvedItem);
    }
    return nonNullableImages;
}
const ogTypeToFields = {
    article: OgTypeFields.article,
    book: OgTypeFields.article,
    'music.song': OgTypeFields.song,
    'music.album': OgTypeFields.song,
    'music.playlist': OgTypeFields.playlist,
    'music.radio_station': OgTypeFields.radio,
    'video.movie': OgTypeFields.video,
    'video.episode': OgTypeFields.video
};
function getFieldsByOgType(ogType) {
    if (!ogType || !(ogType in ogTypeToFields)) return OgTypeFields.basic;
    return ogTypeToFields[ogType].concat(OgTypeFields.basic);
}
const resolveOpenGraph = async (openGraph, metadataBase, pathname, metadataContext, titleTemplate)=>{
    if (!openGraph) return null;
    function resolveProps(target, og) {
        const ogType = og && 'type' in og ? og.type : undefined;
        const keys = getFieldsByOgType(ogType);
        for (const k of keys){
            const key = k;
            if (key in og && key !== 'url') {
                const value = og[key];
                target[key] = value ? (0, _utils.resolveArray)(value) : null;
            }
        }
        target.images = resolveImages(og.images, metadataBase, metadataContext.isStaticMetadataRouteFile);
    }
    const resolved = {
        ...openGraph,
        title: (0, _resolvetitle.resolveTitle)(openGraph.title, titleTemplate)
    };
    resolveProps(resolved, openGraph);
    resolved.url = openGraph.url ? (0, _resolveurl.resolveAbsoluteUrlWithPathname)(openGraph.url, metadataBase, await pathname, metadataContext) : null;
    return resolved;
};
const TwitterBasicInfoKeys = [
    'site',
    'siteId',
    'creator',
    'creatorId',
    'description'
];
const resolveTwitter = (twitter, metadataBase, metadataContext, titleTemplate)=>{
    var _resolved_images;
    if (!twitter) return null;
    let card = 'card' in twitter ? twitter.card : undefined;
    const resolved = {
        ...twitter,
        title: (0, _resolvetitle.resolveTitle)(twitter.title, titleTemplate)
    };
    for (const infoKey of TwitterBasicInfoKeys){
        resolved[infoKey] = twitter[infoKey] || null;
    }
    resolved.images = resolveImages(twitter.images, metadataBase, metadataContext.isStaticMetadataRouteFile);
    card = card || (((_resolved_images = resolved.images) == null ? void 0 : _resolved_images.length) ? 'summary_large_image' : 'summary');
    resolved.card = card;
    if ('card' in resolved) {
        switch(resolved.card){
            case 'player':
                {
                    resolved.players = (0, _utils.resolveAsArrayOrUndefined)(resolved.players) || [];
                    break;
                }
            case 'app':
                {
                    resolved.app = resolved.app || {};
                    break;
                }
            case 'summary':
            case 'summary_large_image':
                break;
            default:
                resolved;
        }
    }
    return resolved;
};

//# sourceMappingURL=resolve-opengraph.js.map