@getvitops/astro 7.0.0 → 8.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 +142 -34
- package/dist/index.mjs +10 -3
- package/dist/index.mjs.map +1 -1
- package/dist/routes/conversion.d.mts +87 -4
- package/dist/routes/conversion.d.mts.map +1 -1
- package/dist/routes/conversion.mjs +142 -34
- package/dist/routes/conversion.mjs.map +1 -1
- package/package.json +22 -7
- package/src/components/Gallery.astro +77 -69
- package/src/components/Marquee.astro +63 -0
- package/src/components/ReviewCard.astro +60 -0
- package/src/components/ReviewCardBody.astro +67 -0
- package/src/schemas/Article.astro +2 -2
- package/src/schemas/Breadcrumb.astro +2 -2
- package/src/schemas/Carousel.astro +2 -2
- package/src/schemas/FAQ.astro +2 -2
- package/src/schemas/LocalBusiness.astro +2 -2
- package/src/schemas/Organization.astro +2 -2
- package/src/scripts/tracking.ts +4 -2
- package/virtual.d.ts +0 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,121 @@
|
|
|
1
1
|
# @getvitops/astro
|
|
2
2
|
|
|
3
|
+
## 8.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- Rebuild the lightbox on one dialog + the existing carousel, fixing the flicker on
|
|
8
|
+
prev/next and the stutter on open.
|
|
9
|
+
|
|
10
|
+
**Breaking (`css`/`bricks` and `tailwind` formats — `.lightbox-dialog`'s markup
|
|
11
|
+
contract changed):**
|
|
12
|
+
|
|
13
|
+
- `<Gallery />` now emits ONE `<dialog class="lightbox-dialog">` per gallery,
|
|
14
|
+
wrapping a `<Carousel />`, instead of one dialog per image. A `.gallery__trigger`
|
|
15
|
+
is now a plain `<a href="#slide-id">`, not a `command="show-modal"` button.
|
|
16
|
+
- `.lightbox-dialog__content` / `__image` / `__nav` / `__nav-button` /
|
|
17
|
+
`__caption` are gone. The dialog's child is `.lightbox-dialog__track` (a
|
|
18
|
+
`.carousel`) — prev/next, dots, arrow keys and swipe are the carousel's,
|
|
19
|
+
reused rather than reimplemented. `.lightbox-dialog__close` is unchanged.
|
|
20
|
+
- `<wc-gallery>` no longer builds nav buttons or steps between images — the
|
|
21
|
+
nested `<wc-carousel>` does. It fires `gallery-open` (unchanged shape) and
|
|
22
|
+
re-emits the carousel's own stepping as `gallery-change`.
|
|
23
|
+
- `packages/core/src/web-components/utils/gallery.ts` dropped `keyToAction` and
|
|
24
|
+
`swipeAction` (the carousel's own key/swipe handling covers both now).
|
|
25
|
+
`stepIndex`/`preloadTargets` are unchanged.
|
|
26
|
+
|
|
27
|
+
**Why:** stepping used to close one `<dialog>` and open another, which made
|
|
28
|
+
`animation.css`'s top-layer driver play a full exit-then-entry transition on
|
|
29
|
+
every step — visible as a flicker on prev/next, by construction, not a bug to
|
|
30
|
+
tune away. Opening also awaited the full image's `decode()` before starting the
|
|
31
|
+
view-transition morph, so the dialog visibly stalled on a slow network. One
|
|
32
|
+
dialog containing one carousel makes the first failure mode unrepresentable
|
|
33
|
+
(stepping is a scroll, not a close/open pair) and removes the wait for the
|
|
34
|
+
second (the morph starts immediately, painting the thumbnail as a CSS
|
|
35
|
+
background placeholder until the full image arrives).
|
|
36
|
+
|
|
37
|
+
**Also improved, not just fixed:** the no-JS fallback is no longer a _stripped_
|
|
38
|
+
lightbox — it's a genuine one. Each trigger is ordinary fragment navigation
|
|
39
|
+
(`:has(:target)` in `lightbox.css` reveals the dialog), which needs no Invoker
|
|
40
|
+
Commands polyfill in any engine, and it now has working prev/next with no
|
|
41
|
+
JavaScript at all — the previous per-dialog fallback had no way to express that.
|
|
42
|
+
|
|
43
|
+
**Migration:** a consumer using `<Gallery />` needs no changes — the component's
|
|
44
|
+
props are unchanged. Anyone who hand-authored `.lightbox-dialog` markup (per
|
|
45
|
+
`docs/concepts/patterns.md` / `docs/css/classes.md`) must move to the new single-
|
|
46
|
+
dialog-wrapping-a-carousel shape; see `patterns.astro`'s "Gallery, hand-authored"
|
|
47
|
+
demo for the reference markup. `<wc-gallery>` consumers listening for
|
|
48
|
+
`gallery-change` keep the same event shape (`{ index, total }`).
|
|
49
|
+
|
|
50
|
+
### Minor Changes
|
|
51
|
+
|
|
52
|
+
- Add Google Business Profile reviews: fetch, cache, render.
|
|
53
|
+
|
|
54
|
+
- **`vitops reviews`** (new CLI command) fetches a client's GBP reviews (legacy v4 API — the only
|
|
55
|
+
one that has them) and writes them to `.vitops/reviews.json`, meant to be committed so a build
|
|
56
|
+
never needs a live Google credential. `--dry` prints the plan; `--check` diffs against the cache
|
|
57
|
+
without writing. Requires the same `VITOPS_GOOGLE_CLIENT_ID`/`_CLIENT_SECRET`/`_REFRESH_TOKEN` (or
|
|
58
|
+
ADC login) `search setup` uses, scoped to `business.manage` — **and the calling GCP project must
|
|
59
|
+
be allowlisted by Google first**, a separate one-time approval from every other Google API here.
|
|
60
|
+
- **`site.reviews`** (config): which `organization.locations` to fetch, and per-location
|
|
61
|
+
`featured`/`minRating`/`sort`/`limit` selection. `schema` (JSON-LD) and `avatars` both default to
|
|
62
|
+
**off** — see the migration notes below.
|
|
63
|
+
- **`@getvitops/utils/reviews`** (new subpath): the pure plan/select/merge functions plus the GBP
|
|
64
|
+
fetcher and cache reader/writer, mirroring `./indexing`'s pure/IO split.
|
|
65
|
+
- **`<ReviewCard>`** (new Astro component, `@getvitops/astro`): one review card from a cache entry.
|
|
66
|
+
No web component — nothing here needs progressive enhancement. Composes the existing
|
|
67
|
+
`schemas/Review.astro` for JSON-LD only when both `schema` and `itemReviewed` are passed.
|
|
68
|
+
- **`<Marquee>`** (new Astro component): the tier-3 wrapper `wc-marquee`/`marquee.css` was missing.
|
|
69
|
+
- **`.review` pattern** (`css`/`bricks` and `tailwind` formats): a new config-generated
|
|
70
|
+
`patterns.items.review` entry plus `packages/core/css/patterns/review.css` for the structural
|
|
71
|
+
parts (rating, identity, body, reply, source link). Two new semantic icon names, `star` and
|
|
72
|
+
`star-half`, across every icon set.
|
|
73
|
+
|
|
74
|
+
**Migration:** no breaking change. A site adding `site.reviews` should read the "Google reviews"
|
|
75
|
+
section in AGENTS.md before enabling `schema` — Google's structured-data policy treats a business
|
|
76
|
+
marking up reviews of itself as ineligible for review rich results and risks a manual action, which
|
|
77
|
+
is why it defaults off.
|
|
78
|
+
|
|
79
|
+
- Repo-wide simplification pass: de-boilerplate the CLI, dedupe shared cache/plan
|
|
80
|
+
primitives in `@getvitops/utils`, drop dead code, and tighten dependency hygiene.
|
|
81
|
+
|
|
82
|
+
No breaking changes. (`vitops icons`'s `--site` flag was briefly going to be renamed to
|
|
83
|
+
`--input` for consistency with the other `Config`-anchored commands — deferred rather than
|
|
84
|
+
spending a major bump on a rename with no other breaking change riding along; it stays
|
|
85
|
+
`--site` for now.)
|
|
86
|
+
|
|
87
|
+
**Fixed:**
|
|
88
|
+
|
|
89
|
+
- `@getvitops/core`'s 12 runtime deps (`lit`, both `@oddbird` polyfills, both
|
|
90
|
+
`@webcomponents` packages, `colorjs.io`, etc.) were listed as `dependencies` despite
|
|
91
|
+
being bundled into `dist/elements.js`/`dist/polyfills.js`/`dist/deferred.js` — a
|
|
92
|
+
consumer installed them twice for nothing. Moved to `devDependencies`; no change to
|
|
93
|
+
what ships.
|
|
94
|
+
- Deleted `old-css-lib/` (59 files), superseded by `packages/core/css/` since the
|
|
95
|
+
in-memory bundling change — no consumer-facing effect, it was not part of any
|
|
96
|
+
published output.
|
|
97
|
+
- Deleted a dead Astro module (`packages/astro/src/scripts/deferred.ts`) that had
|
|
98
|
+
silently diverged from `packages/core/src/js/deferred.ts` and had zero importers.
|
|
99
|
+
|
|
100
|
+
**No consumer-facing change in `@getvitops/vite`** beyond the fixed-group version bump —
|
|
101
|
+
task-graph and caching fixes internal to this repo's own build.
|
|
102
|
+
|
|
103
|
+
Everything else (the `cli.ts` file split into `commands/{search,ads}.ts`, shared
|
|
104
|
+
`json-store.ts`/`plan-format.ts` helpers in `@getvitops/utils`, a `.github/actions/setup`
|
|
105
|
+
composite action, restatement-comment cleanup) is internal refactoring with no change to
|
|
106
|
+
any published API, CLI flag, or generated output.
|
|
107
|
+
|
|
108
|
+
### Patch Changes
|
|
109
|
+
|
|
110
|
+
- Updated dependencies
|
|
111
|
+
- Updated dependencies
|
|
112
|
+
- Updated dependencies
|
|
113
|
+
- Updated dependencies [a84839b]
|
|
114
|
+
- @getvitops/core@8.0.0
|
|
115
|
+
- @getvitops/generator@8.0.0
|
|
116
|
+
- @getvitops/utils@8.0.0
|
|
117
|
+
- @getvitops/vite@8.0.0
|
|
118
|
+
|
|
3
119
|
## 7.0.0
|
|
4
120
|
|
|
5
121
|
### Major Changes
|
|
@@ -719,28 +835,20 @@ hidden` would pull it out of the accessible-name computation along with the visu
|
|
|
719
835
|
{
|
|
720
836
|
"designSystem": {
|
|
721
837
|
"themes": {
|
|
722
|
-
"default": {
|
|
723
|
-
/* … */
|
|
724
|
-
},
|
|
838
|
+
"default": {/* … */},
|
|
725
839
|
},
|
|
726
840
|
},
|
|
727
841
|
"organization": {
|
|
728
842
|
"name": "Acme",
|
|
729
843
|
"contact": "hq",
|
|
730
844
|
"locations": {
|
|
731
|
-
"hq": {
|
|
732
|
-
/* … */
|
|
733
|
-
},
|
|
845
|
+
"hq": {/* … */},
|
|
734
846
|
},
|
|
735
847
|
},
|
|
736
848
|
"site": {
|
|
737
849
|
"defaultLocale": "en",
|
|
738
|
-
"domains": {
|
|
739
|
-
|
|
740
|
-
},
|
|
741
|
-
"analytics": {
|
|
742
|
-
/* … */
|
|
743
|
-
},
|
|
850
|
+
"domains": {/* … */},
|
|
851
|
+
"analytics": {/* … */},
|
|
744
852
|
},
|
|
745
853
|
}
|
|
746
854
|
```
|
|
@@ -909,7 +1017,7 @@ open-fade-in"` composes slide and fade. Applied at zero specificity with identit
|
|
|
909
1017
|
Also new, and worth wiring at the same time — **`gitLastmod()` for real sitemap dates**:
|
|
910
1018
|
|
|
911
1019
|
```js
|
|
912
|
-
import vitops, { gitLastmod } from
|
|
1020
|
+
import vitops, { gitLastmod } from "@getvitops/astro";
|
|
913
1021
|
vitops({ sitemap: { serialize: await gitLastmod() } });
|
|
914
1022
|
```
|
|
915
1023
|
|
|
@@ -1009,8 +1117,8 @@ ffmpeg`, `apt install ffmpeg`, `winget install Gyan.FFmpeg`). The command fails
|
|
|
1009
1117
|
|
|
1010
1118
|
```js
|
|
1011
1119
|
vitops({
|
|
1012
|
-
analytics: { googleAnalytics:
|
|
1013
|
-
consent: { policyUrl:
|
|
1120
|
+
analytics: { googleAnalytics: "G-XXXXXXXXXX", plausible: "acme.com" },
|
|
1121
|
+
consent: { policyUrl: "/legal/cookies" },
|
|
1014
1122
|
});
|
|
1015
1123
|
```
|
|
1016
1124
|
|
|
@@ -1150,7 +1258,7 @@ inset(0 100% 0 0)`, and `clip-path` clips **hit-testing** as well as painting
|
|
|
1150
1258
|
|
|
1151
1259
|
```js
|
|
1152
1260
|
// astro.config.mjs
|
|
1153
|
-
getvitops({ css: { input:
|
|
1261
|
+
getvitops({ css: { input: "company.json", format: "css" } });
|
|
1154
1262
|
```
|
|
1155
1263
|
|
|
1156
1264
|
```
|
|
@@ -1249,11 +1357,11 @@ inset(0 100% 0 0)`, and `clip-path` clips **hit-testing** as well as painting
|
|
|
1249
1357
|
getvitops({
|
|
1250
1358
|
fonts: [
|
|
1251
1359
|
{
|
|
1252
|
-
name:
|
|
1253
|
-
provider:
|
|
1254
|
-
cssVariable:
|
|
1255
|
-
weights: [
|
|
1256
|
-
subsets: [
|
|
1360
|
+
name: "League Spartan",
|
|
1361
|
+
provider: "fontsource",
|
|
1362
|
+
cssVariable: "--font-league-spartan",
|
|
1363
|
+
weights: ["100 900"],
|
|
1364
|
+
subsets: ["latin"],
|
|
1257
1365
|
preload: true,
|
|
1258
1366
|
},
|
|
1259
1367
|
],
|
|
@@ -1481,14 +1589,14 @@ inset(0 100% 0 0)`, and `clip-path` clips **hit-testing** as well as painting
|
|
|
1481
1589
|
// astro.config.mjs
|
|
1482
1590
|
vitops({
|
|
1483
1591
|
seo: {
|
|
1484
|
-
siteName:
|
|
1485
|
-
titleTemplate:
|
|
1486
|
-
defaultDescription:
|
|
1592
|
+
siteName: "Acme",
|
|
1593
|
+
titleTemplate: "%s · Acme",
|
|
1594
|
+
defaultDescription: "We make the thing.",
|
|
1487
1595
|
openGraph: {
|
|
1488
|
-
locale:
|
|
1489
|
-
image: { url:
|
|
1596
|
+
locale: "en_CA",
|
|
1597
|
+
image: { url: "/og.png", alt: "Acme", width: 1200, height: 630 },
|
|
1490
1598
|
},
|
|
1491
|
-
twitter: { site:
|
|
1599
|
+
twitter: { site: "@acme" },
|
|
1492
1600
|
},
|
|
1493
1601
|
});
|
|
1494
1602
|
```
|
|
@@ -1532,7 +1640,7 @@ inset(0 100% 0 0)`, and `clip-path` clips **hit-testing** as well as painting
|
|
|
1532
1640
|
|
|
1533
1641
|
```js
|
|
1534
1642
|
getvitops({ sitemap: true });
|
|
1535
|
-
getvitops({ sitemap: { filter: (page) => !page.includes(
|
|
1643
|
+
getvitops({ sitemap: { filter: (page) => !page.includes("/draft/") } });
|
|
1536
1644
|
```
|
|
1537
1645
|
|
|
1538
1646
|
`@astrojs/sitemap` is an **optional peer** — install it yourself (`pnpm add -D @astrojs/sitemap`) and
|
|
@@ -1767,15 +1875,15 @@ inset(0 100% 0 0)`, and `clip-path` clips **hit-testing** as well as painting
|
|
|
1767
1875
|
which `@getvitops/astro` re-exports wholesale. So from `astro.config.mjs`:
|
|
1768
1876
|
|
|
1769
1877
|
```js
|
|
1770
|
-
import { generateIconInclude } from
|
|
1771
|
-
import icon from
|
|
1878
|
+
import { generateIconInclude } from "@getvitops/astro";
|
|
1879
|
+
import icon from "astro-icon";
|
|
1772
1880
|
|
|
1773
1881
|
integrations: [
|
|
1774
1882
|
icon({
|
|
1775
1883
|
include: generateIconInclude({
|
|
1776
|
-
ui:
|
|
1777
|
-
brand:
|
|
1778
|
-
semantic: [
|
|
1884
|
+
ui: "fa7-solid",
|
|
1885
|
+
brand: "simple-icons",
|
|
1886
|
+
semantic: ["menu", "close", "search", "github"],
|
|
1779
1887
|
}),
|
|
1780
1888
|
}),
|
|
1781
1889
|
];
|
|
@@ -1809,7 +1917,7 @@ inset(0 100% 0 0)`, and `clip-path` clips **hit-testing** as well as painting
|
|
|
1809
1917
|
```js
|
|
1810
1918
|
// astro.config.mjs
|
|
1811
1919
|
getvitops({
|
|
1812
|
-
css: { input:
|
|
1920
|
+
css: { input: "design-system.json", format: "css", out: "src/styles" },
|
|
1813
1921
|
editor: true,
|
|
1814
1922
|
});
|
|
1815
1923
|
```
|
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { n as TRACKING_ENDPOINT, r as resolveTracking, t as TRACKING_COOKIE } fr
|
|
|
2
2
|
import { cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { dirname, join, relative, resolve } from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
-
import { isConfig, resolveConfig } from "@getvitops/generator";
|
|
5
|
+
import { isConfig, renderRobotsTxt, resolveConfig } from "@getvitops/generator";
|
|
6
6
|
import { collectIconRefs, faviconLinks, generateFavicons, generateIconInclude, resolveIcon, scanFiles, writeFaviconManifest } from "@getvitops/utils";
|
|
7
7
|
import vitopsPlugin from "@getvitops/vite";
|
|
8
8
|
import { AD_PLATFORMS, AD_PROVIDER_KEYS } from "@getvitops/utils/ads";
|
|
@@ -672,14 +672,21 @@ function vitops(opts = {}) {
|
|
|
672
672
|
}
|
|
673
673
|
}
|
|
674
674
|
if (siteInput) try {
|
|
675
|
-
const
|
|
675
|
+
const cfg = resolveConfig(JSON.parse(readFileSync(resolve(root, siteInput), "utf8")), opts.site?.siteEnv ?? "production");
|
|
676
|
+
const key = cfg.site.seo?.indexing?.indexNow?.key;
|
|
676
677
|
if (key) {
|
|
677
678
|
mkdirSync(publicDir, { recursive: true });
|
|
678
679
|
writeFileSync(join(publicDir, `${key}.txt`), `${key}\n`);
|
|
679
680
|
logger.info(`IndexNow key file → public/${key}.txt`);
|
|
680
681
|
}
|
|
682
|
+
const robotsPath = join(publicDir, "robots.txt");
|
|
683
|
+
if (!existsSync(robotsPath)) {
|
|
684
|
+
mkdirSync(publicDir, { recursive: true });
|
|
685
|
+
writeFileSync(robotsPath, renderRobotsTxt(cfg, { env: opts.site?.siteEnv ?? "production" }));
|
|
686
|
+
logger.info("robots.txt → public/robots.txt");
|
|
687
|
+
}
|
|
681
688
|
} catch (err) {
|
|
682
|
-
logger.warn(`IndexNow key file skipped: ${err.message}`);
|
|
689
|
+
logger.warn(`IndexNow key file / robots.txt skipped: ${err.message}`);
|
|
683
690
|
}
|
|
684
691
|
let iconsData = null;
|
|
685
692
|
if (opts.icons) {
|