@bygghammar/cms-platform

中文文档
0.102.0发布于 2026/11/01UNLICENSEDES Module

Shared CMS platform: blocks, block types, i18n core, UI primitives and design-token contract used by every Bygghammar/Voyara site.

原始使用文档
文档目录10 节
  1. What lives here
  2. Starting a new site
  3. Editing locks
  4. Feature guides
  5. Server variables
  6. Compatibility policy
  7. What must never live here
  8. Backup core
  9. Per-site wiring
  10. Repository, development and releases

@bygghammar/cms-platform

Shared CMS platform code for every site in this workspace (Voyara, barskola and future sites). Code only — no content, no data, no secrets, no theme.

What lives here

  • src/blocks/types.ts — block prop types and the JSON contract for block props
  • src/blocks/icons.ts — the icon set blocks may reference
  • src/blocks/block-props-context.tsx — block prop plumbing for inline editing
  • src/i18n/* — the localization core (locales, types, resolver, context)
  • src/backup/* — archive/media safety, browser-side large-media export and provider-neutral verification helpers
  • src/trips/* — reusable trips data contract, editor and legacy course-data compatibility. Each host supplies its own terminology (Courses, Cruises or Trips).
  • src/navigation/* — public and backoffice navigation contracts plus shared active-state helpers. Menu content and visual headers remain per-site.
  • src/theme.css — the design-token contract + neutral starter theme

Starting a new site

docs/NEW-SITE.md is the supported starter path: install, assert the contract, apply the canonical schema with bunx cms-platform-migrations, import theme.css, register host components / platform data / translations, wrap the server cores and mount the shared backoffice views.

Editing locks

docs/EDIT-LOCKS.md is what a host wires so two administrators cannot overwrite each other: run the migration, expose one server endpoint through editLockActionCore, mount EditLockProvider with createEditLockApi, and forward editSessionId to the saves. Until that is done every screen behaves exactly as it did before locks existed.

Feature guides

GuideWhat it covers
docs/PAGES.mdDraft/published pages, the publish and unpublish confirmations, duplication
docs/SCHEDULING.mdVisibilitySchedule, site-timezone editing, scheduled menu and footer items
docs/LAYOUT-BLOCKS.mdThe columns block, the nested block tree and its move rules, the Icon Cards mobile carousel
docs/IMAGE-CARDS.mdThe Image Card Gallery block: its props, defaults, overlay and colour rules, links, the phone slider and the editor
docs/MEDIA-FOLDERS.mdAutomatic month folders, custom upload folders and their sanitising, library browsing
docs/GOOGLE-SHEETS.mdService-account form delivery, the connection test, and the server variables it needs
docs/TYPOGRAPHY.mdIndependent Google Fonts for the menu and the footer
docs/PUBLICATION-REVIEW.mdThe cms-review procedure for upgrading a live site to contract v3

Server variables

Beyond the existing provider secrets, Google Sheets delivery reads either GOOGLE_SERVICE_ACCOUNT_JSON, or GOOGLE_SERVICE_ACCOUNT_EMAIL plus GOOGLE_SERVICE_ACCOUNT_PRIVATE_KEY. All three are server-only; nothing Google related is ever read in the browser, and the font picker needs no API key. See docs/GOOGLE-SHEETS.md.

Compatibility policy

  • CHANGELOG.md records every release; read it before upgrading.

  • Pre-1.0, a minor release may break shared views, adapters or cores; patch releases are always compatible.

  • PLATFORM_CONTRACT_VERSION (platform/contract) is bumped when a shared screen starts requiring schema or adapter capabilities an older site lacks. Sites pin it in a test. It is v3: page saves, publishing, trashing and restoring go through database functions (v2), and a release records the five facts it used to assert with one sentence — migration applied, schema capability, publication scan, decisions applied, routes activated — as five separate records the later of which refuse to be written without the earlier (v3). Upgrading straight from the last pre-v2 published package, 0.90.0-m7.12, means applying all five new canonical migrations, in chronological order:

    1. 20260904090000_c54603f8-a155-40f8-a86c-54434aa5c0ae.sql
    2. 20260904140000_9f2a7c41-06d5-4d6b-8b4e-1c7a5d3e9b20.sql
    3. 20260904160000_0d565000-2839-4738-aacc-537d7090398f.sql
    4. 20260905120000_da2db0b2-6048-4aa8-8e4f-13ee33e9cc24.sql
    5. 20261030120000_46a4febc-227e-42ec-bbe3-a0ae9c97feaa.sql

    Files 2 and 3 are the pair that establishes contract-v2 publication behaviour, but the first is canonical schema too, so applying only the pair still leaves missingMigrations and compareSchema reporting drift. File 4 adds contract v3: the release ledger, the review model, the route claims, one lock order every page mutation follows, and duplication as a single transaction. It replaces five publication function bodies at the signatures they already have, without changing what any of them decides, so nothing a visitor sees today changes. File 5 belongs to no contract version: it gives block_templates its own timestamp trigger in place of the pages trigger it was created with, which assigned an updated_by column that table does not have and so failed every update of a template. Apply them before the v3 package is deployed, then verify separately: missingMigrations(applied) reports nothing missing, and assertPlatformContract(3) passes. The second only compares version numbers in the site's own code and never reads the database, so it is no substitute for the first. docs/NEW-SITE.md gives the full order.

  • migrations/ is schema only. Site content, SEO copy and seeds never belong there.

What must never live here

  • colours, fonts or spacing values used by a specific site (see theme.css)
  • page content, SEO copy, media, CMS page JSON
  • Supabase generated types, auth users, secrets, API keys
  • route files and per-site deployment config
  • actual navigation links, public slugs, brand-specific headers or menu styling
  • site table lists, import order, database clients, authentication and RLS policies; each host supplies those adapters to the shared backup core

Backup core

The package owns the CMS-wide, provider-neutral parts of backup and restore:

  • media signature/path validation and secret sanitising
  • streaming large media files into an archive in the authenticated browser
  • archive progress and manifest contracts
  • row-count, user/role and media verification helpers

The browser media exporter accepts a host storage adapter with only list() and download() methods plus the host's expected archive format/schema versions. Keep the dynamic import behind an import.meta.env.SSR guard in SSR applications so the browser-only ZIP code cannot enter the optimized server chunk graph.

Individual media downloads are retried before an export is stopped. Public media-bucket adapters should also fall back to the object's public URL when an authenticated Storage download fails, so one transient large-file request cannot discard an otherwise valid archive.

The consuming site remains responsible for its dataset groups, table import order, Supabase clients, superadmin authorization, HTTP routes, audit records and database migrations. The package never contains site data or credentials.

Per-site wiring

Translation data is per-site content, so each site registers its own maps once at startup:

import { registerTranslations } from "@bygghammar/cms-platform/i18n";
registerTranslations({ generated: TRANSLATIONS, overrides: TRANSLATION_OVERRIDES });

Host components must participate in a value the application actually uses. Do not rely only on import "./register-host" because an optimized build may remove that module when the application's package.json declares "sideEffects": false.

import { initializeHostComponents, type HostComponents } from "@bygghammar/cms-platform/host";

const HOST_COMPONENTS = {
  FocalImage,
  LazyVideo,
  FocusPicker,
  RichTextEditor,
  mediaLibraryQueryOptions,
  useMediaUpload,
} satisfies Partial<HostComponents>;

export const BLOCK_REGISTRY = initializeHostComponents(HOST_COMPONENTS, () =>
  createBlockRegistry(),
);

Keep any existing registration module in the consuming application's sideEffects allowlist as defence in depth until every entry point uses the explicit contract. CSS must also remain in that allowlist.

Repository, development and releases

The canonical source of truth is https://github.com/byggis79/cms-platform (private). This repository is standalone — it is no longer a directory inside a site repository, and it must never be copied back into a consuming site.

bun install
bun run check   # typecheck + tests + package verification

The package ships TypeScript sources; there is no build output. Every change goes through a pull request, and every release is triggered by pushing a vX.Y.Z tag that matches package.json. That tag runs .github/workflows/publish.yml, which publishes to npm using Trusted Publishing: GitHub mints a short-lived OIDC token scoped to that single workflow run, and npm exchanges it for publish rights through the package's Trusted Publisher configuration. No long-lived npm credential takes part — no NPM_TOKEN, no NODE_AUTH_TOKEN, no OTP. RELEASING.md is what the workflow checks and the npm settings it has to match. Never publish manually.

See CONTRIBUTING.md for the full workflow and changelog conventions. Consumers install an explicit released version such as @bygghammar/[email protected].

版本与发布记录

@bygghammar/cms-platform 共发布 131 个版本,首次发布于 2026/08/13;过去 12 个月发布了 131 个版本。

版本发布日期距今
0.102.0latest2026/11/012 天前
0.101.02026/10/304 天前
0.100.02026/10/304 天前
0.99.02026/10/277 天前
0.98.32026/10/268 天前
0.98.22026/10/2311 天前

其他发布通道:m7 → 0.91.0-m7.1。

关于 @bygghammar/cms-platform 的常见问题

@bygghammar/cms-platform 是什么?

共享CMS平台:每个Bygghammar/Voyara站点使用的块,块类型,i18n核心,UI原语和设计令牌合约。

如何安装 @bygghammar/cms-platform?

在项目目录运行 npm install @bygghammar/cms-platform,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:zod(>=4.6.6 <5)、react(>=19)、sonner(>=2)、react-dom(>=19)、lucide-react(>=0.5.0)、@dnd-kit/core(>=6)、@dnd-kit/sortable(>=3)、@dnd-kit/utilities(>=3)、@tanstack/react-query(>=5)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。它还提供命令行工具 cms-review、create-cms-site、cms-platform-migrations,可以用 npx cms-review 直接运行。

@bygghammar/cms-platform 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/bygghammar__cms-platform 是否存在。

@bygghammar/cms-platform 支持 ESM 还是 CommonJS?

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

@bygghammar/cms-platform 可以商用吗?

@bygghammar/cms-platform 使用 UNLICENSED 许可。作者声明为 UNLICENSED,即不授予公开使用许可(与公共领域的 Unlicense 不同)。使用前需获得作者授权。以上为概括,不构成法律意见,请以许可原文为准。

@bygghammar/cms-platform 还在维护吗?

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