@getvitops/utils 6.0.0 → 7.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,122 @@
1
1
  # @getvitops/utils
2
2
 
3
+ ## 7.0.0
4
+
5
+ ### Minor Changes
6
+
7
+ - c0c092b: `vitops search` now works from a `gcloud` login, and attributes API usage per site.
8
+
9
+ **Being logged in is enough.** With no `VITOPS_GOOGLE_*` set, an Application Default Credentials
10
+ login is used — the credential `gcloud auth application-default login` already wrote. It needs the
11
+ Search Console scopes, which are not in the default ADC set:
12
+
13
+ ```
14
+ gcloud auth application-default login \
15
+ --scopes=openid,https://www.googleapis.com/auth/siteverification,\
16
+ https://www.googleapis.com/auth/webmasters,https://www.googleapis.com/auth/cloud-platform
17
+ ```
18
+
19
+ Explicit `VITOPS_GOOGLE_*` vars still win. Ambient credentials are only a fallback, because a stale
20
+ local login silently overriding a deliberate CI secret is the worst available precedence.
21
+
22
+ Beyond convenience, this removes a documented footgun: an OAuth client you create yourself sits in
23
+ _Testing_ publishing status, where Google **expires the refresh token after 7 days**. The Cloud SDK
24
+ client is published, so an ADC credential doesn't rot between onboarding runs.
25
+
26
+ **New: `site.google.project`** — the Google Cloud project API usage is attributed to, sent as
27
+ `x-goog-user-project`. One project per site is what keeps each site's usage and billing separate,
28
+ and it is the same field Maps or anything else will read later, rather than a `quotaProject` here
29
+ and a `mapsProject` there.
30
+
31
+ It is **required for a user credential and wrong for a service account**, which is why it is not
32
+ sent unconditionally. A user credential authenticates through a shared OAuth client that owns no
33
+ project, so Google refuses the call outright — measured: `403 "requires a quota project, which is
34
+ not set by default"`. A service account already belongs to a project, and pointing it at a
35
+ different one would newly require `serviceusage.services.use` there, turning a working CI
36
+ credential into a 403 for no benefit.
37
+
38
+ Using it needs both APIs (`searchconsole.googleapis.com`, `siteverification.googleapis.com`)
39
+ enabled on that project, and `serviceusage.services.use` for the identity — one grant per site,
40
+ which suits an agency administering many sites from one admin identity.
41
+
42
+ An ADC credential with no `site.google.project` is now **refused before any request is made**,
43
+ naming the file the credential came from and the project gcloud recorded with it:
44
+
45
+ ```
46
+ ✖ this Google credential comes from ~/.config/gcloud/application_default_credentials.json,
47
+ which authenticates through a shared OAuth client that owns no project — so it needs
48
+ "site.google.project" in site.json to say which project the API usage belongs to.
49
+ gcloud recorded "acme-web" as the quota project for that login, so that is probably the value.
50
+ ```
51
+
52
+ That is the mistake waiting for the _second_ site: the command gets copied from whatever
53
+ onboarded the first one, the field is left out, and Google's own answer names neither the config
54
+ field nor the credential.
55
+
56
+ **Fixed: an ADC file in `GOOGLE_APPLICATION_CREDENTIALS` no longer hard-exits.** That variable is
57
+ Google's own convention _and_ where gcloud writes ADC, so the same variable carries two kinds of
58
+ credential. Parsing an `authorized_user` file as a service account failed with `service account
59
+ JSON is missing client_email or private_key` — while holding a credential the command already knew
60
+ how to use. It is now discriminated on `type`, the field Google's own libraries switch on.
61
+
62
+ **Also fixed — `search setup --dry` and `--check` are not offline.** The docs implied otherwise. The
63
+ state gather runs before the planner, so both read from Cloudflare and Google and both need
64
+ credentials. They still create and change nothing; `notify --dry` remains genuinely request-free.
65
+
66
+ New in `@getvitops/utils/indexing`: `parseAdcUser`, `adcQuotaProject`, `adcCredentialsPath` (pure,
67
+ so what is decidable is asserted without a filesystem), plus `googleHeaders` and the `GoogleAuth` /
68
+ `GoogleAuthLike` types. The seven exported Google request functions now take a token **or** a
69
+ `{ token, quotaProject }` — a bare string still works everywhere, so nothing needs changing.
70
+
71
+ - **Added — `utils`.** `itemListGraph()`, a pure schema.org `ItemList` JSON-LD builder — a sibling
72
+ of `breadcrumbGraph()`/`localBusinessGraph()`. Extracted from `@getvitops/astro`'s `<Carousel />`
73
+ so any consumer can build a valid `ItemList` (Google's "all-in-one page" carousel format:
74
+ `ListItem.item` carrying `@type`/`name`/`url`) for content that isn't one of the six Google
75
+ carousel rich-result types (`Article`/`Recipe`/`Movie`/`Course`/`Restaurant`/`Product`) — the
76
+ entity type is no longer constrained to that set.
77
+
78
+ **Changed — `astro`.** `<Carousel />`'s `CarouselItem['type']` now accepts any string, not just
79
+ the six carousel rich-result types — non-breaking, the union only widens. It's a thin wrapper
80
+ over `itemListGraph()` now; behaviour for existing callers is unchanged.
81
+
82
+ No consumer-facing change in this release outside `utils` and `astro` — `generator`, `cli` and
83
+ `vite` still ship in this release only because the six share one version.
84
+
85
+ **Fixed — `core` (`css`/`bricks`/`tailwind` build output, all formats).** The CSS and HTML
86
+ authored inside Lit's `css`/`html` tagged templates in `<wc-*>` component sources previously
87
+ survived JS minification verbatim — a JS minifier treats a template literal's cooked text as
88
+ opaque, so `elements.js` shipped ~690 lines of indented, unminified CSS (and the equivalent in
89
+ HTML) inside an otherwise-minified 886-line file. Two source-level build transforms now collapse
90
+ both before bundling: `postcss` + `postcss-lit` + `cssnano` for `css` templates, `minify-html-literals`
91
+ (`conservativeCollapse: true`, so whitespace between inline elements in light-DOM components never
92
+ collapses to zero) for `html` templates. `elements.js` drops from 886 lines / ~101 KB to 49 lines /
93
+ ~96 KB. A second build step deduplicates the 17 `@license` comment blocks (only 6 are textually
94
+ distinct) down to one verbatim copy of each — required by BSD-3/MIT/Apache-2.0's notice-retention
95
+ terms either way, just no longer repeated once per source file that carries it. No API change;
96
+ build-time only, and none of the added tooling (`postcss`, `postcss-lit`, `cssnano`,
97
+ `minify-html-literals`) is a runtime or published dependency.
98
+
99
+ - 2b50f9e: Extract the LocalBusiness JSON-LD builder out of `<LocalBusiness />` into a reusable
100
+ `localBusinessGraph()`, and add the location fields listing platforms (GBP, Bing Places, Apple
101
+ Business Connect) actually need.
102
+
103
+ **Added — `@getvitops/utils`.** `localBusinessGraph(options)` (+ its `LocalBusinessGraphOptions`,
104
+ `OpeningHoursSpecification` and `SpecialHoursSpecification` types) is now exported from
105
+ `@getvitops/utils`, alongside the existing `organizationGraph`/`articleGraph`/`breadcrumbGraph`/
106
+ `faqGraph` builders — same module, same shape, usable anywhere a JSON-LD graph is built outside an
107
+ Astro component.
108
+
109
+ **Added — `authoring`/`config` (`@getvitops/generator`).** Four new `organization.locations.<slug>`
110
+ fields: `hoursSpecial` (dated deviations from the recurring `hours` — holiday hours, a one-off
111
+ closure), `photos` (`ImageRefSchema[]` → JSON-LD `image`), `sameAs` (this location's own listing
112
+ URLs, distinct from `organization.sameAs`, which is the company overall), and `listings` (external
113
+ listing ids keyed by platform — `google` | `bing` | `apple` — not consumed by the generator today;
114
+ recorded so a future listings-sync command has a stable id to match against).
115
+
116
+ **Changed — `astro`.** `<LocalBusiness />`'s `Props` type is now `LocalBusinessGraphOptions`
117
+ (re-exported, not redefined) rather than a local interface that had drifted from what the builder
118
+ actually accepted. No markup or prop-name change for an existing consumer.
119
+
3
120
  ## 6.0.0
