it was weird. i pressed delete on a subfolder, i think one of the pages.off folders that i was using. and then, suddenly, nvim on windows 7 decided to delete every file in the directory. they weren't shred off the space time continuum, but just marked deleted. i had to pay $80 to get access to a software that could see them. bleh! just seeing all my work, a little over a week, was pretty heart shattering. but i remembered that long ago, a close friend said i could call them whenever i was feeling sad. i finally took them up on that offer. the first time i've ever called someone for emotional support. but it's ok. i got it back. and the site framework is better than ever. i'm gonna commit and push more often. the repo is private anyways.
147 lines
3.9 KiB
TypeScript
147 lines
3.9 KiB
TypeScript
import type { Metadata, ResolvedMetadata } from "../types/metadata-interface";
|
|
import type {
|
|
OpenGraph,
|
|
OpenGraphType,
|
|
ResolvedOpenGraph,
|
|
} from "../types/opengraph-types";
|
|
import type { FieldResolverWithMetadataBase } from "../types/resolvers";
|
|
import type { ResolvedTwitterMetadata, Twitter } from "../types/twitter-types";
|
|
import { resolveAsArrayOrUndefined } from "../generate/utils";
|
|
import { isStringOrURL, resolveUrl } from "./resolve-url";
|
|
|
|
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",
|
|
],
|
|
} as const;
|
|
|
|
function resolveImages(
|
|
images: Twitter["images"],
|
|
metadataBase: ResolvedMetadata["metadataBase"],
|
|
): NonNullable<ResolvedMetadata["twitter"]>["images"];
|
|
function resolveImages(
|
|
images: OpenGraph["images"],
|
|
metadataBase: ResolvedMetadata["metadataBase"],
|
|
): NonNullable<ResolvedMetadata["openGraph"]>["images"];
|
|
function resolveImages(
|
|
images: OpenGraph["images"] | Twitter["images"],
|
|
metadataBase: ResolvedMetadata["metadataBase"],
|
|
):
|
|
| NonNullable<ResolvedMetadata["twitter"]>["images"]
|
|
| NonNullable<ResolvedMetadata["openGraph"]>["images"] {
|
|
const resolvedImages = resolveAsArrayOrUndefined(images);
|
|
resolvedImages?.forEach((item, index, array) => {
|
|
if (isStringOrURL(item)) {
|
|
array[index] = {
|
|
url: resolveUrl(item, metadataBase)!,
|
|
};
|
|
} else {
|
|
// Update image descriptor url
|
|
item.url = resolveUrl(item.url, metadataBase)!;
|
|
}
|
|
});
|
|
return resolvedImages;
|
|
}
|
|
|
|
function getFieldsByOgType(ogType: OpenGraphType | undefined) {
|
|
switch (ogType) {
|
|
case "article":
|
|
case "book":
|
|
return OgTypeFields.article;
|
|
case "music.song":
|
|
case "music.album":
|
|
return OgTypeFields.song;
|
|
case "music.playlist":
|
|
return OgTypeFields.playlist;
|
|
case "music.radio_station":
|
|
return OgTypeFields.radio;
|
|
case "video.movie":
|
|
case "video.episode":
|
|
return OgTypeFields.video;
|
|
default:
|
|
return OgTypeFields.basic;
|
|
}
|
|
}
|
|
|
|
export const resolveOpenGraph: FieldResolverWithMetadataBase<"openGraph"> = (
|
|
openGraph: Metadata["openGraph"],
|
|
metadataBase: ResolvedMetadata["metadataBase"],
|
|
) => {
|
|
if (!openGraph) return null;
|
|
|
|
const url = resolveUrl(openGraph.url, metadataBase);
|
|
const resolved = { ...openGraph } as ResolvedOpenGraph;
|
|
|
|
function assignProps(og: OpenGraph) {
|
|
const ogType = og && "type" in og ? og.type : undefined;
|
|
const keys = getFieldsByOgType(ogType);
|
|
for (const k of keys) {
|
|
const key = k as keyof ResolvedOpenGraph;
|
|
if (key in og && key !== "url") {
|
|
const value = og[key];
|
|
if (value) {
|
|
const arrayValue = resolveAsArrayOrUndefined(value); /// TODO: improve typing inferring
|
|
(resolved as any)[key] = arrayValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
resolved.images = resolveImages(og.images, metadataBase);
|
|
}
|
|
|
|
assignProps(openGraph);
|
|
|
|
resolved.url = url;
|
|
|
|
return resolved;
|
|
};
|
|
|
|
const TwitterBasicInfoKeys = [
|
|
"site",
|
|
"siteId",
|
|
"creator",
|
|
"creatorId",
|
|
"description",
|
|
] as const;
|
|
|
|
export const resolveTwitter: FieldResolverWithMetadataBase<"twitter"> = (
|
|
twitter,
|
|
metadataBase,
|
|
) => {
|
|
if (!twitter) return null;
|
|
const resolved = {
|
|
...twitter,
|
|
card: "card" in twitter ? twitter.card : "summary",
|
|
} as ResolvedTwitterMetadata;
|
|
for (const infoKey of TwitterBasicInfoKeys) {
|
|
resolved[infoKey] = twitter[infoKey] || null;
|
|
}
|
|
resolved.images = resolveImages(twitter.images, metadataBase);
|
|
|
|
if ("card" in resolved) {
|
|
switch (resolved.card) {
|
|
case "player": {
|
|
resolved.players = resolveAsArrayOrUndefined(resolved.players) || [];
|
|
break;
|
|
}
|
|
case "app": {
|
|
resolved.app = resolved.app || {};
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return resolved;
|
|
};
|