
Company News
Jerod Santo Joins Socket as Head of Media
Allow myself to introduce... myself.
@contentrain/types
Advanced tools
@contentrain/typesShared TypeScript types for the Contentrain ecosystem.
Start here:
This package is the common schema layer used by:
@contentrain/mcpcontentrain@contentrain/query@contentrain/rulesIt defines the stable type vocabulary for models, config, metadata, validation, scanning, context files, and provider contracts (enabling third-party RepoProvider implementations).
Use @contentrain/types when you are:
RepoProvider for a new git backendpnpm add @contentrain/types
Core unions:
FieldTypeModelKindContentStatusContentSourceWorkflowModeStackTypePlatformContextSourceCollectionRuntimeFormatLocaleStrategyCore interfaces:
FieldDefModelDefinitionModelSummaryContentrainConfigVocabularyEntryMetaAssetEntryValidationErrorValidationResultScaffoldTemplateScanCandidateDuplicateGroupGraphNodeProjectGraphScanCandidatesResultScanSummaryResultContextJsonStorage/runtime helper types:
SingletonContentFileCollectionContentFileDictionaryContentFileCollectionEntryCollectionContentOutputDocumentEntryDocumentContentOutputSingletonMetaCollectionMetaDocumentMetaDictionaryMetaNormalize/plan types:
NormalizePlanNormalizePlanModelNormalizePlanExtractionNormalizePlanPatchProvider contracts (re-exported from provider.ts — implement these to add a new git backend):
RepoProviderRepoReaderRepoWriterProviderCapabilitiesFileChangeCommitAuthorCommitApplyPlanInputBranchFileDiffMergeResult (includes optional sync?: SyncResult for local-worktree providers)LOCAL_CAPABILITIES (const — capability set for LocalProvider)Git transaction types:
SyncResultContentrainErrorValidate functions (pure, dependency-free):
validateSlug(slug) — kebab-case slug validationvalidateEntryId(id) — entry ID format validationvalidateLocale(locale, config) — locale format + config support checkdetectSecrets(value) — detect potential secrets in field values (provider-shaped patterns, plus an api_key = … assignment whose tail passes looksLikeCredential)validateFieldValue(value, fieldDef) — full field schema validation (type, required, min/max, pattern, select)Serialize functions (pure, dependency-free):
sortKeys(obj, fieldOrder?) — recursive key sorting for canonical outputcanonicalStringify(data, fieldOrder?) — deterministic JSON serializationgenerateEntryId() — 12-char hex ID generationparseMarkdownFrontmatter(content) — parse YAML frontmatter + body from markdownserializeMarkdownFrontmatter(data, body) — serialize data + body into markdown frontmatterConstants:
CONTENTRAIN_DIR — default .contentrain folder nameCONTENTRAIN_BRANCH — default contentrain branch name for content trackingPATH_PATTERNS — file path conventions for models, content, metaSLUG_PATTERN — regex for valid slugsENTRY_ID_PATTERN — regex for valid entry IDsLOCALE_PATTERN — regex for valid locale codesCANONICAL_JSON — serialization rules (indent, encoding, trailing newline, key sort)SECRET_PATTERNS — provider-shaped regex patterns for secret detection (the generic api_key rule lives in detectSecrets, gated by looksLikeCredential)This package is intended to be the shared public contract across the Contentrain ecosystem.
In practice that means:
RepoProvider contract enables third-party implementations without depending on @contentrain/mcp internalsimport type {
ContentrainConfig,
FieldDef,
ModelDefinition,
ValidationResult,
} from '@contentrain/types'
const fields: Record<string, FieldDef> = {
title: { type: 'string', required: true },
slug: { type: 'slug', required: true, unique: true },
}
const model: ModelDefinition = {
id: 'blog-post',
name: 'Blog Post',
kind: 'collection',
domain: 'blog',
i18n: true,
fields,
}
const config: ContentrainConfig = {
version: 1,
stack: 'next',
workflow: 'review',
locales: { default: 'en', supported: ['en', 'tr'] },
domains: ['blog'],
}
const result: ValidationResult = {
valid: true,
errors: [],
}
Type-only usage:
import type { ModelDefinition, ContentrainConfig } from '@contentrain/types'
Mixed usage (types + runtime functions):
import type { FieldDef, ValidationError } from '@contentrain/types'
import {
validateFieldValue,
validateSlug,
detectSecrets,
canonicalStringify,
parseMarkdownFrontmatter,
} from '@contentrain/types'
Provider contract usage (for custom RepoProvider implementations):
import type { RepoProvider, ProviderCapabilities } from '@contentrain/types'
export class MyCustomProvider implements RepoProvider {
readonly capabilities: ProviderCapabilities = {
localWorktree: false,
sourceRead: true,
sourceWrite: true,
pushRemote: true,
branchProtection: true,
pullRequestFallback: true,
astScan: false,
}
// ...implement RepoProvider methods
}
Studio (Nuxt 4, web) cannot import @contentrain/mcp directly because MCP depends on Node.js-only packages (simple-git, @modelcontextprotocol/sdk). The validate and serialize functions in this package are pure, dependency-free, and browser-compatible — designed for Studio to share the same validation contract as MCP.
@contentrain/types| Function | Use case |
|---|---|
validateSlug(slug) | Form validation for document slugs |
validateEntryId(id) | Validate collection entry IDs |
validateLocale(locale, config) | Locale picker validation |
detectSecrets(value) | Content editor secret detection warnings |
validateFieldValue(value, fieldDef) | Full field-level validation in content forms |
canonicalStringify(data, fieldOrder?) | Preview canonical JSON output |
parseMarkdownFrontmatter(content) | Document editor frontmatter parsing |
serializeMarkdownFrontmatter(data, body) | Document editor serialization |
generateEntryId() | Client-side entry ID generation |
SECRET_PATTERNS | Extend or customize secret detection |
looksLikeCredential(tail) | Decide whether a value assigned to an API-key setting is a credential or documentation |
These require file system I/O or Node.js dependencies:
checkRelation() — validates relation references against actual content files on diskvalidateProject() — full project validation with file readingwriteContent() / deleteContent() — content persistence with git worktreeresolveContentDir() / resolveJsonFilePath() — path resolution with node:pathvalidateFieldValue handles schema-level checks. Two things require external state:
These are left to Studio's server-side or API layer to implement on top of the pure validation.
@contentrain/types exists so every package in the monorepo speaks the same domain language.
Examples:
ModelDefinitionContextJsonModelDefinition and FieldDefRepoProvider to plug into MCPThis package should stay:
From the monorepo root:
pnpm --filter @contentrain/types build
pnpm --filter @contentrain/types test
pnpm --filter @contentrain/types typecheck
@contentrain/mcpcontentrain@contentrain/query@contentrain/rulesMIT
Shared shapes for the WordPress → static-site migration pipeline. They exist here — in the one MIT package every side may depend on — because the documents cross repository and license boundaries: a GPL WordPress plugin produces them, a proprietary migration service consumes them, an open emitter renders from them.
| Contract | Role |
|---|---|
RawIR | Source-faithful extraction of a WordPress site (posts, terms, menus, comments, media, redirects) with provenance: which access rung produced it (rest_public → rest_auth → wxr → bridge). Unresolved references are kept and marked, never dropped. |
CapabilityManifest | Evidence-based inventory of what the site uses (SEO, forms, comments, i18n, ACF, …) — the input for migration planning and the "what happens to X" conversation. |
ProjectIR | The reproducible model of the site: route model, layout families, component variants, query bindings, design tokens. Not "this page's HTML" — the design system that generates unseen pages correctly. |
MigrationHandoff | What the migration hands the user: repository, per-capability dispositions, and offers for runtime capabilities (with cost comparison) — offering is this document's job; fulfilling is the receiving product's. runtime (RuntimeBinding) records where the generated site's runtime components were bound once an offer was fulfilled. |
RuntimeBinding | The provider's public API origin (base_url) and project_id — all a static site needs to mount comments and forms. Never a credential: the public endpoints are unauthenticated by design. |
All are plain JSON (snake_case keys), stamped with MIGRATION_CONTRACT_VERSION.
Chrome markers the emitter honours: CHROME_BODY_SLOT (where page content goes), CHROME_REPEAT_OPEN/CHROME_IF_OPEN (per-item and conditional regions), LIST_ITEMS_SLOT (where a list section's items go) and componentSlot(id) (<!--@@component:ID@@-->, where a ComponentDef — a comments thread, a form — is mounted).
ModelDefinition can carry runtime-owned form and comments configuration.
MODEL_EXTENSION_KEYS identifies these preserved blocks; canonical model
serialization places them after fields. The content engine does not interpret
the runtime settings.
FAQs
Shared TypeScript types for Contentrain ecosystem
The npm package @contentrain/types receives a total of 1,206 weekly downloads. As such, @contentrain/types popularity was classified as popular.
We found that @contentrain/types demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Company News
Allow myself to introduce... myself.

Research
/Security News
A Twitch browser extension on Chrome and Firefox forwards users’ live OAuth session tokens through proxies controlled by a Russian bot service.

Security News
Anthropic found biased reasoning and recklessness drove Claude Mythos 5 to publish malware on PyPI and compromise a security vendor.