@crvouga/mockingbird-service-payload-cms

中文文档
3.11.0发布于 2026/11/11MITTypeScriptES Module构建来源已验证近 30 天下载 3093

Stateful emulator of the Payload CMS collection REST API: paginated finds with a where-query subset, find by id, a seeded marketing collection and admin-editable documents.

原始使用文档
文档目录7 节
  1. Install
  2. Usage
  3. Routes
  4. Admin (beyond the standard contract)
  5. Namespaces
  6. Deliberately not modelled
  7. API

@crvouga/mockingbird-service-payload-cms

Local emulators. Real API contracts. Part of Mockingbird.

Stateful emulator of Payload CMS's collection REST API for test suites: GET /api/<collection> with Payload's paginated envelope (docs, totalDocs, limit, totalPages, page, pagingCounter, hasPrevPage, hasNextPage, prevPage, nextPage) and a where query subset, and GET /api/<collection>/<id>. The marketing collection is seeded with an active referral card, so the backend's referral content comes from the "CMS" deterministically, and the admin plane lets a test change it.

  • Operation coverage: SUPPORT.md
  • The contract (openapi.yaml) is hand-authored from Payload's REST and query docs and the consumer's response type (payload-cms-response.type.ts).

Install

npm install -D @crvouga/mockingbird-service-payload-cms

ESM only. Node >= 22 or Bun >= 1.2. No native dependencies. Serve it with npx mockingbird-payload-cms serve, createServer from ./server (Node), or createRuntime with any Fetch server.

Usage

Point PAYLOAD_CMS_API_URL at the emulator. The backend validates it as https-only (validation.schema.ts), so either relax that for loopback or put the emulator behind TLS. Anything that goes wrong (non-2xx, empty docs, bad JSON, a dropped connection) makes the backend fall back to its default referral content, which the presets exercise.

npx mockingbird-payload-cms serve --port 8822
# or seed your own collections: --collections ./cms-seed.json   ({"marketing": [ … ]})

In a test, the application's Payload SDK (@payloadcms/sdk) takes the emulator as its fetch:

import { PayloadSDK } from "@payloadcms/sdk"
import { createRuntime } from "@crvouga/mockingbird-service-payload-cms"

// Test setup: an in-process CMS, with one more marketing document added through the admin plane.
const emulator = createRuntime()
await emulator.fetch(
  new Request("http://cms.test/__admin/collections/marketing/docs", {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({ name: "Fall", type: "referral", isActive: true, cardTitle: "Fall Rewards" }),
  }),
)

// Application code: Payload's SDK. Only its fetch changes, so requests reach the emulator in
// this process instead of the CMS.
const cms = new PayloadSDK({
  baseURL: "http://cms.test/api",
  fetch: ((url: string, init: RequestInit) =>
    emulator.fetch(new Request(url, init))) as typeof fetch,
})
const page = await cms.find({
  collection: "marketing",
  where: { type: { equals: "referral" }, isActive: { equals: true } },
  limit: 1,
})
// → {docs: [{id: 4, cardTitle: "Fall Rewards", …}], totalDocs: 2, limit: 1, …}

Routes

RouteBehaviour
GET /api/<collection>where[<field>][<op>]=<value> with equals, not_equals, in / not_in (comma lists), exists, greater_than(_equal), less_than(_equal), like (all words, case-insensitive), contains; nested where[and|or][<i>][…]; dotted field paths. Values are cast to the document field's type ("true" → true). sort=<field> / -<field> (default -createdAt), limit (default 10; 0 = no limit), page. An unknown field is 400 {errors: [{message: "The following path cannot be queried: <field>"}]}; an unknown collection 404. depth, locale, draft are accepted and ignored.
GET /api/<collection>/<id>The document, or 404 {errors: [{message: "The requested resource was not found."}]}.

