summaryrefslogtreecommitdiff
path: root/src/lib/collection/helpers.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/collection/helpers.ts')
-rw-r--r--src/lib/collection/helpers.ts115
1 files changed, 103 insertions, 12 deletions
diff --git a/src/lib/collection/helpers.ts b/src/lib/collection/helpers.ts
index f65e7c0..4dfafff 100644
--- a/src/lib/collection/helpers.ts
+++ b/src/lib/collection/helpers.ts
@@ -2,18 +2,26 @@ import type { CollectionEntry } from "astro:content";
import {
Blog,
Entity,
+ ENTITY_TYPES,
+ type EntityTypesEnum,
type Entry,
+ type LICENSES,
type MicroEntry,
+ Original,
type OriginalEntry,
+ Translation,
type TranslationEntry,
} from "./schemas.ts";
-import { getEntries, type z } from "astro:content";
-import { defined, get, identity } from "../../utils/anonymous.ts";
+import type { z } from "astro:content";
+import { defined, get, identity, transform } from "../../utils/anonymous.ts";
import { createKeyFromArmor } from "../pgp/create.ts";
import { getUserIDsFromKey } from "../pgp/user.ts";
import type { UserIDPacket } from "openpgp";
+import readingTime from "reading-time";
import { getCollection } from "astro:content";
import { getEntry } from "astro:content";
+import { getEntries } from "astro:content";
+import { listYearsWithRanges } from "../../utils/datetime.ts";
export function getLastUpdate({ data }: CollectionEntry<"blog">): Date {
return data.dateUpdated ?? data.dateCreated;
@@ -36,20 +44,28 @@ export const sortFirstUpdated = (
b: CollectionEntry<"blog">,
): number => sortLastUpdated(b, a);
+export function getSignersIDs(
+ { data }: CollectionEntry<"blog">,
+): Record<z.infer<typeof EntityTypesEnum>, string[]> {
+ const { signers } = Blog.parse(data);
+ const id = ({ entity }: typeof signers[number]) => entity.id;
+ return Object.fromEntries(
+ ENTITY_TYPES.map((x) => [x, signers.filter((s) => s.role === x).map(id)]),
+ ) as ReturnType<typeof getSignersIDs>;
+}
+
export async function getSigners(
{ data }: CollectionEntry<"blog">,
): Promise<{
- id: string;
entity: CollectionEntry<"entity">;
- role: z.infer<typeof Blog>["signers"][number]["role"] | undefined;
+ role?: z.infer<typeof Blog>["signers"][number]["role"];
}[]> {
const post = Blog.parse(data);
- return await getEntries(post.signers.map(get("entity"))).then((x) =>
- x.map((x) => ({
- id: x.id,
- entity: x,
- role: post.signers?.find((y) => y.entity.id === x.id)?.role,
- })).filter(({ role }) => defined(role))
+ return await Promise.all(
+ post.signers.map(async ({ entity, role }) => ({
+ entity: await getEntry(entity),
+ role,
+ })),
);
}
@@ -76,13 +92,13 @@ export async function getFirstUserID(
const signers = await getSigners(blog);
const userIDs = await Promise.all(
signers.filter(({ role }) => role === "author").map(
- async ({ id, entity }) => {
+ async ({ entity }) => {
const { publickey, websites } = Entity.parse(entity.data);
const website = websites?.[0];
const key = await createKeyFromArmor(publickey.armor);
const users = getUserIDsFromKey(undefined, key);
return users.map((user) => {
- return { ...user, entity: id, website };
+ return { ...user, entity: entity.id, website };
})?.[0];
},
),
@@ -118,3 +134,78 @@ export async function getTranslationOriginal(
}
return await getEntry(translation.data.translationOf);
}
+
+export function licenseNotice(
+ license: typeof LICENSES[number],
+ { title, holders, years }: {
+ title: string;
+ holders: { name: string; email?: string }[];
+ years: number[];
+ },
+ locale?: Intl.LocalesArgument,
+): string | undefined {
+ const list = new Intl.ListFormat(locale, {
+ style: "narrow",
+ type: "unit",
+ });
+ switch (license) {
+ case "CC0":
+ return `${title} by ${
+ list.format(holders.map(get("name")))
+ } is marked CC0 1.0 Universal. To view a copy of this mark, visit https://creativecommons.org/publicdomain/zero/1.0/`;
+ case "CC-BY":
+ case "CC-BY-SA":
+ case "CC-BY-ND":
+ case "CC-BY-NC":
+ case "CC-BY-NC-SA":
+ case "CC-BY-NC-ND":
+ return `${title} © ${
+ listYearsWithRanges(years, {
+ locale,
+ list: { type: "unit", style: "narrow" },
+ })
+ } by ${
+ list.format(holders.map(get("name")))
+ } is licensed under Creative Commons ${
+ license.slice(3).replace("BY", "Attribution").replace(
+ "SA",
+ "ShareAlike",
+ ).replace("ND", "NoDerivatives").replace("NC", "NonCommercial")
+ } 4.0 International. To view a copy of this license, visit https://creativecommons.org/licenses/${
+ license.slice(3).toLowerCase()
+ }/4.0/`;
+ case "WTFPL":
+ return `Copyright (C) ${
+ listYearsWithRanges(years, {
+ locale,
+ list: { type: "unit", style: "narrow" },
+ })
+ } ${
+ list.format(holders.map(({ name, email }) =>
+ name + (email !== undefined ? ` ${email}` : "")
+ ))
+ }`;
+ case "public domain":
+ undefined;
+ }
+}
+export function licenseURL(license: typeof LICENSES[number]): URL | undefined {
+ switch (license) {
+ case "CC0":
+ case "CC-BY":
+ case "CC-BY-SA":
+ case "CC-BY-ND":
+ case "CC-BY-NC":
+ case "CC-BY-NC-SA":
+ case "CC-BY-NC-ND":
+ return new URL(
+ `https://creativecommons.org/licenses/${
+ license.slice(3).toLowerCase()
+ }/4.0/`,
+ );
+ case "WTFPL":
+ return new URL("http://www.wtfpl.net/");
+ case "public domain":
+ return undefined;
+ }
+}