@optiqlabs/onecms-utils
v0.5.1
Published
**Framework-agnostic helpers** for OneCMS: **slugs**, **TipTap / ProseMirror JSON**, **Markdown ↔ TipTap**, and **reading time**. The API and Studio use these same functions so behavior stays consistent wherever content is transformed.
Readme
@optiqlabs/onecms-utils
Framework-agnostic helpers for OneCMS: slugs, TipTap / ProseMirror JSON, Markdown ↔ TipTap, and reading time. The API and Studio use these same functions so behavior stays consistent wherever content is transformed.
What it does
| Concern | Functions / exports |
| ----------------------- | ----------------------------------------------------------------------------------------- |
| IDs & slugs | isMongoObjectIdString, slugifyTitle |
| TipTap as text/time | plainTextFromTipTap, readingTimeFromTipTap, readingTimeMinutesFromPlainText |
| TipTap as Markdown/HTML | tipTapToMarkdown, tipTapToHtml |
| Markdown → TipTap | markdownToTipTap, blockTokenToNodes, inlineTokensToNodes, paragraphTokensToBlocks |
| Types | TipTapNode (from ./tiptap-format barrel) |
Dependencies: slugify for URL-safe slugs, marked for Markdown parsing on the Markdown → TipTap path.
Install
npm install @optiqlabs/onecms-utilsHow it works
- Slugify —
slugifyTitle(title)lowercases, strips unsafe characters, truncates (default max length 96), and falls back to"post"if empty. - Plain text from editor JSON — walks TipTap/ProseMirror-like
contenttrees, concatenatestextnodes, normalizes whitespace. Used for excerpts, search text, and reading time. - Reading time — assumes ~200 words per minute from plain text;
readingTimeFromTipTappipes TipTap JSON through the same plain-text path. - TipTap → Markdown / HTML — serializes structured JSON to strings suitable for public APIs (
contentFormat=markdown/html) or storage. - Markdown → TipTap — parses Markdown (via
marked) into TipTap-compatible node arrays for importing drafts or AI output.
All exports are synchronous except where they delegate to parsing; there is no network I/O.
Examples
import {
slugifyTitle,
plainTextFromTipTap,
readingTimeFromTipTap,
tipTapToMarkdown,
markdownToTipTap,
} from "@optiqlabs/onecms-utils";
const slug = slugifyTitle("Hello World: Part 2"); // "hello-world-part-2"
const doc = {
type: "doc",
content: [
/* ... */
],
};
const excerpt = plainTextFromTipTap(doc).slice(0, 160);
const minutes = readingTimeFromTipTap(doc);
const md = tipTapToMarkdown(doc);
const roundTrip = markdownToTipTap(md);When to use this vs @optiqlabs/onecms-types
@optiqlabs/onecms-types— Zod schemas for API payloads and domain types.@optiqlabs/onecms-utils— string/content transformations and editor helpers.
License
See the OneCMS monorepo license for this package’s terms when published from source.