4
121
 
5
122
  **No consumer-facing change in this package.** The major is the toolchain's shared version, bumped
package/dist/index.d.mts CHANGED
@@ -153,6 +153,95 @@ interface FAQGraphOptions {
153
153
  */
154
154
  declare function faqGraph(options: FAQGraphOptions): Record<string, unknown>;
155
155
  //#endregion
156
+ //#region src/schema/itemList.d.ts
157
+ type ItemListEntryType = 'Article' | 'Recipe' | 'Movie' | 'Course' | 'Restaurant' | 'Product' | (string & {});
158
+ interface ItemListEntry {
159
+ type: ItemListEntryType;
160
+ name: string;
161
+ /**
162
+ * Summary-page format: the item's own detail page (unique, same domain).
163
+ * All-in-one-page format: this page's URL plus an HTML anchor pointing at
164
+ * the item on it.
165
+ */
166
+ url: string;
167
+ image?: string;
168
+ description?: string;
169
+ }
170
+ interface ItemListGraphOptions {
171
+ items: ItemListEntry[];
172
+ /** Recommended, not required by the spec — names the list itself. */
173
+ name?: string;
174
+ }
175
+ /** Build a schema.org ItemList JSON-LD graph (e.g. for a carousel rich result). */
176
+ declare function itemListGraph(options: ItemListGraphOptions): Record<string, unknown>;
177
+ //#endregion
178
+ //#region src/schema/localBusiness.d.ts
179
+ interface OpeningHoursSpecification {
180
+ dayOfWeek: ('Monday' | 'Tuesday' | 'Wednesday' | 'Thursday' | 'Friday' | 'Saturday' | 'Sunday')[];
181
+ opens: string;
182
+ closes: string;
183
+ }
184
+ /**
185
+ * A dated deviation from the recurring `openingHoursSpecification` — holiday
186
+ * hours, a one-off closure, a temporary schedule. Same schema.org shape
187
+ * (`OpeningHoursSpecification`), distinguished by carrying `validFrom`. A full
188
+ * closure omits `opens`/`closes` rather than encoding it as an open interval.
189
+ */
190
+ interface SpecialHoursSpecification {
191
+ validFrom: string;
192
+ validThrough?: string;
193
+ opens?: string;
194
+ closes?: string;
195
+ }
196
+ interface LocalBusinessGraphOptions {
197
+ /** schema.org `LocalBusiness` subtype, e.g. `'Restaurant'`, `'ProfessionalService'`. Defaults to `'LocalBusiness'`. */
198
+ type?: string;
199
+ name: string;
200
+ description?: string;
201
+ url?: string;
202
+ telephone?: string;
203
+ email?: string;
204
+ image?: string | string[];
205
+ priceRange?: string;
206
+ address?: {
207
+ streetAddress?: string;
208
+ addressLocality?: string;
209
+ addressRegion?: string;
210
+ postalCode?: string;
211
+ addressCountry?: string;
212
+ };
213
+ geo?: {
214
+ latitude: number;
215
+ longitude: number;
216
+ };
217
+ openingHoursSpecification?: OpeningHoursSpecification[];
218
+ specialOpeningHoursSpecification?: SpecialHoursSpecification[];
219
+ aggregateRating?: {
220
+ ratingValue: number;
221
+ reviewCount?: number;
222
+ ratingCount?: number;
223
+ bestRating?: number;
224
+ worstRating?: number;
225
+ };
226
+ review?: {
227
+ author: string;
228
+ datePublished: string;
229
+ reviewBody: string;
230
+ reviewRating?: {
231
+ ratingValue: number;
232
+ bestRating?: number;
233
+ worstRating?: number;
234
+ };
235
+ }[];
236
+ paymentAccepted?: string[];
237
+ currenciesAccepted?: string;
238
+ areaServed?: string[];
239
+ sameAs?: string[];
240
+ knowsLanguage?: string[];
241
+ }
242
+ /** Build a schema.org LocalBusiness (or subtype) JSON-LD graph. */
243
+ declare function localBusinessGraph(options: LocalBusinessGraphOptions): Record<string, unknown>;
244
+ //#endregion
156
245
  //#region src/schema/organization.d.ts
157
246
  interface OrganizationGraphOptions {
158
247
  name: string;
@@ -799,5 +888,5 @@ declare function collectIconRefs(files: readonly {
799
888
  text: string;
800
889
  }[], opts?: IconScanOptions): IconScanResult;
801
890
  //#endregion
802
- export { type ArticleAuthor, type ArticleGraphOptions, type Attrs, type BrandIcon, type BreadcrumbGraphOptions, type BreadcrumbItem, type ChildNode, type ContentNode, type DynamicIconRef, type El, type Elmnt, type FAQGraphOptions, type FAQItem, type FaviconLink, type FaviconOptions, type FaviconTagOptions, type IconRef, type IconRefKind, type IconScanOptions, type IconScanResult, type IconSet, type ImageLink, type ImageRef, type Link, type Localizable, type OrganizationGraphOptions, SCAN_EXT, SCAN_SKIP, type ScanOptions, type SemanticIcon, type SourceFile, type StyleList, type StyleValue, type TextLink, WEIGHTED_SETS, type WebManifestOptions, articleGraph, breadcrumbGraph, collectIconRefs, extractIconRefs, faqGraph, faviconLinks, faviconManifest, generateFavicons, generateIconInclude, getAttribute, iconMap, isElmnt, isImageLink, isLink, isTextLink, nodesToHtml, organizationGraph, parseRenderedSlots, partAttrs, prefixToMapKey, resolveBrandIcon, resolveIcon, scanFiles, serialize, styleList, t, toHtml, writeFaviconManifest };
891
+ export { type ArticleAuthor, type ArticleGraphOptions, type Attrs, type BrandIcon, type BreadcrumbGraphOptions, type BreadcrumbItem, type ChildNode, type ContentNode, type DynamicIconRef, type El, type Elmnt, type FAQGraphOptions, type FAQItem, type FaviconLink, type FaviconOptions, type FaviconTagOptions, type IconRef, type IconRefKind, type IconScanOptions, type IconScanResult, type IconSet, type ImageLink, type ImageRef, type ItemListEntry, type ItemListEntryType, type ItemListGraphOptions, type Link, type LocalBusinessGraphOptions, type Localizable, type OpeningHoursSpecification, type OrganizationGraphOptions, SCAN_EXT, SCAN_SKIP, type ScanOptions, type SemanticIcon, type SourceFile, type SpecialHoursSpecification, type StyleList, type StyleValue, type TextLink, WEIGHTED_SETS, type WebManifestOptions, articleGraph, breadcrumbGraph, collectIconRefs, extractIconRefs, faqGraph, faviconLinks, faviconManifest, generateFavicons, generateIconInclude, getAttribute, iconMap, isElmnt, isImageLink, isLink, isTextLink, itemListGraph, localBusinessGraph, nodesToHtml, organizationGraph, parseRenderedSlots, partAttrs, prefixToMapKey, resolveBrandIcon, resolveIcon, scanFiles, serialize, styleList, t, toHtml, writeFaviconManifest };
803
892
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/content.ts","../src/html.ts","../src/schema/article.ts","../src/schema/breadcrumb.ts","../src/schema/faq.ts","../src/schema/organization.ts","../src/icons.ts","../src/scan.ts","../src/icons-scan.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/content.ts","../src/html.ts","../src/schema/article.ts","../src/schema/breadcrumb.ts","../src/schema/faq.ts","../src/schema/itemList.ts","../src/schema/localBusiness.ts","../src/schema/organization.ts","../src/icons.ts","../src/scan.ts","../src/icons-scan.ts"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -230,6 +230,101 @@ function faqGraph(options) {
230
230
  };
231
231
  }
