Files
myeasycms-v2/packages/cms/keystatic/src/client.ts
giancarlo 2c7478abff Update language setting and versions in several packages
This commit includes an update of the language setting in the DocsPage and BlogPage functions in the marketing app to make it more dynamic. Additionally, the package versions of next, @makerkit/data-loader-supabase-nextjs, and various Next packages in the Supabase package have been updated.
2024-04-11 13:55:37 +08:00

150 lines
3.6 KiB
TypeScript

import { Entry, createReader } from '@keystatic/core/reader';
import { Cms, CmsClient } from '@kit/cms';
import config from './keystatic.config';
const reader = createReader('.', config);
type EntryProps = Entry<(typeof config)['collections']['posts']>;
export class KeystaticClient implements CmsClient {
async getContentItems(options: Cms.GetContentItemsOptions) {
const collection =
options.collection as keyof (typeof config)['collections'];
if (!reader.collections[collection]) {
throw new Error(`Collection ${collection} not found`);
}
const docs = await reader.collections[collection].all();
const startOffset = options?.offset ?? 0;
const endOffset = startOffset + (options?.limit ?? 10);
const filtered = docs.filter((item) => {
const categoryMatch = options?.categories?.length
? options.categories.find((category) =>
item.entry.categories.includes(category),
)
: true;
if (!categoryMatch) {
return false;
}
if (options.language) {
if (item.entry.language && item.entry.language !== options.language) {
return false;
}
}
const tagMatch = options?.tags?.length
? options.tags.find((tag) => item.entry.tags.includes(tag))
: true;
if (!tagMatch) {
return false;
}
return true;
});
const items = await Promise.all(
filtered.slice(startOffset, endOffset).map(async (item) => {
const children = docs.filter((item) => item.entry.parent === item.slug);
return this.mapPost(item, children);
}),
);
return {
total: filtered.length,
items,
};
}
async getContentItemBySlug(params: { slug: string; collection: string }) {
const collection =
params.collection as keyof (typeof config)['collections'];
if (!reader.collections[collection]) {
throw new Error(`Collection ${collection} not found`);
}
const doc = await reader.collections[collection].read(params.slug);
if (!doc) {
return Promise.resolve(undefined);
}
const allPosts = await reader.collections[collection].all();
const children = allPosts.filter(
(item) => item.entry.parent === params.slug,
);
return this.mapPost({ entry: doc, slug: params.slug }, children);
}
async getCategories() {
return Promise.resolve([]);
}
async getTags() {
return Promise.resolve([]);
}
async getTagBySlug() {
return Promise.resolve(undefined);
}
async getCategoryBySlug() {
return Promise.resolve(undefined);
}
private async mapPost<
Type extends {
entry: EntryProps;
slug: string;
},
>(item: Type, children: Type[] = []): Promise<Cms.ContentItem> {
const publishedAt = item.entry.publishedAt
? new Date(item.entry.publishedAt)
: new Date();
const content = await item.entry.content();
return {
id: item.slug,
title: item.entry.title,
url: item.slug,
slug: item.slug,
description: item.entry.description,
publishedAt,
content,
image: item.entry.image ?? undefined,
categories:
item.entry.categories.map((item) => {
return {
id: item,
name: item,
slug: item,
};
}) ?? [],
tags: item.entry.tags.map((item) => {
return {
id: item,
name: item,
slug: item,
};
}),
parentId: item.entry.parent ?? undefined,
order: item.entry.order ?? 1,
children: await Promise.all(
children.map(async (child) => this.mapPost(child, [])),
),
};
}
}