diff --git a/api/src/models/utils/index.ts b/api/src/models/utils/index.ts new file mode 100644 index 00000000..0b7bef19 --- /dev/null +++ b/api/src/models/utils/index.ts @@ -0,0 +1,7 @@ +export const ref = (id: string) => `#/components/schemas/${id}`; + +export * from "./external-id"; +export * from "./genres"; +export * from "./image"; +export * from "./language"; +export * from "./resource"; diff --git a/api/src/models/utils/language.ts b/api/src/models/utils/language.ts new file mode 100644 index 00000000..302e67f9 --- /dev/null +++ b/api/src/models/utils/language.ts @@ -0,0 +1,28 @@ +import { FormatRegistry } from "@sinclair/typebox"; +import { t } from "elysia"; +import { comment } from "../../utils"; + +FormatRegistry.Set("language", (lang) => { + try { + const normalized = new Intl.Locale(lang).baseName; + // TODO: we should actually replace the locale with normalized if we managed to parse it but transforms aren't working + return lang === normalized; + } catch { + return false; + } +}); + +type StringProps = NonNullable[0]>; + +// TODO: format validation doesn't work in record's key. We should have a proper way to check that. +export const Language = (props?: StringProps) => + t.String({ + format: "language", + description: comment` + ${props?.description ?? ""} + This is a BCP 47 language code (the IETF Best Current Practices on Tags for Identifying Languages). + BCP 47 is also known as RFC 5646. It subsumes ISO 639 and is backward compatible with it. + `, + error: "Expected a valid (and NORMALIZED) bcp-47 language code.", + ...props, + }); diff --git a/api/src/models/utils/resource.ts b/api/src/models/utils/resource.ts new file mode 100644 index 00000000..0de06436 --- /dev/null +++ b/api/src/models/utils/resource.ts @@ -0,0 +1,11 @@ +import { FormatRegistry } from "@sinclair/typebox"; +import { t } from "elysia"; + +FormatRegistry.Set("slug", (slug) => { + return /^[a-z0-9-]+$/g.test(slug); +}); + +export const Resource = t.Object({ + id: t.String({ format: "uuid" }), + slug: t.String({ format: "slug" }), +});