@getvitops/cli 8.1.0 → 8.2.0-alpha.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 +216 -14
- package/dist/cli.d.mts +1 -1
- package/dist/cli.mjs +657 -29
- package/dist/cli.mjs.map +1 -1
- package/package.json +4 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,202 @@
|
|
|
1
1
|
# @getvitops/cli
|
|
2
2
|
|
|
3
|
+
## 8.2.0-alpha.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 0574388: Add `site.crm` — push form submissions into HubSpot, Zoho Bigin, or Jobber.
|
|
8
|
+
|
|
9
|
+
Client sites need form submissions to land in the client's CRM. The options available before this
|
|
10
|
+
— a HubSpot/Bigin/Jobber iframe or JS embed — fail on three counts: the markup can't be
|
|
11
|
+
white-labelled against this design system, nothing can operate on the submission before it leaves
|
|
12
|
+
the page, and the submission never touched `createConversionRoute()`, so `_ac` ad-click attribution
|
|
13
|
+
was lost and no conversion notification was planned.
|
|
14
|
+
|
|
15
|
+
This adds one server-side path for all three CRMs, hung off the conversion route that already
|
|
16
|
+
exists. `createConversionRoute()` gets a new `crm` option (`{ config, credentials, fetch?,
|
|
17
|
+
timeoutMs? }`); credentials arrive as a function of `locals`, exactly like the existing `binding`
|
|
18
|
+
option, and are never config. A failed CRM write never fails the request and is folded into the
|
|
19
|
+
notification email's new "Delivery" section, so a broken CRM token is never silent.
|
|
20
|
+
|
|
21
|
+
New `@getvitops/utils/crm` subpath: `deliverToCrm()`, `mapSubmission()`, `deriveLastName()` (Bigin
|
|
22
|
+
requires a last name; this derives one from an explicit field, a full name, or an email address,
|
|
23
|
+
refusing rather than fabricating one), `submitToHubSpot()`, `submitToBigin()`, `submitToJobber()`.
|
|
24
|
+
`identifySubmitter()` was promoted out of `notify`'s private name-guessing cascade into
|
|
25
|
+
`@getvitops/utils/tracking`, since the CRM mapper needed the whole identity (first/last name,
|
|
26
|
+
email, phone, company), not just a display name.
|
|
27
|
+
|
|
28
|
+
Jobber is GraphQL, not REST, and answers `200 OK` for failures — a rejected `clientCreate` returns
|
|
29
|
+
`userErrors[]`, a malformed request returns top-level `errors[]`. `submitToJobber()` classifies on
|
|
30
|
+
the response body, not just the status. Its refresh tokens also rotate by default: **Refresh Token
|
|
31
|
+
Rotation must be turned off** in the app's Developer Center settings, since a Worker reading a
|
|
32
|
+
static `VITOPS_JOBBER_REFRESH_TOKEN` cannot persist a rotated one — a rotated token is detected at
|
|
33
|
+
exchange time and reported with the fix, rather than surfacing an hour later as an opaque 401.
|
|
34
|
+
Attribution and unmapped extra fields render into a best-effort note by default (works on every
|
|
35
|
+
Jobber plan); a resubmitting visitor creates a second Jobber client unless `crm.jobber.dedupe: true`
|
|
36
|
+
is set once its lookup query has been verified against a live account (defaults `false` pending
|
|
37
|
+
that verification — see `jobber.ts`'s docblock).
|
|
38
|
+
|
|
39
|
+
New `site.crm` config block (`provider`, `hubspot`/`bigin`/`jobber`, `fieldMap`, `trackingFields`)
|
|
40
|
+
and two CLI commands: `vitops crm check` (fetches the live HubSpot property list or Bigin field
|
|
41
|
+
list and reports every mapped name that doesn't exist there — HubSpot rejects an unknown field
|
|
42
|
+
outright, Bigin silently drops it; Jobber has nothing live to check yet, since its mapped values
|
|
43
|
+
currently render as note text) and `vitops crm setup` (creates missing HubSpot properties; Bigin
|
|
44
|
+
and Jobber have no such API, so both always print a manual reminder).
|
|
45
|
+
|
|
46
|
+
The generated privacy policy now names HubSpot, Zoho Bigin, or Jobber when `site.crm` configures
|
|
47
|
+
one. Bigin gets the same cross-border-transfer derivation Matomo Cloud already gets: a
|
|
48
|
+
`dataCenter: 'ca'` asserts no transfer outside Canada, any other data centre does. Jobber's
|
|
49
|
+
operator (Octopusapp Inc. d/b/a Jobber) is Canadian, but its own privacy policy names the United
|
|
50
|
+
States as a processing location too, so the policy always asserts a cross-border transfer for
|
|
51
|
+
Jobber regardless of config — a Canadian operator is not read as Canadian-only storage.
|
|
52
|
+
|
|
53
|
+
Credentials: `VITOPS_HUBSPOT_ACCESS_TOKEN` for HubSpot; `VITOPS_ZOHO_CLIENT_ID` /
|
|
54
|
+
`VITOPS_ZOHO_CLIENT_SECRET` / `VITOPS_ZOHO_REFRESH_TOKEN` for Bigin; `VITOPS_JOBBER_CLIENT_ID` /
|
|
55
|
+
`VITOPS_JOBBER_CLIENT_SECRET` / `VITOPS_JOBBER_REFRESH_TOKEN` for Jobber. Never config.
|
|
56
|
+
|
|
57
|
+
No consumer-facing change in `@getvitops/astro` beyond the new `crm` route option and a build
|
|
58
|
+
warning when `site.crm` is configured with no route answering `TRACKING_ENDPOINT` — CSS/Bricks/
|
|
59
|
+
tailwind outputs are unaffected.
|
|
60
|
+
|
|
61
|
+
- 0574388: Add `vitops email setup|check` — connect `site.notifications.email.from` to whether its domain is
|
|
62
|
+
actually onboarded onto an outbound email provider.
|
|
63
|
+
|
|
64
|
+
Before this, nothing checked that. `EMAIL.send()` throws `E_SENDER_NOT_VERIFIED` at runtime with no
|
|
65
|
+
build or deploy-time warning — the failure mode is silent and production-only.
|
|
66
|
+
|
|
67
|
+
`vitops email setup [domain]` onboards a sending domain (currently Cloudflare Email Sending only)
|
|
68
|
+
and polls DNS until its SPF/DKIM/DMARC records resolve or a timeout is reached; `vitops email
|
|
69
|
+
check` is the non-blocking deploy guard both `@getvitops/create` templates' `deploy`/`deploy:dev`
|
|
70
|
+
scripts now run first (`--strict` makes it a real gate; opt out per-site with
|
|
71
|
+
`site.notifications.email.verifySender: false`, or globally with `--skip` /
|
|
72
|
+
`VITOPS_SKIP_EMAIL_CHECK`).
|
|
73
|
+
|
|
74
|
+
Two things worth knowing before running it:
|
|
75
|
+
- **The onboarded entity is an exact name, and it is usually a subdomain**
|
|
76
|
+
(`send.yourdomain.com`), never the apex your `from` address names. When the exact domain isn't
|
|
77
|
+
onboarded but a sibling in the same zone already is, the command reports that as the fix — send
|
|
78
|
+
from the onboarded subdomain — rather than silently trying to onboard the apex, which rewrites
|
|
79
|
+
`_dmarc.<domain>` and can tighten DMARC policy on every other mail your domain sends.
|
|
80
|
+
- Candidates come from `site.notifications.email.from` (or its derived `noreply@<domains
|
|
81
|
+
.canonical>` default) first; a best-effort scan of `--src` only supplements it, and never guesses
|
|
82
|
+
at a computed `from` value.
|
|
83
|
+
|
|
84
|
+
New `@getvitops/utils/email` subpath and `site.notifications.email.verifySender` config field.
|
|
85
|
+
Needs `CLOUDFLARE_API_TOKEN` with an Email Sending scope in addition to the `Zone:Read` other
|
|
86
|
+
commands already use.
|
|
87
|
+
|
|
88
|
+
### Patch Changes
|
|
89
|
+
|
|
90
|
+
- c3c1bcb: **New: the design-system editor, mounted inside the EmDash admin.** `vitopsEmdash({
|
|
91
|
+
designSystemEditor: { config } })` (`config` is your `site.json`, e.g. `import config from
|
|
92
|
+
'./site.json' with { type: 'json' }`) adds a `/design-system` admin page mounting
|
|
93
|
+
`<wc-theme-editor>` — the same live token editor `@getvitops/vite`'s dev server has always
|
|
94
|
+
offered, now usable by the client directly, no dev server required. An edit is visible
|
|
95
|
+
site-wide immediately (a runtime `:root` override, served via a new plugin API route and
|
|
96
|
+
`page:fragments`) and — once `site.deployment.repo`/`branch` and a `VITOPS_GITHUB_TOKEN`
|
|
97
|
+
secret are set (see the scaffold's `SETUP.html`) — auto-commits to your `dev` branch, so it
|
|
98
|
+
reaches the git-tracked `site.json` through your repo's normal review path rather than
|
|
99
|
+
becoming a second, unreviewed source of truth. Until that's configured, the live half still
|
|
100
|
+
works; only the auto-commit half is skipped (and says so in the admin page). The save route
|
|
101
|
+
runs the exact same accessibility (APCA contrast) gate `generate()` enforces at build time,
|
|
102
|
+
synchronously, before persisting — nothing non-compliant ever goes live even momentarily.
|
|
103
|
+
|
|
104
|
+
Requires `@astrojs/react` + `react` + `react-dom` (already scaffold dependencies, for
|
|
105
|
+
EmDash's own admin) and `@getvitops/core` (added as a new scaffold dependency this release).
|
|
106
|
+
Declares two new plugin capabilities when enabled: `network:request` (for the GitHub
|
|
107
|
+
auto-commit) and `hooks.page-fragments:register` (for the live override) — reviewed once at
|
|
108
|
+
plugin-install time.
|
|
109
|
+
|
|
110
|
+
**Breaking for `@getvitops/emdash`**: `vitopsEmdash()`'s `hooks.page-fragments:register`
|
|
111
|
+
capability is now also granted whenever `designSystemEditor` is set, independent of the
|
|
112
|
+
existing `scripts: 'fragments'` option (which governs something unrelated — web-component
|
|
113
|
+
script delivery). No change if you don't use `designSystemEditor`.
|
|
114
|
+
|
|
115
|
+
Also new, supporting the above:
|
|
116
|
+
- `@getvitops/generator`: `validateColorContract()` and `buildReverseIndex()` (both
|
|
117
|
+
`/tokens` subpath, Worker-safe) — the monotonicity/contrast gate and the
|
|
118
|
+
`design-manifest.json` reverse-index, each extracted from `generate()`'s `build()` into
|
|
119
|
+
standalone, non-throwing functions. `patchToOverrideCss()` turns a design-system patch
|
|
120
|
+
into the `:root` override `<style>` block. `designSystemPath`/`getAt`/`setAt`/
|
|
121
|
+
`mergePatch`/`formatConfig` moved from `@getvitops/vite` into `@getvitops/generator/config`
|
|
122
|
+
(re-exported from `@getvitops/vite` unchanged) — one "patch a config file's design-system
|
|
123
|
+
subtree" implementation shared by the dev endpoint and the new plugin route. New
|
|
124
|
+
`site.deployment.repo`/`branch` config fields.
|
|
125
|
+
- `@getvitops/utils`: new `/git` subpath — `commitFile()`, a Worker-safe (fetch-only)
|
|
126
|
+
wrapper over GitHub's Contents API.
|
|
127
|
+
- `@getvitops/core`: `<wc-theme-editor>` gains a `save-endpoint` attribute (default
|
|
128
|
+
unchanged — `/__vitops/design-system`) so the same element can target the new plugin
|
|
129
|
+
route instead of the dev-only Vite endpoint.
|
|
130
|
+
|
|
131
|
+
- 0574388: Bump `emdash`/`@emdash-cms/cloudflare` peers to `>=1.0.0 <2` and `vite-plus` to `^1.0.0`, following
|
|
132
|
+
both projects' GA releases.
|
|
133
|
+
|
|
134
|
+
**Breaking for `@getvitops/emdash` consumers on EmDash 0.x**: the peer range no longer admits
|
|
135
|
+
`emdash@0.31.x`/`@emdash-cms/cloudflare@0.31.x`. Upgrade `emdash` and `@emdash-cms/cloudflare` to
|
|
136
|
+
`^1.0.1` first — nothing in `@getvitops/emdash`'s own plugin surface (`admin.portableTextBlocks`,
|
|
137
|
+
the `hooks.page-fragments:register` capability, `definePlugin()`) changed against EmDash 1.0, so no
|
|
138
|
+
code here needed to change, only the declared range.
|
|
139
|
+
|
|
140
|
+
The `emdash` scaffold template (`vp create @getvitops:emdash`) picks up several fixes alongside
|
|
141
|
+
the version bump:
|
|
142
|
+
- `tailwindcss`/`@tailwindcss/vite` are now real dependencies — the template selected
|
|
143
|
+
`css.format: 'tailwind'` without installing either, which threw on build.
|
|
144
|
+
- `site.json` now sets `site.icons.sprite: true` plus the full `semantic` list the
|
|
145
|
+
`vitops.actionLink` block's icon picker offers — previously its sprite icons pointed at a file
|
|
146
|
+
the build never generated.
|
|
147
|
+
- `astro.config.mjs` sets `migrations: { runtime: 'check', dev: 'auto' }`, and
|
|
148
|
+
`site-deploy-emdash.yml` runs EmDash 1.0's documented `build → status → apply → deploy → check`
|
|
149
|
+
migration sequence explicitly, rather than relying solely on first-request auto-migration. This
|
|
150
|
+
needs a new GitHub Environment variable, `EMDASH_TARGET_FINGERPRINT` (one per environment),
|
|
151
|
+
which only a human can set — run `emdash migrate --status` against the real deployed database,
|
|
152
|
+
review the printed identity, then `gh variable set EMDASH_TARGET_FINGERPRINT --env <env> --body
|
|
153
|
+
<value>`. Deploys fail clearly on the migration-apply step until it's set.
|
|
154
|
+
- `lint.options.typeAware`/`typeCheck` in the template's own `vite.config.ts` are commented out,
|
|
155
|
+
not deleted: vite-plus 1.0 only honours that option in a project's actual root config, and hard
|
|
156
|
+
errors on it in a nested one (which this file is, sitting inside the `design-system` monorepo).
|
|
157
|
+
Uncomment it once scaffolded into its own repo.
|
|
158
|
+
|
|
159
|
+
No config schema changes. `@getvitops/generator` also switches from the `zod/mini` subpath import
|
|
160
|
+
to the standalone `@zod/mini` package (zod 4.5+; same API) and fixes `validateConfig()` silently
|
|
161
|
+
losing the offending key name on an `unrecognized_keys` error (e.g. a typo'd `site.ads` platform
|
|
162
|
+
now names the bad key instead of reporting a bare "Invalid input").
|
|
163
|
+
|
|
164
|
+
Also fixed: `vp check`'s `tsconfig-error` for `packages/create/templates/emdash/tsconfig.json`
|
|
165
|
+
(`extends: "astro/tsconfigs/strict"`, unresolvable from inside this monorepo since the template
|
|
166
|
+
has no `node_modules` of its own — a pre-existing, structural gap, newly surfaced as a hard error
|
|
167
|
+
by oxlint 1.85's deeper config discovery, and blocking on every commit since this repo's pre-commit
|
|
168
|
+
hook runs `vp check --fix`). Fixed with a new `scripts/link-template-deps.mjs`, wired as the root
|
|
169
|
+
`postinstall` script: symlinks `astro`/`emdash`/`@emdash-cms/cloudflare` into the template's own
|
|
170
|
+
`node_modules/` (resolved fresh from sibling packages that already depend on them for real, not a
|
|
171
|
+
hardcoded `.pnpm` hash) and writes a minimal `astro:content` ambient shim at `.astro/types.d.ts`
|
|
172
|
+
(the same path `astro sync` would generate for real). Both are gitignored and only ever exist
|
|
173
|
+
inside this monorepo's copy of the template — a real scaffold installs its own real copies instead.
|
|
174
|
+
Considered and rejected first: inlining astro's strict preset (drift risk against astro's own
|
|
175
|
+
evolving default) and making the template a real pnpm workspace member (would change how its
|
|
176
|
+
`@getvitops/*: "latest"` deps resolve locally, which `templates.test.ts` exists to protect).
|
|
177
|
+
|
|
178
|
+
**Known gap, not fixed here**: `packages/astro/src/components/container.test.ts` (the
|
|
179
|
+
`AstroContainer`-based render tests) fails to even load under vite-plus 1.0's Vite 8 — direct
|
|
180
|
+
`.astro` imports in a Vitest file need the Astro Vite plugin registered, which nothing in this
|
|
181
|
+
repo's test config actually does (Astro's own docs call for `getViteConfig()`, which doesn't
|
|
182
|
+
compose with vite-plus's own `defineConfig`). A type-level shim
|
|
183
|
+
(`packages/astro/src/components/astro-modules.d.ts`) fixes `vp check`'s type-aware pass, but the
|
|
184
|
+
runtime `vp test` failure for this one file is still open.
|
|
185
|
+
|
|
186
|
+
- Updated dependencies [65a13cc]
|
|
187
|
+
- Updated dependencies [67e2088]
|
|
188
|
+
- Updated dependencies [0574388]
|
|
189
|
+
- Updated dependencies [c3c1bcb]
|
|
190
|
+
- Updated dependencies [0574388]
|
|
191
|
+
- Updated dependencies [0574388]
|
|
192
|
+
- Updated dependencies [0574388]
|
|
193
|
+
- Updated dependencies [1a3e811]
|
|
194
|
+
- Updated dependencies [0574388]
|
|
195
|
+
- Updated dependencies [dde3df3]
|
|
196
|
+
- Updated dependencies [d9f213b]
|
|
197
|
+
- @getvitops/generator@8.2.0-alpha.0
|
|
198
|
+
- @getvitops/utils@8.2.0-alpha.0
|
|
199
|
+
|
|
3
200
|
## 8.1.0
|
|
4
201
|
|
|
5
202
|
### Minor Changes
|
|
@@ -54,7 +251,6 @@
|
|
|
54
251
|
|
|
55
252
|
**Breaking (`css`/`bricks` and `tailwind` formats — `.lightbox-dialog`'s markup
|
|
56
253
|
contract changed):**
|
|
57
|
-
|
|
58
254
|
- `<Gallery />` now emits ONE `<dialog class="lightbox-dialog">` per gallery,
|
|
59
255
|
wrapping a `<Carousel />`, instead of one dialog per image. A `.gallery__trigger`
|
|
60
256
|
is now a plain `<a href="#slide-id">`, not a `command="show-modal"` button.
|
|
@@ -95,7 +291,6 @@
|
|
|
95
291
|
### Minor Changes
|
|
96
292
|
|
|
97
293
|
- Add Google Business Profile reviews: fetch, cache, render.
|
|
98
|
-
|
|
99
294
|
- **`vitops reviews`** (new CLI command) fetches a client's GBP reviews (legacy v4 API — the only
|
|
100
295
|
one that has them) and writes them to `.vitops/reviews.json`, meant to be committed so a build
|
|
101
296
|
never needs a live Google credential. `--dry` prints the plan; `--check` diffs against the cache
|
|
@@ -130,7 +325,6 @@
|
|
|
130
325
|
`--site` for now.)
|
|
131
326
|
|
|
132
327
|
**Fixed:**
|
|
133
|
-
|
|
134
328
|
- `@getvitops/core`'s 12 runtime deps (`lit`, both `@oddbird` polyfills, both
|
|
135
329
|
`@webcomponents` packages, `colorjs.io`, etc.) were listed as `dependencies` despite
|
|
136
330
|
being bundled into `dist/elements.js`/`dist/polyfills.js`/`dist/deferred.js` — a
|
|
@@ -817,20 +1011,28 @@ carousel vocabulary, because they render live from the generator.
|
|
|
817
1011
|
{
|
|
818
1012
|
"designSystem": {
|
|
819
1013
|
"themes": {
|
|
820
|
-
"default": {
|
|
1014
|
+
"default": {
|
|
1015
|
+
/* … */
|
|
1016
|
+
},
|
|
821
1017
|
},
|
|
822
1018
|
},
|
|
823
1019
|
"organization": {
|
|
824
1020
|
"name": "Acme",
|
|
825
1021
|
"contact": "hq",
|
|
826
1022
|
"locations": {
|
|
827
|
-
"hq": {
|
|
1023
|
+
"hq": {
|
|
1024
|
+
/* … */
|
|
1025
|
+
},
|
|
828
1026
|
},
|
|
829
1027
|
},
|
|
830
1028
|
"site": {
|
|
831
1029
|
"defaultLocale": "en",
|
|
832
|
-
"domains": {
|
|
833
|
-
|
|
1030
|
+
"domains": {
|
|
1031
|
+
/* … */
|
|
1032
|
+
},
|
|
1033
|
+
"analytics": {
|
|
1034
|
+
/* … */
|
|
1035
|
+
},
|
|
834
1036
|
},
|
|
835
1037
|
}
|
|
836
1038
|
```
|
|
@@ -906,7 +1108,7 @@ carousel vocabulary, because they render live from the generator.
|
|
|
906
1108
|
Also new, and worth wiring at the same time — **`gitLastmod()` for real sitemap dates**:
|
|
907
1109
|
|
|
908
1110
|
```js
|
|
909
|
-
import vitops, { gitLastmod } from
|
|
1111
|
+
import vitops, { gitLastmod } from '@getvitops/astro';
|
|
910
1112
|
vitops({ sitemap: { serialize: await gitLastmod() } });
|
|
911
1113
|
```
|
|
912
1114
|
|
|
@@ -1000,7 +1202,7 @@ ffmpeg`, `apt install ffmpeg`, `winget install Gyan.FFmpeg`). The command fails
|
|
|
1000
1202
|
|
|
1001
1203
|
```js
|
|
1002
1204
|
// astro.config.mjs
|
|
1003
|
-
getvitops({ css: { input:
|
|
1205
|
+
getvitops({ css: { input: 'company.json', format: 'css' } });
|
|
1004
1206
|
```
|
|
1005
1207
|
|
|
1006
1208
|
```
|
|
@@ -1487,15 +1689,15 @@ ffmpeg`, `apt install ffmpeg`, `winget install Gyan.FFmpeg`). The command fails
|
|
|
1487
1689
|
which `@getvitops/astro` re-exports wholesale. So from `astro.config.mjs`:
|
|
1488
1690
|
|
|
1489
1691
|
```js
|
|
1490
|
-
import { generateIconInclude } from
|
|
1491
|
-
import icon from
|
|
1692
|
+
import { generateIconInclude } from '@getvitops/astro';
|
|
1693
|
+
import icon from 'astro-icon';
|
|
1492
1694
|
|
|
1493
1695
|
integrations: [
|
|
1494
1696
|
icon({
|
|
1495
1697
|
include: generateIconInclude({
|
|
1496
|
-
ui:
|
|
1497
|
-
brand:
|
|
1498
|
-
semantic: [
|
|
1698
|
+
ui: 'fa7-solid',
|
|
1699
|
+
brand: 'simple-icons',
|
|
1700
|
+
semantic: ['menu', 'close', 'search', 'github'],
|
|
1499
1701
|
}),
|
|
1500
1702
|
}),
|
|
1501
1703
|
];
|
package/dist/cli.d.mts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export {}
|