This commit is contained in:
Morten Olsen
2024-03-30 20:53:01 +01:00
commit 98e39a54cc
94 changed files with 11654 additions and 0 deletions

13
src/data/data.articles.ts Normal file
View File

@@ -0,0 +1,13 @@
import { getCollection } from 'astro:content';
class Articles {
public find = () => getCollection('articles');
public get = async (slug: string) => {
const collection = await this.find();
return collection.find((entry) => entry.slug === slug);
};
}
type Article = Exclude<Awaited<ReturnType<Articles['get']>>, undefined>;
export { Articles, type Article };

View File

@@ -0,0 +1,13 @@
import { getCollection } from 'astro:content';
class References {
public find = () => getCollection('references');
public get = async (slug: string) => {
const collection = await this.find();
return collection.find((entry) => entry.slug === slug);
};
}
type Reference = Exclude<Awaited<ReturnType<References['get']>>, undefined>;
export { References, type Reference };

5
src/data/data.site.ts Normal file
View File

@@ -0,0 +1,5 @@
const site = {
theme: '#30E130',
};
export { site };

13
src/data/data.skills.ts Normal file
View File

@@ -0,0 +1,13 @@
import { getCollection } from 'astro:content';
class Skills {
public find = () => getCollection('skills');
public get = async (slug: string) => {
const collection = await this.find();
return collection.find((entry) => entry.slug === slug);
};
}
type Skill = Exclude<Awaited<ReturnType<Skills['get']>>, undefined>;
export { Skills, type Skill };

25
src/data/data.ts Normal file
View File

@@ -0,0 +1,25 @@
import { profile } from '../content/profile/profile.js';
import { type Article, Articles } from './data.articles.js';
import { References } from './data.references.ts';
import { site } from './data.site.ts';
import { Skills } from './data.skills.ts';
import { getJsonLDResume, getJsonResume } from './data.utils.js';
import { Work, type WorkItem } from './data.work.js';
class Data {
public articles = new Articles();
public work = new Work();
public references = new References();
public skills = new Skills();
public profile = profile;
public site = site;
public getJsonResume = getJsonResume.bind(null, this);
public getJsonLDResume = getJsonLDResume.bind(null, this);
}
const data = new Data();
type Profile = typeof profile;
export type { Article, Profile, WorkItem };
export { data, Data };

89
src/data/data.utils.ts Normal file
View File

@@ -0,0 +1,89 @@
import type { ResumeSchema } from '@/types/resume-schema.js';
import type { Article, Data } from './data';
const getJsonResume = async (data: Data) => {
const profile = data.profile;
const resume = {
basics: profile.basics,
} satisfies ResumeSchema;
return resume;
};
const getArticleJsonLD = async (data: Data, article: Article) => {
const jsonld = {
'@context': 'https://schema.org',
'@type': 'BlogPosting',
headline: article.data.title,
image: article.data.heroImage.src,
datePublished: article.data.pubDate.toISOString(),
keywords: article.data.tags,
inLanguage: 'en-US',
author: {
'@type': 'Person',
name: data.profile.basics.name,
url: data.profile.basics.url,
},
};
return jsonld;
};
const getJsonLDResume = async (data: Data) => {
const work = await data.work.find();
const currentWork = work.find((w) => !w.data.endDate);
const otherWork = work.filter((w) => w !== currentWork);
const jsonld = {
'@context': 'https://schema.org',
'@type': 'Person',
id: '#me',
name: data.profile.basics.name,
email: data.profile.basics.email,
image: data.profile.basics.image,
url: data.profile.basics.url,
jobTitle: currentWork?.data.position,
contactPoint: data.profile.basics.profiles.map((profile) => ({
'@type': 'ContactPoint',
contactType: profile.network.toLowerCase(),
identifier: profile.username,
url: profile.url,
})),
address: {
'@type': 'PostalAddress',
addressLocality: data.profile.basics.location.city,
addressRegion: data.profile.basics.location.region,
addressCountry: data.profile.basics.location.countryCode,
},
sameAs: data.profile.basics.profiles.map((profile) => profile.url),
hasOccupation: currentWork && {
'@type': 'EmployeeRole',
roleName: currentWork.data.position,
startDate: currentWork.data.startDate.toISOString(),
},
worksFor: currentWork && {
'@type': 'Organization',
name: currentWork?.data.name,
sameAs: currentWork?.data.url,
},
alumniOf: otherWork.map((w) => ({
'@type': 'Organization',
name: w.data.name,
sameAs: w.data.url,
employee: {
'@type': 'Person',
hasOccupation: {
'@type': 'EmployeeRole',
roleName: w.data.position,
startDate: w.data.startDate.toISOString(),
endDate: w.data.endDate?.toISOString(),
},
sameAs: '#me',
},
})),
};
return jsonld;
};
export { getJsonResume, getJsonLDResume, getArticleJsonLD };

12
src/data/data.work.ts Normal file
View File

@@ -0,0 +1,12 @@
import { getCollection } from 'astro:content';
class Work {
public find = () => getCollection('work');
public get = async (slug: string) => {
const collection = await this.find();
return collection.find((entry) => entry.slug === slug);
};
}
type WorkItem = Exclude<Awaited<ReturnType<Work['get']>>, undefined>;
export { Work, type WorkItem };