JavaScript SDK
Content Types API
任意内容类型的 CRUD 操作、过滤、排序、分页、文件上传和版本管理。
使用 client.collection() 访问任意内容类型的数据。支持自定义和内置内容类型。
访问内容类型
const portfolios = client.collection<Portfolio>("portfolios");
// 管理 API(绕过过滤器,显示私有字段)
const adminPortfolios = client.adminCollection<Portfolio>("portfolios");读取操作
分页列表
const result = await portfolios.getList(1, 20);
// result.items → Portfolio[]
// result.total → number(总数)
// result.page → 1
// result.page_size → 20带选项的列表
const result = await portfolios.getList(1, 20, {
filter: 'status = "published"',
sort: "-created_at",
expand: "category,tags",
search: "rust",
fields: "title,slug,cover",
});ListOptions
| 选项 | 类型 | 说明 |
|---|---|---|
filter | string | 规则引擎过滤表达式 |
sort | string | 排序字段。- 前缀为降序(如 "-created_at") |
expand | string | 逗号分隔的关联字段,填充为完整记录 |
search | string | 全文搜索词 |
fields | string | 逗号分隔的字段白名单 |
status | string | 按状态过滤(需 statusable 协议) |
requestKey | string | 自动取消相同 key 的上一个请求 |
headers | object | 自定义请求头 |
signal | AbortSignal | AbortController 信号 |
获取单条记录
const item = await portfolios.getOne("item_id");
// 带选项
const item = await portfolios.getOne("item_id", {
expand: "category,tags",
});按条件查询
const item = await portfolios.getFirstListItem('slug = "my-saas"');无匹配时抛出 SDKError(status 404)。
获取全部(自动翻页)
const all = await portfolios.getFullList({
filter: 'status = "published"',
sort: "-created_at",
});
// all → Portfolio[](自动获取所有页)写入操作
创建
const created = await portfolios.create({
title: "My SaaS App",
url: "https://mysaas.com",
tech_stack: ["Rust", "React"],
});更新
const updated = await portfolios.update(created.id, {
url: "https://mysaas.app",
status: "published",
});删除
await portfolios.delete(created.id);过滤语法
filter 选项使用与 REST API 相同的规则引擎:
// 简单比较
'status = "published"'
// 多条件
'status = "published" && price > 0'
// OR 逻辑
'status = "published" || featured = true'
// LIKE 匹配
'title ~ "%rust%"'
// 字段非空
'avatar:isset'
// 长度检查
'tags:length > 0'完整语法见 API 参考 - 规则引擎。
排序语法
// 单字段
{ sort: "-created_at" } // 降序
{ sort: "title" } // 升序
// 多字段
{ sort: "status,-created_at" }填充关联
使用 expand 将关联字段从 ID 填充为完整记录:
// 单个关联
const result = await portfolios.getList(1, 20, {
expand: "category",
});
// result.items[0].category → { id, name, ... } 而非 "cat_id"
// 多个关联
const result = await portfolios.getList(1, 20, {
expand: "category,tags,instructor",
});文件上传
为已有记录附加文件:
const fileInput = document.querySelector<HTMLInputElement>("#cover")!;
const file = fileInput.files![0];
const updated = await portfolios.upload(created.id, file, "cover");| 参数 | 说明 |
|---|---|
id | 记录 ID |
file | File 对象 |
fileField | 字段名(默认 "file") |
独立文件上传请使用 client.media.upload(file)。
版本管理
仅适用于启用了 versionable 协议的内容类型。
列出版本
const revisions = await portfolios.listRevisions("item_id", 1, 20);
// revisions.items → Revision[]获取版本
const revision = await portfolios.getRevision("item_id", "revision_id");恢复版本
const restored = await portfolios.restoreRevision("item_id", "revision_id");对比版本
const diff = await portfolios.diffRevisions("item_id", "rev_a_id", "rev_b_id");
// diff → { field: { old, new }, ... }TypeScript
定义类型
interface Portfolio {
id: string;
title: string;
url?: string;
cover?: string;
description?: string;
tech_stack?: string[];
status: string;
created_at: string;
updated_at: string;
}使用泛型
const portfolios = client.collection<Portfolio>("portfolios");
const item = await portfolios.getOne("abc123");
// ^? Portfolio
const result = await portfolios.getList(1, 20);
// result.items → Portfolio[]从 CLI 生成类型
raisfast ct types portfolio -o types/portfolio.ts从内容类型 TOML 定义自动生成 TypeScript 接口。
PaginatedData 类型
interface PaginatedData<T> {
items: T[];
total: number;
page: number;
page_size: number;
}RequestOptions
所有方法接受可选的 RequestOptions:
interface RequestOptions {
headers?: Record<string, string>;
query?: Record<string, string>;
signal?: AbortSignal;
requestKey?: string;
fetch?: typeof fetch;
}