✨ feat: enhance medialib image handling and add asset URL resolution
- Implemented `resolveApiAssetUrl` function to normalize asset URLs based on API base. - Updated `MedialibImage` component to utilize new asset URL resolution and added support for alt text and class properties. - Enhanced image loading behavior with improved width measurement and focal point handling. - Added placeholder image handling and improved accessibility with alt text. - Introduced new test script for auditing broken links in skill documentation. - Expanded seeded test content to include medialib entries and updated related tests for pagebuilder previews. - Improved global setup and teardown logging for clarity on seeded content management.
This commit is contained in:
+17
-10
@@ -137,13 +137,15 @@ const CACHE_TTL = 1000 * 60 * 60 // 1 hour
|
||||
// Generic collection helpers
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
type CollectionNameT = "medialib" | "content" | string
|
||||
type CollectionNameT = "medialib" | "content" | "navigation" | string
|
||||
|
||||
type EntryTypeSwitch<T extends string> = T extends "medialib"
|
||||
? MedialibEntry
|
||||
: T extends "content"
|
||||
? ContentEntry
|
||||
: Record<string, unknown>
|
||||
: T extends "navigation"
|
||||
? NavigationEntry
|
||||
: Record<string, unknown>
|
||||
|
||||
export async function getDBEntries<T extends CollectionNameT>(
|
||||
collectionName: T,
|
||||
@@ -152,7 +154,8 @@ export async function getDBEntries<T extends CollectionNameT>(
|
||||
limit?: number,
|
||||
offset?: number,
|
||||
projection?: string,
|
||||
params?: Record<string, string>
|
||||
params?: Record<string, string>,
|
||||
lookup?: string
|
||||
): Promise<EntryTypeSwitch<T>[]> {
|
||||
const c = await api<EntryTypeSwitch<T>[]>(collectionName, {
|
||||
filter,
|
||||
@@ -161,6 +164,7 @@ export async function getDBEntries<T extends CollectionNameT>(
|
||||
offset,
|
||||
projection,
|
||||
params,
|
||||
lookup,
|
||||
})
|
||||
return c.data
|
||||
}
|
||||
@@ -172,13 +176,14 @@ export async function getCachedEntries<T extends CollectionNameT>(
|
||||
limit?: number,
|
||||
offset?: number,
|
||||
projection?: string,
|
||||
params?: Record<string, string>
|
||||
params?: Record<string, string>,
|
||||
lookup?: string
|
||||
): Promise<EntryTypeSwitch<T>[]> {
|
||||
const filterStr = obj2str({ collectionName, filter, sort, limit, offset, projection, params })
|
||||
const filterStr = obj2str({ collectionName, filter, sort, limit, offset, projection, params, lookup })
|
||||
if (cache[filterStr] && cache[filterStr].expire >= Date.now()) {
|
||||
return cache[filterStr].data as EntryTypeSwitch<T>[]
|
||||
}
|
||||
const entries = await getDBEntries<T>(collectionName, filter, sort, limit, offset, projection, params)
|
||||
const entries = await getDBEntries<T>(collectionName, filter, sort, limit, offset, projection, params, lookup)
|
||||
cache[filterStr] = { expire: Date.now() + CACHE_TTL, data: entries }
|
||||
return entries
|
||||
}
|
||||
@@ -187,18 +192,20 @@ export async function getDBEntry<T extends CollectionNameT>(
|
||||
collectionName: T,
|
||||
filter: MongoFilter,
|
||||
projection?: string,
|
||||
params?: Record<string, string>
|
||||
params?: Record<string, string>,
|
||||
lookup?: string
|
||||
): Promise<EntryTypeSwitch<T> | undefined> {
|
||||
return (await getDBEntries<T>(collectionName, filter, "_id", 1, undefined, projection, params))?.[0]
|
||||
return (await getDBEntries<T>(collectionName, filter, "_id", 1, undefined, projection, params, lookup))?.[0]
|
||||
}
|
||||
|
||||
export async function getCachedEntry<T extends CollectionNameT>(
|
||||
collectionName: T,
|
||||
filter: MongoFilter,
|
||||
projection?: string,
|
||||
params?: Record<string, string>
|
||||
params?: Record<string, string>,
|
||||
lookup?: string
|
||||
): Promise<EntryTypeSwitch<T> | undefined> {
|
||||
return (await getCachedEntries<T>(collectionName, filter, "_id", 1, undefined, projection, params))?.[0]
|
||||
return (await getCachedEntries<T>(collectionName, filter, "_id", 1, undefined, projection, params, lookup))?.[0]
|
||||
}
|
||||
|
||||
export async function postDBEntry<T extends CollectionNameT>(
|
||||
|
||||
@@ -1,3 +1,32 @@
|
||||
import { get } from "svelte/store"
|
||||
import { apiBaseURL } from "../config"
|
||||
import { apiBaseOverride } from "./store"
|
||||
|
||||
function isAbsoluteUrl(url: string | undefined): boolean {
|
||||
return !!url && (/^(?:https?:)?\/\//.test(url) || url.startsWith("data:") || url.startsWith("blob:"))
|
||||
}
|
||||
|
||||
function normalizeBase(base: string | null | undefined): string | null {
|
||||
return base ? base.replace(/\/+$/, "") + "/" : null
|
||||
}
|
||||
|
||||
export function resolveApiAssetUrl(
|
||||
url: string | null | undefined,
|
||||
apiBase: string | null | undefined = get(apiBaseOverride) || apiBaseURL
|
||||
): string | null | undefined {
|
||||
if (!url || isAbsoluteUrl(url) || !url.startsWith("/assets/")) {
|
||||
return url
|
||||
}
|
||||
|
||||
const normalizedApiBase = normalizeBase(apiBase)
|
||||
|
||||
if (!normalizedApiBase) {
|
||||
return url
|
||||
}
|
||||
|
||||
return normalizedApiBase + "_/assets/" + url.replace(/^\/+/, "")
|
||||
}
|
||||
|
||||
export function debounce<T extends (...args: never[]) => void>(
|
||||
func: T,
|
||||
wait: number
|
||||
|
||||
Reference in New Issue
Block a user