@contentrain/types 1.16.0 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -2
- package/dist/index.d.mts +531 -7
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +188 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -55,6 +55,7 @@ Core interfaces:
|
|
|
55
55
|
|
|
56
56
|
- `FieldDef`
|
|
57
57
|
- `ModelDefinition`
|
|
58
|
+
- `ModelLocaleScope`
|
|
58
59
|
- `ModelSummary`
|
|
59
60
|
- `ContentrainConfig`
|
|
60
61
|
- `Vocabulary`
|
|
@@ -127,6 +128,9 @@ Validate functions (pure, dependency-free):
|
|
|
127
128
|
- `validateSlug(slug)` — kebab-case slug validation
|
|
128
129
|
- `validateEntryId(id)` — entry ID format validation
|
|
129
130
|
- `validateLocale(locale, config)` — locale format + config support check
|
|
131
|
+
- `resolveModelLocales(model, config)` — the locales a model's content is expected to cover: `model.locales` when it declares one, otherwise `config.locales.supported` (the default locale alone when `i18n: false`)
|
|
132
|
+
- `describeModelLocaleScope(scope)` — name a resolved scope the way a validation message should quote it
|
|
133
|
+
- `validateModelLocales(model, config)` — check a `locales` declaration is a subset of `config.locales.supported`
|
|
130
134
|
- `detectSecrets(value)` — detect potential secrets in field values (provider-shaped patterns, plus an `api_key = …` assignment whose tail passes `looksLikeCredential`)
|
|
131
135
|
- `validateFieldValue(value, fieldDef)` — full field schema validation (type, required, min/max, pattern, select)
|
|
132
136
|
|
|
@@ -182,6 +186,9 @@ const model: ModelDefinition = {
|
|
|
182
186
|
kind: 'collection',
|
|
183
187
|
domain: 'blog',
|
|
184
188
|
i18n: true,
|
|
189
|
+
// Optional. Absent means every locale in config.locales.supported; a subset
|
|
190
|
+
// narrows validation for a partially-translated model.
|
|
191
|
+
locales: ['en', 'tr'],
|
|
185
192
|
fields,
|
|
186
193
|
}
|
|
187
194
|
|
|
@@ -250,6 +257,8 @@ Studio (Nuxt 4, web) cannot import `@contentrain/mcp` directly because MCP depen
|
|
|
250
257
|
| `validateSlug(slug)` | Form validation for document slugs |
|
|
251
258
|
| `validateEntryId(id)` | Validate collection entry IDs |
|
|
252
259
|
| `validateLocale(locale, config)` | Locale picker validation |
|
|
260
|
+
| `resolveModelLocales(model, config)` | Which locales to show, or require, for one model |
|
|
261
|
+
| `validateModelLocales(model, config)` | Validate a model's locale-coverage subset in a model editor |
|
|
253
262
|
| `detectSecrets(value)` | Content editor secret detection warnings |
|
|
254
263
|
| `validateFieldValue(value, fieldDef)` | Full field-level validation in content forms |
|
|
255
264
|
| `canonicalStringify(data, fieldOrder?)` | Preview canonical JSON output |
|
|
@@ -328,14 +337,24 @@ Shared shapes for the WordPress → static-site migration pipeline. They exist h
|
|
|
328
337
|
|
|
329
338
|
| Contract | Role |
|
|
330
339
|
|---|---|
|
|
331
|
-
| `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. |
|
|
340
|
+
| `RawIR` | Source-faithful extraction of a WordPress site (posts, terms, menus, comments, media, redirects, and from the bridge rung SEO and routing) with provenance: which access rung produced it (`rest_public` → `rest_auth` → `wxr` → `bridge`). Unresolved references are kept and marked, never dropped. |
|
|
332
341
|
| `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. `access.achieved` is the highest source-access rung actually reached, or `null` when none was: a site behind an access wall still gets a manifest, and a producer that writes a rung it did not reach makes the coverage figures unreadable. |
|
|
333
342
|
| `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. |
|
|
334
|
-
| `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. |
|
|
343
|
+
| `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. `content_summary.body_kinds` counts standalone pages by `PageBodyKind` — `html` (editor markup, still editable), `builder_html` (rendered by a page builder, carried as rendered), `none` (the theme renders it) — because each promises something different to the person receiving the site. |
|
|
335
344
|
| `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. |
|
|
336
345
|
|
|
337
346
|
All are plain JSON (snake_case keys), stamped with `MIGRATION_CONTRACT_VERSION`.
|
|
338
347
|
|
|
348
|
+
`RawIR` also carries five optional parts from the bridge rung:
|
|
349
|
+
|
|
350
|
+
- **`seo`** (`RawSeo`) holds which plugin serves the head (`serving`: `yoast` / `rank_math` / `aioseo` / `wordpress-core`), each provider's status and settings, and each page's values keyed by `post:<id>` or `term:<taxonomy>:<id>`. `status: 'none'` is an answer, not a missing export: no SEO plugin, and WordPress core renders only the title. `resolved: true` marks values the running plugin rendered; `false` marks stored values and templates only. `robots_served` is what the page actually carries after WordPress core and the plugin reconcile it.
|
|
351
|
+
- **`routing`** (`RawRouting`) states the URL rules that `RawPost.link` holds as facts: permalink structure, bases, the front and posts pages, and each post type's and taxonomy's permastruct, with `with_front` applied.
|
|
352
|
+
- **`redirects_excluded`** (`RawRedirectExcluded`) lists every rule a source holds that the site does not serve as a plain redirect, with the reason (`disabled`, `source-inactive`, `conditional-match:*`, `not-a-redirect:*`, …). Served plus excluded accounts for the whole table.
|
|
353
|
+
- **`hardcoded_text`** (`RawHardcodedText`) accounts for the interface text outside the content tables — theme templates, scripts, widgets, menus, options, Customizer mods and rendered pages. Each `RawTextCandidate` has one outcome: `transfer` to a `target` (`dictionary:ui-strings`, `theme-settings.<mod>`, `site.title`, `site.description`, `content:wp-menu-items`) or `exclude` with a `reason` (`TEXT_EXCLUDE_REASONS`); a source that could not be read is listed in `errors`. Candidates merge only when text, locale and context are equal, and `key` depends on text and context only. Page text that also appears in source is `rendered-from-source` with `related` pointing at the source candidate, so the same words never land twice. `totals` closes: transfer + exclude = candidates, and error = `errors.length`.
|
|
354
|
+
- **`integrations`** (`RawIntegration[]`) lists the outside services the site is connected to (`INTEGRATION_CATEGORIES`: analytics, crm, newsletter, ads, comments, captcha, cdn, other), each with its evidence. Evidence names a plugin, a setting, a script host, a form's wiring or an embed host, never a value. `reconnect_required` is `false` only for an embed, which has no account. `secret_present` says a credential is set on WordPress; the credential itself is never exported. `IntegrationReconnectRequiredIssue` (`code: 'integration_reconnect_required'`) is the one intake/handoff issue that lists every service to connect again.
|
|
355
|
+
|
|
356
|
+
`RawRedirect` gains `id`, `match` and `regex`. Only `match: 'url'` without `regex` is a one-to-one mapping. A consumer that writes a regex or prefix rule as a literal `from` produces the wrong redirect.
|
|
357
|
+
|
|
339
358
|
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).
|
|
340
359
|
|
|
341
360
|
`ModelDefinition` can carry runtime-owned `form` and `comments` configuration.
|
|
@@ -365,6 +384,7 @@ approval guarding it would be theatre.
|
|
|
365
384
|
| `DeploymentTarget` | Where a build is published. Carries a `secret_ref`, never a secret — this document is written to git. |
|
|
366
385
|
| `AutomationDefinition` | Reserved shape for `.contentrain/automations.json`. Nothing reads it yet; it exists so the first writer does not invent a fourth vocabulary for schedules. |
|
|
367
386
|
| `SourceDeltaPlan` | The WordPress→repo delta — *not* `contentrain_reconcile`, which merges two git branches and knows nothing about WordPress. Carries explicit deletion tombstones, because `modified_after` is a filter on changed records and never reports a deletion, plus slug moves (which generate redirects) and semantic conflicts. `deletions_detectable: false` must not be read as "nothing was deleted". |
|
|
387
|
+
| `SourceInventory` / `SourceInventoryRecord` | Every origin record in scope at one moment — what a `bridge_inventory` cursor's hash identifies. Deletions and moves are proven by comparing two inventories (records keyed by `wp_type` + `wp_id`, updates decided on `fingerprint`); `modified_after` only narrows what to fetch again. `SourceDeltaEntry` also carries `path_before`/`path_after` for moves a slug cannot express, and `deleted_kind` (`trashed` / `purged`). |
|
|
368
388
|
|
|
369
389
|
### The evaluator
|
|
370
390
|
|