232
232
 
233
+ //#endregion
234
+ //#region src/schema/itemList.ts
235
+ /** Build a schema.org ItemList JSON-LD graph (e.g. for a carousel rich result). */
236
+ function itemListGraph(options) {
237
+ const { items, name } = options;
238
+ return {
239
+ "@context": "https://schema.org",
240
+ "@type": "ItemList",
241
+ ...name && { name },
242
+ itemListElement: items.map((item, index) => ({
243
+ "@type": "ListItem",
244
+ position: index + 1,
245
+ item: {
246
+ "@type": item.type,
247
+ name: item.name,
248
+ url: item.url,
249
+ ...item.image && { image: item.image },
250
+ ...item.description && { description: item.description }
251
+ }
252
+ }))
253
+ };
254
+ }
255
+
256
+ //#endregion
257
+ //#region src/schema/localBusiness.ts
258
+ /** Build a schema.org LocalBusiness (or subtype) JSON-LD graph. */
259
+ function localBusinessGraph(options) {
260
+ const { type = "LocalBusiness", name, description, url, telephone, email, image, priceRange, address, geo, openingHoursSpecification, specialOpeningHoursSpecification, aggregateRating, review, paymentAccepted, currenciesAccepted, areaServed, sameAs, knowsLanguage } = options;
261
+ const hours = [...(openingHoursSpecification ?? []).map((spec) => ({
262
+ "@type": "OpeningHoursSpecification",
263
+ dayOfWeek: spec.dayOfWeek,
264
+ opens: spec.opens,
265
+ closes: spec.closes
266
+ })), ...(specialOpeningHoursSpecification ?? []).map((spec) => ({
267
+ "@type": "OpeningHoursSpecification",
268
+ validFrom: spec.validFrom,
269
+ ...spec.validThrough && { validThrough: spec.validThrough },
270
+ ...spec.opens && { opens: spec.opens },
271
+ ...spec.closes && { closes: spec.closes }
272
+ }))];
273
+ return {
274
+ "@context": "https://schema.org",
275
+ "@type": type,
276
+ name,
277
+ ...description && { description },
278
+ ...url && { url },
279
+ ...telephone && { telephone },
280
+ ...email && { email },
281
+ ...image && { image: Array.isArray(image) ? image : [image] },
282
+ ...priceRange && { priceRange },
283
+ ...address && { address: {
284
+ "@type": "PostalAddress",
285
+ ...address.streetAddress && { streetAddress: address.streetAddress },
286
+ ...address.addressLocality && { addressLocality: address.addressLocality },
287
+ ...address.addressRegion && { addressRegion: address.addressRegion },
288
+ ...address.postalCode && { postalCode: address.postalCode },
289
+ ...address.addressCountry && { addressCountry: address.addressCountry }
290
+ } },
291
+ ...geo && { geo: {
292
+ "@type": "GeoCoordinates",
293
+ latitude: geo.latitude,
294
+ longitude: geo.longitude
295
+ } },
296
+ ...hours.length > 0 && { openingHoursSpecification: hours },
297
+ ...aggregateRating && { aggregateRating: {
298
+ "@type": "AggregateRating",
299
+ ratingValue: aggregateRating.ratingValue,
300
+ ...aggregateRating.reviewCount && { reviewCount: aggregateRating.reviewCount },
301
+ ...aggregateRating.ratingCount && { ratingCount: aggregateRating.ratingCount },
302
+ bestRating: aggregateRating.bestRating ?? 5,
303
+ worstRating: aggregateRating.worstRating ?? 1
304
+ } },
305
+ ...review && { review: review.map((r) => ({
306
+ "@type": "Review",
307
+ author: {
308
+ "@type": "Person",
309
+ name: r.author
310
+ },
311
+ datePublished: r.datePublished,
312
+ reviewBody: r.reviewBody,
313
+ ...r.reviewRating && { reviewRating: {
314
+ "@type": "Rating",
315
+ ratingValue: r.reviewRating.ratingValue,
316
+ bestRating: r.reviewRating.bestRating ?? 5,
317
+ worstRating: r.reviewRating.worstRating ?? 1
318
+ } }
319
+ })) },
320
+ ...paymentAccepted && { paymentAccepted },
321
+ ...currenciesAccepted && { currenciesAccepted },
322
+ ...areaServed && { areaServed },
323
+ ...sameAs && { sameAs },
324
+ ...knowsLanguage && { knowsLanguage }
325
+ };
326
+ }
327
+
233
328
  //#endregion
