diff --git a/src/asDate.ts b/src/asDate.ts new file mode 100644 index 0000000..ebf99ff --- /dev/null +++ b/src/asDate.ts @@ -0,0 +1,39 @@ +import type { DateField, TimestampField } from "@prismicio/types"; + +/** + * Transforms a date or timestamp field into a JavaScript Date object + * + * @param dateOrTimestampField - a date or timestamp field from Prismic + * @returns a Date object, null if provided date is falsy + * + * @see Templating date field from Prismic {@link https://prismic.io/docs/technologies/templating-date-field-javascript} + */ +export function asDate( + dateOrTimestampField: DateField | TimestampField +): Date | null { + if (!dateOrTimestampField) { + return null; + } + + // If field is a timestamp field... + if (dateOrTimestampField.length === 24) { + /** + * Converts basic ISO 8601 to ECMAScript simplified ISO 8601 format for browser compatibility issues + * + * From: YYYY-MM-DDTHH:mm:ssZ + * To: YYYY-MM-DDTHH:mm:ss.sssZ + * + * @see MDN documentation: {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date#timestamp_string} + * @see ECMAScript 2020 language specification: {@link https://262.ecma-international.org/11.0/#sec-date-time-string-format} + * @see Related forum issue: {@link https://community.prismic.io/t/prismics-date-api/2520} + * + * @see Regex101 expression: {@link https://regex101.com/r/jxyETT/1} + */ + return new Date( + dateOrTimestampField.replace(/(\+|-)(\d{2})(\d{2})$/, ".000$1$2:$3") + ); + } else { + // ...else field is a date field + return new Date(dateOrTimestampField); + } +} diff --git a/src/asLink.ts b/src/asLink.ts new file mode 100644 index 0000000..2dd5f7b --- /dev/null +++ b/src/asLink.ts @@ -0,0 +1,38 @@ +import { LinkField, LinkType } from "@prismicio/types"; +import { LinkResolverFunction } from "./types"; + +// TODO: provide a way to handle v1 fields + +/** + * Resolves any type of link field to a URL + * + * @param linkField - any kind of link field to resolve + * @param linkResolver - a link resolver function, without it you're expected to use the `routes` from the API + * @returns resolved URL, an empty string if provided link is empty + * + * @see Prismic link resolver documentation: {@link https://prismic.io/docs/technologies/link-resolver-javascript} + * @see Prismic API `routes` options documentation: {@link https://prismic.io/docs/technologies/route-resolver-nuxtjs} + */ +export function asLink( + linkField: LinkField, + linkResolver: LinkResolverFunction = () => "/" // TODO: Not sure providing a failsafe default is the right idea +): string { + switch (linkField.link_type) { + case LinkType.Document: + if (linkField.url) { + // When using `apiOptions.routes`... + return linkField.url; + } else { + // ...when not + return linkResolver(linkField); + } + + case LinkType.Web: + case LinkType.Media: + return linkField.url; + + case LinkType.Any: + default: + return ""; + } +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..ae292a4 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,4 @@ +export { asDate } from "./asDate"; +export { asLink } from "./asLink"; + +export type { LinkResolverFunction } from "./types"; diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..e190fb4 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,5 @@ +import { FilledRelationField } from "@prismicio/types"; + +export type LinkResolverFunction = ( + doc: Omit +) => string;