sd-webui-lobe-theme/src/components/StructuredData/ld.ts

217 lines
5.5 KiB
TypeScript

import urlJoin from 'url-join';
import pkg from '@/../package.json';
import { EMAIL_BUSINESS, EMAIL_SUPPORT, OFFICIAL_SITE, SITE_URL, X } from '@/const/url';
const LAST_MODIFIED = new Date().toISOString();
export const AUTHOR_LIST = {
arvinxx: {
avatar: 'https://avatars.githubusercontent.com/u/28616219?v=4',
desc: 'Founder, Design Engineer',
name: 'Arvin Xu',
url: 'https://github.com/arvinxx',
},
canisminor: {
avatar: 'https://avatars.githubusercontent.com/u/17870709?v=4',
desc: 'Founder, Design Engineer',
name: 'CanisMinor',
url: 'https://github.com/arvinxx',
},
lobehub: {
avatar: 'https://avatars.githubusercontent.com/u/131470832?v=4',
desc: 'Official Account',
name: 'LobeHub',
url: 'https://github.com/lobehub',
},
};
class Ld {
generate({
image = '/og/cover.png',
url,
title,
description,
date,
webpage = {
enable: true,
},
}: {
date?: string;
description: string;
image?: string;
title: string;
url: string;
webpage?: {
enable?: boolean;
search?: boolean;
};
}) {
return {
'@context': 'https://schema.org',
'@graph': [
this.genWebSite(),
webpage?.enable &&
this.genWebPage({
...webpage,
date,
description,
image,
title,
url,
}),
image && this.genImageObject({ image, url }),
this.genOrganization(),
].filter(Boolean),
};
}
genOrganization() {
return {
'@id': this.getId(SITE_URL, '#organization'),
'@type': 'Organization',
'alternateName': 'LobeTheme',
'contactPoint': {
'@type': 'ContactPoint',
'contactType': 'customer support',
'email': EMAIL_SUPPORT,
},
'description':
'We are a group of e/acc design-engineers, hoping to provide modern design components and tools for AIGC, and creating a technology-driven forum, fostering knowledge interaction and the exchange of ideas that may culminate in mutual inspiration and collaborative innovation.',
'email': EMAIL_BUSINESS,
'founders': [this.getAuthors(['arvinxx']), this.getAuthors(['canisminor'])],
'image': urlJoin(OFFICIAL_SITE, '/icon-512x512.png'),
'logo': {
'@type': 'ImageObject',
'height': 512,
'url': urlJoin(OFFICIAL_SITE, '/icon-512x512.png'),
'width': 512,
},
'name': 'LobeHub',
'sameAs': [
X,
'https://github.com/lobehub',
'https://medium.com/@lobehub',
'https://www.youtube.com/@lobehub',
],
'url': OFFICIAL_SITE,
};
}
getAuthors(ids: string[] = []) {
const defaultAuthor = {
'@id': this.getId(SITE_URL, '#organization'),
'@type': 'Organization',
};
if (!ids || ids.length === 0) return defaultAuthor;
if (ids.length === 1 && ids[0] === 'lobehub') return defaultAuthor;
const personId = ids.find((id) => id !== 'lobehub');
if (!personId) return defaultAuthor;
const person = (AUTHOR_LIST as any)?.[personId];
if (!person) return defaultAuthor;
return {
'@type': 'Person',
'name': person.name,
'url': person.url,
};
}
genWebPage({
date,
image,
search,
description,
title,
url,
}: {
breadcrumbs?: { title: string; url: string }[];
date?: string;
description: string;
image?: string;
search?: boolean;
title: string;
url: string;
}) {
const fixedUrl = this.fixUrl(url);
const dateCreated = date ? new Date(date).toISOString() : LAST_MODIFIED;
const dateModified = date ? new Date(date).toISOString() : LAST_MODIFIED;
const baseInfo: any = {
'@id': fixedUrl,
'@type': 'WebPage',
'about': {
'@id': this.getId(SITE_URL, '#organization'),
},
'breadcrumbs': {
'@id': this.getId(fixedUrl, '#breadcrumb'),
},
'dateModified': dateModified,
'datePublished': dateCreated,
'description': description,
'image': {
'@id': this.getId(fixedUrl, '#primaryimage'),
},
'inLanguage': 'en-US',
'isPartOf': {
'@id': this.getId(SITE_URL, '#website'),
},
'name': this.fixTitle(title),
'primaryImageOfPage': {
'@id': this.getId(fixedUrl, '#primaryimage'),
},
'thumbnailUrl': image,
};
if (search) {
baseInfo.potentialAction = {
'@type': 'SearchAction',
'query-input': 'required name=search_term_string',
'target': `${fixedUrl}?q={search_term_string}`,
};
}
return baseInfo;
}
genImageObject({ image, url }: { image: string; url: string }) {
const fixedUrl = this.fixUrl(url);
return {
'@id': this.getId(fixedUrl, '#primaryimage'),
'@type': 'ImageObject',
'contentUrl': image,
'inLanguage': 'en-US',
'url': image,
};
}
genWebSite() {
const baseInfo: any = {
'@id': this.getId(SITE_URL, '#website'),
'@type': 'WebSite',
'description': pkg.description,
'inLanguage': 'en-US',
'name': 'LobeTheme',
'publisher': {
'@id': this.getId(SITE_URL, '#organization'),
},
'url': SITE_URL,
};
return baseInfo;
}
private getId(url: string, id: string) {
return [url, id].join('/');
}
private fixTitle(title: string) {
return title.includes('LobeTheme') ? title : `${title} · LobeTheme`;
}
private fixUrl(url: string) {
return urlJoin(SITE_URL, url);
}
}
export const ldModule = new Ld();