@duffcloudservices/cms 0.10.0 → 0.12.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/README.md +59 -2
- package/dist/chunk-DAYLLSEE.js +3 -0
- package/dist/{chunk-KCWMS7P4.js.map → chunk-DAYLLSEE.js.map} +1 -1
- package/dist/{chunk-UPAMLKOQ.js → chunk-F3EIWEZD.js} +158 -11
- package/dist/chunk-F3EIWEZD.js.map +1 -0
- package/dist/editor/editorBridge.d.ts +41 -1
- package/dist/editor/editorBridge.js +68 -2
- package/dist/editor/editorBridge.js.map +1 -1
- package/dist/index.d.ts +78 -6
- package/dist/index.js +91 -7
- package/dist/index.js.map +1 -1
- package/dist/plugins/index.d.ts +174 -3
- package/dist/plugins/index.js +448 -87
- package/dist/plugins/index.js.map +1 -1
- package/dist/seo/index.d.ts +132 -226
- package/dist/seo/index.js +2 -2
- package/dist/spliceHeadHtml-CsBEucGy.d.ts +254 -0
- package/dist/{vitepressTransform-DeEzgGWU.d.ts → vitepressTransform-DfmABXmK.d.ts} +53 -2
- package/package.json +25 -14
- package/src/components/DcsCallButton.test.ts +126 -0
- package/src/components/DcsCallButton.vue +185 -0
- package/src/components/DcsReviewShowcase.vue +18 -3
- package/src/components/LiteMediaEmbed.test.ts +229 -0
- package/src/components/LiteMediaEmbed.vue +399 -0
- package/src/components/ManagedImage.test.ts +60 -0
- package/src/components/ManagedImage.vue +53 -6
- package/src/composables/useMediaCarousel.ts +6 -1
- package/src/composables/useResponsiveImage.ts +6 -0
- package/src/composables/useReviewContent.test.ts +86 -0
- package/src/composables/useReviewContent.ts +34 -2
- package/src/composables/useSiteVisitorSession.test.ts +120 -0
- package/src/composables/useSiteVisitorSession.ts +160 -0
- package/dist/chunk-KCWMS7P4.js +0 -3
- package/dist/chunk-UPAMLKOQ.js.map +0 -1
package/dist/plugins/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Plugin, HtmlTagDescriptor } from 'vite';
|
|
2
|
-
import { D as DcsRobotsOptions,
|
|
3
|
-
export {
|
|
2
|
+
import { D as DcsRobotsOptions, Y as PageRouteEntry, H as SeoConfiguration, E as ContentConfig } from '../vitepressTransform-DfmABXmK.js';
|
|
3
|
+
export { C as CreateSeoTransformPageDataOptions, R as ResolvedPageOverrides, S as SeoPageContext, r as SeoPageTypeRule, t as VitePressHeadConfig, V as VitePressPageData, b as buildVitePressSeoHead, c as createSeoTransformPageData, d as defaultRelativePathToRoute } from '../vitepressTransform-DfmABXmK.js';
|
|
4
4
|
import { Component, Plugin as Plugin$1 } from 'vue';
|
|
5
5
|
import MarkdownIt from 'markdown-it';
|
|
6
6
|
|
|
@@ -109,6 +109,22 @@ interface DcsSeoPluginOptions {
|
|
|
109
109
|
* site that bakes its own SEO are unaffected when this is off.
|
|
110
110
|
*/
|
|
111
111
|
emitStaticHtml?: boolean;
|
|
112
|
+
/**
|
|
113
|
+
* Build-time BODY prerender: after the per-route `<head>` is emitted, render
|
|
114
|
+
* each indexable route's real DOM from the just-built SPA (headless Chromium
|
|
115
|
+
* via the site's `playwright`) and splice it into the mount container so non-JS
|
|
116
|
+
* AI crawlers see the page's body prose — not just `<div id="app"></div>`.
|
|
117
|
+
*
|
|
118
|
+
* Defaults to whatever `emitStaticHtml` is, so every SPA already emitting
|
|
119
|
+
* per-route HTML gains crawler-visible bodies on a cms bump with no per-site
|
|
120
|
+
* edit. Set `false` here to keep head-only emission. It is ALSO overridable
|
|
121
|
+
* per-site (no code change / no cms republish) via `.dcs/seo.yaml`
|
|
122
|
+
* `prerenderBody: false`. noindex/auth-gated routes are never body-prerendered;
|
|
123
|
+
* a route that crashes at render time fails the build loud rather than shipping
|
|
124
|
+
* a broken body. Requires `playwright` in the site (already the fleet default);
|
|
125
|
+
* absent ⇒ graceful no-op (head + JSON-LD still emitted).
|
|
126
|
+
*/
|
|
127
|
+
prerenderBody?: boolean;
|
|
112
128
|
/**
|
|
113
129
|
* Path to the route manifest relative to project root, used only when
|
|
114
130
|
* `emitStaticHtml` is true. Default `'.dcs/pages.yaml'`.
|
|
@@ -467,6 +483,89 @@ declare function dcsCdnBuildEnd(options?: DcsCdnBuildEndOptions): (siteConfig: {
|
|
|
467
483
|
|
|
468
484
|
declare function responsiveImagePlugin(md: MarkdownIt): void;
|
|
469
485
|
|
|
486
|
+
/**
|
|
487
|
+
* Build-time responsive-variant lint for DCS customer sites.
|
|
488
|
+
*
|
|
489
|
+
* The 2026-07-03 flagship-excellence review (P7) found desktop pages shipping
|
|
490
|
+
* un-suffixed **full-size** CDN images (e.g. a 321.9 KB hero `47af1e8f….webp`)
|
|
491
|
+
* instead of a `-md`/`-lg` responsive step. That happens when an image reaches
|
|
492
|
+
* the output HTML through a path that does NOT run the `<img>` → `<picture>`
|
|
493
|
+
* transform — content injected via `__DCS_CONTENT__` and then swapped to the
|
|
494
|
+
* base `cdnUrl` by `dcsCdnBuildEnd`, or a hand-authored `<img src>` pointing at
|
|
495
|
+
* a base CDN asset URL.
|
|
496
|
+
*
|
|
497
|
+
* A DCS CDN asset URL has the shape
|
|
498
|
+
* `https://files.<host>/[content/]<slug>/assets/[<dir>/]<uuid>.<ext>`
|
|
499
|
+
* Responsive variants insert a `-sm`/`-md`/`-lg` suffix before the extension
|
|
500
|
+
* (`…<uuid>-md.webp`). Those suffixes contain non-hex letters, so a URL that
|
|
501
|
+
* still matches the *base* pattern below is, by definition, an un-suffixed
|
|
502
|
+
* full-size asset. This lint scans the built HTML's `<img src>` and
|
|
503
|
+
* `<source srcset>` attributes for such URLs and reports (or fails on) them.
|
|
504
|
+
*
|
|
505
|
+
* It is intentionally a **static-output** lint (VitePress generates HTML after
|
|
506
|
+
* both Vite builds finish, so a Vite plugin hook cannot see the SSG output) and
|
|
507
|
+
* is registered via VitePress `buildEnd`.
|
|
508
|
+
*
|
|
509
|
+
* @example
|
|
510
|
+
* ```ts
|
|
511
|
+
* // .vitepress/config.ts
|
|
512
|
+
* import { dcsCdnBuildEnd, dcsResponsiveImageLint, chainBuildEnd } from '@duffcloudservices/cms/plugins'
|
|
513
|
+
*
|
|
514
|
+
* export default defineConfig({
|
|
515
|
+
* // run the CDN rewrite first, then lint the result
|
|
516
|
+
* buildEnd: chainBuildEnd(dcsCdnBuildEnd(), dcsResponsiveImageLint()),
|
|
517
|
+
* })
|
|
518
|
+
* ```
|
|
519
|
+
*/
|
|
520
|
+
interface ResponsiveImageViolation {
|
|
521
|
+
/** The un-suffixed full-size CDN URL that should have been a responsive variant. */
|
|
522
|
+
url: string;
|
|
523
|
+
/** Which element referenced it. */
|
|
524
|
+
tag: 'img' | 'source';
|
|
525
|
+
}
|
|
526
|
+
/** True when `url` is a base (un-suffixed, full-size) DCS CDN asset URL. */
|
|
527
|
+
declare function isFullSizeCdnUrl(url: string): boolean;
|
|
528
|
+
/**
|
|
529
|
+
* Scan an HTML string and return every `<img src>` / `<source srcset>` reference
|
|
530
|
+
* that resolves to a base (un-suffixed) full-size DCS CDN asset. `srcset`
|
|
531
|
+
* candidates are split on commas and only the URL portion (before the width /
|
|
532
|
+
* density descriptor) is tested. `onerror` and other attributes are ignored —
|
|
533
|
+
* only the actual `src` / `srcset` sources are inspected.
|
|
534
|
+
*/
|
|
535
|
+
declare function findFullSizeCdnImages(html: string): ResponsiveImageViolation[];
|
|
536
|
+
interface DcsResponsiveImageLintOptions {
|
|
537
|
+
/**
|
|
538
|
+
* Throw (fail the build) when full-size images are found. Default `false`
|
|
539
|
+
* (warn only) so the guard can land ahead of the per-site cleanup; flip to
|
|
540
|
+
* `true` in CI once a site's output is clean to prevent regressions.
|
|
541
|
+
*/
|
|
542
|
+
failOnViolation?: boolean;
|
|
543
|
+
/** File extensions to scan in the output directory. Default `['.html']`. */
|
|
544
|
+
extensions?: string[];
|
|
545
|
+
/** Enable per-file debug logging. */
|
|
546
|
+
debug?: boolean;
|
|
547
|
+
}
|
|
548
|
+
interface ResponsiveImageLintReport {
|
|
549
|
+
filesScanned: number;
|
|
550
|
+
violations: Array<ResponsiveImageViolation & {
|
|
551
|
+
file: string;
|
|
552
|
+
}>;
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* VitePress `buildEnd` factory that lints the generated HTML for un-suffixed
|
|
556
|
+
* full-size CDN images. Returns the report (also useful for tests) and either
|
|
557
|
+
* warns or throws depending on `failOnViolation`.
|
|
558
|
+
*/
|
|
559
|
+
declare function dcsResponsiveImageLint(options?: DcsResponsiveImageLintOptions): (siteConfig: {
|
|
560
|
+
outDir: string;
|
|
561
|
+
}) => Promise<ResponsiveImageLintReport>;
|
|
562
|
+
/**
|
|
563
|
+
* Compose multiple VitePress `buildEnd` hooks into one (VitePress accepts a
|
|
564
|
+
* single `buildEnd`). Hooks run sequentially in the order given, so a rewrite
|
|
565
|
+
* hook (`dcsCdnBuildEnd`) can precede a lint (`dcsResponsiveImageLint`).
|
|
566
|
+
*/
|
|
567
|
+
declare function chainBuildEnd<T>(...hooks: Array<((siteConfig: T) => unknown | Promise<unknown>) | undefined | null>): (siteConfig: T) => Promise<void>;
|
|
568
|
+
|
|
470
569
|
/**
|
|
471
570
|
* DCS motion tokens — the customer-site copy of the shared motion vocabulary.
|
|
472
571
|
*
|
|
@@ -489,4 +588,76 @@ declare const DCS_MOTION_TOKENS_CSS = ":root {\n --motion-duration-stagger: 40m
|
|
|
489
588
|
*/
|
|
490
589
|
declare function dcsMotionTokensStyleTag(): HtmlTagDescriptor;
|
|
491
590
|
|
|
492
|
-
|
|
591
|
+
/**
|
|
592
|
+
* DCS AI-assistant widget loader — the cms head-inject seam for Phase 3 of the
|
|
593
|
+
* Managed Site AI Agents plan (.docs/plans/managed-site-ai-agents/plan.md).
|
|
594
|
+
*
|
|
595
|
+
* This rides the same always-on `dcsContentPlugin.transformIndexHtml` seam that
|
|
596
|
+
* ships the motion tokens: every DCS site already wires `dcsContentPlugin`, so a
|
|
597
|
+
* cms version bump delivers this loader to the whole fleet with ZERO per-site
|
|
598
|
+
* source edits, and the portal per-site toggle turns the widget on/off at
|
|
599
|
+
* runtime with no rebuild.
|
|
600
|
+
*
|
|
601
|
+
* What gets injected is a tiny (<2 KB) inline `<script>` — NOT the widget. On
|
|
602
|
+
* idle it fetches the public agent config for this site; only if the agent is
|
|
603
|
+
* enabled (HTTP 200) does it publish `window.__DCS_AGENT_BOOTSTRAP__` and inject
|
|
604
|
+
* the real widget bundle from the CDN. The loader is **fail-silent**: a disabled
|
|
605
|
+
* agent (404), a dead backend, a blocked request, or a malformed response all
|
|
606
|
+
* result in no mount and no console error, so the assistant can never break a
|
|
607
|
+
* customer page.
|
|
608
|
+
*
|
|
609
|
+
* Build-only: the loader is injected into the production build output (the fleet
|
|
610
|
+
* delivery), not into `vite dev`. In local dev the config fetch would hit the
|
|
611
|
+
* prod API from a non-whitelisted `localhost` origin and log an uncatchable CORS
|
|
612
|
+
* error for every site developer — so, unlike the constant motion-token block,
|
|
613
|
+
* this network-touching loader stays out of the dev server.
|
|
614
|
+
*/
|
|
615
|
+
|
|
616
|
+
/** DCS API origin the loader calls (matches the cms runtime composables). */
|
|
617
|
+
declare const DEFAULT_AGENT_API_BASE_URL = "https://portal.duffcloudservices.com";
|
|
618
|
+
/**
|
|
619
|
+
* Versioned CDN URL of the widget bundle. Both `cdn.` (branding CDN, CorsAllowAll)
|
|
620
|
+
* and the already-live `files.` route serve the same `sgdcs` blob origin with an
|
|
621
|
+
* identical `/agent-widget/v1/...` layout, so this is a plain classic-script
|
|
622
|
+
* include that needs no CORS on the bundle host. Defaults to `files.` because the
|
|
623
|
+
* `cdn.` Front Door route is still provisioning-gated (enableCdnDomain=false) —
|
|
624
|
+
* flip the default only after that domain is live, or pass cdnScriptUrl.
|
|
625
|
+
*/
|
|
626
|
+
declare const DEFAULT_AGENT_WIDGET_SCRIPT_URL = "https://files.duffcloudservices.com/agent-widget/v1/dcs-agent-widget.js";
|
|
627
|
+
interface DcsAgentWidgetLoaderOptions {
|
|
628
|
+
/** Owning site slug — baked into the loader so it can build the config URL. */
|
|
629
|
+
siteSlug: string;
|
|
630
|
+
/** DCS API base (default: the shared portal origin). */
|
|
631
|
+
apiBaseUrl?: string;
|
|
632
|
+
/** Full URL of the CDN widget bundle. */
|
|
633
|
+
cdnScriptUrl?: string;
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* Builds the inline loader script body. Slug + URLs are HTML-safe-encoded (see
|
|
637
|
+
* encodeForInlineScript) so no value can break out of the string literal OR the
|
|
638
|
+
* `<script>` element. Kept intentionally compact to stay under the ~2 KB perf
|
|
639
|
+
* budget (G4).
|
|
640
|
+
*/
|
|
641
|
+
declare function buildAgentWidgetLoaderScript(options: DcsAgentWidgetLoaderOptions): string;
|
|
642
|
+
/**
|
|
643
|
+
* Reads `site_slug` from the site's `.dcs/site.yaml` (the same identity file the
|
|
644
|
+
* announcements/provisioning path uses). Returns null when no site.yaml exists
|
|
645
|
+
* or it carries no slug — the caller then injects nothing (silence for non-DCS
|
|
646
|
+
* builds).
|
|
647
|
+
*/
|
|
648
|
+
declare function readSiteSlug(projectRoot: string): string | null;
|
|
649
|
+
interface DcsAgentWidgetTagOptions {
|
|
650
|
+
/** Vite project root used to resolve the site slug. */
|
|
651
|
+
projectRoot: string;
|
|
652
|
+
/** Override the DCS API base (default: process.env.VITE_API_BASE_URL, else the shared origin). */
|
|
653
|
+
apiBaseUrl?: string;
|
|
654
|
+
/** Override the CDN bundle URL. */
|
|
655
|
+
cdnScriptUrl?: string;
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* The `<head>` tag descriptor for the loader, or `null` when this build is not a
|
|
659
|
+
* DCS-managed site (no resolvable slug) — in which case nothing is injected.
|
|
660
|
+
*/
|
|
661
|
+
declare function dcsAgentWidgetLoaderTag(options: DcsAgentWidgetTagOptions): HtmlTagDescriptor | null;
|
|
662
|
+
|
|
663
|
+
export { DCS_MOTION_TOKENS_CSS, DEFAULT_AGENT_API_BASE_URL, DEFAULT_AGENT_WIDGET_SCRIPT_URL, type DcsAgentWidgetLoaderOptions, type DcsAgentWidgetTagOptions, type DcsCdnBuildEndOptions, type DcsCdnImagePluginOptions, type DcsContentPluginOptions, type DcsEditorPluginOptions, type DcsPreviewPluginOptions, type DcsResponsiveImageLintOptions, type DcsSeoPluginOptions, type ResponsiveImageLintReport, type ResponsiveImageViolation, buildAgentWidgetLoaderScript, chainBuildEnd, dcsAgentWidgetLoaderTag, dcsCdnBuildEnd, dcsCdnImagePlugin, dcsContentPlugin, dcsEditorPlugin, dcsMotionTokensStyleTag, dcsPreviewPlugin, dcsResponsiveImageLint, dcsSeoPlugin, emitSiteFiles, emitStaticSeoHtml, findFullSizeCdnImages, isFullSizeCdnUrl, readSiteSlug, responsiveImagePlugin };
|