feat: extract shop from mp/shop — initial libreshop/shop
Some checks failed
Build and publish / build (push) Failing after 19s
Some checks failed
Build and publish / build (push) Failing after 19s
Source moved verbatim from mp/shop/ on 2026-04-29; mp was the first concrete adapter consuming the libreshop toolkit. Builds and publishes git.librete.ch/libreshop/shop on every main / v* push via the standard .gitea/workflows/build.yml shared across libreshop components.
This commit is contained in:
17
server/utils/cmsApi.ts
Normal file
17
server/utils/cmsApi.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Server-side CMS API utility.
|
||||
* Use this for direct CMS access during SSR.
|
||||
*/
|
||||
export async function fetchCms<T>(endpoint: string, options: Parameters<typeof $fetch>[1] = {}): Promise<T> {
|
||||
const config = useRuntimeConfig();
|
||||
const url = `${config.cmsInternalUrl}/api${endpoint}`;
|
||||
|
||||
return await $fetch<T>(url, {
|
||||
...options,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${config.shopApiToken}`,
|
||||
...((options.headers as Record<string, string>) || {})
|
||||
}
|
||||
});
|
||||
}
|
||||
37
server/utils/coverSlug.ts
Normal file
37
server/utils/coverSlug.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { fetchCms } from "./cmsApi";
|
||||
|
||||
export function slugify(text: string): string {
|
||||
return text
|
||||
.toLowerCase()
|
||||
.replace(/\s+/g, "-")
|
||||
.replace(/ü/g, "ue")
|
||||
.replace(/ä/g, "ae")
|
||||
.replace(/ö/g, "oe")
|
||||
.replace(/ß/g, "ss");
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a cover slug or ID to the actual cover ID.
|
||||
* If the input is already a numeric ID, returns it as-is.
|
||||
* If it's a slug, looks up the cover by name and returns the ID.
|
||||
*/
|
||||
export async function resolveCoverId(idOrSlug: string): Promise<string | null> {
|
||||
// If it's already a numeric ID, return it
|
||||
if (/^\d+$/.test(idOrSlug)) {
|
||||
return idOrSlug;
|
||||
}
|
||||
|
||||
// Otherwise, fetch all covers and find by slug
|
||||
try {
|
||||
const allCovers = await fetchCms<{ data: any[] }>(`/product-covers`);
|
||||
const cover = allCovers.data?.find((c: any) => {
|
||||
const name = c.attributes?.name || c.name;
|
||||
const slug = slugify(name || "");
|
||||
return slug === idOrSlug;
|
||||
});
|
||||
|
||||
return cover?.id?.toString() || null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user