234
329
  //#region src/schema/organization.ts
235
330
  /** Build a schema.org Organization JSON-LD graph. */
@@ -1079,5 +1174,5 @@ function collectIconRefs(files, opts) {
1079
1174
  }
1080
1175
 
1081
1176
  //#endregion
1082
- export { SCAN_EXT, SCAN_SKIP, WEIGHTED_SETS, articleGraph, breadcrumbGraph, collectIconRefs, extractIconRefs, faqGraph, faviconLinks, faviconManifest, generateFavicons, generateIconInclude, getAttribute, iconMap, isElmnt, isImageLink, isLink, isTextLink, nodesToHtml, organizationGraph, parseRenderedSlots, partAttrs, prefixToMapKey, resolveBrandIcon, resolveIcon, scanFiles, serialize, styleList, t, toHtml, writeFaviconManifest };
1177
+ export { SCAN_EXT, SCAN_SKIP, WEIGHTED_SETS, articleGraph, breadcrumbGraph, collectIconRefs, extractIconRefs, faqGraph, faviconLinks, faviconManifest, generateFavicons, generateIconInclude, getAttribute, iconMap, isElmnt, isImageLink, isLink, isTextLink, itemListGraph, localBusinessGraph, nodesToHtml, organizationGraph, parseRenderedSlots, partAttrs, prefixToMapKey, resolveBrandIcon, resolveIcon, scanFiles, serialize, styleList, t, toHtml, writeFaviconManifest };
1083
1178
  //# sourceMappingURL=index.mjs.map