-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.ts
More file actions
68 lines (59 loc) · 3.33 KB
/
Copy pathindex.ts
File metadata and controls
68 lines (59 loc) · 3.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/**
* ┌─────────────────────────────────────────────────────────────────────────┐
* │ THE CMS SEAM │
* │ │
* │ Everything above the application reads content through THIS module and │
* │ nowhere else. Today it returns local fixtures; to wire in a real │
* │ headless CMS (Contentful, Sanity, Hygraph, Strapi, ...) you replace the │
* │ bodies of these functions with network calls and map the response onto │
* │ the types in `./types`. Run that mapped response through │
* │ `lib/contract/validate.ts` so schema drift is caught at the boundary. │
* │ │
* │ The functions are async on purpose: a real CMS fetch returns a promise, │
* │ and Server Components await it. Keeping the signatures async now means │
* │ swapping the implementation is the ONLY change required later. │
* │ │
* │ See `lib/cms/adapters/contentful.ts` for a shape-mapping stub. │
* └─────────────────────────────────────────────────────────────────────────┘
*/
import type { Category, Content, Post, Product } from './types';
import { posts } from './fixtures/posts';
import { products } from './fixtures/products';
import { categories } from './fixtures/categories';
function isPublished<T extends { status: Content['status'] }>(record: T): boolean {
return record.status === 'published';
}
/** A single published post by slug, or null. Drafts/archived resolve to null. */
export async function getPost(slug: string): Promise<Post | null> {
return posts.find((post) => post.slug === slug && isPublished(post)) ?? null;
}
/** A single published product by handle, or null. */
export async function getProduct(handle: string): Promise<Product | null> {
return products.find((product) => product.handle === handle && isPublished(product)) ?? null;
}
/** A single published category by slug, or null. */
export async function getCategory(slug: string): Promise<Category | null> {
return categories.find((category) => category.slug === slug && isPublished(category)) ?? null;
}
export async function getPublishedPosts(): Promise<Post[]> {
return posts.filter(isPublished);
}
export async function getPublishedProducts(): Promise<Product[]> {
return products.filter(isPublished);
}
export async function getPublishedCategories(): Promise<Category[]> {
return categories.filter(isPublished);
}
/**
* Every published record across content types. This is the route source of
* truth that `app/sitemap.ts` builds from.
*/
export async function getAllPublished(): Promise<Content[]> {
const [p, pr, c] = await Promise.all([
getPublishedPosts(),
getPublishedProducts(),
getPublishedCategories(),
]);
return [...p, ...pr, ...c];
}
export type { Category, Content, Post, Product } from './types';