Direct R2 assets
This commit is contained in:
+55
-8
@@ -35,6 +35,13 @@ const directusUrl = process.env.DIRECTUS_URL ?? 'http://directus:8055';
|
||||
const directusPublicUrl = process.env.DIRECTUS_PUBLIC_URL && !process.env.DIRECTUS_PUBLIC_URL.includes('example.com')
|
||||
? process.env.DIRECTUS_PUBLIC_URL
|
||||
: directusUrl;
|
||||
const directusAssetBaseUrl = process.env.DIRECTUS_ASSET_BASE_URL && !process.env.DIRECTUS_ASSET_BASE_URL.includes('example.com')
|
||||
? process.env.DIRECTUS_ASSET_BASE_URL
|
||||
: undefined;
|
||||
const directusAssetUrlTemplate =
|
||||
process.env.DIRECTUS_ASSET_URL_TEMPLATE && !process.env.DIRECTUS_ASSET_URL_TEMPLATE.includes('example.com')
|
||||
? process.env.DIRECTUS_ASSET_URL_TEMPLATE
|
||||
: undefined;
|
||||
const directusToken = process.env.DIRECTUS_ADMIN_TOKEN;
|
||||
const homepageBannerFolder = process.env.DIRECTUS_HOMEPAGE_BANNER_FOLDER ?? 'homepage-banners';
|
||||
const cafePageFolder = process.env.DIRECTUS_CAFE_PAGE_FOLDER ?? 'cafe-page';
|
||||
@@ -49,6 +56,7 @@ type DirectusFile = {
|
||||
title?: string;
|
||||
description?: string;
|
||||
filename_download?: string;
|
||||
filename_disk?: string;
|
||||
type?: string;
|
||||
};
|
||||
|
||||
@@ -57,8 +65,8 @@ type EventTemplateRecord = {
|
||||
title?: string;
|
||||
slug?: string;
|
||||
description?: string;
|
||||
image?: string;
|
||||
logo?: string;
|
||||
image?: string | DirectusFile;
|
||||
logo?: string | DirectusFile;
|
||||
booking_url?: string;
|
||||
};
|
||||
|
||||
@@ -113,7 +121,46 @@ async function readDirectusEndpoint<T>(endpoint: URL): Promise<T[]> {
|
||||
return payload.data ?? [];
|
||||
}
|
||||
|
||||
export function resolveDirectusAssetUrl(fileId: string): string {
|
||||
function extensionFromFilename(filename?: string): string {
|
||||
if (!filename) return '';
|
||||
|
||||
const lastSegment = filename.split('/').pop() ?? '';
|
||||
const dotIndex = lastSegment.lastIndexOf('.');
|
||||
|
||||
if (dotIndex <= 0 || dotIndex === lastSegment.length - 1) return '';
|
||||
return lastSegment.slice(dotIndex);
|
||||
}
|
||||
|
||||
function directusFileId(file: string | DirectusFile): string {
|
||||
return typeof file === 'string' ? file : file.id;
|
||||
}
|
||||
|
||||
function directusObjectKey(file: string | DirectusFile): string {
|
||||
if (typeof file !== 'string' && file.filename_disk) {
|
||||
return file.filename_disk;
|
||||
}
|
||||
|
||||
const fileId = directusFileId(file);
|
||||
return `${fileId}${extensionFromFilename(typeof file === 'string' ? undefined : file.filename_download)}`;
|
||||
}
|
||||
|
||||
export function resolveDirectusAssetUrl(file: string | DirectusFile): string {
|
||||
const fileId = directusFileId(file);
|
||||
const r2ObjectKey = directusObjectKey(file);
|
||||
const encodedObjectKey = encodeURIComponent(r2ObjectKey);
|
||||
|
||||
if (directusAssetUrlTemplate) {
|
||||
return directusAssetUrlTemplate
|
||||
.replaceAll('{fileId}', encodedObjectKey)
|
||||
.replaceAll('{id}', encodedObjectKey)
|
||||
.replaceAll('{key}', encodedObjectKey);
|
||||
}
|
||||
|
||||
if (directusAssetBaseUrl) {
|
||||
const baseUrl = directusAssetBaseUrl.endsWith('/') ? directusAssetBaseUrl : `${directusAssetBaseUrl}/`;
|
||||
return new URL(encodedObjectKey, baseUrl).toString();
|
||||
}
|
||||
|
||||
return new URL(`/assets/${fileId}`, directusPublicUrl).toString();
|
||||
}
|
||||
|
||||
@@ -137,11 +184,11 @@ async function getImagesFromFolder(folderName: string, fallbackImages: HomepageB
|
||||
endpoint.searchParams.set('sort', '-uploaded_on');
|
||||
endpoint.searchParams.set('filter[folder][_eq]', folder.id);
|
||||
endpoint.searchParams.set('filter[type][_starts_with]', 'image/');
|
||||
endpoint.searchParams.set('fields', 'id,title,description,filename_download,type');
|
||||
endpoint.searchParams.set('fields', 'id,title,description,filename_download,filename_disk,type');
|
||||
|
||||
const files = await readDirectusEndpoint<DirectusFile>(endpoint);
|
||||
const images = files.map((file) => ({
|
||||
src: resolveDirectusAssetUrl(file.id),
|
||||
src: resolveDirectusAssetUrl(file),
|
||||
alt: file.description || file.title || file.filename_download || 'Swansea Airport',
|
||||
}));
|
||||
|
||||
@@ -195,9 +242,9 @@ async function getRecurringEvents(): Promise<EventItem[]> {
|
||||
const endpoint = new URL('/items/event_dates', directusUrl);
|
||||
endpoint.searchParams.set('limit', '100');
|
||||
endpoint.searchParams.set('sort', 'date');
|
||||
endpoint.searchParams.set(
|
||||
'fields',
|
||||
'id,date,template.id,template.title,template.slug,template.description,template.image,template.logo,template.booking_url',
|
||||
endpoint.searchParams.set(
|
||||
'fields',
|
||||
'id,date,template.id,template.title,template.slug,template.description,template.image.id,template.image.filename_download,template.image.filename_disk,template.logo.id,template.logo.filename_download,template.logo.filename_disk,template.booking_url',
|
||||
);
|
||||
|
||||
const eventDates = await readDirectusEndpoint<EventDateRecord>(endpoint);
|
||||
|
||||
Reference in New Issue
Block a user