From 1e936a4384900cc8c6cc889b72948d139462cf58 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 6 Jul 2026 01:38:20 +0000 Subject: [PATCH] Version Packages --- .changeset/atomic-design-components.md | 35 ---- .changeset/canonical-urn-identity.md | 28 --- .changeset/chrome-blocks.md | 28 --- .changeset/component-canonical.md | 13 -- .changeset/component-picker-ux.md | 20 -- .changeset/cookie-consent-plugin.md | 42 ---- .changeset/custom-block-kinds.md | 20 -- .changeset/press-editable-navigation.md | 20 -- .changeset/privacy-policy-page-seed.md | 17 -- .changeset/quiet-schema-poll-log.md | 12 -- .changeset/section-blocks.md | 17 -- apps/playground/CHANGELOG.md | 8 + apps/playground/package.json | 2 +- apps/playground/packages/cms/CHANGELOG.md | 8 + apps/playground/packages/cms/package.json | 2 +- packages/cli/CHANGELOG.md | 35 ++++ packages/cli/package.json | 16 +- packages/cli/src/create/versions.generated.ts | 6 +- packages/cms/CHANGELOG.md | 186 ++++++++++++++++++ packages/cms/package.json | 6 +- packages/shared/CHANGELOG.md | 28 +++ packages/shared/package.json | 11 +- packages/web/CHANGELOG.md | 161 +++++++++++++++ packages/web/package.json | 2 +- 24 files changed, 456 insertions(+), 267 deletions(-) delete mode 100644 .changeset/atomic-design-components.md delete mode 100644 .changeset/canonical-urn-identity.md delete mode 100644 .changeset/chrome-blocks.md delete mode 100644 .changeset/component-canonical.md delete mode 100644 .changeset/component-picker-ux.md delete mode 100644 .changeset/cookie-consent-plugin.md delete mode 100644 .changeset/custom-block-kinds.md delete mode 100644 .changeset/press-editable-navigation.md delete mode 100644 .changeset/privacy-policy-page-seed.md delete mode 100644 .changeset/quiet-schema-poll-log.md delete mode 100644 .changeset/section-blocks.md create mode 100644 apps/playground/CHANGELOG.md create mode 100644 apps/playground/packages/cms/CHANGELOG.md create mode 100644 packages/cli/CHANGELOG.md create mode 100644 packages/cms/CHANGELOG.md create mode 100644 packages/shared/CHANGELOG.md diff --git a/.changeset/atomic-design-components.md b/.changeset/atomic-design-components.md deleted file mode 100644 index c76f2e7..0000000 --- a/.changeset/atomic-design-components.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -'@ogs-tech/press-cms': major -'@ogs-tech/press-web': major -'@ogs-tech/create-press': patch ---- - -feat!: Atomic Design component palette — unified `{owner}-{layer}.{name}` scheme - -BREAKING (wire + API): the ad-hoc `press.*` / `section.*` / `chrome.*` prefixes -are replaced by ONE Atomic Design scheme where the Strapi category encodes -`{owner}-{layer}` (owner ∈ preset|custom, layer ∈ atom|molecule|organism|config| -layout|template) and stored `__component` values change accordingly: - -- `press.{paragraph,heading,list,quote,image,button,separator,spacer}` → - `preset-atom.*`; `press.nav-item` → `preset-molecule.nav-item`; - `press.{seo,theme-colors,theme-radius,cookie-consent,cookie-category}` → - `preset-config.*`. -- `section.{hero,cta}` and `chrome.{navbar,footer}` unify under - `preset-organism.*` (one layer; placement — body vs header/footer — is declared - per content-type `schema.json`, not by the category). `hero`/`cta` are now - **body-only**. -- Adopter blocks move from placement folders (`custom` / `custom-section` / - `custom-chrome`) to atomic-LAYER folders (`custom-/`, e.g. - `custom-organism/`); `admitCustomBlocks` now admits every `custom-*` block into - ALL engine Dynamic Zones (universal placement — the editor decides where), - dropping the per-category placement map. Legacy bare `custom.*` is still - admitted for a forgiving migration. - -**press-web**: exported registries renamed (`referenceBlocks` → `atomBlocks`; -`sectionBlocks` + `chromeBlocks` → `organismBlocks`) and the base block types -renamed (`PressParagraph` → `PresetAtomParagraph`, `SectionHero` → -`PresetOrganismHero`, `ChromeNavbar` → `PresetOrganismNavbar`, …). The generator, -`PressSchema` contract, `urn`/`blockKey` primitives, and the `plugin::press-cms.*` -plugin id are unchanged (the product name "press" is not a component category). -The scaffolder ships the migrated `custom-organism.callout` example. diff --git a/.changeset/canonical-urn-identity.md b/.changeset/canonical-urn-identity.md deleted file mode 100644 index dc6e313..0000000 --- a/.changeset/canonical-urn-identity.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -'@ogs-tech/press-web': major ---- - -feat(web)!: canonical urn identity — `urn:{entity}:{id}` on Page and Site Settings - -New web-only identity primitives in `packages/web/src/urn.ts`, exported from the -package root: the closed `Entity` union (`'page' | 'site-setting'`), the -template-literal `Urn` (`urn:{entity}:{id}`), the `Canonical` interface -(`{ urn: Urn }`), and the pure `buildUrn(entity, id)` factory. The wire -contract, press-cms, and press-shared are untouched — a urn is never sent or -stored by the CMS. - -`Page` now extends `Canonical<'page'>`: the new pure `mapPage` mapper (mirroring -the `mapSiteSettings` pure-mapper + thin-fetcher split) attaches -`urn:page:{documentId}` right after the fetch. `ResolvedPressConfig` extends -`Canonical<'site-setting'>`: `mapSiteSettings` attaches the synthetic constant -`urn:site-setting:default` (single type — one record, identity never -CMS-sourced, present even when the CMS is unreachable). `blockKey` now formats -its React key through the same primitive (`press.image:5` → -`urn:press.image:5`) — a computed identity, never stored on the block; blockKey -was never exported, so no public surface changes shape there. - -BREAKING (press-web): `Page` and `ResolvedPressConfig` gain a REQUIRED `urn` -field. Runtime is additive — every object produced by `getPage`/`getSiteConfig` -carries it automatically — but adopter code that hand-constructs a literal of -either type (e.g. a test fixture or a mock) fails `tsc` until it adds `urn` -(`'urn:page:'` / `'urn:site-setting:default'`). diff --git a/.changeset/chrome-blocks.md b/.changeset/chrome-blocks.md deleted file mode 100644 index 64d3a41..0000000 --- a/.changeset/chrome-blocks.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -'@ogs-tech/press-cms': major -'@ogs-tech/press-web': major -'@ogs-tech/press-shared': minor ---- - -feat!: block-composable site chrome (chrome.*) - -The site header and footer become block-composed: the `site-setting` single type -gains two Dynamic Zones (`header`, `footer`) admitting a new engine-owned -`chrome.*` category (`chrome.navbar`, `chrome.footer`) plus `press.*`, -`section.*`, and adopter `custom.*` blocks. The serializer walks all three engine -DZs and follows nested component references; the generator types nested -components (without `__component`), skips relations, and emits -`HeaderBlocks`/`FooterBlocks` unions. `mapSiteSettings` hydrates the zones (brand -injection + nav resolution); `BlockRenderer` merges a new `chromeBlocks` registry -(adopter-overridable); the host layout renders both zones through the block -pipeline. `bootstrap()` seeds a default composition (navbar + footer) exactly -once. `press-shared`: `Attr` gains typed `component`/`repeatable` keys (additive). - -BREAKING (press-cms): `site-setting.headerNav` is removed. Strapi drops its data -on schema sync — there is no automated migration. After upgrading, re-enter the -nav links once inside the seeded Navbar block (Site Settings → Header). - -BREAKING (press-web): `SiteNav` is no longer exported (the navbar renders links -internally) and `ResolvedPressConfig.nav` is replaced by -`ResolvedPressConfig.chrome` (`{ header, footer }` hydrated block arrays). -Override the chrome like any block: `components={{ 'chrome.navbar': MyNavbar }}`. diff --git a/.changeset/component-canonical.md b/.changeset/component-canonical.md deleted file mode 100644 index 062172c..0000000 --- a/.changeset/component-canonical.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -'@ogs-tech/press-web': minor ---- - -feat(web): `component` canonical — `urn:component:{uid}` type-level identity - -`Entity` gains a 4th member `'component'` (additive), plus a `componentUrn(uid)` -factory (exported from the package root) formatting `urn:component:{uid}` for the -palette registries (`press.*`/`section.*`/`chrome.*`/`custom.*`). This is a -TYPE-level identity — distinct from the STORED identities (page/site-setting/ -plugin) and from `blockKey`'s COMPUTED per-instance key. No object implements -`Canonical<'component'>`; the first consumer is `BlockRenderer`'s -unknown-component dev warning, now citing the canonical `urn:component:…` form. diff --git a/.changeset/component-picker-ux.md b/.changeset/component-picker-ux.md deleted file mode 100644 index 4820ec6..0000000 --- a/.changeset/component-picker-ux.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -'@ogs-tech/press-cms': minor ---- - -feat(cms): component-picker UX — per-block icons + human category labels - -Every engine component JSON now sets `info.icon` (Strapi's fixed icon enum), so -the admin "Pick one component" dialog stops rendering the generic grid fallback -for all blocks: `press.paragraph` → `write`, `press.image` → `picture`, -`section.hero` → `landscape`, `chrome.navbar` → `layout`, and so on. - -The plugin also ships its first admin bundle (`./strapi-admin` export, built by -the same `strapi-plugin build`). Its single job is `registerTrads`: the picker -resolves each category accordion title through react-intl using the RAW -category string as the message id, so the bundle registers unprefixed keys — -`press` → "Blocks", `section` → "Sections", `chrome` → "Site chrome", -`custom` → "Custom blocks" (en + pt/pt-BR) — labelling the picker without -touching component uids (a uid is wire/DB contract; labels are presentation). -Adopters keep the final word: `src/admin/app.tsx` `config.translations` takes -precedence over these engine defaults. diff --git a/.changeset/cookie-consent-plugin.md b/.changeset/cookie-consent-plugin.md deleted file mode 100644 index cc4ac25..0000000 --- a/.changeset/cookie-consent-plugin.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -'@ogs-tech/press-web': major -'@ogs-tech/press-cms': minor ---- - -feat!: cookie-consent — the first engine plugin, introducing the `'plugin'` canonical - -**Engine plugins (press-web).** `Entity` gains `'plugin'` (additive) and the -new `PressPlugin` contract (`extends Canonical<'plugin'>`, `id`, `enabled`) -formalizes the plugin family: an optional engine capability configured through -Site Settings, resolved by a pure mapper into the new -`ResolvedPressConfig.plugins` named map, and mounted explicitly by the host -layout — no runtime registry. Plugin identity is synthetic -(`urn:plugin:cookie-consent`), never CMS-sourced. - -**Cookie consent (press-web).** New `CookieConsentBanner` (the engine's first -stateful client component), the `useConsent()` hook, and the consent store: -`hasConsent('analytics')` (fail-closed), `acceptAll`/`rejectAll`/`setConsent`/ -`resetConsent`, `parseConsentCookie` (server-side seam), and -`buildConsentBootstrapScript()` — a pre-paint inline script the host layout -injects so a decided visitor never sees the banner flash. The decision lives -in a versioned first-party cookie (`press_consent`, SameSite=Lax, 180d), never -read via `cookies()` in the RSC tree (static/ISR stays intact). The resolved -plugin FAILS OPEN: an unreachable CMS still yields an enabled banner with the -engine's default copy — a consent gate must not vanish on a CMS hiccup. -Consent categories are a closed code union (`necessary | analytics | -marketing`); editors toggle and re-word them, never rename keys. - -**Cookie consent (press-cms).** New `press.cookie-consent` + -`press.cookie-category` config components (injected, never DZ-admitted), a -`cookieConsent` attribute on Site Settings with deep populate (nested -categories + privacy page slug), and a run-once seed (`cookieConsentSeeded` -plugin-store flag) that writes only the `enabled` booleans — default copy -lives web-side; an editor-disabled banner is respected forever. - -BREAKING (press-web): `ResolvedPressConfig` gains a REQUIRED `plugins` field. -Runtime is additive — every object produced by `getSiteConfig` carries it — -but adopter code that hand-constructs a literal (test fixtures, mocks) fails -`tsc` until it adds `plugins: { cookieConsent: ... }` (or builds the value -through `mapSiteSettings`). The host template's `layout.tsx` also changed -(bootstrap script + banner mount) and is re-materialized on the next -`press dev`/`build`. diff --git a/.changeset/custom-block-kinds.md b/.changeset/custom-block-kinds.md deleted file mode 100644 index fc9d788..0000000 --- a/.changeset/custom-block-kinds.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -'@ogs-tech/press-cms': minor ---- - -feat(cms): custom block kinds — placement-scoped adopter categories - -The adopter extension point now carries placement semantics per category -folder (`admitCustomBlocks`): - -- `src/components/custom/` → every engine Dynamic Zone (page `body` + - site-setting `header`/`footer`) — the existing contract, unchanged; -- `src/components/custom-section/` → the page `body` only; -- `src/components/custom-chrome/` → the site-setting `header`/`footer` only, - never the page body. - -Purely additive: existing `custom.*` blocks keep their behavior and uids. The -engine still never names individual adopter blocks — only the `custom*` -categories are the stable contract. Note: `custom-chrome.*` blocks do not -receive the brand/links hydration that `chrome.navbar` gets from -`mapSiteSettings`; they render from their stored attributes alone. diff --git a/.changeset/press-editable-navigation.md b/.changeset/press-editable-navigation.md deleted file mode 100644 index 09fe547..0000000 --- a/.changeset/press-editable-navigation.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -'@ogs-tech/press-cms': minor -'@ogs-tech/press-web': minor ---- - -feat: editable header navigation - -CMS gains the `press.nav-item` component (injected, Site-Settings-only) and a -repeatable `headerNav` field on the Site Settings single type. The Site Settings -controller deep-populates `headerNav.page` (slug only), and Web resolves each item -into a final link (page wins over url; the home slug collapses to `/`; items with -neither are dropped) and ships a `SiteNav` client component rendered in the host -header with active-link highlighting. Additive only — no -PressSchema/generator/generated.ts/adopter-zone change. Empty/unreachable/malformed -CMS → header renders the logo only. - -Side effect: replacing the Site Settings `populate=*` with an explicit deep -populate (required to reach `headerNav.page`) also deep-populates `seo.image`, -which the one-level `populate=*` did not reach — so the SEO OG image -(`defaultOgImage`) now resolves from the CMS instead of always being undefined. diff --git a/.changeset/privacy-policy-page-seed.md b/.changeset/privacy-policy-page-seed.md deleted file mode 100644 index a1694ad..0000000 --- a/.changeset/privacy-policy-page-seed.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -'@ogs-tech/press-cms': minor ---- - -feat(cms): seed a Privacy Policy page template once at bootstrap - -`bootstrap()` now seeds a "Privacy Policy" page (slug `privacy-policy`) exactly -once, following the chrome-seed semantics: a `privacyPageSeeded` plugin-store -flag makes the pass literal-once, an adopter page already occupying the slug -wins (seed marks itself done without writing), and an editor-deleted page is -respected forever. The page is created as a DRAFT — the engine never publishes -content on its own. - -The template is structure + placeholder guidance composed from existing -`press.*` atoms (intro, Data We Collect, Cookies, How We Use Your Data, Data -Sharing, Your Rights, Contact) — no legal boilerplate is embedded; the editor -writes and owns the actual policy text. diff --git a/.changeset/quiet-schema-poll-log.md b/.changeset/quiet-schema-poll-log.md deleted file mode 100644 index bb23652..0000000 --- a/.changeset/quiet-schema-poll-log.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -'@ogs-tech/press-cms': patch ---- - -fix(cms): silence the schema-poll http log line in development - -`press dev` polls `GET /api/press/schema` every ~2s (the type-sync watcher), -and Strapi's `strapi::logger` middleware logs every request unconditionally — -flooding the dev log with one line per poll. The plugin now wraps -`strapi.log.http` during `register()` and drops messages for that one -engine-owned path, in development only: in production the watcher never runs, -and a stray hit on the schema endpoint stays visible. diff --git a/.changeset/section-blocks.md b/.changeset/section-blocks.md deleted file mode 100644 index 8970aef..0000000 --- a/.changeset/section-blocks.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -'@ogs-tech/press-cms': minor -'@ogs-tech/press-web': minor ---- - -feat: composite section blocks (section.*) - -Adds an engine-owned palette of composite sections under a new `section.*` -category: `section.hero` and `section.cta`. CMS injects both components and lists -them statically in the page `body` Dynamic Zone; they flow through the unchanged -type-sync pipeline (all fields are flat scalar/media/enum), so `serialize-schema` -and the generator are untouched. Web ships `Hero`/`Cta` renderers behind a separate -`sectionBlocks` registry that `BlockRenderer` merges between `referenceBlocks` and -the adopter's `components` — each section is born branded by the Site Settings theme -(theme.css consumes `var(--press-*)` tokens) and overridable via -`components={{ 'section.hero': MyHero }}`. Additive and non-breaking: `press.*` and -`custom.*` are unchanged; adopters gain `section.*` on `press upgrade`. diff --git a/apps/playground/CHANGELOG.md b/apps/playground/CHANGELOG.md new file mode 100644 index 0000000..690a67f --- /dev/null +++ b/apps/playground/CHANGELOG.md @@ -0,0 +1,8 @@ +# playground + +## 0.1.1 + +### Patch Changes + +- Updated dependencies [[`936ece7`](https://github.com/ogs-tech/press/commit/936ece7cdf9fadf17f5174512855a10506d3c6ad), [`a6bdc84`](https://github.com/ogs-tech/press/commit/a6bdc84ca26eebe65a78ecfbdd7407e096ee839f), [`a6bdc84`](https://github.com/ogs-tech/press/commit/a6bdc84ca26eebe65a78ecfbdd7407e096ee839f), [`260d8ea`](https://github.com/ogs-tech/press/commit/260d8eacd4df2518b74133678d1c476d0aa637f4), [`21c793b`](https://github.com/ogs-tech/press/commit/21c793b456331a7f6a1e3246ebc2d967416b5f3c), [`b11ced9`](https://github.com/ogs-tech/press/commit/b11ced9730896101871952e4627fcc2b3cb19fb8), [`490bdc7`](https://github.com/ogs-tech/press/commit/490bdc7f63c9fe893c249e32be8f60fd13891061)]: + - @ogs-tech/press-web@1.0.0 diff --git a/apps/playground/package.json b/apps/playground/package.json index 586032c..8738399 100644 --- a/apps/playground/package.json +++ b/apps/playground/package.json @@ -1,6 +1,6 @@ { "name": "playground", - "version": "0.1.0", + "version": "0.1.1", "private": true, "scripts": { "dev": "press dev", diff --git a/apps/playground/packages/cms/CHANGELOG.md b/apps/playground/packages/cms/CHANGELOG.md new file mode 100644 index 0000000..fa97cc6 --- /dev/null +++ b/apps/playground/packages/cms/CHANGELOG.md @@ -0,0 +1,8 @@ +# playground-cms + +## 0.1.1 + +### Patch Changes + +- Updated dependencies [[`936ece7`](https://github.com/ogs-tech/press/commit/936ece7cdf9fadf17f5174512855a10506d3c6ad), [`a6bdc84`](https://github.com/ogs-tech/press/commit/a6bdc84ca26eebe65a78ecfbdd7407e096ee839f), [`21c793b`](https://github.com/ogs-tech/press/commit/21c793b456331a7f6a1e3246ebc2d967416b5f3c), [`21c793b`](https://github.com/ogs-tech/press/commit/21c793b456331a7f6a1e3246ebc2d967416b5f3c), [`21c793b`](https://github.com/ogs-tech/press/commit/21c793b456331a7f6a1e3246ebc2d967416b5f3c), [`b11ced9`](https://github.com/ogs-tech/press/commit/b11ced9730896101871952e4627fcc2b3cb19fb8), [`21c793b`](https://github.com/ogs-tech/press/commit/21c793b456331a7f6a1e3246ebc2d967416b5f3c), [`a6bdc84`](https://github.com/ogs-tech/press/commit/a6bdc84ca26eebe65a78ecfbdd7407e096ee839f), [`490bdc7`](https://github.com/ogs-tech/press/commit/490bdc7f63c9fe893c249e32be8f60fd13891061)]: + - @ogs-tech/press-cms@1.0.0 diff --git a/apps/playground/packages/cms/package.json b/apps/playground/packages/cms/package.json index 4183179..c80227d 100644 --- a/apps/playground/packages/cms/package.json +++ b/apps/playground/packages/cms/package.json @@ -1,6 +1,6 @@ { "name": "playground-cms", - "version": "0.1.0", + "version": "0.1.1", "private": true, "description": "press cms host (Strapi)", "scripts": { diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md new file mode 100644 index 0000000..ee500d7 --- /dev/null +++ b/packages/cli/CHANGELOG.md @@ -0,0 +1,35 @@ +# @ogs-tech/create-press + +## 0.1.1 + +### Patch Changes + +- [`936ece7`](https://github.com/ogs-tech/press/commit/936ece7cdf9fadf17f5174512855a10506d3c6ad) Thanks [@odenirdev](https://github.com/odenirdev)! - feat!: Atomic Design component palette — unified `{owner}-{layer}.{name}` scheme + + BREAKING (wire + API): the ad-hoc `press.*` / `section.*` / `chrome.*` prefixes + are replaced by ONE Atomic Design scheme where the Strapi category encodes + `{owner}-{layer}` (owner ∈ preset|custom, layer ∈ atom|molecule|organism|config| + layout|template) and stored `__component` values change accordingly: + + - `press.{paragraph,heading,list,quote,image,button,separator,spacer}` → + `preset-atom.*`; `press.nav-item` → `preset-molecule.nav-item`; + `press.{seo,theme-colors,theme-radius,cookie-consent,cookie-category}` → + `preset-config.*`. + - `section.{hero,cta}` and `chrome.{navbar,footer}` unify under + `preset-organism.*` (one layer; placement — body vs header/footer — is declared + per content-type `schema.json`, not by the category). `hero`/`cta` are now + **body-only**. + - Adopter blocks move from placement folders (`custom` / `custom-section` / + `custom-chrome`) to atomic-LAYER folders (`custom-/`, e.g. + `custom-organism/`); `admitCustomBlocks` now admits every `custom-*` block into + ALL engine Dynamic Zones (universal placement — the editor decides where), + dropping the per-category placement map. Legacy bare `custom.*` is still + admitted for a forgiving migration. + + **press-web**: exported registries renamed (`referenceBlocks` → `atomBlocks`; + `sectionBlocks` + `chromeBlocks` → `organismBlocks`) and the base block types + renamed (`PressParagraph` → `PresetAtomParagraph`, `SectionHero` → + `PresetOrganismHero`, `ChromeNavbar` → `PresetOrganismNavbar`, …). The generator, + `PressSchema` contract, `urn`/`blockKey` primitives, and the `plugin::press-cms.*` + plugin id are unchanged (the product name "press" is not a component category). + The scaffolder ships the migrated `custom-organism.callout` example. diff --git a/packages/cli/package.json b/packages/cli/package.json index 0166484..c63e810 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,13 +1,21 @@ { "name": "@ogs-tech/create-press", - "version": "0.1.0", + "version": "0.1.1", "description": "Scaffold a new press project (ultra-thin Project zone)", "license": "MIT", "author": "Odenir Gomes", "type": "commonjs", - "bin": { "create-press": "bin/create-press.js" }, - "files": ["bin", "dist", "templates"], - "publishConfig": { "access": "public" }, + "bin": { + "create-press": "bin/create-press.js" + }, + "files": [ + "bin", + "dist", + "templates" + ], + "publishConfig": { + "access": "public" + }, "repository": { "type": "git", "url": "git+https://github.com/ogs-tech/press.git", diff --git a/packages/cli/src/create/versions.generated.ts b/packages/cli/src/create/versions.generated.ts index 0b5c045..603b2ce 100644 --- a/packages/cli/src/create/versions.generated.ts +++ b/packages/cli/src/create/versions.generated.ts @@ -2,9 +2,9 @@ // Regenerate with: pnpm --filter @ogs-tech/create-press gen:versions // Source of truth: the engine packages' own package.json manifests. export const VERSIONS = { - pressCli: '0.1.0', - pressWeb: '0.4.1', - pressCms: '0.3.2', + pressCli: '0.1.1', + pressWeb: '1.0.0', + pressCms: '1.0.0', next: '^15.1.0', react: '^18.3.1', strapi: '5.48.0', diff --git a/packages/cms/CHANGELOG.md b/packages/cms/CHANGELOG.md new file mode 100644 index 0000000..9bfe750 --- /dev/null +++ b/packages/cms/CHANGELOG.md @@ -0,0 +1,186 @@ +# @ogs-tech/press-cms + +## 1.0.0 + +### Major Changes + +- [`936ece7`](https://github.com/ogs-tech/press/commit/936ece7cdf9fadf17f5174512855a10506d3c6ad) Thanks [@odenirdev](https://github.com/odenirdev)! - feat!: Atomic Design component palette — unified `{owner}-{layer}.{name}` scheme + + BREAKING (wire + API): the ad-hoc `press.*` / `section.*` / `chrome.*` prefixes + are replaced by ONE Atomic Design scheme where the Strapi category encodes + `{owner}-{layer}` (owner ∈ preset|custom, layer ∈ atom|molecule|organism|config| + layout|template) and stored `__component` values change accordingly: + + - `press.{paragraph,heading,list,quote,image,button,separator,spacer}` → + `preset-atom.*`; `press.nav-item` → `preset-molecule.nav-item`; + `press.{seo,theme-colors,theme-radius,cookie-consent,cookie-category}` → + `preset-config.*`. + - `section.{hero,cta}` and `chrome.{navbar,footer}` unify under + `preset-organism.*` (one layer; placement — body vs header/footer — is declared + per content-type `schema.json`, not by the category). `hero`/`cta` are now + **body-only**. + - Adopter blocks move from placement folders (`custom` / `custom-section` / + `custom-chrome`) to atomic-LAYER folders (`custom-/`, e.g. + `custom-organism/`); `admitCustomBlocks` now admits every `custom-*` block into + ALL engine Dynamic Zones (universal placement — the editor decides where), + dropping the per-category placement map. Legacy bare `custom.*` is still + admitted for a forgiving migration. + + **press-web**: exported registries renamed (`referenceBlocks` → `atomBlocks`; + `sectionBlocks` + `chromeBlocks` → `organismBlocks`) and the base block types + renamed (`PressParagraph` → `PresetAtomParagraph`, `SectionHero` → + `PresetOrganismHero`, `ChromeNavbar` → `PresetOrganismNavbar`, …). The generator, + `PressSchema` contract, `urn`/`blockKey` primitives, and the `plugin::press-cms.*` + plugin id are unchanged (the product name "press" is not a component category). + The scaffolder ships the migrated `custom-organism.callout` example. + +- [#8](https://github.com/ogs-tech/press/pull/8) [`a6bdc84`](https://github.com/ogs-tech/press/commit/a6bdc84ca26eebe65a78ecfbdd7407e096ee839f) Thanks [@odenirdev](https://github.com/odenirdev)! - feat!: block-composable site chrome (chrome.\*) + + The site header and footer become block-composed: the `site-setting` single type + gains two Dynamic Zones (`header`, `footer`) admitting a new engine-owned + `chrome.*` category (`chrome.navbar`, `chrome.footer`) plus `press.*`, + `section.*`, and adopter `custom.*` blocks. The serializer walks all three engine + DZs and follows nested component references; the generator types nested + components (without `__component`), skips relations, and emits + `HeaderBlocks`/`FooterBlocks` unions. `mapSiteSettings` hydrates the zones (brand + injection + nav resolution); `BlockRenderer` merges a new `chromeBlocks` registry + (adopter-overridable); the host layout renders both zones through the block + pipeline. `bootstrap()` seeds a default composition (navbar + footer) exactly + once. `press-shared`: `Attr` gains typed `component`/`repeatable` keys (additive). + + BREAKING (press-cms): `site-setting.headerNav` is removed. Strapi drops its data + on schema sync — there is no automated migration. After upgrading, re-enter the + nav links once inside the seeded Navbar block (Site Settings → Header). + + BREAKING (press-web): `SiteNav` is no longer exported (the navbar renders links + internally) and `ResolvedPressConfig.nav` is replaced by + `ResolvedPressConfig.chrome` (`{ header, footer }` hydrated block arrays). + Override the chrome like any block: `components={{ 'chrome.navbar': MyNavbar }}`. + +### Minor Changes + +- [#9](https://github.com/ogs-tech/press/pull/9) [`21c793b`](https://github.com/ogs-tech/press/commit/21c793b456331a7f6a1e3246ebc2d967416b5f3c) Thanks [@odenirdev](https://github.com/odenirdev)! - feat(cms): component-picker UX — per-block icons + human category labels + + Every engine component JSON now sets `info.icon` (Strapi's fixed icon enum), so + the admin "Pick one component" dialog stops rendering the generic grid fallback + for all blocks: `press.paragraph` → `write`, `press.image` → `picture`, + `section.hero` → `landscape`, `chrome.navbar` → `layout`, and so on. + + The plugin also ships its first admin bundle (`./strapi-admin` export, built by + the same `strapi-plugin build`). Its single job is `registerTrads`: the picker + resolves each category accordion title through react-intl using the RAW + category string as the message id, so the bundle registers unprefixed keys — + `press` → "Blocks", `section` → "Sections", `chrome` → "Site chrome", + `custom` → "Custom blocks" (en + pt/pt-BR) — labelling the picker without + touching component uids (a uid is wire/DB contract; labels are presentation). + Adopters keep the final word: `src/admin/app.tsx` `config.translations` takes + precedence over these engine defaults. + +- [#9](https://github.com/ogs-tech/press/pull/9) [`21c793b`](https://github.com/ogs-tech/press/commit/21c793b456331a7f6a1e3246ebc2d967416b5f3c) Thanks [@odenirdev](https://github.com/odenirdev)! - feat!: cookie-consent — the first engine plugin, introducing the `'plugin'` canonical + + **Engine plugins (press-web).** `Entity` gains `'plugin'` (additive) and the + new `PressPlugin` contract (`extends Canonical<'plugin'>`, `id`, `enabled`) + formalizes the plugin family: an optional engine capability configured through + Site Settings, resolved by a pure mapper into the new + `ResolvedPressConfig.plugins` named map, and mounted explicitly by the host + layout — no runtime registry. Plugin identity is synthetic + (`urn:plugin:cookie-consent`), never CMS-sourced. + + **Cookie consent (press-web).** New `CookieConsentBanner` (the engine's first + stateful client component), the `useConsent()` hook, and the consent store: + `hasConsent('analytics')` (fail-closed), `acceptAll`/`rejectAll`/`setConsent`/ + `resetConsent`, `parseConsentCookie` (server-side seam), and + `buildConsentBootstrapScript()` — a pre-paint inline script the host layout + injects so a decided visitor never sees the banner flash. The decision lives + in a versioned first-party cookie (`press_consent`, SameSite=Lax, 180d), never + read via `cookies()` in the RSC tree (static/ISR stays intact). The resolved + plugin FAILS OPEN: an unreachable CMS still yields an enabled banner with the + engine's default copy — a consent gate must not vanish on a CMS hiccup. + Consent categories are a closed code union (`necessary | analytics | +marketing`); editors toggle and re-word them, never rename keys. + + **Cookie consent (press-cms).** New `press.cookie-consent` + + `press.cookie-category` config components (injected, never DZ-admitted), a + `cookieConsent` attribute on Site Settings with deep populate (nested + categories + privacy page slug), and a run-once seed (`cookieConsentSeeded` + plugin-store flag) that writes only the `enabled` booleans — default copy + lives web-side; an editor-disabled banner is respected forever. + + BREAKING (press-web): `ResolvedPressConfig` gains a REQUIRED `plugins` field. + Runtime is additive — every object produced by `getSiteConfig` carries it — + but adopter code that hand-constructs a literal (test fixtures, mocks) fails + `tsc` until it adds `plugins: { cookieConsent: ... }` (or builds the value + through `mapSiteSettings`). The host template's `layout.tsx` also changed + (bootstrap script + banner mount) and is re-materialized on the next + `press dev`/`build`. + +- [#9](https://github.com/ogs-tech/press/pull/9) [`21c793b`](https://github.com/ogs-tech/press/commit/21c793b456331a7f6a1e3246ebc2d967416b5f3c) Thanks [@odenirdev](https://github.com/odenirdev)! - feat(cms): custom block kinds — placement-scoped adopter categories + + The adopter extension point now carries placement semantics per category + folder (`admitCustomBlocks`): + + - `src/components/custom/` → every engine Dynamic Zone (page `body` + + site-setting `header`/`footer`) — the existing contract, unchanged; + - `src/components/custom-section/` → the page `body` only; + - `src/components/custom-chrome/` → the site-setting `header`/`footer` only, + never the page body. + + Purely additive: existing `custom.*` blocks keep their behavior and uids. The + engine still never names individual adopter blocks — only the `custom*` + categories are the stable contract. Note: `custom-chrome.*` blocks do not + receive the brand/links hydration that `chrome.navbar` gets from + `mapSiteSettings`; they render from their stored attributes alone. + +- [`b11ced9`](https://github.com/ogs-tech/press/commit/b11ced9730896101871952e4627fcc2b3cb19fb8) Thanks [@odenirdev](https://github.com/odenirdev)! - feat: editable header navigation + + CMS gains the `press.nav-item` component (injected, Site-Settings-only) and a + repeatable `headerNav` field on the Site Settings single type. The Site Settings + controller deep-populates `headerNav.page` (slug only), and Web resolves each item + into a final link (page wins over url; the home slug collapses to `/`; items with + neither are dropped) and ships a `SiteNav` client component rendered in the host + header with active-link highlighting. Additive only — no + PressSchema/generator/generated.ts/adopter-zone change. Empty/unreachable/malformed + CMS → header renders the logo only. + + Side effect: replacing the Site Settings `populate=*` with an explicit deep + populate (required to reach `headerNav.page`) also deep-populates `seo.image`, + which the one-level `populate=*` did not reach — so the SEO OG image + (`defaultOgImage`) now resolves from the CMS instead of always being undefined. + +- [#9](https://github.com/ogs-tech/press/pull/9) [`21c793b`](https://github.com/ogs-tech/press/commit/21c793b456331a7f6a1e3246ebc2d967416b5f3c) Thanks [@odenirdev](https://github.com/odenirdev)! - feat(cms): seed a Privacy Policy page template once at bootstrap + + `bootstrap()` now seeds a "Privacy Policy" page (slug `privacy-policy`) exactly + once, following the chrome-seed semantics: a `privacyPageSeeded` plugin-store + flag makes the pass literal-once, an adopter page already occupying the slug + wins (seed marks itself done without writing), and an editor-deleted page is + respected forever. The page is created as a DRAFT — the engine never publishes + content on its own. + + The template is structure + placeholder guidance composed from existing + `press.*` atoms (intro, Data We Collect, Cookies, How We Use Your Data, Data + Sharing, Your Rights, Contact) — no legal boilerplate is embedded; the editor + writes and owns the actual policy text. + +- [#6](https://github.com/ogs-tech/press/pull/6) [`490bdc7`](https://github.com/ogs-tech/press/commit/490bdc7f63c9fe893c249e32be8f60fd13891061) Thanks [@odenirdev](https://github.com/odenirdev)! - feat: composite section blocks (section.\*) + + Adds an engine-owned palette of composite sections under a new `section.*` + category: `section.hero` and `section.cta`. CMS injects both components and lists + them statically in the page `body` Dynamic Zone; they flow through the unchanged + type-sync pipeline (all fields are flat scalar/media/enum), so `serialize-schema` + and the generator are untouched. Web ships `Hero`/`Cta` renderers behind a separate + `sectionBlocks` registry that `BlockRenderer` merges between `referenceBlocks` and + the adopter's `components` — each section is born branded by the Site Settings theme + (theme.css consumes `var(--press-*)` tokens) and overridable via + `components={{ 'section.hero': MyHero }}`. Additive and non-breaking: `press.*` and + `custom.*` are unchanged; adopters gain `section.*` on `press upgrade`. + +### Patch Changes + +- [#8](https://github.com/ogs-tech/press/pull/8) [`a6bdc84`](https://github.com/ogs-tech/press/commit/a6bdc84ca26eebe65a78ecfbdd7407e096ee839f) Thanks [@odenirdev](https://github.com/odenirdev)! - fix(cms): silence the schema-poll http log line in development + + `press dev` polls `GET /api/press/schema` every ~2s (the type-sync watcher), + and Strapi's `strapi::logger` middleware logs every request unconditionally — + flooding the dev log with one line per poll. The plugin now wraps + `strapi.log.http` during `register()` and drops messages for that one + engine-owned path, in development only: in production the watcher never runs, + and a stray hit on the schema endpoint stays visible. diff --git a/packages/cms/package.json b/packages/cms/package.json index 6df6234..6d14991 100644 --- a/packages/cms/package.json +++ b/packages/cms/package.json @@ -1,12 +1,14 @@ { "name": "@ogs-tech/press-cms", - "version": "0.3.2", + "version": "1.0.0", "description": "press engine — content-types and reference blocks", "keywords": [], "license": "MIT", "author": "Odenir Gomes", "type": "commonjs", - "publishConfig": { "access": "public" }, + "publishConfig": { + "access": "public" + }, "repository": { "type": "git", "url": "git+https://github.com/ogs-tech/press.git", diff --git a/packages/shared/CHANGELOG.md b/packages/shared/CHANGELOG.md new file mode 100644 index 0000000..5bc388c --- /dev/null +++ b/packages/shared/CHANGELOG.md @@ -0,0 +1,28 @@ +# @ogs-tech/press-shared + +## 0.2.0 + +### Minor Changes + +- [#8](https://github.com/ogs-tech/press/pull/8) [`a6bdc84`](https://github.com/ogs-tech/press/commit/a6bdc84ca26eebe65a78ecfbdd7407e096ee839f) Thanks [@odenirdev](https://github.com/odenirdev)! - feat!: block-composable site chrome (chrome.\*) + + The site header and footer become block-composed: the `site-setting` single type + gains two Dynamic Zones (`header`, `footer`) admitting a new engine-owned + `chrome.*` category (`chrome.navbar`, `chrome.footer`) plus `press.*`, + `section.*`, and adopter `custom.*` blocks. The serializer walks all three engine + DZs and follows nested component references; the generator types nested + components (without `__component`), skips relations, and emits + `HeaderBlocks`/`FooterBlocks` unions. `mapSiteSettings` hydrates the zones (brand + injection + nav resolution); `BlockRenderer` merges a new `chromeBlocks` registry + (adopter-overridable); the host layout renders both zones through the block + pipeline. `bootstrap()` seeds a default composition (navbar + footer) exactly + once. `press-shared`: `Attr` gains typed `component`/`repeatable` keys (additive). + + BREAKING (press-cms): `site-setting.headerNav` is removed. Strapi drops its data + on schema sync — there is no automated migration. After upgrading, re-enter the + nav links once inside the seeded Navbar block (Site Settings → Header). + + BREAKING (press-web): `SiteNav` is no longer exported (the navbar renders links + internally) and `ResolvedPressConfig.nav` is replaced by + `ResolvedPressConfig.chrome` (`{ header, footer }` hydrated block arrays). + Override the chrome like any block: `components={{ 'chrome.navbar': MyNavbar }}`. diff --git a/packages/shared/package.json b/packages/shared/package.json index c5fc2ba..a91f071 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "@ogs-tech/press-shared", - "version": "0.1.0", + "version": "0.2.0", "private": true, "description": "press — framework-agnostic contract types shared by the engine packages", "license": "MIT", @@ -10,9 +10,14 @@ "types": "./src/index.ts", "exports": { "./package.json": "./package.json", - ".": { "types": "./src/index.ts", "default": "./src/index.ts" } + ".": { + "types": "./src/index.ts", + "default": "./src/index.ts" + } }, - "files": ["src"], + "files": [ + "src" + ], "scripts": { "build": "echo '@ogs-tech/press-shared ships TS source; nothing to build'", "typecheck": "tsc --noEmit" diff --git a/packages/web/CHANGELOG.md b/packages/web/CHANGELOG.md index 757e664..011b95a 100644 --- a/packages/web/CHANGELOG.md +++ b/packages/web/CHANGELOG.md @@ -1,5 +1,166 @@ # @ogs-tech/press-web +## 1.0.0 + +### Major Changes + +- [`936ece7`](https://github.com/ogs-tech/press/commit/936ece7cdf9fadf17f5174512855a10506d3c6ad) Thanks [@odenirdev](https://github.com/odenirdev)! - feat!: Atomic Design component palette — unified `{owner}-{layer}.{name}` scheme + + BREAKING (wire + API): the ad-hoc `press.*` / `section.*` / `chrome.*` prefixes + are replaced by ONE Atomic Design scheme where the Strapi category encodes + `{owner}-{layer}` (owner ∈ preset|custom, layer ∈ atom|molecule|organism|config| + layout|template) and stored `__component` values change accordingly: + + - `press.{paragraph,heading,list,quote,image,button,separator,spacer}` → + `preset-atom.*`; `press.nav-item` → `preset-molecule.nav-item`; + `press.{seo,theme-colors,theme-radius,cookie-consent,cookie-category}` → + `preset-config.*`. + - `section.{hero,cta}` and `chrome.{navbar,footer}` unify under + `preset-organism.*` (one layer; placement — body vs header/footer — is declared + per content-type `schema.json`, not by the category). `hero`/`cta` are now + **body-only**. + - Adopter blocks move from placement folders (`custom` / `custom-section` / + `custom-chrome`) to atomic-LAYER folders (`custom-/`, e.g. + `custom-organism/`); `admitCustomBlocks` now admits every `custom-*` block into + ALL engine Dynamic Zones (universal placement — the editor decides where), + dropping the per-category placement map. Legacy bare `custom.*` is still + admitted for a forgiving migration. + + **press-web**: exported registries renamed (`referenceBlocks` → `atomBlocks`; + `sectionBlocks` + `chromeBlocks` → `organismBlocks`) and the base block types + renamed (`PressParagraph` → `PresetAtomParagraph`, `SectionHero` → + `PresetOrganismHero`, `ChromeNavbar` → `PresetOrganismNavbar`, …). The generator, + `PressSchema` contract, `urn`/`blockKey` primitives, and the `plugin::press-cms.*` + plugin id are unchanged (the product name "press" is not a component category). + The scaffolder ships the migrated `custom-organism.callout` example. + +- [#8](https://github.com/ogs-tech/press/pull/8) [`a6bdc84`](https://github.com/ogs-tech/press/commit/a6bdc84ca26eebe65a78ecfbdd7407e096ee839f) Thanks [@odenirdev](https://github.com/odenirdev)! - feat(web)!: canonical urn identity — `urn:{entity}:{id}` on Page and Site Settings + + New web-only identity primitives in `packages/web/src/urn.ts`, exported from the + package root: the closed `Entity` union (`'page' | 'site-setting'`), the + template-literal `Urn` (`urn:{entity}:{id}`), the `Canonical` interface + (`{ urn: Urn }`), and the pure `buildUrn(entity, id)` factory. The wire + contract, press-cms, and press-shared are untouched — a urn is never sent or + stored by the CMS. + + `Page` now extends `Canonical<'page'>`: the new pure `mapPage` mapper (mirroring + the `mapSiteSettings` pure-mapper + thin-fetcher split) attaches + `urn:page:{documentId}` right after the fetch. `ResolvedPressConfig` extends + `Canonical<'site-setting'>`: `mapSiteSettings` attaches the synthetic constant + `urn:site-setting:default` (single type — one record, identity never + CMS-sourced, present even when the CMS is unreachable). `blockKey` now formats + its React key through the same primitive (`press.image:5` → + `urn:press.image:5`) — a computed identity, never stored on the block; blockKey + was never exported, so no public surface changes shape there. + + BREAKING (press-web): `Page` and `ResolvedPressConfig` gain a REQUIRED `urn` + field. Runtime is additive — every object produced by `getPage`/`getSiteConfig` + carries it automatically — but adopter code that hand-constructs a literal of + either type (e.g. a test fixture or a mock) fails `tsc` until it adds `urn` + (`'urn:page:'` / `'urn:site-setting:default'`). + +- [#8](https://github.com/ogs-tech/press/pull/8) [`a6bdc84`](https://github.com/ogs-tech/press/commit/a6bdc84ca26eebe65a78ecfbdd7407e096ee839f) Thanks [@odenirdev](https://github.com/odenirdev)! - feat!: block-composable site chrome (chrome.\*) + + The site header and footer become block-composed: the `site-setting` single type + gains two Dynamic Zones (`header`, `footer`) admitting a new engine-owned + `chrome.*` category (`chrome.navbar`, `chrome.footer`) plus `press.*`, + `section.*`, and adopter `custom.*` blocks. The serializer walks all three engine + DZs and follows nested component references; the generator types nested + components (without `__component`), skips relations, and emits + `HeaderBlocks`/`FooterBlocks` unions. `mapSiteSettings` hydrates the zones (brand + injection + nav resolution); `BlockRenderer` merges a new `chromeBlocks` registry + (adopter-overridable); the host layout renders both zones through the block + pipeline. `bootstrap()` seeds a default composition (navbar + footer) exactly + once. `press-shared`: `Attr` gains typed `component`/`repeatable` keys (additive). + + BREAKING (press-cms): `site-setting.headerNav` is removed. Strapi drops its data + on schema sync — there is no automated migration. After upgrading, re-enter the + nav links once inside the seeded Navbar block (Site Settings → Header). + + BREAKING (press-web): `SiteNav` is no longer exported (the navbar renders links + internally) and `ResolvedPressConfig.nav` is replaced by + `ResolvedPressConfig.chrome` (`{ header, footer }` hydrated block arrays). + Override the chrome like any block: `components={{ 'chrome.navbar': MyNavbar }}`. + +- [#9](https://github.com/ogs-tech/press/pull/9) [`21c793b`](https://github.com/ogs-tech/press/commit/21c793b456331a7f6a1e3246ebc2d967416b5f3c) Thanks [@odenirdev](https://github.com/odenirdev)! - feat!: cookie-consent — the first engine plugin, introducing the `'plugin'` canonical + + **Engine plugins (press-web).** `Entity` gains `'plugin'` (additive) and the + new `PressPlugin` contract (`extends Canonical<'plugin'>`, `id`, `enabled`) + formalizes the plugin family: an optional engine capability configured through + Site Settings, resolved by a pure mapper into the new + `ResolvedPressConfig.plugins` named map, and mounted explicitly by the host + layout — no runtime registry. Plugin identity is synthetic + (`urn:plugin:cookie-consent`), never CMS-sourced. + + **Cookie consent (press-web).** New `CookieConsentBanner` (the engine's first + stateful client component), the `useConsent()` hook, and the consent store: + `hasConsent('analytics')` (fail-closed), `acceptAll`/`rejectAll`/`setConsent`/ + `resetConsent`, `parseConsentCookie` (server-side seam), and + `buildConsentBootstrapScript()` — a pre-paint inline script the host layout + injects so a decided visitor never sees the banner flash. The decision lives + in a versioned first-party cookie (`press_consent`, SameSite=Lax, 180d), never + read via `cookies()` in the RSC tree (static/ISR stays intact). The resolved + plugin FAILS OPEN: an unreachable CMS still yields an enabled banner with the + engine's default copy — a consent gate must not vanish on a CMS hiccup. + Consent categories are a closed code union (`necessary | analytics | +marketing`); editors toggle and re-word them, never rename keys. + + **Cookie consent (press-cms).** New `press.cookie-consent` + + `press.cookie-category` config components (injected, never DZ-admitted), a + `cookieConsent` attribute on Site Settings with deep populate (nested + categories + privacy page slug), and a run-once seed (`cookieConsentSeeded` + plugin-store flag) that writes only the `enabled` booleans — default copy + lives web-side; an editor-disabled banner is respected forever. + + BREAKING (press-web): `ResolvedPressConfig` gains a REQUIRED `plugins` field. + Runtime is additive — every object produced by `getSiteConfig` carries it — + but adopter code that hand-constructs a literal (test fixtures, mocks) fails + `tsc` until it adds `plugins: { cookieConsent: ... }` (or builds the value + through `mapSiteSettings`). The host template's `layout.tsx` also changed + (bootstrap script + banner mount) and is re-materialized on the next + `press dev`/`build`. + +### Minor Changes + +- [#10](https://github.com/ogs-tech/press/pull/10) [`260d8ea`](https://github.com/ogs-tech/press/commit/260d8eacd4df2518b74133678d1c476d0aa637f4) Thanks [@odenirdev](https://github.com/odenirdev)! - feat(web): `component` canonical — `urn:component:{uid}` type-level identity + + `Entity` gains a 4th member `'component'` (additive), plus a `componentUrn(uid)` + factory (exported from the package root) formatting `urn:component:{uid}` for the + palette registries (`press.*`/`section.*`/`chrome.*`/`custom.*`). This is a + TYPE-level identity — distinct from the STORED identities (page/site-setting/ + plugin) and from `blockKey`'s COMPUTED per-instance key. No object implements + `Canonical<'component'>`; the first consumer is `BlockRenderer`'s + unknown-component dev warning, now citing the canonical `urn:component:…` form. + +- [`b11ced9`](https://github.com/ogs-tech/press/commit/b11ced9730896101871952e4627fcc2b3cb19fb8) Thanks [@odenirdev](https://github.com/odenirdev)! - feat: editable header navigation + + CMS gains the `press.nav-item` component (injected, Site-Settings-only) and a + repeatable `headerNav` field on the Site Settings single type. The Site Settings + controller deep-populates `headerNav.page` (slug only), and Web resolves each item + into a final link (page wins over url; the home slug collapses to `/`; items with + neither are dropped) and ships a `SiteNav` client component rendered in the host + header with active-link highlighting. Additive only — no + PressSchema/generator/generated.ts/adopter-zone change. Empty/unreachable/malformed + CMS → header renders the logo only. + + Side effect: replacing the Site Settings `populate=*` with an explicit deep + populate (required to reach `headerNav.page`) also deep-populates `seo.image`, + which the one-level `populate=*` did not reach — so the SEO OG image + (`defaultOgImage`) now resolves from the CMS instead of always being undefined. + +- [#6](https://github.com/ogs-tech/press/pull/6) [`490bdc7`](https://github.com/ogs-tech/press/commit/490bdc7f63c9fe893c249e32be8f60fd13891061) Thanks [@odenirdev](https://github.com/odenirdev)! - feat: composite section blocks (section.\*) + + Adds an engine-owned palette of composite sections under a new `section.*` + category: `section.hero` and `section.cta`. CMS injects both components and lists + them statically in the page `body` Dynamic Zone; they flow through the unchanged + type-sync pipeline (all fields are flat scalar/media/enum), so `serialize-schema` + and the generator are untouched. Web ships `Hero`/`Cta` renderers behind a separate + `sectionBlocks` registry that `BlockRenderer` merges between `referenceBlocks` and + the adopter's `components` — each section is born branded by the Site Settings theme + (theme.css consumes `var(--press-*)` tokens) and overridable via + `components={{ 'section.hero': MyHero }}`. Additive and non-breaking: `press.*` and + `custom.*` are unchanged; adopters gain `section.*` on `press upgrade`. + ## 0.4.1 ### Patch Changes diff --git a/packages/web/package.json b/packages/web/package.json index 3f47fc7..c10a7e0 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -1,6 +1,6 @@ { "name": "@ogs-tech/press-web", - "version": "0.4.1", + "version": "1.0.0", "description": "press engine — front-end renderer + CMS→TS type-sync", "license": "MIT", "author": "Odenir Gomes",