Only marketing is declared in the contract (it is what our backend reads); any collection seeded through the admin plane is served the same way. Ids are integers (Payload's Postgres adapter), matching the consumer's id: number.

Seed (DEFAULT_MARKETING_DOCS): 1 an inactive referral card, 2 the active referral card, 3 an active banner.

Admin (beyond the standard contract)

RouteEffect
GET /__admin/collections{collections: {<slug>: <doc count>}}.
GET /__admin/collections/:slugThe collection's documents.
PUT /__admin/collections/:slug{docs: [...]} replaces the collection (creates it if new).
POST /__admin/collections/:slug/docsAdds a document (next integer id, timestamps from the emulator clock).
PATCH /__admin/collections/:slug/docs/:idMerges fields into a document.
DELETE /__admin/collections/:slug/docs/:idRemoves a document.

Fault presets (POST /__admin/faults {"preset": "<name>", "count"?: n}): server_error (500), forbidden (403), collection_not_found (404), no_active_docs (an empty page), malformed_json (200 HTML), unavailable (503 HTML), connection_drop, slow (10 s).

Namespaces

Our backend's fetch sends no credential, so use a /__admin/ns/<name> suffix on PAYLOAD_CMS_API_URL (e.g. http://127.0.0.1:8822/__admin/ns/worker-1) or x-mockingbird-namespace. A request carrying Authorization: <collection> API-Key <key> or a bearer token can also be mapped with PUT /__admin/credentials.

Deliberately not modelled

  • Writes through the REST API (create/update/delete), auth endpoints, access control, drafts, versions, locales, relationship population (depth), uploads and GraphQL.
  • where operators beyond the subset above (near, within, intersects, all).

API

ExportKindDescription
PayloadCmsAPIclassThe in-process emulator: fetch(request), reset(), addDoc(slug, fields), updateDoc(slug, id, patch), deleteDoc(slug, id), collections(). Options: sqlite, now, namespace, collections.
createRuntimefunctionThe emulator with the full service contract (health, admin, namespaces, presets). Options: collections, clock, seed, adminKey, onLog, sqlite.
PAYLOAD_CMS_PRESETSobjectEvery named fault preset.
PAYLOAD_CMS_NAMESPACEstringThe service name, "payload-cms".
DEFAULT_MARKETING_DOCSarrayThe marketing collection seed.
MARKETING_FIELDSarrayThe marketing collection's queryable fields.
compileWherefunctionCompile a Payload where object into a predicate (or the 400 message).
payloadCredentialfunctionThe API key or bearer token a request carries.
payloadErrorfunctionBuild a Payload error response {errors: [{message}]}.
document, operationIds, supportedOperationIdsvaluesThe OpenAPI contract and its operation ids.
createServer, serveTarget, DEFAULT_PORT (./server)NodeServe over node:http; the serve CLI target (--collections <file>); port 8822.

Part of mockingbird.

版本与发布记录

@crvouga/mockingbird-service-payload-cms 共发布 42 个版本,首次发布于 2026/09/23;过去 12 个月发布了 42 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
3.11.0latest2026/11/11今天
3.10.92026/11/038 天前
3.10.82026/11/038 天前
3.10.72026/11/038 天前
3.10.62026/11/038 天前
3.10.52026/11/038 天前

关于 @crvouga/mockingbird-service-payload-cms 的常见问题

@crvouga/mockingbird-service-payload-cms 是什么?

Stateful emulator of the Payload CMS collection REST API: paginated finds with a where-query subset, find by id, a seeded marketing collection and admin-editable documents.

如何安装 @crvouga/mockingbird-service-payload-cms?

在项目目录运行 npm install @crvouga/mockingbird-service-payload-cms,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 mockingbird-payload-cms,可以用 npx mockingbird-payload-cms 直接运行。

@crvouga/mockingbird-service-payload-cms 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@crvouga/mockingbird-service-payload-cms 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@crvouga/mockingbird-service-payload-cms 可以商用吗?

@crvouga/mockingbird-service-payload-cms 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@crvouga/mockingbird-service-payload-cms 的下载量有多少?

根据 npm 官方下载统计,@crvouga/mockingbird-service-payload-cms 在 2026/10/11 – 2026/11/09 这 30 天内被下载 3,093 次,日均约 103 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@crvouga/mockingbird-service-payload-cms 还在维护吗?

最新版本 3.11.0 发布于 2026/11/11(今天);至今共发布 42 个版本,其中过去 12 个月发布了 42 个;首次发布于 2026/09/23。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。