@getvitops/create 0.7.0 → 0.8.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 +148 -6
- package/package.json +2 -3
- package/templates/emdash/.astro/types.d.ts +3 -0
- package/templates/emdash/.github/workflows/deploy-prod.yml +1 -1
- package/templates/emdash/README.md +5 -0
- package/templates/emdash/SETUP.html +50 -0
- package/templates/emdash/astro.config.mjs +26 -2
- package/templates/emdash/package.json +8 -5
- package/templates/emdash/site.json +75 -0
- package/templates/emdash/src/layouts/Layout.astro +7 -1
- package/templates/emdash/src/pages/404.astro +5 -0
- package/templates/emdash/src/pages/[...slug].astro +7 -0
- package/templates/emdash/src/pages/index.astro +7 -0
- package/templates/emdash/vite.config.ts +18 -4
- package/templates/static/.github/workflows/deploy-prod.yml +1 -1
- package/templates/static/SETUP.html +50 -0
- package/templates/static/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,148 @@
|
|
|
1
1
|
# @getvitops/create
|
|
2
2
|
|
|
3
|
+
## 0.8.0-alpha.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- c3c1bcb: **New: the design-system editor, mounted inside the EmDash admin.** `vitopsEmdash({
|
|
8
|
+
designSystemEditor: { config } })` (`config` is your `site.json`, e.g. `import config from
|
|
9
|
+
'./site.json' with { type: 'json' }`) adds a `/design-system` admin page mounting
|
|
10
|
+
`<wc-theme-editor>` — the same live token editor `@getvitops/vite`'s dev server has always
|
|
11
|
+
offered, now usable by the client directly, no dev server required. An edit is visible
|
|
12
|
+
site-wide immediately (a runtime `:root` override, served via a new plugin API route and
|
|
13
|
+
`page:fragments`) and — once `site.deployment.repo`/`branch` and a `VITOPS_GITHUB_TOKEN`
|
|
14
|
+
secret are set (see the scaffold's `SETUP.html`) — auto-commits to your `dev` branch, so it
|
|
15
|
+
reaches the git-tracked `site.json` through your repo's normal review path rather than
|
|
16
|
+
becoming a second, unreviewed source of truth. Until that's configured, the live half still
|
|
17
|
+
works; only the auto-commit half is skipped (and says so in the admin page). The save route
|
|
18
|
+
runs the exact same accessibility (APCA contrast) gate `generate()` enforces at build time,
|
|
19
|
+
synchronously, before persisting — nothing non-compliant ever goes live even momentarily.
|
|
20
|
+
|
|
21
|
+
Requires `@astrojs/react` + `react` + `react-dom` (already scaffold dependencies, for
|
|
22
|
+
EmDash's own admin) and `@getvitops/core` (added as a new scaffold dependency this release).
|
|
23
|
+
Declares two new plugin capabilities when enabled: `network:request` (for the GitHub
|
|
24
|
+
auto-commit) and `hooks.page-fragments:register` (for the live override) — reviewed once at
|
|
25
|
+
plugin-install time.
|
|
26
|
+
|
|
27
|
+
**Breaking for `@getvitops/emdash`**: `vitopsEmdash()`'s `hooks.page-fragments:register`
|
|
28
|
+
capability is now also granted whenever `designSystemEditor` is set, independent of the
|
|
29
|
+
existing `scripts: 'fragments'` option (which governs something unrelated — web-component
|
|
30
|
+
script delivery). No change if you don't use `designSystemEditor`.
|
|
31
|
+
|
|
32
|
+
Also new, supporting the above:
|
|
33
|
+
- `@getvitops/generator`: `validateColorContract()` and `buildReverseIndex()` (both
|
|
34
|
+
`/tokens` subpath, Worker-safe) — the monotonicity/contrast gate and the
|
|
35
|
+
`design-manifest.json` reverse-index, each extracted from `generate()`'s `build()` into
|
|
36
|
+
standalone, non-throwing functions. `patchToOverrideCss()` turns a design-system patch
|
|
37
|
+
into the `:root` override `<style>` block. `designSystemPath`/`getAt`/`setAt`/
|
|
38
|
+
`mergePatch`/`formatConfig` moved from `@getvitops/vite` into `@getvitops/generator/config`
|
|
39
|
+
(re-exported from `@getvitops/vite` unchanged) — one "patch a config file's design-system
|
|
40
|
+
subtree" implementation shared by the dev endpoint and the new plugin route. New
|
|
41
|
+
`site.deployment.repo`/`branch` config fields.
|
|
42
|
+
- `@getvitops/utils`: new `/git` subpath — `commitFile()`, a Worker-safe (fetch-only)
|
|
43
|
+
wrapper over GitHub's Contents API.
|
|
44
|
+
- `@getvitops/core`: `<wc-theme-editor>` gains a `save-endpoint` attribute (default
|
|
45
|
+
unchanged — `/__vitops/design-system`) so the same element can target the new plugin
|
|
46
|
+
route instead of the dev-only Vite endpoint.
|
|
47
|
+
|
|
48
|
+
### Patch Changes
|
|
49
|
+
|
|
50
|
+
- 0574388: Add `vitops email setup|check` — connect `site.notifications.email.from` to whether its domain is
|
|
51
|
+
actually onboarded onto an outbound email provider.
|
|
52
|
+
|
|
53
|
+
Before this, nothing checked that. `EMAIL.send()` throws `E_SENDER_NOT_VERIFIED` at runtime with no
|
|
54
|
+
build or deploy-time warning — the failure mode is silent and production-only.
|
|
55
|
+
|
|
56
|
+
`vitops email setup [domain]` onboards a sending domain (currently Cloudflare Email Sending only)
|
|
57
|
+
and polls DNS until its SPF/DKIM/DMARC records resolve or a timeout is reached; `vitops email
|
|
58
|
+
check` is the non-blocking deploy guard both `@getvitops/create` templates' `deploy`/`deploy:dev`
|
|
59
|
+
scripts now run first (`--strict` makes it a real gate; opt out per-site with
|
|
60
|
+
`site.notifications.email.verifySender: false`, or globally with `--skip` /
|
|
61
|
+
`VITOPS_SKIP_EMAIL_CHECK`).
|
|
62
|
+
|
|
63
|
+
Two things worth knowing before running it:
|
|
64
|
+
- **The onboarded entity is an exact name, and it is usually a subdomain**
|
|
65
|
+
(`send.yourdomain.com`), never the apex your `from` address names. When the exact domain isn't
|
|
66
|
+
onboarded but a sibling in the same zone already is, the command reports that as the fix — send
|
|
67
|
+
from the onboarded subdomain — rather than silently trying to onboard the apex, which rewrites
|
|
68
|
+
`_dmarc.<domain>` and can tighten DMARC policy on every other mail your domain sends.
|
|
69
|
+
- Candidates come from `site.notifications.email.from` (or its derived `noreply@<domains
|
|
70
|
+
.canonical>` default) first; a best-effort scan of `--src` only supplements it, and never guesses
|
|
71
|
+
at a computed `from` value.
|
|
72
|
+
|
|
73
|
+
New `@getvitops/utils/email` subpath and `site.notifications.email.verifySender` config field.
|
|
74
|
+
Needs `CLOUDFLARE_API_TOKEN` with an Email Sending scope in addition to the `Zone:Read` other
|
|
75
|
+
commands already use.
|
|
76
|
+
|
|
77
|
+
- 0574388: Bump `emdash`/`@emdash-cms/cloudflare` peers to `>=1.0.0 <2` and `vite-plus` to `^1.0.0`, following
|
|
78
|
+
both projects' GA releases.
|
|
79
|
+
|
|
80
|
+
**Breaking for `@getvitops/emdash` consumers on EmDash 0.x**: the peer range no longer admits
|
|
81
|
+
`emdash@0.31.x`/`@emdash-cms/cloudflare@0.31.x`. Upgrade `emdash` and `@emdash-cms/cloudflare` to
|
|
82
|
+
`^1.0.1` first — nothing in `@getvitops/emdash`'s own plugin surface (`admin.portableTextBlocks`,
|
|
83
|
+
the `hooks.page-fragments:register` capability, `definePlugin()`) changed against EmDash 1.0, so no
|
|
84
|
+
code here needed to change, only the declared range.
|
|
85
|
+
|
|
86
|
+
The `emdash` scaffold template (`vp create @getvitops:emdash`) picks up several fixes alongside
|
|
87
|
+
the version bump:
|
|
88
|
+
- `tailwindcss`/`@tailwindcss/vite` are now real dependencies — the template selected
|
|
89
|
+
`css.format: 'tailwind'` without installing either, which threw on build.
|
|
90
|
+
- `site.json` now sets `site.icons.sprite: true` plus the full `semantic` list the
|
|
91
|
+
`vitops.actionLink` block's icon picker offers — previously its sprite icons pointed at a file
|
|
92
|
+
the build never generated.
|
|
93
|
+
- `astro.config.mjs` sets `migrations: { runtime: 'check', dev: 'auto' }`, and
|
|
94
|
+
`site-deploy-emdash.yml` runs EmDash 1.0's documented `build → status → apply → deploy → check`
|
|
95
|
+
migration sequence explicitly, rather than relying solely on first-request auto-migration. This
|
|
96
|
+
needs a new GitHub Environment variable, `EMDASH_TARGET_FINGERPRINT` (one per environment),
|
|
97
|
+
which only a human can set — run `emdash migrate --status` against the real deployed database,
|
|
98
|
+
review the printed identity, then `gh variable set EMDASH_TARGET_FINGERPRINT --env <env> --body
|
|
99
|
+
<value>`. Deploys fail clearly on the migration-apply step until it's set.
|
|
100
|
+
- `lint.options.typeAware`/`typeCheck` in the template's own `vite.config.ts` are commented out,
|
|
101
|
+
not deleted: vite-plus 1.0 only honours that option in a project's actual root config, and hard
|
|
102
|
+
errors on it in a nested one (which this file is, sitting inside the `design-system` monorepo).
|
|
103
|
+
Uncomment it once scaffolded into its own repo.
|
|
104
|
+
|
|
105
|
+
No config schema changes. `@getvitops/generator` also switches from the `zod/mini` subpath import
|
|
106
|
+
to the standalone `@zod/mini` package (zod 4.5+; same API) and fixes `validateConfig()` silently
|
|
107
|
+
losing the offending key name on an `unrecognized_keys` error (e.g. a typo'd `site.ads` platform
|
|
108
|
+
now names the bad key instead of reporting a bare "Invalid input").
|
|
109
|
+
|
|
110
|
+
Also fixed: `vp check`'s `tsconfig-error` for `packages/create/templates/emdash/tsconfig.json`
|
|
111
|
+
(`extends: "astro/tsconfigs/strict"`, unresolvable from inside this monorepo since the template
|
|
112
|
+
has no `node_modules` of its own — a pre-existing, structural gap, newly surfaced as a hard error
|
|
113
|
+
by oxlint 1.85's deeper config discovery, and blocking on every commit since this repo's pre-commit
|
|
114
|
+
hook runs `vp check --fix`). Fixed with a new `scripts/link-template-deps.mjs`, wired as the root
|
|
115
|
+
`postinstall` script: symlinks `astro`/`emdash`/`@emdash-cms/cloudflare` into the template's own
|
|
116
|
+
`node_modules/` (resolved fresh from sibling packages that already depend on them for real, not a
|
|
117
|
+
hardcoded `.pnpm` hash) and writes a minimal `astro:content` ambient shim at `.astro/types.d.ts`
|
|
118
|
+
(the same path `astro sync` would generate for real). Both are gitignored and only ever exist
|
|
119
|
+
inside this monorepo's copy of the template — a real scaffold installs its own real copies instead.
|
|
120
|
+
Considered and rejected first: inlining astro's strict preset (drift risk against astro's own
|
|
121
|
+
evolving default) and making the template a real pnpm workspace member (would change how its
|
|
122
|
+
`@getvitops/*: "latest"` deps resolve locally, which `templates.test.ts` exists to protect).
|
|
123
|
+
|
|
124
|
+
**Known gap, not fixed here**: `packages/astro/src/components/container.test.ts` (the
|
|
125
|
+
`AstroContainer`-based render tests) fails to even load under vite-plus 1.0's Vite 8 — direct
|
|
126
|
+
`.astro` imports in a Vitest file need the Astro Vite plugin registered, which nothing in this
|
|
127
|
+
repo's test config actually does (Astro's own docs call for `getViteConfig()`, which doesn't
|
|
128
|
+
compose with vite-plus's own `defineConfig`). A type-level shim
|
|
129
|
+
(`packages/astro/src/components/astro-modules.d.ts`) fixes `vp check`'s type-aware pass, but the
|
|
130
|
+
runtime `vp test` failure for this one file is still open.
|
|
131
|
+
|
|
132
|
+
- 0f8c018: **New: `resolveOrganizationName(config, locale?)`**, exported from `@getvitops/astro/routes`
|
|
133
|
+
alongside `toNotifyContext`/`toCrmConfig` — the same `organization.name` → `legalName` →
|
|
134
|
+
`undefined` fallback chain `toNotifyContext` already used for its `organizationName` field,
|
|
135
|
+
now usable standalone anywhere a build-time-only display name is needed (favicon generation,
|
|
136
|
+
a scaffold's `astro.config.mjs`, a `Layout.astro` fallback). `toNotifyContext` is unchanged —
|
|
137
|
+
it now delegates to this helper internally.
|
|
138
|
+
|
|
139
|
+
The emdash scaffold uses it to remove a three-way duplicated `'My EmDash Site'` string:
|
|
140
|
+
`astro.config.mjs`'s favicon `name` and `Layout.astro`'s title fallback both previously
|
|
141
|
+
hardcoded it independently of `site.json`'s `organization.name`. EmDash's own
|
|
142
|
+
`getSiteSettings().title` (set in the admin) still wins at render time when it's set — it's a
|
|
143
|
+
runtime-only fact that can't be read at build time at all — this only replaces the two
|
|
144
|
+
hardcoded _fallback_ strings.
|
|
145
|
+
|
|
3
146
|
## 0.7.0
|
|
4
147
|
|
|
5
148
|
### Minor Changes
|
|
@@ -18,7 +161,6 @@
|
|
|
18
161
|
`astro.config.mjs`. Not reachable by `vitops lint --fix` — this is the whole migration.
|
|
19
162
|
|
|
20
163
|
Also new in both templates:
|
|
21
|
-
|
|
22
164
|
- **`SETUP.html`** — a client-onboarding checklist (styled entirely with the framework's own
|
|
23
165
|
classes, checkbox state in `localStorage`), generated a stylesheet for via the new
|
|
24
166
|
`pnpm run sop` script.
|
|
@@ -266,15 +408,15 @@
|
|
|
266
408
|
which `@getvitops/astro` re-exports wholesale. So from `astro.config.mjs`:
|
|
267
409
|
|
|
268
410
|
```js
|
|
269
|
-
import { generateIconInclude } from
|
|
270
|
-
import icon from
|
|
411
|
+
import { generateIconInclude } from '@getvitops/astro';
|
|
412
|
+
import icon from 'astro-icon';
|
|
271
413
|
|
|
272
414
|
integrations: [
|
|
273
415
|
icon({
|
|
274
416
|
include: generateIconInclude({
|
|
275
|
-
ui:
|
|
276
|
-
brand:
|
|
277
|
-
semantic: [
|
|
417
|
+
ui: 'fa7-solid',
|
|
418
|
+
brand: 'simple-icons',
|
|
419
|
+
semantic: ['menu', 'close', 'search', 'github'],
|
|
278
420
|
}),
|
|
279
421
|
}),
|
|
280
422
|
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getvitops/create",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0-alpha.0",
|
|
4
4
|
"description": "Project templates for the Vitops design system — scaffold wired-up sites with `vp create @getvitops`.",
|
|
5
5
|
"homepage": "https://docs.vitops.ca",
|
|
6
6
|
"bugs": "https://github.com/getvitops/design-system/issues",
|
|
@@ -19,8 +19,7 @@
|
|
|
19
19
|
"access": "public"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"
|
|
23
|
-
"@getvitops/generator": "8.1.0"
|
|
22
|
+
"@getvitops/generator": "8.2.0-alpha.0"
|
|
24
23
|
},
|
|
25
24
|
"engines": {
|
|
26
25
|
"node": ">=24"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Deploys `main` to production.
|
|
2
2
|
# `main` should be branch-protected — it then only advances via the Promote
|
|
3
3
|
# workflow (promote.yml), so a push here always represents promoted code. The
|
|
4
|
-
# `production` GitHub Environment (set up by `
|
|
4
|
+
# `production` GitHub Environment (set up by `vitops setup repo`) has
|
|
5
5
|
# required reviewers restricted to admins, so this PAUSES for approval before
|
|
6
6
|
# deploying.
|
|
7
7
|
#
|
|
@@ -27,6 +27,11 @@ pnpm install
|
|
|
27
27
|
pnpm dev
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
+
Once this is its own repo (not sitting inside the `getvitops/design-system`
|
|
31
|
+
monorepo), uncomment `lint.options` in `vite.config.ts` for type-aware
|
|
32
|
+
`vp check`/`vp lint` — it ships commented out because vite-plus 1.0 only
|
|
33
|
+
honours that option at a project's actual root, and errors on it otherwise.
|
|
34
|
+
|
|
30
35
|
No Cloudflare account needed: `astro dev` runs the Worker locally with local
|
|
31
36
|
D1/R2 emulation (state in `.wrangler/`). On first boot EmDash runs its
|
|
32
37
|
migrations and applies the structure from `seed/seed.json` — a `pages`
|
|
@@ -159,6 +159,41 @@
|
|
|
159
159
|
this exists.
|
|
160
160
|
</span>
|
|
161
161
|
</label>
|
|
162
|
+
<label class="custom-check">
|
|
163
|
+
<input type="checkbox" data-sop="hosting.emdash-fingerprint" />
|
|
164
|
+
<span class="custom-check__box"
|
|
165
|
+
><span class="custom-check__indicator custom-check__indicator--check"></span
|
|
166
|
+
></span>
|
|
167
|
+
<span>
|
|
168
|
+
<strong>(EmDash template)</strong> After the first deploy to each environment, run
|
|
169
|
+
<code>npx emdash migrate --status</code> locally against that environment's real
|
|
170
|
+
database, review the printed account/database identity, and set the reviewed
|
|
171
|
+
fingerprint:
|
|
172
|
+
<code
|
|
173
|
+
>gh variable set EMDASH_TARGET_FINGERPRINT --env dev --body <value></code
|
|
174
|
+
>
|
|
175
|
+
and again with <code>--env production</code>. No command can do this for you — it's
|
|
176
|
+
the human review the fingerprint guard exists for. Deploys fail clearly on the
|
|
177
|
+
migration-apply step until it's set for that environment.
|
|
178
|
+
</span>
|
|
179
|
+
</label>
|
|
180
|
+
<label class="custom-check">
|
|
181
|
+
<input type="checkbox" data-sop="hosting.design-system-editor-token" />
|
|
182
|
+
<span class="custom-check__box"
|
|
183
|
+
><span class="custom-check__indicator custom-check__indicator--check"></span
|
|
184
|
+
></span>
|
|
185
|
+
<span>
|
|
186
|
+
<strong>(EmDash template, only if <code>designSystemEditor</code> is on)</strong>
|
|
187
|
+
Create a fine-grained GitHub PAT scoped to this one repository,
|
|
188
|
+
<code>Contents: Read and write</code> only — no <code>admin</code> scope, no access
|
|
189
|
+
to any other repo — then <code>gh secret set VITOPS_GITHUB_TOKEN</code>. Also set
|
|
190
|
+
<code>site.deployment.repo</code> (<code>"owner/name"</code>) and
|
|
191
|
+
<code>site.deployment.branch</code> (default <code>"dev"</code>) in
|
|
192
|
+
<code>site.json</code>. Without these the live design-system editor still works —
|
|
193
|
+
only the auto-commit-to-source half is skipped, and the admin page's response says
|
|
194
|
+
so.
|
|
195
|
+
</span>
|
|
196
|
+
</label>
|
|
162
197
|
</div>
|
|
163
198
|
</details>
|
|
164
199
|
|
|
@@ -326,6 +361,21 @@
|
|
|
326
361
|
<code>npx vitops setup ads</code>.
|
|
327
362
|
</span>
|
|
328
363
|
</label>
|
|
364
|
+
<label class="custom-check">
|
|
365
|
+
<input type="checkbox" data-sop="connections.email" />
|
|
366
|
+
<span class="custom-check__box"
|
|
367
|
+
><span class="custom-check__indicator custom-check__indicator--check"></span
|
|
368
|
+
></span>
|
|
369
|
+
<span>
|
|
370
|
+
If <code>site.notifications.email</code> sends mail, onboard its sender domain:
|
|
371
|
+
<code>npx vitops email setup --dry</code>, then <code>npx vitops email setup</code>.
|
|
372
|
+
Cloudflare onboards an exact name — usually a subdomain like
|
|
373
|
+
<code>send.<domain></code>, not the apex — so a mismatch here is silent at
|
|
374
|
+
build time and only fails when a form is actually submitted in production. Both
|
|
375
|
+
templates' <code>deploy</code> script already runs
|
|
376
|
+
<code>vitops email check</code> first as a non-blocking warning.
|
|
377
|
+
</span>
|
|
378
|
+
</label>
|
|
329
379
|
<label class="custom-check">
|
|
330
380
|
<input type="checkbox" data-sop="connections.manual" />
|
|
331
381
|
<span class="custom-check__box"
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
import react from '@astrojs/react';
|
|
2
2
|
import vitops from '@getvitops/astro';
|
|
3
|
+
import { resolveOrganizationName } from '@getvitops/astro/routes';
|
|
3
4
|
import { vitopsEmdash, vitopsHosting } from '@getvitops/emdash';
|
|
4
5
|
import { defineConfig } from 'astro/config';
|
|
5
6
|
import emdash from 'emdash/astro';
|
|
7
|
+
import config from './site.json' with { type: 'json' };
|
|
8
|
+
|
|
9
|
+
// site.json's organization.name is the one build-time-readable source for a
|
|
10
|
+
// display name — EmDash's own getSiteSettings() only resolves inside a live
|
|
11
|
+
// Worker request (AsyncLocalStorage + a DB binding), so it can't be read here
|
|
12
|
+
// even though it's what Layout.astro shows on rendered pages. See AGENTS.md's
|
|
13
|
+
// "EmDash plugin as the design-system editing surface".
|
|
14
|
+
const organizationName = resolveOrganizationName(config) ?? 'My EmDash Site';
|
|
6
15
|
|
|
7
16
|
// Hosting seam: adapter + EmDash database/storage for the configured target.
|
|
8
17
|
// Default 'cloudflare' (Workers + D1 + R2 — see wrangler.jsonc / src/worker.ts).
|
|
@@ -30,12 +39,27 @@ export default defineConfig({
|
|
|
30
39
|
// disclosure, carousel) in the editor slash menu. Default 'integration'
|
|
31
40
|
// script delivery: Layout.astro renders <Head /> from @getvitops/astro,
|
|
32
41
|
// which emits the web-component runtime tags.
|
|
33
|
-
|
|
42
|
+
//
|
|
43
|
+
// designSystemEditor mounts a live <wc-theme-editor> admin page at
|
|
44
|
+
// /design-system — edits are visible site-wide immediately (no
|
|
45
|
+
// rebuild) and auto-sync back to source once site.deployment.repo and
|
|
46
|
+
// a VITOPS_GITHUB_TOKEN secret are set (see SETUP.html) — see
|
|
47
|
+
// AGENTS.md's "EmDash plugin as the design-system editing surface".
|
|
48
|
+
// Until then the live half still works; only the sync half is skipped.
|
|
49
|
+
plugins: [vitopsEmdash({ designSystemEditor: { config } })],
|
|
50
|
+
// 1.0's runtime migration mode defaults to 'auto' (apply pending core
|
|
51
|
+
// migrations on first request) — fine for local dev, but a deploy
|
|
52
|
+
// should have already migrated before traffic arrives. 'check' 503s a
|
|
53
|
+
// request instead of migrating behind it if the explicit `emdash
|
|
54
|
+
// migrate` step in site-deploy-emdash.yml (see AGENTS.md's CI/CD
|
|
55
|
+
// section) was skipped or failed. `dev: 'auto'` keeps the convenient
|
|
56
|
+
// first-run behaviour for `pnpm dev`.
|
|
57
|
+
migrations: { runtime: 'check', dev: 'auto' },
|
|
34
58
|
}),
|
|
35
59
|
vitops({
|
|
36
60
|
favicon: {
|
|
37
61
|
source: 'src/assets/logo.svg',
|
|
38
|
-
name:
|
|
62
|
+
name: organizationName,
|
|
39
63
|
themeColor: '#2e9b73',
|
|
40
64
|
backgroundColor: '#ffffff',
|
|
41
65
|
},
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
"dev": "astro dev",
|
|
8
8
|
"build": "astro build",
|
|
9
9
|
"preview": "astro preview",
|
|
10
|
-
"deploy": "astro build && wrangler deploy",
|
|
11
|
-
"deploy:dev": "astro build && node scripts/build-dev-wrangler.mjs && wrangler deploy --config dist/server/wrangler.dev.json",
|
|
10
|
+
"deploy": "vitops email check && astro build && emdash migrate --wrangler-config wrangler.jsonc && wrangler deploy",
|
|
11
|
+
"deploy:dev": "vitops email check && astro build && node scripts/build-dev-wrangler.mjs && emdash migrate --wrangler-config dist/server/wrangler.dev.json && wrangler deploy --config dist/server/wrangler.dev.json",
|
|
12
12
|
"init:github": "vitops setup repo",
|
|
13
13
|
"init:hosting": "vitops setup hosting",
|
|
14
14
|
"setup": "vitops setup all",
|
|
@@ -21,13 +21,16 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@astrojs/cloudflare": "^14.0.0",
|
|
23
23
|
"@astrojs/react": "^6.0.0",
|
|
24
|
-
"@emdash-cms/cloudflare": "^0.
|
|
24
|
+
"@emdash-cms/cloudflare": "^1.0.1",
|
|
25
25
|
"@getvitops/astro": "latest",
|
|
26
|
+
"@getvitops/core": "latest",
|
|
26
27
|
"@getvitops/emdash": "latest",
|
|
28
|
+
"@tailwindcss/vite": "^4.3.3",
|
|
27
29
|
"astro": "^7.1.2",
|
|
28
|
-
"emdash": "^0.
|
|
30
|
+
"emdash": "^1.0.1",
|
|
29
31
|
"react": "^19.2.4",
|
|
30
|
-
"react-dom": "^19.2.4"
|
|
32
|
+
"react-dom": "^19.2.4",
|
|
33
|
+
"tailwindcss": "^4.3.3"
|
|
31
34
|
},
|
|
32
35
|
"devDependencies": {
|
|
33
36
|
"@astrojs/check": "^0.9.7",
|
|
@@ -223,6 +223,81 @@
|
|
|
223
223
|
"url": "https://dev.my-emdash-site.example.com",
|
|
224
224
|
"robots": "noindex,nofollow"
|
|
225
225
|
}
|
|
226
|
+
},
|
|
227
|
+
"icons": {
|
|
228
|
+
"sprite": true,
|
|
229
|
+
"semantic": [
|
|
230
|
+
"menu",
|
|
231
|
+
"close",
|
|
232
|
+
"home",
|
|
233
|
+
"settings",
|
|
234
|
+
"search",
|
|
235
|
+
"add",
|
|
236
|
+
"remove",
|
|
237
|
+
"delete",
|
|
238
|
+
"edit",
|
|
239
|
+
"save",
|
|
240
|
+
"copy",
|
|
241
|
+
"paste",
|
|
242
|
+
"attach",
|
|
243
|
+
"upload",
|
|
244
|
+
"download",
|
|
245
|
+
"share",
|
|
246
|
+
"bookmark",
|
|
247
|
+
"favorite",
|
|
248
|
+
"star",
|
|
249
|
+
"login",
|
|
250
|
+
"logout",
|
|
251
|
+
"email",
|
|
252
|
+
"phone",
|
|
253
|
+
"location",
|
|
254
|
+
"globe",
|
|
255
|
+
"link",
|
|
256
|
+
"clock",
|
|
257
|
+
"calendar",
|
|
258
|
+
"schedule",
|
|
259
|
+
"person",
|
|
260
|
+
"group",
|
|
261
|
+
"file",
|
|
262
|
+
"folder",
|
|
263
|
+
"image",
|
|
264
|
+
"export",
|
|
265
|
+
"import",
|
|
266
|
+
"backup",
|
|
267
|
+
"compress",
|
|
268
|
+
"check",
|
|
269
|
+
"error",
|
|
270
|
+
"warning",
|
|
271
|
+
"info",
|
|
272
|
+
"help",
|
|
273
|
+
"cart",
|
|
274
|
+
"tag",
|
|
275
|
+
"receipt",
|
|
276
|
+
"leaf",
|
|
277
|
+
"tree",
|
|
278
|
+
"seedling",
|
|
279
|
+
"trowel",
|
|
280
|
+
"droplet",
|
|
281
|
+
"snowflake",
|
|
282
|
+
"sun",
|
|
283
|
+
"cloud",
|
|
284
|
+
"grid",
|
|
285
|
+
"list",
|
|
286
|
+
"filter",
|
|
287
|
+
"sort",
|
|
288
|
+
"fullscreen",
|
|
289
|
+
"collapse",
|
|
290
|
+
"building",
|
|
291
|
+
"video",
|
|
292
|
+
"lock",
|
|
293
|
+
"unlock",
|
|
294
|
+
"eye",
|
|
295
|
+
"print",
|
|
296
|
+
"code",
|
|
297
|
+
"palette",
|
|
298
|
+
"lightbulb",
|
|
299
|
+
"lightning"
|
|
300
|
+
]
|
|
226
301
|
}
|
|
227
302
|
}
|
|
228
303
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
import VitopsHead from '@getvitops/astro/Head.astro';
|
|
3
|
+
import { resolveOrganizationName } from '@getvitops/astro/routes';
|
|
3
4
|
import { getMenu, getSiteSettings } from 'emdash';
|
|
4
5
|
import { createPublicPageContext } from 'emdash/page';
|
|
5
6
|
import { EmDashHead } from 'emdash/ui';
|
|
7
|
+
import config from '../../site.json' with { type: 'json' };
|
|
6
8
|
// Design-system CSS, layout-scoped (vitops css.inject: false): only pages
|
|
7
9
|
// rendered through this layout get it — keeps it out of /_emdash/admin, while
|
|
8
10
|
// EmDash previews (rendered through this layout) keep it.
|
|
@@ -19,7 +21,11 @@ interface Props {
|
|
|
19
21
|
|
|
20
22
|
const { title, description, image } = Astro.props;
|
|
21
23
|
const settings = await getSiteSettings();
|
|
22
|
-
|
|
24
|
+
// getSiteSettings().title is the editable, client-facing display name (set in
|
|
25
|
+
// the EmDash admin) — it wins whenever it's set. resolveOrganizationName(config)
|
|
26
|
+
// is the fallback rather than a second hardcoded string, so a fresh scaffold
|
|
27
|
+
// shows organization.name (from site.json) before anyone's touched the admin.
|
|
28
|
+
const siteTitle = settings?.title || resolveOrganizationName(config) || 'My EmDash Site';
|
|
23
29
|
const fullTitle = title ? `${title} — ${siteTitle}` : siteTitle;
|
|
24
30
|
const siteDescription = settings?.tagline || 'An EmDash website with the Vitops design system';
|
|
25
31
|
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
import Layout from '../layouts/Layout.astro';
|
|
3
|
+
|
|
4
|
+
// No per-request data — safe to prerender per AGENTS.md's "Prerender by
|
|
5
|
+
// default" rule. [...slug].astro reaches this via Astro.rewrite('/404'),
|
|
6
|
+
// which resolves a prerendered destination the same as a server-rendered one.
|
|
7
|
+
export const prerender = true;
|
|
3
8
|
---
|
|
4
9
|
|
|
5
10
|
<Layout title="Page not found">
|
|
@@ -4,6 +4,13 @@ import { PortableText } from 'emdash/ui';
|
|
|
4
4
|
import Layout from '../layouts/Layout.astro';
|
|
5
5
|
|
|
6
6
|
// Catch-all: any entry in the `pages` collection renders at its slug.
|
|
7
|
+
//
|
|
8
|
+
// Deliberately NOT prerendered, unlike AGENTS.md's general "prerender by
|
|
9
|
+
// default" rule — see index.astro's comment for why: a live EmDash publish
|
|
10
|
+
// should reach visitors without a redeploy. A page that's known ahead of
|
|
11
|
+
// time and doesn't need that (rarely edited, or fine to lag a build) can
|
|
12
|
+
// move to its own prerendered route with `getStaticPaths()` over the
|
|
13
|
+
// `pages` collection instead of relying on this catch-all.
|
|
7
14
|
const { slug } = Astro.params;
|
|
8
15
|
const { entry: page } = slug ? await getEmDashEntry('pages', slug) : { entry: null };
|
|
9
16
|
|
|
@@ -6,6 +6,13 @@ import Layout from '../layouts/Layout.astro';
|
|
|
6
6
|
// The seeded home page (seed/seed.json → pages/home). Edit it in the admin;
|
|
7
7
|
// the Vitops blocks from @getvitops/emdash render automatically — EmDash
|
|
8
8
|
// merges the plugin's block components into <PortableText>.
|
|
9
|
+
//
|
|
10
|
+
// Deliberately NOT prerendered, unlike AGENTS.md's general "prerender by
|
|
11
|
+
// default" rule: this is the one route where the tradeoff that rule names
|
|
12
|
+
// (prerendered = fast, but reflects the database as of the last build) is
|
|
13
|
+
// unacceptable — the whole point of editing in EmDash is that a publish
|
|
14
|
+
// shows up without a redeploy. Add `getStaticPaths()` + `prerender = true`
|
|
15
|
+
// here only if this site's home page genuinely doesn't need that.
|
|
9
16
|
const { entry: page } = await getEmDashEntry('pages', 'home');
|
|
10
17
|
---
|
|
11
18
|
|
|
@@ -11,13 +11,27 @@ export default defineConfig({
|
|
|
11
11
|
'vitops lint -i site.json -f tailwind --strict',
|
|
12
12
|
},
|
|
13
13
|
fmt: {
|
|
14
|
+
// Explicit, matching the monorepo root's style: unlike `lint`, a nested
|
|
15
|
+
// `fmt` config genuinely takes effect independently here rather than
|
|
16
|
+
// being root-only, so leaving these unset let this file (and anything
|
|
17
|
+
// else oxfmt formats under this directory, e.g. SETUP.html's embedded
|
|
18
|
+
// `<script>`) drift to a different default quote style each time
|
|
19
|
+
// `vp check --fix` ran, breaking `templates.test.ts`'s byte-identical
|
|
20
|
+
// mirror assertion.
|
|
21
|
+
semi: true,
|
|
22
|
+
singleQuote: true,
|
|
14
23
|
ignorePatterns: ['dist/**', 'node_modules/**', 'src/styles/**', 'public/vitops/**'],
|
|
15
24
|
},
|
|
16
25
|
lint: {
|
|
17
26
|
ignorePatterns: ['dist/**', 'node_modules/**', 'src/styles/**', 'public/vitops/**'],
|
|
18
|
-
options:
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
27
|
+
// `options.typeAware`/`typeCheck` commented out, not deleted: vite-plus 1.0
|
|
28
|
+
// only honours those at the root config, and while this file sits nested
|
|
29
|
+
// inside the getvitops/design-system monorepo (which has its own root
|
|
30
|
+
// vite.config.ts), setting them here is a hard error — "typeAware is only
|
|
31
|
+
// supported in the root config" — rather than the silent no-op it was
|
|
32
|
+
// pre-1.0. Once `vp create @getvitops:emdash` scaffolds this file out into
|
|
33
|
+
// its own project, it *becomes* that project's root config, and
|
|
34
|
+
// uncommenting this is the right move there.
|
|
35
|
+
// options: { typeAware: true, typeCheck: true },
|
|
22
36
|
},
|
|
23
37
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Deploys `main` to production.
|
|
2
2
|
# `main` should be branch-protected — it then only advances via the Promote
|
|
3
3
|
# workflow (promote.yml), so a push here always represents promoted code. The
|
|
4
|
-
# `production` GitHub Environment (set up by `
|
|
4
|
+
# `production` GitHub Environment (set up by `vitops setup repo`) has
|
|
5
5
|
# required reviewers restricted to admins, so this PAUSES for approval before
|
|
6
6
|
# deploying.
|
|
7
7
|
#
|
|
@@ -159,6 +159,41 @@
|
|
|
159
159
|
this exists.
|
|
160
160
|
</span>
|
|
161
161
|
</label>
|
|
162
|
+
<label class="custom-check">
|
|
163
|
+
<input type="checkbox" data-sop="hosting.emdash-fingerprint" />
|
|
164
|
+
<span class="custom-check__box"
|
|
165
|
+
><span class="custom-check__indicator custom-check__indicator--check"></span
|
|
166
|
+
></span>
|
|
167
|
+
<span>
|
|
168
|
+
<strong>(EmDash template)</strong> After the first deploy to each environment, run
|
|
169
|
+
<code>npx emdash migrate --status</code> locally against that environment's real
|
|
170
|
+
database, review the printed account/database identity, and set the reviewed
|
|
171
|
+
fingerprint:
|
|
172
|
+
<code
|
|
173
|
+
>gh variable set EMDASH_TARGET_FINGERPRINT --env dev --body <value></code
|
|
174
|
+
>
|
|
175
|
+
and again with <code>--env production</code>. No command can do this for you — it's
|
|
176
|
+
the human review the fingerprint guard exists for. Deploys fail clearly on the
|
|
177
|
+
migration-apply step until it's set for that environment.
|
|
178
|
+
</span>
|
|
179
|
+
</label>
|
|
180
|
+
<label class="custom-check">
|
|
181
|
+
<input type="checkbox" data-sop="hosting.design-system-editor-token" />
|
|
182
|
+
<span class="custom-check__box"
|
|
183
|
+
><span class="custom-check__indicator custom-check__indicator--check"></span
|
|
184
|
+
></span>
|
|
185
|
+
<span>
|
|
186
|
+
<strong>(EmDash template, only if <code>designSystemEditor</code> is on)</strong>
|
|
187
|
+
Create a fine-grained GitHub PAT scoped to this one repository,
|
|
188
|
+
<code>Contents: Read and write</code> only — no <code>admin</code> scope, no access
|
|
189
|
+
to any other repo — then <code>gh secret set VITOPS_GITHUB_TOKEN</code>. Also set
|
|
190
|
+
<code>site.deployment.repo</code> (<code>"owner/name"</code>) and
|
|
191
|
+
<code>site.deployment.branch</code> (default <code>"dev"</code>) in
|
|
192
|
+
<code>site.json</code>. Without these the live design-system editor still works —
|
|
193
|
+
only the auto-commit-to-source half is skipped, and the admin page's response says
|
|
194
|
+
so.
|
|
195
|
+
</span>
|
|
196
|
+
</label>
|
|
162
197
|
</div>
|
|
163
198
|
</details>
|
|
164
199
|
|
|
@@ -326,6 +361,21 @@
|
|
|
326
361
|
<code>npx vitops setup ads</code>.
|
|
327
362
|
</span>
|
|
328
363
|
</label>
|
|
364
|
+
<label class="custom-check">
|
|
365
|
+
<input type="checkbox" data-sop="connections.email" />
|
|
366
|
+
<span class="custom-check__box"
|
|
367
|
+
><span class="custom-check__indicator custom-check__indicator--check"></span
|
|
368
|
+
></span>
|
|
369
|
+
<span>
|
|
370
|
+
If <code>site.notifications.email</code> sends mail, onboard its sender domain:
|
|
371
|
+
<code>npx vitops email setup --dry</code>, then <code>npx vitops email setup</code>.
|
|
372
|
+
Cloudflare onboards an exact name — usually a subdomain like
|
|
373
|
+
<code>send.<domain></code>, not the apex — so a mismatch here is silent at
|
|
374
|
+
build time and only fails when a form is actually submitted in production. Both
|
|
375
|
+
templates' <code>deploy</code> script already runs
|
|
376
|
+
<code>vitops email check</code> first as a non-blocking warning.
|
|
377
|
+
</span>
|
|
378
|
+
</label>
|
|
329
379
|
<label class="custom-check">
|
|
330
380
|
<input type="checkbox" data-sop="connections.manual" />
|
|
331
381
|
<span class="custom-check__box"
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
"dev": "astro dev",
|
|
8
8
|
"build": "astro build",
|
|
9
9
|
"preview": "astro preview",
|
|
10
|
-
"deploy": "astro build && wrangler deploy",
|
|
11
|
-
"deploy:dev": "astro build && node scripts/dev-wrangler-config.mjs && wrangler deploy --config .wrangler.dev.json",
|
|
10
|
+
"deploy": "vitops email check && astro build && wrangler deploy",
|
|
11
|
+
"deploy:dev": "vitops email check && astro build && node scripts/dev-wrangler-config.mjs && wrangler deploy --config .wrangler.dev.json",
|
|
12
12
|
"init:github": "vitops setup repo",
|
|
13
13
|
"init:hosting": "vitops setup hosting --no-dev-resources",
|
|
14
14
|
"setup": "vitops setup repo && vitops setup hosting --no-dev-resources",
|