@getvitops/astro 2.1.0 → 4.0.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/CHANGELOG.md CHANGED
@@ -1,5 +1,342 @@
1
1
  # @getvitops/astro
2
2
 
3
+ ## 4.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - c6b99e7: Consent is now demand-driven: the banner appears when something actually needs permission, not on every first visit.
8
+
9
+ Previously, enabling the gate showed a banner to every new visitor regardless of what the site did — including sites whose only analytics provider was cookieless, where there was nothing to consent to. The build decided whether the machinery shipped and the runtime showed the banner because no cookie existed yet.
10
+
11
+ Now those are two separate facts. The build decides what the banner _can_ ask (rows in the markup); the runtime decides what it _does_ ask. A gated tag registers its demand when it reaches its loading strategy, and `<color-scheme-toggle>` registers `preferences` when a visitor picks a scheme. A site that gates nothing never interrupts anyone.
12
+
13
+ **Breaking — consent cookie schema (v1 → v2).** Consent is now recorded per category as granted / declined / **not yet asked**. The third state is what lets a later demand ask about a category an earlier prompt didn't cover: accepting an analytics banner no longer silently declines preferences. Every stored v1 choice is invalid and re-prompts once — a v1 cookie asserted a definite answer for categories the visitor was never shown.
14
+
15
+ **Breaking — `ConsentApi`.**
16
+ - `needed()` now means "something demanded a category the visitor hasn't answered", not "no cookie yet". A custom banner calling it will now stay hidden until something asks.
17
+ - `ConsentState.decided` (a single boolean) is gone. Use `decidedFor(state, category)`, or `undecidedCategories(state)`.
18
+ - New: `require(category)` registers a demand and reports whether it is granted; `request(category)` resolves once the visitor answers it; `demanded()` lists what has asked so far.
19
+ - `acceptAll()` / `rejectAll()` still mean every optional category. The banner no longer routes its buttons through them — "Accept" applies to the categories on screen.
20
+
21
+ **Breaking — `<color-scheme-toggle>` persistence.** The chosen scheme still applies immediately, but writing it to `localStorage` now waits on the `preferences` category **when the site has a consent gate**. Sites without `consent` enabled are unaffected and keep storing as before. If your site enables consent and offers a theme toggle, make sure `preferences` is among the offered categories (it is by default).
22
+
23
+ **Changed — offered categories.** `consent.categories` defaults to `['analytics', 'preferences']` (plus `marketing` when a configured tag needs it) rather than only what analytics detection could see. An unused row is hidden markup, so offering broadly costs nothing and covers `data-consent` markup no build-time scan can find. Pass `categories` explicitly to narrow it.
24
+
25
+ **Added — `<Head />` emits a small inline consent stub** when the gate is on. `consent.js` and `elements.js` are both deferred with no ordering between them, so without it a theme toggle could be clicked before the gate existed, read "no gate", and store. The stub answers `false` and queues, and the runtime replays the queue on load.
26
+
27
+ **Fixed — the generated cookie notice** now discloses the stored display preference when `preferences` is offered, and no longer promises a banner "shown when you first visit", which is no longer how the banner works.
28
+
29
+ ### Minor Changes
30
+
31
+ - c6b99e7: Ad-click attribution and conversion notifications ship as part of the toolchain.
32
+
33
+ A visitor arriving on an ad carries a click ID in the URL; `<Tracking />` captures it into a first-party `_ac` cookie, and when that visitor later submits a form or taps a `tel:` link, the conversion handler reads the cookie back and notifies whoever the config says. Previously this was per-site code.
34
+
35
+ **Added — `@getvitops/utils/tracking`.** The attribution vocabulary and cookie, as pure functions over a cookie _string_ so the browser capture and the server-side handler share one implementation: `parseTrackingCookie`, `serializeTrackingCookie`, `mergeTracking`, `identifyPlatform`, `getPrimaryClickId`, plus the click-ID/UTM tables. No DOM, no network, no clock — every function that needs "now" takes it as an argument, so it runs unchanged in a Worker.
36
+
37
+ **Added — `@getvitops/utils/notify`.** Conversion notifications, split the way `indexing/` is: `plan.ts` decides everything purely (which channels fire, who they reach, and **why anything is skipped**), `render.ts` turns the event into prose, `email.ts` executes and decides nothing. A misconfigured site can therefore be told exactly why no notification will arrive — a silently unsent one is indistinguishable from no conversion.
38
+
39
+ The `ConversionEvent` is the abstraction: the event is the _fact_, and how it reads is the channel's business.
40
+
41
+ **Added — the `email` channel, via Cloudflare Email Sending.** Uses the current structured binding (`env.EMAIL.send({ to, from, subject, html, text })`), not the legacy `EmailMessage` + hand-built MIME path. The binding is **passed in, never imported**, so `@getvitops/utils` takes no Cloudflare dependency and the sender is testable with a stub. Retries only the transient error codes; a configuration fault like `E_SENDER_NOT_VERIFIED` is surfaced verbatim rather than collapsed into "send failed". With no binding it prints the notification — the dev path.
42
+
43
+ Remember to onboard the sending domain (`wrangler email sending enable <domain>`) and add `"send_email": [{ "name": "EMAIL" }]` to `wrangler.jsonc`, or every send fails.
44
+
45
+ **Added — `<Tracking />` and `createConversionRoute()`** in `@getvitops/astro` (`@getvitops/astro/Tracking.astro`, `@getvitops/astro/routes`). The route factory handles both the `tel:` beacon and a form POST; validation and business rules stay the consumer's, because every site's form differs. A failed notification never fails the request — the visitor has already submitted, and refusing them because our mail didn't go out turns a lost notification into a lost conversion.
46
+
47
+ **Added — `site.tracking` and a widened `site.notifications`.** `notifications.email` now accepts a full channel object as well as a bare address (which still means what it did). `tracking` gains `category`.
48
+
49
+ **Fixed — the capture script now asks for consent instead of only reading it.** It previously checked `granted('marketing')` passively, which under the demand-driven banner is a permanent no-op: nothing else on a page demands `marketing`, so the banner never offered it, so it was never granted, so `_ac` was never written — silently, on every site with the gate enabled. It now calls `require()`, which is what raises the banner, and only when the URL actually carried a click ID or UTM. A visitor arriving organically has nothing to attribute and is never asked.
50
+
51
+ The integration adds `marketing` to the offered categories when tracking is on, so the banner has a row for the category the script will demand, and warns when tracking is enabled with `consent` off.
52
+
53
+ **Fixed — revoking consent now clears `_ac`.** The marker `<Tracking />` emits carries `data-consent-cookies`, which the consent runtime's cleanup reads. There was no cleanup path for this cookie before.
54
+
55
+ **Fixed — the cookie notice discloses `_ac`.** It is first-party, so no provider table would ever name it, and a site running attribution alongside a cookieless analytics provider was previously described as setting no cookies at all.
56
+
57
+ - 14813fa: Add `<wc-tree>`, and a schema walker that feeds it.
58
+
59
+ `<wc-tree>` is progressive enhancement for the existing `.tree` pattern: given a nested
60
+ `<details>` disclosure tree it adds a filter, expand-all / collapse-all, and hash deep-linking.
61
+ It ships in `elements.js`.
62
+
63
+ `@getvitops/astro` gains `./components/Tree.astro` and `./components/tree.ts` (its `TreeItem`
64
+ type) to build that markup from data. As with every wrapper over a web component, `<Tree />`
65
+ emits the `<wc-tree>` tag itself with the accessible fallback inside — so `<Tree items={…} />`
66
+ is the whole call, and wrapping it in your own `<wc-tree>` nests two elements on one tree.
67
+
68
+ The slotted markup is the whole content and works without it — every node readable, expandable
69
+ and linkable — so the element only adds what CSS cannot do. Four things worth knowing:
70
+ - **The toolbar is generated, never authored.** A search field that does nothing is worse than
71
+ no search field, so the controls exist only once the element upgrades.
72
+ - **Deep-linking is the non-obvious one.** A node inside a closed `<details>` has no layout box,
73
+ so the browser's own fragment navigation finds nothing and silently stays at the top of the
74
+ page. `<wc-tree>` opens the target's ancestors — and the target's own disclosure — then scrolls.
75
+ - **Filtering matches a node's own label and description, never its subtree's text.** The obvious
76
+ `textContent` implementation makes every ancestor of a hit match, so the root matches any query
77
+ and the filter narrows nothing. That decision lives in a pure, tested module (`matchTree`)
78
+ rather than in the DOM wiring.
79
+ - **It initialises even when upgraded mid-insertion.** An element connected during an
80
+ `innerHTML` write — a view-transition swap, a client-side navigation — has no children yet
81
+ (measured: zero). Setup retries once the insertion completes, because the failure mode was
82
+ silent: no toolbar, no filter, no deep link, no error.
83
+
84
+ `patterns/tree.css` now supports two markup shapes: the item may be the `<details>` (the
85
+ pattern's original contract) or an `<li class="tree__item">` wrapping one, which is what gives
86
+ assistive tech list position and depth.
87
+
88
+ **`.tree` indent is fixed and now fluid**, which matters for any deep tree. Three separate leaks
89
+ compounded, each invisible in the CSS and each charging roughly one extra indent per level:
90
+ - the rule set both `margin-inline-start` and `padding-inline-start` to `--tree-indent`;
91
+ - `.tree { padding: var(--_p) }` applied to every nested `.tree`, not just the outermost — on all
92
+ four sides, so it narrowed from the end as well;
93
+ - `patterns/details.css` gives every non-summary child of a `<details>`
94
+ `margin-inline: var(--_content-margin)`, and its `details, .details` selector takes `:is()`
95
+ specificity under CSS nesting (**0-1-1**), so `.tree { margin: 0 }` at 0-1-0 _loses_ to it. A
96
+ nested tree is exactly such a child.
97
+
98
+ Measured in a browser: **41px per level against a 24px design**, so a 9-deep tree spent 382px on
99
+ indent and left its deepest label 162px wide. Now 24px per level, 198px total, and 653px of label.
100
+ The nested rule resets both box axes before applying the one indent it owes, and the default is
101
+ `clamp(0.75rem, 2.5vw, 1.5rem)` — 12px on a phone, 24px on a desktop — because a tree's depth is a
102
+ property of the data and cannot be known when the pattern is written. `--tree-indent` still
103
+ overrides it, and the `--lines` elbow derives from the same resolved value so the two cannot
104
+ disagree.
105
+
106
+ **Leaf rows now align with their branch siblings.** A branch spends a toggle column on its chevron
107
+ before its label; a leaf has none, so every leaf label sat one full column (24px, measured) to the
108
+ inline-start of its siblings and nothing at a given depth lined up. `.tree` exposes
109
+ `--_node-indent` (the toggle column) and `--_leaf-indent` (what a row without a toggle owes to
110
+ reach the same label column); `.tree__content` and `.tree__desc` both read the latter rather than
111
+ re-deriving the sum.
112
+
113
+ `<wc-tree>` also wraps its generated filter in `.input-group`, because `forms.css` styles text
114
+ controls as `.form-group > input` / `.input-group > input` — a bare `<input>` rendered with the
115
+ browser's 2px inset border and square corners next to the framework's own rounded controls.
116
+
117
+ `schemaTreeNodes(schema, { idPrefix, maxDepth, prune })` is new in `@getvitops/generator`: it walks
118
+ a JSON Schema — the same walk behind the `authoring.md` / `config.md` references — and returns tree
119
+ **data**, not markup, so each medium renders it (markdown for agents, an accessible `<details>`
120
+ tree for a site). Field ids are dotted config paths (`site.analytics.clarityId`), so any field can
121
+ be linked to directly.
122
+
123
+ `prune` exists for a specific hazard. The project config declares `designSystem.themes` as a
124
+ looser shape than `DesignSystemSchema`, because the full one is applied separately by
125
+ `resolveTheme` — so its embedded copy is an **approximation**, and measurably missing the
126
+ descriptions for `colors`, `colors.palette`, `colors.roles` and `colors.utilities`. Anything
127
+ rendering that copy as the token reference would silently document the colour system less well
128
+ than the toolchain already does; `prune` lets a caller stop at the wrapper and render `jsonSchema`
129
+ alongside instead.
130
+
131
+ `renderInlineMarkdown()` is exported for schema description text. It **lifts code spans out before
132
+ applying emphasis**, and that ordering is load-bearing rather than tidy: `colors.utilities`
133
+ describes its families as `` `bg-*` ``, `` `text-*` ``, `` `border-*` `` — literal asterisk
134
+ _wildcards_. Run emphasis over the raw string and the `*` closing `bg-*` pairs with the one
135
+ closing `text-*`, italicising the text between two unrelated utilities and eating both asterisks,
136
+ leaving prose that names families which don't exist. It also now renders single-asterisk emphasis,
137
+ which the schema does use (`*presentation*`, `*domain properties*`) and which previously printed
138
+ the asterisks literally.
139
+
140
+ Also fixed: `config.md` claimed "Only the wrapper is listed here" under `designSystem` and then
141
+ emitted the entire token schema anyway — `themes.<name>` _is_ a design system, so the walk
142
+ descended into it. It now stops at the wrapper and delegates to `authoring.md` as it always said
143
+ it did.
144
+
145
+ ### Patch Changes
146
+
147
+ - Updated dependencies [14813fa]
148
+ - Updated dependencies [c6b99e7]
149
+ - Updated dependencies [c6b99e7]
150
+ - Updated dependencies [f7bc0a0]
151
+ - Updated dependencies [14813fa]
152
+ - Updated dependencies [ceed51f]
153
+ - Updated dependencies [a9d7916]
154
+ - Updated dependencies [14813fa]
155
+ - Updated dependencies
156
+ - Updated dependencies [14813fa]
157
+ - @getvitops/generator@4.0.0
158
+ - @getvitops/utils@4.0.0
159
+ - @getvitops/core@4.0.0
160
+ - @getvitops/vite@4.0.0
161
+
162
+ ## 3.0.0
163
+
164
+ ### Major Changes
165
+
166
+ - 6e68ace: **Breaking:** the site config is now a three-section `Config` — `designSystem`,
167
+ `organization`, `site`.
168
+
169
+ The flat `SiteConfig` held the company (`organization`, `contact`, `locations`) and the
170
+ deployment (`analytics`, `environments`, `seo`, `legal`) as peers, so no single noun
171
+ described it, and a second site sharing the same company had no way to say so. The three
172
+ sections split those apart: several sites can now carry one `organization` and differ only
173
+ in `site`.
174
+
175
+ **Migrating.** `designSystem` stays at the root, and the fields already under
176
+ `organization` stay where they are. Everything else moves into one of two sections:
177
+ - → `site`: `defaultLocale`, `locales`, `domains`, `dns`, `cloudflare`, `environments`,
178
+ `abTesting`, `fonts`, `tags`, `postTypes`, `galleries`, `testimonials`, `templates`,
179
+ `navigation`, `seo`, `analytics`, `notifications`, `tracking`, `security`, `legal`,
180
+ `icons`, `favicon`, `deployment`
181
+ - → `organization`: `contact`, `primaryLocation`, `locations`, `services`, `links`
182
+
183
+ You do not have to work this out from the list: `vitops validate` detects a pre-3.0 flat
184
+ config and prints every move by name, rather than reporting a dozen unknown keys.
185
+
186
+ ```jsonc
187
+ {
188
+ "designSystem": {
189
+ "themes": {
190
+ "default": {
191
+ /* … */
192
+ },
193
+ },
194
+ },
195
+ "organization": {
196
+ "name": "Acme",
197
+ "contact": "hq",
198
+ "locations": {
199
+ "hq": {
200
+ /* … */
201
+ },
202
+ },
203
+ },
204
+ "site": {
205
+ "defaultLocale": "en",
206
+ "domains": {
207
+ /* … */
208
+ },
209
+ "analytics": {
210
+ /* … */
211
+ },
212
+ },
213
+ }
214
+ ```
215
+
216
+ **Renamed exports** (`@getvitops/generator`): `SiteConfigSchema` → `ConfigSchema`,
217
+ `SiteConfig` → `Config`, `validateSite` → `validateConfig`, `resolveSiteConfig` →
218
+ `resolveConfig`, `isSiteConfig` → `isConfig`, `siteJsonSchema` → `configJsonSchema`,
219
+ `SITE_SCHEMA_URL` → `CONFIG_SCHEMA_URL`, `SiteValidationResult` →
220
+ `ConfigValidationResult`. `ResolvedInput.site` is now `ResolvedInput.config`. New:
221
+ `OrganizationConfig` and `SiteSection` for the two sections.
222
+
223
+ **Renamed schema file:** `@getvitops/generator/site.schema.json` →
224
+ `@getvitops/generator/config.schema.json`. Update the `$schema` key in your config.
225
+
226
+ Option names are unchanged — `vitops({ site: { input } })`, the Vite plugin's `site`,
227
+ and `generate({ site })` still point at the config file.
228
+
229
+ **The Astro integration is now `vitops()`, not `getvitops()`.** It is a default export,
230
+ so the name is yours and nothing breaks on upgrade, but every example now reads
231
+ `import vitops from '@getvitops/astro'` — matching the Vite plugin, which has always been
232
+ `vitops`. The `@getvitops/*` package scope and the internal `virtual:getvitops/*` module
233
+ ids are unchanged; neither is an import name.
234
+
235
+ **Added:** a generated config authoring reference — `vitops docs config`, `docs/config.md`
236
+ in the OKF bundle, and _Config reference_ on the docs site. It is walked from the published
237
+ JSON Schema by the same helper that renders the `design-system.json` reference, so it
238
+ cannot describe a field validation does not accept.
239
+
240
+ - b115993: Nav shells, a top-layer animation driver, and a pile of fixes to things that never worked
241
+
242
+ ### Breaking
243
+ - **Two custom elements renamed.** `<copy-button>` → `<wc-copy>`, `<multi-field>` →
244
+ `<wc-multifield>`. Update your markup. The Bricks element keys
245
+ (`vitops-copy-button`, `vitops-multi-field`) are **unchanged**, so elements already
246
+ placed on a Bricks page keep working; so are the `--multi-field-*` custom properties
247
+ and the `multi-field-*` events.
248
+ - **`<details>` now animates open and closed** where `prefers-reduced-motion` allows.
249
+ It was previously instant by deliberate choice — the transition used to deadlock the
250
+ disclosure shut. Re-verified on Chrome 149 with a real click; both `block-size` and
251
+ `content-visibility` must stay in the transition list, and dropping the latter
252
+ reproduces the deadlock.
253
+ - **Drawers and dialogs now animate on close.** Both drove their entry with
254
+ `animation:` on `[open]`, which by construction plays once — so the close was
255
+ instant. They now use the top-layer driver and animate both ways.
256
+ - **`.rhythm` gives every non-heading block heading-spacing before a heading.** The
257
+ pairs used to enumerate `p` (later `p, pre, blockquote, table, dl, ul, ol`), so a
258
+ heading after anything else got paragraph spacing. They are now defined by what a
259
+ heading _is_ — `h1`–`h6` plus the `font-display` / `font-title` / `font-heading` type
260
+ roles — and inverted to `:not(<heading>) + <heading>`. Expect slightly more space
261
+ above headings that follow a code block, table, figure-like `<div>` or component.
262
+ - **`popover.css` no longer pins `[popover]:popover-open { opacity: 1 }`.** It never
263
+ animated anything on its own, but it outranked `.transition` and made every
264
+ top-layer fade impossible. Removing it is what lets the driver work.
265
+ - **`nav.css`'s `.drawer-menu` timing** now follows `--animation-duration` /
266
+ `--custom-ease-out` instead of hand-set 0.4s / 0.7s.
267
+
268
+ ### Fixed
269
+ - **`.sitenav--bp-sm` dropdowns could never open.** Its desktop block had drifted onto
270
+ an older markup shape, selecting `.sitenav__disclosure > .sitenav__submenu` where the
271
+ submenu is the disclosure's _sibling_. The four "intentionally parallel" breakpoint
272
+ blocks are now one shared block behind a style query — `md`/`lg`/`xl` were
273
+ byte-identical and only `sm` had rotted, which is exactly the drift the arrangement
274
+ invited. 583 → 361 lines.
275
+ - **Hover dropdowns rendered off-screen.** A closed popover is not in the top layer but
276
+ keeps the UA's `position: fixed`, and `.dropdown--show-on-hover` reset only `inset` —
277
+ so the panel faithfully faded in ~3300px from its trigger. Now anchored to it, and it
278
+ follows on scroll. Affects `.split-link--show-on-hover` too.
279
+ - **Horizontal overflow on narrow screens.** `.centered > *` floors at
280
+ `min-inline-size: 0`; `body` gets `overflow-wrap: break-word`; `patterns/code.css`
281
+ gains the `pre` rules it never had (`max-inline-size: 100%`, `overflow-x: auto`) and
282
+ gives inline `<code>` `overflow-wrap: anywhere`. Note a scroll container does _not_
283
+ zero its min-content contribution in Chrome, which is what made a single `<pre>` hold
284
+ a 390px viewport open at 797px.
285
+ - **`.split-<a>-<b>` now publishes `--_flex-direction: row`.** Only `.flex-*` did, so
286
+ `class="split flex-col md-split-1-2"` left the variable reading `column` at every
287
+ width and a nested `.grouped` collapsed its borders on the wrong axis.
288
+ - **`.toc-layout` uses `minmax(0, 1fr)`** instead of a bare `1fr`, whose automatic
289
+ minimum is min-content.
290
+
291
+ ### Added
292
+ - **`patterns/navshell.css` + `<NavShell>` / `<NavShellToggle>`** — a navigation aside
293
+ beside content at width, collapsing to a toggle and drawer below it. **It nests**: a
294
+ site nav wrapping an on-this-page nav, each promoting at its own breakpoint, via a
295
+ style query on an inherited flag rather than four copied blocks. Its content column
296
+ is a container, so an inner shell measures the space it actually has. The toggle can
297
+ live outside the shell (a site header) with `toggle="external"`.
298
+ - **`patterns/navbar.css`** — `.navbar` extracted from `nav.css`, where it was only
299
+ half of that file's drawer⇄navbar pair, plus `--start` / `--center` / `--end`,
300
+ `__spacer` and `--sticky` (old `.navbar-sticky` aliased).
301
+ - **A top-layer animation driver.** `animation.css` gained the fourth driver alongside
302
+ `animate-view` / `animate-scroll` / `animate-trigger` / `transition`, and every effect
303
+ gained an `open-<fx>` state variant. Overlays now state _where they start_
304
+ (`--translate-x-from`) instead of owning a keyframe: `class="drawer drawer--right
305
+ open-fade-in"` composes slide and fade. Applied at zero specificity with identity
306
+ defaults, so a popover that sets no effect vars is unchanged.
307
+ - **One scrim.** `--scrim` / `--scrim-filter` tokens and `.no-scrim` in `popover.css`,
308
+ replacing 18 `::backdrop` blocks across seven partials. `.drawer--modeless` is aliased.
309
+ - **`<wc-marquee>`** — clones the content enough times to cover the track, so every gap
310
+ matches including the seam. The CSS-only `.marquee` is unchanged and still works
311
+ without it; the element only makes the spacing right. `--marquee-gap` added.
312
+ - **`--width-nav`** joins `--width-measure` / `-breakout` / `-spotlight` as the nav
313
+ column width.
314
+ - **`.skip-link`** in `patterns/anchor-link.css`, using a clip rather than the
315
+ `-100vw` idiom (which overflows in RTL and ignores the scrollbar gutter).
316
+ - **`.table-wrapper`** documented as the scroll wrapper for wide tables.
317
+
318
+ ### Notes
319
+ - `patterns/nav.css` is marked legacy. Its header promised a Lit nav component that was
320
+ never written and is not planned — the house pattern is native. Use `navbar`,
321
+ `sitenav` or `navshell`; removal is a later change.
322
+ - `scroll-target.css`'s `.is-current` no longer claims to be a JS scroll-spy fallback.
323
+ There is no such code; `:target-current` is the only working highlight, which today
324
+ means Chrome.
325
+ - `elements.js` gains one element (`wc-marquee`), so the shared bundle is slightly
326
+ larger for every consumer.
327
+ - A registered custom property's `initial-value` must be computationally independent —
328
+ `16rem` is not, so `@property` silently drops the whole rule. `navshell` uses an
329
+ inline fallback instead.
330
+
331
+ ### Patch Changes
332
+
333
+ - Updated dependencies [6e68ace]
334
+ - Updated dependencies [b115993]
335
+ - @getvitops/generator@3.0.0
336
+ - @getvitops/utils@3.0.0
337
+ - @getvitops/core@3.0.0
338
+ - @getvitops/vite@3.0.0
339
+
3
340
  ## 2.1.0
4
341
 
5
342
  ### Minor Changes
package/README.md CHANGED
@@ -171,7 +171,7 @@ weighs `lastmod` only while it stays consistent with what actually changed:
171
171
  - **A shallow clone gets nothing, loudly.** It shells out to `git`, so `fetch-depth: 1` (the
172
172
  actions/checkout default) yields no history — it warns and emits no dates. Set `fetch-depth: 0`.
173
173
 
174
- This is also what makes `vitops indexing` able to submit only what changed, rather than everything on
174
+ This is also what makes `vitops search notify` able to submit only what changed, rather than everything on
175
175
  every deploy.
176
176
 
177
177
  ## `<Seo />`
@@ -363,7 +363,7 @@ Behaviour worth knowing:
363
363
  ### Keep it in step with your cookie notice
364
364
 
365
365
  `vitops legal` derives the privacy policy and cookie notice from your **site config**, and
366
- `getvitops({ analytics })` is a separate surface. Declare each provider in both:
366
+ `vitops({ analytics })` is a separate surface. Declare each provider in both:
367
367
 
368
368
  ```jsonc
369
369
  // site config — what the documents disclose
package/dist/index.d.mts CHANGED
@@ -131,7 +131,7 @@ interface ResolvedAnalytics {
131
131
  warnings: string[];
132
132
  }
133
133
  interface ResolveAnalyticsContext {
134
- /** Is the consent gate enabled on this site (`getvitops({ consent })`)? */
134
+ /** Is the consent gate enabled on this site (`vitops({ consent })`)? */
135
135
  consent?: boolean;
136
136
  }
137
137
  /**
@@ -162,11 +162,11 @@ type SeoTwitterCard = 'summary' | 'summary_large_image' | 'app' | 'player';
162
162
  /** Open Graph object types this component knows how to describe. */
163
163
  type SeoOgType = 'website' | 'article' | 'profile';
164
164
  /**
165
- * Site-level SEO defaults, passed to `getvitops({ seo })` and baked into the
165
+ * Site-level SEO defaults, passed to `vitops({ seo })` and baked into the
166
166
  * `virtual:getvitops/head` module. Per-page `<Seo />` props override these.
167
167
  *
168
168
  * The vocabulary mirrors the site-config schema's `seo` block
169
- * (`@getvitops/generator`, `src/site.ts`) so a `SiteConfig` → these adapter would
169
+ * (`@getvitops/generator`, `src/config.ts`) so a `Config` → these adapter would
170
170
  * be a flat field map — but it is not imported from there. This is the
171
171
  * integration's own option surface, and it must stay JSON-serialisable: it is
172
172
  * `JSON.stringify`d into the virtual module, so no functions, no `URL`s, no dates.
@@ -324,6 +324,57 @@ interface SeoContext {
324
324
  */
325
325
  declare function resolveSeo(defaults: GetvitopsSeoOptions, props: SeoProps, ctx: SeoContext): ResolvedSeo;
326
326
  //#endregion
327
+ //#region src/tracking.d.ts
328
+ /**
329
+ * The `<Tracking />` resolution layer — tracking config in, what to emit out.
330
+ *
331
+ * Separate from `Tracking.astro` for the same reason `analytics.ts` is separate
332
+ * from `Analytics.astro`: everything decidable is a pure function asserted in
333
+ * `tracking.test.ts`, and the component only renders what this returns.
334
+ *
335
+ * The one decision here is **which consent category the `_ac` cookie waits on**,
336
+ * and it is stated rather than inferred. `_ac` is a 90-day identifier tying a
337
+ * visitor to the ad that brought them, so `marketing` is the default — but a site
338
+ * using click IDs purely for its own campaign reporting may reasonably file it
339
+ * under `analytics`, and that is the consumer's call to make, not ours to guess.
340
+ */
341
+ /** Which consent category the attribution cookie waits on. */
342
+ type TrackingCategory = 'marketing' | 'analytics';
343
+ interface GetvitopsTrackingOptions {
344
+ /** Capture ad click IDs and UTMs into `_ac`. */
345
+ enabled?: boolean;
346
+ /** Default `marketing`. */
347
+ category?: TrackingCategory;
348
+ /** Informational; capture recognises every known click-ID parameter regardless. */
349
+ platforms?: string[];
350
+ }
351
+ /** The cookie the capture script writes. Mirrors `TRACKING_COOKIE` in utils. */
352
+ declare const TRACKING_COOKIE = "_ac";
353
+ interface ResolvedTracking {
354
+ enabled: boolean;
355
+ category: TrackingCategory;
356
+ /** Cookie names to clear on revoke — rides on `data-consent-cookies`. */
357
+ cookies: string[];
358
+ /** Configuration problems, as prose. The integration logs these. */
359
+ warnings: string[];
360
+ }
361
+ interface ResolveTrackingContext {
362
+ /** Is the consent gate enabled on this site (`vitops({ consent })`)? */
363
+ consent?: boolean;
364
+ /** Categories the banner offers, so we can catch a demand with no row. */
365
+ consentCategories?: readonly string[];
366
+ }
367
+ /**
368
+ * Resolve the tracking config into what the component emits.
369
+ *
370
+ * Two warnings, both about the same failure — a persistent identifier written
371
+ * with no way for the visitor to decline, or a permission asked for with no way
372
+ * to answer. Returned as data rather than logged here so the check is a test
373
+ * rather than a line someone might scroll past, exactly as `resolveAnalytics`
374
+ * does.
375
+ */
376
+ declare function resolveTracking(opts: GetvitopsTrackingOptions | undefined, ctx?: ResolveTrackingContext): ResolvedTracking;
377
+ //#endregion
327
378
  //#region src/integration.d.ts
328
379
  interface GetvitopsFaviconOptions {
329
380
  /** Source SVG or PNG. */
@@ -400,13 +451,13 @@ interface GetvitopsCssOptions {
400
451
  *
401
452
  * Off by default: turning it on flips the site dark for dark-OS visitors, which
402
453
  * is a visible change to an existing site. Turning it **on** is what makes
403
- * `<color-scheme-toggle>`'s "System" position do anything (System removes the
454
+ * `<wc-color-scheme-toggle>`'s "System" position do anything (System removes the
404
455
  * theme attribute, so without this block it falls through to light), and it is
405
456
  * the only way a no-JS page gets the OS appearance at all.
406
457
  *
407
458
  * The site config's `designSystem.defaultColorScheme: "system"` says the same thing and is the
408
459
  * better home for it when you have one — this option wins if both are set, and
409
- * exists because requiring a whole `SiteConfig` to set one boolean would be out
460
+ * exists because requiring a whole `Config` to set one boolean would be out
410
461
  * of proportion.
411
462
  */
412
463
  systemColorScheme?: boolean;
@@ -498,7 +549,7 @@ interface GetvitopsOptions {
498
549
  /**
499
550
  * Your site config — the one place to name it.
500
551
  *
501
- * A `SiteConfig` records site-level facts, several of which other options here
552
+ * A `Config` records site-level facts, several of which other options here
502
553
  * need: `designSystem.defaultColorScheme` decides whether the generated colour layer
503
554
  * carries a `prefers-color-scheme` block, `fonts` can supply the webfont
504
555
  * declarations, and `legal` renders from it. Set this and each of those reads
@@ -570,7 +621,7 @@ interface GetvitopsOptions {
570
621
  * `cssVariable` rather than at a literal stack the browser has no file for:
571
622
  *
572
623
  * ```js
573
- * getvitops({ fonts: [{ name: 'League Spartan', provider: 'fontsource',
624
+ * vitops({ fonts: [{ name: 'League Spartan', provider: 'fontsource',
574
625
  * cssVariable: '--font-league-spartan',
575
626
  * weights: ['100 900'], subsets: ['latin'], preload: true }] })
576
627
  * ```
@@ -663,6 +714,21 @@ interface GetvitopsOptions {
663
714
  * actually offers.
664
715
  */
665
716
  consent?: boolean | GetvitopsConsentOptions;
717
+ /**
718
+ * Ad-click attribution for `<Tracking />` — capture click IDs and UTMs from the
719
+ * landing URL into the `_ac` cookie, so a conversion can be attributed to the
720
+ * ad that produced it. Off unless provided.
721
+ *
722
+ * `_ac` is a 90-day identifier, so writing it waits on consent (`marketing` by
723
+ * default) — and **asking for that permission is what raises the banner**, on
724
+ * the arrival that carried a click ID and on no other. A visitor who arrives
725
+ * organically has nothing to attribute and is never asked.
726
+ *
727
+ * Read the cookie back with `parseTrackingCookie` from
728
+ * `@getvitops/utils/tracking`, and turn a conversion into a notification with
729
+ * `@getvitops/utils/notify`.
730
+ */
731
+ tracking?: boolean | GetvitopsTrackingOptions;
666
732
  }
667
733
  interface GetvitopsFontsOptions {
668
734
  /** Path to a site config (JSON) whose `fonts` array holds the declarations. */
@@ -716,7 +782,7 @@ interface GetvitopsIconsOptions {
716
782
  /** Aliases applied before the semantic map — legacy names, or values stored in CMS content. */
717
783
  overrides?: Record<string, string>;
718
784
  }
719
- declare function getvitops(opts?: GetvitopsOptions): AstroIntegration;
785
+ declare function vitops(opts?: GetvitopsOptions): AstroIntegration;
720
786
  //#endregion
721
787
  //#region src/lastmod.d.ts
722
788
  interface GitLastmodOptions {
@@ -747,5 +813,5 @@ declare function slugFromContent(file: string): string | undefined;
747
813
  */
748
814
  declare function gitLastmod(options?: GitLastmodOptions): Promise<(item: GetvitopsSitemapEntry) => GetvitopsSitemapEntry>;
749
815
  //#endregion
750
- export { type AnalyticsStrategy, type ClarityOptions, type ConsentCategory, type GetvitopsAnalyticsOptions, type GetvitopsConsentOptions, type GetvitopsCssOptions, type GetvitopsFaviconOptions, type GetvitopsMediaOptions, type GetvitopsOptions, type GetvitopsSeoOptions, type GetvitopsSitemapChangeFreq, type GetvitopsSitemapEntry, type GetvitopsSitemapOptions, type GitLastmodOptions, type GoogleAnalyticsOptions, type MatomoOptions, type OptionalConsentCategory, type PlausibleOptions, type ResolveAnalyticsContext, type ResolvedAnalytics, type ResolvedSeo, type ResolvedTag, type SeoContext, type SeoNameTag, type SeoOgType, type SeoPropertyTag, type SeoProps, type SeoTwitterCard, consentCategories, getvitops as default, gitLastmod, resolveAnalytics, resolveSeo, routeFromPage, slugFromContent };
816
+ export { type AnalyticsStrategy, type ClarityOptions, type ConsentCategory, type GetvitopsAnalyticsOptions, type GetvitopsConsentOptions, type GetvitopsCssOptions, type GetvitopsFaviconOptions, type GetvitopsMediaOptions, type GetvitopsOptions, type GetvitopsSeoOptions, type GetvitopsSitemapChangeFreq, type GetvitopsSitemapEntry, type GetvitopsSitemapOptions, type GetvitopsTrackingOptions, type GitLastmodOptions, type GoogleAnalyticsOptions, type MatomoOptions, type OptionalConsentCategory, type PlausibleOptions, type ResolveAnalyticsContext, type ResolveTrackingContext, type ResolvedAnalytics, type ResolvedSeo, type ResolvedTag, type ResolvedTracking, type SeoContext, type SeoNameTag, type SeoOgType, type SeoPropertyTag, type SeoProps, type SeoTwitterCard, TRACKING_COOKIE, type TrackingCategory, consentCategories, vitops as default, gitLastmod, resolveAnalytics, resolveSeo, resolveTracking, routeFromPage, slugFromContent };
751
817
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/analytics.ts","../src/seo.ts","../src/integration.ts","../src/lastmod.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/analytics.ts","../src/seo.ts","../src/tracking.ts","../src/integration.ts","../src/lastmod.ts"],"mappings":"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"}