@407dev/cms-astro 1.0.0 → 1.0.2

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.
@@ -0,0 +1,76 @@
1
+ // src/image.ts
2
+ var CDN_IMAGE_WIDTHS = [320, 400, 640, 800, 1024, 1280, 1600, 1920, 2560];
3
+ var ALLOWED_IMAGE_FITS = ["scale-down", "contain", "cover", "crop", "pad"];
4
+ var ALLOWED_IMAGE_QUALITIES = [60, 75, 80, 85, 90, 100];
5
+ function snapToAllowedWidth(width) {
6
+ let closest = CDN_IMAGE_WIDTHS[0];
7
+ let minDiff = Math.abs(width - closest);
8
+ for (const w of CDN_IMAGE_WIDTHS) {
9
+ const diff = Math.abs(width - w);
10
+ if (diff < minDiff) {
11
+ minDiff = diff;
12
+ closest = w;
13
+ }
14
+ }
15
+ return closest;
16
+ }
17
+ function snapToAllowedQuality(quality) {
18
+ let closest = ALLOWED_IMAGE_QUALITIES[0];
19
+ let minDiff = Math.abs(quality - closest);
20
+ for (const q of ALLOWED_IMAGE_QUALITIES) {
21
+ const diff = Math.abs(quality - q);
22
+ if (diff < minDiff) {
23
+ minDiff = diff;
24
+ closest = q;
25
+ }
26
+ }
27
+ return closest;
28
+ }
29
+ var CMS_ASSET_PATH_REGEX = /^\/sites\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\/assets\/.+/i;
30
+ function isCdnTransformableUrl(url) {
31
+ if (!url || typeof url !== "string") return false;
32
+ if (url.startsWith("data:") || url.startsWith("blob:")) return false;
33
+ if (url.includes("localhost") || url.includes("127.0.0.1") || url.includes(".r2.dev")) {
34
+ return false;
35
+ }
36
+ try {
37
+ const parsed = new URL(url);
38
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
39
+ return false;
40
+ }
41
+ return CMS_ASSET_PATH_REGEX.test(parsed.pathname);
42
+ } catch {
43
+ return false;
44
+ }
45
+ }
46
+ function buildCdnImageUrl(url, options = {}) {
47
+ if (!isCdnTransformableUrl(url)) {
48
+ return url;
49
+ }
50
+ const params = [];
51
+ if (options.width !== void 0 && options.width !== null) {
52
+ params.push(`width=${snapToAllowedWidth(options.width)}`);
53
+ }
54
+ if (options.fit && ALLOWED_IMAGE_FITS.includes(options.fit)) {
55
+ params.push(`fit=${options.fit}`);
56
+ }
57
+ if (options.quality !== void 0 && options.quality !== null && ALLOWED_IMAGE_QUALITIES.includes(options.quality)) {
58
+ params.push(`quality=${options.quality}`);
59
+ }
60
+ if (params.length === 0) {
61
+ return url;
62
+ }
63
+ const optionString = params.join(",");
64
+ const { origin, pathname, search } = new URL(url);
65
+ return `${origin}/img/${optionString}${pathname}${search}`;
66
+ }
67
+ function buildSrcSet(url, widths = CDN_IMAGE_WIDTHS, options = {}) {
68
+ if (!url) return "";
69
+ if (!isCdnTransformableUrl(url)) return "";
70
+ const snappedWidths = Array.from(new Set(widths.map((w) => snapToAllowedWidth(w))));
71
+ return snappedWidths.map((w) => `${buildCdnImageUrl(url, { ...options, width: w })} ${w}w`).join(", ");
72
+ }
73
+
74
+ export { ALLOWED_IMAGE_FITS, ALLOWED_IMAGE_QUALITIES, CDN_IMAGE_WIDTHS, buildCdnImageUrl, buildSrcSet, isCdnTransformableUrl, snapToAllowedQuality, snapToAllowedWidth };
75
+ //# sourceMappingURL=chunk-6FH3C4FF.js.map
76
+ //# sourceMappingURL=chunk-6FH3C4FF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/image.ts"],"names":[],"mappings":"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","file":"chunk-6FH3C4FF.js","sourcesContent":["export const CDN_IMAGE_WIDTHS = [320, 400, 640, 800, 1024, 1280, 1600, 1920, 2560] as const;\nexport type CdnImageWidth = (typeof CDN_IMAGE_WIDTHS)[number];\n\nexport const ALLOWED_IMAGE_FITS = ['scale-down', 'contain', 'cover', 'crop', 'pad'] as const;\nexport type CdnImageFit = (typeof ALLOWED_IMAGE_FITS)[number];\n\nexport const ALLOWED_IMAGE_QUALITIES = [60, 75, 80, 85, 90, 100] as const;\nexport type CdnImageQuality = (typeof ALLOWED_IMAGE_QUALITIES)[number];\n\nexport interface ImageTransformOptions {\n width?: number;\n fit?: CdnImageFit;\n quality?: CdnImageQuality | number;\n}\n\nexport function snapToAllowedWidth(width: number): CdnImageWidth {\n let closest: CdnImageWidth = CDN_IMAGE_WIDTHS[0];\n let minDiff = Math.abs(width - closest);\n for (const w of CDN_IMAGE_WIDTHS) {\n const diff = Math.abs(width - w);\n if (diff < minDiff) {\n minDiff = diff;\n closest = w;\n }\n }\n return closest;\n}\n\nexport function snapToAllowedQuality(quality: number): CdnImageQuality {\n let closest: CdnImageQuality = ALLOWED_IMAGE_QUALITIES[0];\n let minDiff = Math.abs(quality - closest);\n for (const q of ALLOWED_IMAGE_QUALITIES) {\n const diff = Math.abs(quality - q);\n if (diff < minDiff) {\n minDiff = diff;\n closest = q;\n }\n }\n return closest;\n}\n\nconst CMS_ASSET_PATH_REGEX =\n /^\\/sites\\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\\/assets\\/.+/i;\n\nexport function isCdnTransformableUrl(url: string): boolean {\n if (!url || typeof url !== 'string') return false;\n if (url.startsWith('data:') || url.startsWith('blob:')) return false;\n if (url.includes('localhost') || url.includes('127.0.0.1') || url.includes('.r2.dev')) {\n return false;\n }\n try {\n const parsed = new URL(url);\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n return false;\n }\n return CMS_ASSET_PATH_REGEX.test(parsed.pathname);\n } catch {\n return false;\n }\n}\n\nexport function buildCdnImageUrl(url: string, options: ImageTransformOptions = {}): string {\n if (!isCdnTransformableUrl(url)) {\n return url;\n }\n\n const params: string[] = [];\n if (options.width !== undefined && options.width !== null) {\n params.push(`width=${snapToAllowedWidth(options.width)}`);\n }\n if (options.fit && (ALLOWED_IMAGE_FITS as readonly string[]).includes(options.fit)) {\n params.push(`fit=${options.fit}`);\n }\n if (\n options.quality !== undefined &&\n options.quality !== null &&\n (ALLOWED_IMAGE_QUALITIES as readonly number[]).includes(options.quality as CdnImageQuality)\n ) {\n params.push(`quality=${options.quality}`);\n }\n\n if (params.length === 0) {\n return url;\n }\n\n const optionString = params.join(',');\n const { origin, pathname, search } = new URL(url);\n return `${origin}/img/${optionString}${pathname}${search}`;\n}\n\nexport function buildSrcSet(\n url: string,\n widths: readonly number[] | number[] = CDN_IMAGE_WIDTHS,\n options: Omit<ImageTransformOptions, 'width'> = {},\n): string {\n if (!url) return '';\n if (!isCdnTransformableUrl(url)) return '';\n\n const snappedWidths = Array.from(new Set(widths.map((w) => snapToAllowedWidth(w))));\n return snappedWidths\n .map((w) => `${buildCdnImageUrl(url, { ...options, width: w })} ${w}w`)\n .join(', ');\n}\n"]}
@@ -88,6 +88,16 @@ var darkTokens = {
88
88
  // blue-950
89
89
  infoBorder: "#1e40af",
90
90
  // blue-800
91
+ // Categorical: Highlight (violet)
92
+ highlight: "#a78bfa",
93
+ // violet-400
94
+ highlightForeground: "#ffffff",
95
+ highlightText: "#c4b5fd",
96
+ // violet-300
97
+ highlightMuted: "#2e1065",
98
+ // violet-950
99
+ highlightBorder: "#5b21b6",
100
+ // violet-800
91
101
  // Sidebar
92
102
  sidebar: "#171717",
93
103
  sidebarForeground: "#f5f5f5",
@@ -114,5 +124,5 @@ var chromeTokens = {
114
124
  };
115
125
 
116
126
  export { chromeTokens };
117
- //# sourceMappingURL=chunk-2TKIQIOE.js.map
118
- //# sourceMappingURL=chunk-2TKIQIOE.js.map
127
+ //# sourceMappingURL=chunk-AIUAT7FF.js.map
128
+ //# sourceMappingURL=chunk-AIUAT7FF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../design-tokens/src/tokens.ts"],"names":[],"mappings":";AA2JO,IAAM,UAAA,GAA+B;AAAA;AAAA,EAE1C,UAAA,EAAY,SAAA;AAAA;AAAA,EACZ,IAAA,EAAM,SAAA;AAAA;AAAA,EACN,cAAA,EAAgB,SAAA;AAAA;AAAA,EAChB,OAAA,EAAS,SAAA;AAAA,EACT,iBAAA,EAAmB,SAAA;AAAA,EACnB,KAAA,EAAO,SAAA;AAAA;AAAA,EACP,eAAA,EAAiB,SAAA;AAAA;AAAA,EACjB,WAAA,EAAa,SAAA;AAAA;AAAA,EACb,MAAA,EAAQ,SAAA;AAAA;AAAA,EACR,SAAA,EAAW,SAAA;AAAA,EACX,mBAAA,EAAqB,SAAA;AAAA,EACrB,MAAA,EAAQ,SAAA;AAAA,EACR,gBAAA,EAAkB,SAAA;AAAA;AAAA,EAGlB,UAAA,EAAY,SAAA;AAAA;AAAA,EACZ,mBAAA,EAAqB,SAAA;AAAA;AAAA,EACrB,gBAAA,EAAkB,SAAA;AAAA;AAAA;AAAA,EAGlB,MAAA,EAAQ,SAAA;AAAA;AAAA,EACR,YAAA,EAAc,SAAA;AAAA;AAAA,EACd,KAAA,EAAO,SAAA;AAAA;AAAA,EACP,WAAA,EAAa,SAAA;AAAA,EACb,IAAA,EAAM,SAAA;AAAA;AAAA;AAAA,EAGN,OAAA,EAAS,SAAA;AAAA;AAAA,EACT,iBAAA,EAAmB,SAAA;AAAA,EACnB,WAAA,EAAa,SAAA;AAAA;AAAA,EACb,YAAA,EAAc,SAAA;AAAA;AAAA,EACd,aAAA,EAAe,SAAA;AAAA;AAAA;AAAA,EAGf,OAAA,EAAS,SAAA;AAAA;AAAA,EACT,iBAAA,EAAmB,SAAA;AAAA,EACnB,WAAA,EAAa,SAAA;AAAA;AAAA,EACb,YAAA,EAAc,SAAA;AAAA;AAAA,EACd,aAAA,EAAe,SAAA;AAAA;AAAA;AAAA,EAGf,OAAA,EAAS,SAAA;AAAA;AAAA,EACT,iBAAA,EAAmB,SAAA;AAAA,EACnB,WAAA,EAAa,SAAA;AAAA;AAAA,EACb,YAAA,EAAc,SAAA;AAAA;AAAA,EACd,aAAA,EAAe,SAAA;AAAA;AAAA;AAAA,EAGf,WAAA,EAAa,SAAA;AAAA;AAAA,EACb,qBAAA,EAAuB,SAAA;AAAA,EACvB,eAAA,EAAiB,SAAA;AAAA;AAAA,EACjB,gBAAA,EAAkB,SAAA;AAAA;AAAA,EAClB,iBAAA,EAAmB,SAAA;AAAA;AAAA;AAAA,EAGnB,IAAA,EAAM,SAAA;AAAA;AAAA,EACN,cAAA,EAAgB,SAAA;AAAA,EAChB,QAAA,EAAU,SAAA;AAAA;AAAA,EACV,SAAA,EAAW,SAAA;AAAA;AAAA,EACX,UAAA,EAAY,SAAA;AAAA;AAAA;AAAA,EAGZ,SAAA,EAAW,SAAA;AAAA;AAAA,EACX,mBAAA,EAAqB,SAAA;AAAA,EACrB,aAAA,EAAe,SAAA;AAAA;AAAA,EACf,cAAA,EAAgB,SAAA;AAAA;AAAA,EAChB,eAAA,EAAiB,SAAA;AAAA;AAAA;AAAA,EAGjB,OAAA,EAAS,SAAA;AAAA,EACT,iBAAA,EAAmB,SAAA;AAAA,EACnB,cAAA,EAAgB,SAAA;AAAA,EAChB,wBAAA,EAA0B,SAAA;AAAA,EAC1B,aAAA,EAAe,SAAA;AAAA,EACf,uBAAA,EAAyB,SAAA;AAAA,EACzB,aAAA,EAAe,SAAA;AAAA,EACf,WAAA,EAAa,SAAA;AAAA;AAAA,EAGb,MAAA,EAAQ,SAAA;AAAA;AAAA,EACR,MAAA,EAAQ,SAAA;AAAA;AAAA,EACR,MAAA,EAAQ,SAAA;AAAA;AAAA,EACR,MAAA,EAAQ,SAAA;AAAA;AAAA,EACR,MAAA,EAAQ;AAAA;AACV,CAAA;AAMO,IAAM,YAAA,GAAiC;AAAA,EAC5C,GAAG;AACL","file":"chunk-AIUAT7FF.js","sourcesContent":["export interface ThemeColorTokens {\n background: string;\n card: string;\n cardForeground: string;\n popover: string;\n popoverForeground: string;\n muted: string;\n mutedForeground: string;\n mutedStrong: string;\n sunken: string;\n secondary: string;\n secondaryForeground: string;\n accent: string;\n accentForeground: string;\n foreground: string;\n foregroundSecondary: string;\n foregroundSubtle: string;\n border: string;\n borderStrong: string;\n input: string;\n outlineHalo: string;\n ring: string;\n primary: string;\n primaryForeground: string;\n primaryText: string;\n primaryMuted: string;\n primaryBorder: string;\n success: string;\n successForeground: string;\n successText: string;\n successMuted: string;\n successBorder: string;\n warning: string;\n warningForeground: string;\n warningText: string;\n warningMuted: string;\n warningBorder: string;\n destructive: string;\n destructiveForeground: string;\n destructiveText: string;\n destructiveMuted: string;\n destructiveBorder: string;\n info: string;\n infoForeground: string;\n infoText: string;\n infoMuted: string;\n infoBorder: string;\n highlight: string;\n highlightForeground: string;\n highlightText: string;\n highlightMuted: string;\n highlightBorder: string;\n sidebar: string;\n sidebarForeground: string;\n sidebarPrimary: string;\n sidebarPrimaryForeground: string;\n sidebarAccent: string;\n sidebarAccentForeground: string;\n sidebarBorder: string;\n sidebarRing: string;\n chart1: string;\n chart2: string;\n chart3: string;\n chart4: string;\n chart5: string;\n}\n\nexport const lightTokens: ThemeColorTokens = {\n // Surfaces\n background: '#f6f6f6',\n card: '#ffffff',\n cardForeground: '#171717',\n popover: '#ffffff',\n popoverForeground: '#171717',\n muted: '#f0f0f0',\n mutedForeground: '#6b6b6b',\n mutedStrong: '#e4e4e4',\n sunken: '#f0f0f0',\n secondary: '#f0f0f0',\n secondaryForeground: '#171717',\n accent: '#f0f0f0',\n accentForeground: '#171717',\n\n // Text\n foreground: '#171717',\n foregroundSecondary: '#4a4a4a',\n foregroundSubtle: '#8a8a8a',\n\n // Borders\n border: '#e4e4e4',\n borderStrong: '#bfbfbf',\n input: '#bfbfbf',\n outlineHalo: '#f0f0f0',\n ring: '#0091ff',\n\n // Brand: Primary\n primary: '#0091ff',\n primaryForeground: '#ffffff',\n primaryText: '#006ec2',\n primaryMuted: '#ebf6ff',\n primaryBorder: '#b3e0ff',\n\n // Status: Success\n success: '#059669',\n successForeground: '#ffffff',\n successText: '#047857',\n successMuted: '#ecfdf5',\n successBorder: '#a7f3d0',\n\n // Status: Warning\n warning: '#d97706',\n warningForeground: '#ffffff',\n warningText: '#b45309',\n warningMuted: '#fffbeb',\n warningBorder: '#fde68a',\n\n // Status: Destructive\n destructive: '#dc2626',\n destructiveForeground: '#ffffff',\n destructiveText: '#b91c1c',\n destructiveMuted: '#fef2f2',\n destructiveBorder: '#fecaca',\n\n // Status: Info\n info: '#2563eb',\n infoForeground: '#ffffff',\n infoText: '#1d4ed8',\n infoMuted: '#eff6ff',\n infoBorder: '#bfdbfe',\n\n // Categorical: Highlight (violet)\n highlight: '#7c3aed',\n highlightForeground: '#ffffff',\n highlightText: '#6d28d9',\n highlightMuted: '#f5f3ff',\n highlightBorder: '#ddd6fe',\n\n // Sidebar\n sidebar: '#ffffff',\n sidebarForeground: '#171717',\n sidebarPrimary: '#0091ff',\n sidebarPrimaryForeground: '#ffffff',\n sidebarAccent: '#f0f0f0',\n sidebarAccentForeground: '#171717',\n sidebarBorder: '#e4e4e4',\n sidebarRing: '#0091ff',\n\n // Charts\n chart1: '#0091ff',\n chart2: '#10b981',\n chart3: '#f59e0b',\n chart4: '#8b5cf6',\n chart5: '#f43f5e',\n};\n\nexport const darkTokens: ThemeColorTokens = {\n // Surfaces\n background: '#0a0a0a', // neutral-950\n card: '#171717', // neutral-900\n cardForeground: '#f5f5f5', // neutral-100\n popover: '#171717',\n popoverForeground: '#f5f5f5',\n muted: '#262626', // neutral-800\n mutedForeground: '#a3a3a3', // neutral-400\n mutedStrong: '#404040', // neutral-700\n sunken: '#0a0a0a', // neutral-950\n secondary: '#262626',\n secondaryForeground: '#f5f5f5',\n accent: '#262626',\n accentForeground: '#f5f5f5',\n\n // Text\n foreground: '#f5f5f5', // neutral-100\n foregroundSecondary: '#d4d4d4', // neutral-300\n foregroundSubtle: '#737373', // neutral-500\n\n // Borders\n border: '#262626', // neutral-800\n borderStrong: '#404040', // neutral-700\n input: '#404040', // neutral-700\n outlineHalo: '#262626',\n ring: '#6366f1', // indigo-500\n\n // Brand: Primary\n primary: '#6366f1', // indigo-500\n primaryForeground: '#ffffff',\n primaryText: '#a5b4fc', // indigo-300\n primaryMuted: '#1e1b4b', // indigo-950\n primaryBorder: '#3730a3', // indigo-800\n\n // Status: Success\n success: '#34d399', // emerald-400\n successForeground: '#022c22',\n successText: '#6ee7b7', // emerald-300\n successMuted: '#022c22', // emerald-950\n successBorder: '#065f46', // emerald-800\n\n // Status: Warning\n warning: '#fbbf24', // amber-400\n warningForeground: '#451a03',\n warningText: '#fcd34d', // amber-300\n warningMuted: '#451a03', // amber-950\n warningBorder: '#92400e', // amber-800\n\n // Status: Destructive\n destructive: '#ef4444', // red-500\n destructiveForeground: '#ffffff',\n destructiveText: '#fca5a5', // red-300\n destructiveMuted: '#450a0a', // red-950\n destructiveBorder: '#991b1b', // red-800\n\n // Status: Info\n info: '#60a5fa', // blue-400\n infoForeground: '#ffffff',\n infoText: '#93c5fd', // blue-300\n infoMuted: '#172554', // blue-950\n infoBorder: '#1e40af', // blue-800\n\n // Categorical: Highlight (violet)\n highlight: '#a78bfa', // violet-400\n highlightForeground: '#ffffff',\n highlightText: '#c4b5fd', // violet-300\n highlightMuted: '#2e1065', // violet-950\n highlightBorder: '#5b21b6', // violet-800\n\n // Sidebar\n sidebar: '#171717',\n sidebarForeground: '#f5f5f5',\n sidebarPrimary: '#6366f1',\n sidebarPrimaryForeground: '#ffffff',\n sidebarAccent: '#262626',\n sidebarAccentForeground: '#f5f5f5',\n sidebarBorder: '#262626',\n sidebarRing: '#6366f1',\n\n // Charts\n chart1: '#6366f1', // Brand Indigo\n chart2: '#34d399', // Emerald\n chart3: '#fbbf24', // Amber\n chart4: '#a78bfa', // Violet\n chart5: '#38bdf8', // Sky\n};\n\n/**\n * Chrome tokens match dark tokens for tool surfaces (site editor shell & preview canvas)\n * so that editor chrome stays dark regardless of active page theme.\n */\nexport const chromeTokens: ThemeColorTokens = {\n ...darkTokens,\n};\n\nexport const tokens = {\n light: lightTokens,\n dark: darkTokens,\n chrome: chromeTokens,\n} as const;\n\nexport const typography = {\n text3xs: { fontSize: '0.625rem', lineHeight: '0.875rem' }, // 10px / 14px\n text2xs: { fontSize: '0.6875rem', lineHeight: '1rem' }, // 11px / 16px\n textXs: { fontSize: '0.75rem', lineHeight: '1rem' }, // 12px / 16px\n textSm: { fontSize: '0.875rem', lineHeight: '1.25rem' }, // 14px / 20px\n} as const;\n\nexport const radii = {\n radius: '0.625rem',\n sm: 'calc(0.625rem * 0.6)',\n md: 'calc(0.625rem * 0.8)',\n lg: '0.625rem',\n xl: 'calc(0.625rem * 1.4)',\n '2xl': 'calc(0.625rem * 1.8)',\n '3xl': 'calc(0.625rem * 2.2)',\n '4xl': 'calc(0.625rem * 2.6)',\n} as const;\n"]}
@@ -1,11 +1,11 @@
1
1
  import { DEFAULT_DEV_CONTENT_URL } from './chunk-B4YYLS7Y.js';
2
2
  import { isDraftMode, setActiveDraftBundle, runWithDraftBundle } from './chunk-DMLOBKYE.js';
3
- import { chromeTokens } from './chunk-2TKIQIOE.js';
3
+ import { chromeTokens } from './chunk-AIUAT7FF.js';
4
4
  import { resolveEditorOrigins } from './chunk-XJPVYMZM.js';
5
5
 
6
6
  // package.json
7
7
  var package_default = {
8
- version: "1.0.0"};
8
+ version: "1.0.2"};
9
9
 
10
10
  // src/version.ts
11
11
  var CMS_ASTRO_VERSION = package_default.version;
@@ -1053,5 +1053,5 @@ function createPreviewMiddleware(options = {}) {
1053
1053
  }
1054
1054
 
1055
1055
  export { buildBridgeScript, createCmsClient, createPreviewMiddleware, getClient, initCmsClient, setClient };
1056
- //# sourceMappingURL=chunk-TT6O4N3H.js.map
1057
- //# sourceMappingURL=chunk-TT6O4N3H.js.map
1056
+ //# sourceMappingURL=chunk-ZAAWLJPU.js.map
1057
+ //# sourceMappingURL=chunk-ZAAWLJPU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../package.json","../src/version.ts","../src/client.ts","../src/preview/bridge-script.ts","../src/middleware/preview.ts"],"names":["globalWithCms"],"mappings":"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;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AA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","file":"chunk-ZAAWLJPU.js","sourcesContent":["{\n \"name\": \"@407dev/cms-astro\",\n \"version\": \"1.0.2\",\n \"type\": \"module\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/407dev/cms.git\",\n \"directory\": \"packages/astro\"\n },\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"source\": \"./src/index.ts\",\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"default\": \"./dist/index.js\"\n },\n \"./collections\": {\n \"source\": \"./src/fields/collections.ts\",\n \"types\": \"./dist/fields/collections.d.ts\",\n \"import\": \"./dist/fields/collections.js\"\n },\n \"./image\": {\n \"source\": \"./src/image.ts\",\n \"types\": \"./dist/image.d.ts\",\n \"import\": \"./dist/image.js\",\n \"default\": \"./dist/image.js\"\n },\n \"./CmsImage.astro\": \"./src/CmsImage.astro\",\n \"./CmsVideo.astro\": \"./src/CmsVideo.astro\",\n \"./CmsHead.astro\": \"./src/CmsHead.astro\",\n \"./RichText.astro\": \"./src/RichText.astro\",\n \"./middleware\": {\n \"source\": \"./src/middleware/index.ts\",\n \"types\": \"./dist/middleware/index.d.ts\",\n \"import\": \"./dist/middleware/index.js\",\n \"default\": \"./dist/middleware/index.js\"\n },\n \"./toolbar\": {\n \"source\": \"./src/toolbar/app.ts\",\n \"types\": \"./dist/toolbar/app.d.ts\",\n \"import\": \"./dist/toolbar/app.js\",\n \"default\": \"./dist/toolbar/app.js\"\n },\n \"./dev\": {\n \"source\": \"./src/dev/index.ts\",\n \"types\": \"./dist/dev/index.d.ts\",\n \"import\": \"./dist/dev/index.js\",\n \"default\": \"./dist/dev/index.js\"\n }\n },\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"files\": [\n \"dist\",\n \"src\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"lint\": \"biome check src\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run\"\n },\n \"dependencies\": {\n \"@407dev/blocks\": \"workspace:*\",\n \"@407dev/field-types\": \"workspace:*\",\n \"zod\": \"^4.4.3\"\n },\n \"peerDependencies\": {\n \"@407dev/cli\": \"workspace:*\",\n \"astro\": \"^5.0.0\"\n },\n \"peerDependenciesMeta\": {\n \"@407dev/cli\": {\n \"optional\": true\n },\n \"astro\": {\n \"optional\": true\n }\n },\n \"devDependencies\": {\n \"@407dev/api-client\": \"workspace:*\",\n \"@407dev/cli\": \"workspace:*\",\n \"@407dev/config\": \"workspace:*\",\n \"@407dev/design-tokens\": \"workspace:*\",\n \"astro\": \"^5.3.0\",\n \"expect-type\": \"^0.20.0\",\n \"tsup\": \"^8.4.0\",\n \"typescript\": \"^5.7.3\",\n \"vite\": \"^6.1.0\",\n \"vitest\": \"3.0.7\"\n }\n}\n","import pkg from '../package.json';\n\nexport const CMS_ASTRO_VERSION: string = pkg.version;\n","import { DEFAULT_DEV_CONTENT_URL } from '@407dev/config';\nimport type {\n CmsClient,\n CmsClientConfig,\n CmsSiteConfig,\n ContentBundle,\n GetBundleOptions,\n} from './types';\nimport { CMS_ASTRO_VERSION } from './version.js';\n\nexport function createCmsClient(config: CmsClientConfig): CmsClient {\n const siteId = config.siteId;\n const contentUrl = config.contentUrl.replace(/\\/+$/, '');\n const fetchFn = config.fetch || fetch;\n\n // In-memory cache for published bundle to ensure build determinism\n let cachedPublishedBundle: ContentBundle | null = null;\n\n const client: CmsClient = {\n siteId,\n contentUrl,\n previewSecret: config.previewSecret,\n\n async getBundle(options?: GetBundleOptions): Promise<ContentBundle> {\n const isDraft = Boolean(options?.previewToken);\n\n if (!isDraft && cachedPublishedBundle) {\n return cachedPublishedBundle;\n }\n\n const url = isDraft\n ? `${contentUrl}/draft/${siteId}/bundle`\n : `${contentUrl}/content/${siteId}/bundle`;\n\n const headers: Record<string, string> = {\n 'x-cms-sdk': `cms-astro@${CMS_ASTRO_VERSION}`,\n };\n if (options?.previewToken) {\n headers['x-preview-token'] = options.previewToken;\n }\n\n const res = await fetchFn(url, {\n headers,\n });\n if (!res.ok) {\n const error = new Error(\n `CMS Client: Failed to fetch bundle from ${url} (status ${res.status}): ${res.statusText}`,\n );\n (error as unknown as { status?: number }).status = res.status;\n throw error;\n }\n\n const bundle = (await res.json()) as ContentBundle;\n\n if (!isDraft) {\n cachedPublishedBundle = bundle;\n }\n\n return bundle;\n },\n\n async getFields(options?: GetBundleOptions): Promise<ContentBundle['fields']> {\n const bundle = await this.getBundle(options);\n return bundle.fields || {};\n },\n\n async getField<T = unknown>(key: string, options?: GetBundleOptions): Promise<T | null> {\n const fields = await this.getFields(options);\n return (fields[key] as T) ?? null;\n },\n\n async getCollections(options?: GetBundleOptions): Promise<ContentBundle['collections']> {\n const bundle = await this.getBundle(options);\n return bundle.collections || {};\n },\n\n async getEntries(\n collectionKey: string,\n options?: GetBundleOptions,\n ): Promise<ContentBundle['entries'][string]> {\n const bundle = await this.getBundle(options);\n return bundle.entries?.[collectionKey] || [];\n },\n\n async getEntry(\n collectionKey: string,\n slug: string,\n options?: GetBundleOptions,\n ): Promise<ContentBundle['entries'][string][number] | null> {\n const entries = await this.getEntries(collectionKey, options);\n return entries.find((e) => e.slug === slug) || null;\n },\n\n async getRoutes(options?: GetBundleOptions): Promise<ContentBundle['routes']> {\n const bundle = await this.getBundle(options);\n return bundle.routes || [];\n },\n\n async getSiteConfig(options?: GetBundleOptions): Promise<CmsSiteConfig> {\n const bundle = await this.getBundle(options);\n return {\n site_id: bundle.site_id,\n redirects: bundle.redirects || [],\n robots: bundle.settings?.robots || {},\n default_seo: bundle.settings?.default_seo || {},\n sitemap: bundle.settings?.sitemap || {},\n not_found_path: bundle.settings?.not_found_path || null,\n };\n },\n\n clearCache(): void {\n cachedPublishedBundle = null;\n },\n };\n\n return client;\n}\n\nconst globalWithCms = globalThis as typeof globalThis & {\n __CMS_CLIENT__?: CmsClient | null;\n};\n\nlet globalClient: CmsClient | null =\n (typeof globalThis !== 'undefined' && globalWithCms.__CMS_CLIENT__) || null;\n\nexport function initCmsClient(options: {\n siteId?: string;\n contentUrl?: string;\n previewSecret?: string;\n client?: CmsClient;\n}): CmsClient {\n if (options.client) {\n globalClient = options.client;\n if (typeof globalThis !== 'undefined') {\n globalWithCms.__CMS_CLIENT__ = options.client;\n }\n return globalClient;\n }\n\n globalClient = createCmsClient({\n siteId: options.siteId || process.env.CMS_SITE_ID || '',\n contentUrl: options.contentUrl || process.env.CMS_CONTENT_URL || DEFAULT_DEV_CONTENT_URL,\n previewSecret: options.previewSecret || process.env.CMS_PREVIEW_SECRET,\n });\n if (typeof globalThis !== 'undefined') {\n globalWithCms.__CMS_CLIENT__ = globalClient;\n }\n\n return globalClient;\n}\n\nexport function getClient(): CmsClient | null {\n return (\n globalClient || (typeof globalThis !== 'undefined' && globalWithCms.__CMS_CLIENT__) || null\n );\n}\n\nexport function setClient(client: CmsClient | null): void {\n globalClient = client;\n if (typeof globalThis !== 'undefined') {\n globalWithCms.__CMS_CLIENT__ = client;\n }\n}\n","import { chromeTokens } from '@407dev/design-tokens/tokens';\nimport { resolveEditorOrigins } from './origins';\n\nexport const BRIDGE_PROTOCOL_VERSION = 1;\n\nexport interface BridgeScriptOptions {\n editorOrigins?: string[];\n}\n\nexport function buildBridgeScript(options: BridgeScriptOptions = {}): string {\n const allowedOrigins = resolveEditorOrigins(options.editorOrigins);\n const allowedOriginsJson = JSON.stringify(allowedOrigins);\n\n return `(function() {\n if (typeof window === 'undefined') return;\n if (window.__CMS_BRIDGE_INITIALIZED__) return;\n window.__CMS_BRIDGE_INITIALIZED__ = true;\n\n var PROTOCOL_VERSION = ${BRIDGE_PROTOCOL_VERSION};\n var allowedOrigins = ${allowedOriginsJson};\n var connectedOrigin = null;\n var connectedSource = null;\n var activeKey = null;\n var watchedAnchors = [];\n var rafScheduled = false;\n var isPatchingDom = false;\n var debounceRescanTimer = null;\n\n function normalizeOrigin(raw) {\n if (!raw || typeof raw !== 'string') return null;\n var trimmed = raw.trim();\n if (!trimmed) return null;\n try {\n var withScheme = /^[a-zA-Z][a-zA-Z0-9+.-]*:\\\\/\\\\//.test(trimmed) ? trimmed : 'https://' + trimmed;\n var url = new URL(withScheme);\n if (!url.protocol || !url.host) return null;\n return (url.protocol + '//' + url.host).toLowerCase();\n } catch (e) {\n return null;\n }\n }\n\n var normalizedAllowed = allowedOrigins.map(normalizeOrigin).filter(Boolean);\n\n function isOriginAllowed(origin) {\n var norm = normalizeOrigin(origin);\n if (!norm) return false;\n return normalizedAllowed.indexOf(norm) !== -1;\n }\n\n function postToEditor(msg) {\n if (!connectedSource || !connectedOrigin) return;\n try {\n connectedSource.postMessage(msg, connectedOrigin);\n } catch (err) {\n // Failed to post\n }\n }\n\n // Inject Bridge Styles\n var isEmbedded = false;\n try {\n isEmbedded = window.self !== window.top || window.parent !== window;\n } catch (_e) {\n isEmbedded = true;\n }\n\n var toolbarTag = 'astro-' + 'dev-toolbar';\n\n function ensureBridgeStyles() {\n if (typeof document === 'undefined' || !document || typeof document.getElementById !== 'function') return;\n if (document.getElementById('cms-bridge-styles')) return;\n var style = document.createElement('style');\n style.id = 'cms-bridge-styles';\n style.textContent = [\n isEmbedded ? toolbarTag + ' { display: none !important; }' : '',\n 'html[data-cms-comment-mode],',\n 'html[data-cms-comment-mode] * {',\n ' cursor: crosshair !important;',\n '}',\n 'html[data-cms-edit-mode] [data-cms-field],',\n 'html[data-cms-edit-mode] [data-cms-entry-field] {',\n ' cursor: pointer !important;',\n ' outline: 1px dashed rgba(99, 102, 241, 0.5) !important;',\n ' outline-offset: 2px !important;',\n ' transition: outline 0.15s ease-in-out !important;',\n '}',\n 'html[data-cms-edit-mode] [data-cms-field]:hover,',\n 'html[data-cms-edit-mode] [data-cms-entry-field]:hover {',\n ' outline: 2px solid ${chromeTokens.primary} !important;',\n ' outline-offset: 2px !important;',\n '}',\n 'html[data-cms-edit-mode] [data-cms-group] {',\n ' outline: 1px dashed rgba(16, 185, 129, 0.4) !important;',\n ' outline-offset: 3px !important;',\n '}',\n 'html[data-cms-edit-mode] [data-cms-group]:hover {',\n ' outline: 2px solid ${chromeTokens.success} !important;',\n ' outline-offset: 3px !important;',\n '}',\n 'html[data-cms-edit-mode] [data-cms-collection] {',\n ' cursor: pointer !important;',\n ' outline: 1px dashed rgba(251, 191, 36, 0.4) !important;',\n ' outline-offset: 4px !important;',\n ' transition: outline 0.15s ease-in-out !important;',\n '}',\n 'html[data-cms-edit-mode] [data-cms-collection]:hover {',\n ' outline: 2px solid ${chromeTokens.warning} !important;',\n ' outline-offset: 4px !important;',\n '}'\n ].filter(Boolean).join('\\\\n');\n\n var target = document.head || document.documentElement;\n if (target) {\n target.appendChild(style);\n }\n }\n\n function hideDevToolbar() {\n if (!isEmbedded) return;\n ensureBridgeStyles();\n if (typeof document === 'undefined' || !document || typeof document.querySelector !== 'function') return;\n try {\n var tb = document.querySelector(toolbarTag);\n if (tb && tb instanceof HTMLElement) {\n tb.style.setProperty('display', 'none', 'important');\n }\n } catch (_e) {}\n }\n\n ensureBridgeStyles();\n hideDevToolbar();\n\n function inferFieldKind(el) {\n if (!el) return 'unknown';\n var tag = el.tagName ? el.tagName.toLowerCase() : '';\n if (tag === 'img') return 'image';\n if (tag === 'video') return 'video';\n var explicitKind = el.getAttribute('data-cms-kind');\n if (explicitKind) return explicitKind;\n if (el.classList.contains('rich-body') || el.classList.contains('cms-richtext') || el.getAttribute('data-cms-richtext') === 'true') {\n return 'richtext';\n }\n return 'text';\n }\n\n function getElementRect(el) {\n var r = el.getBoundingClientRect();\n return {\n top: r.top,\n left: r.left,\n width: r.width,\n height: r.height\n };\n }\n\n function parseGroupAttr(raw) {\n if (!raw) return undefined;\n var idx = raw.indexOf(':');\n if (idx === -1) return { group: raw, scope: '' };\n return {\n group: raw.slice(0, idx),\n scope: raw.slice(idx + 1)\n };\n }\n\n function scanRenderedFields() {\n var fieldEls = document.querySelectorAll('[data-cms-field], [data-cms-entry-field]');\n var fieldMap = {};\n\n for (var i = 0; i < fieldEls.length; i++) {\n var el = fieldEls[i];\n var key = el.getAttribute('data-cms-field') || el.getAttribute('data-cms-entry-field') || '';\n if (!key) continue;\n\n var isEntry = el.hasAttribute('data-cms-entry-field');\n var groupEl = el.closest('[data-cms-group]');\n var collectionEl = el.closest('[data-cms-collection]');\n var groupName = undefined;\n if (groupEl) {\n var g = parseGroupAttr(groupEl.getAttribute('data-cms-group'));\n if (g) groupName = g.group;\n }\n\n var entryRef = undefined;\n if (isEntry || collectionEl) {\n entryRef = {\n collection: collectionEl ? collectionEl.getAttribute('data-cms-collection') || '' : '',\n slug: collectionEl ? collectionEl.getAttribute('data-cms-entry') || '' : '',\n path: isEntry ? key : key\n };\n }\n\n var uniqueId = (isEntry && entryRef ? entryRef.collection + ':' + entryRef.slug + ':' : '') + key;\n\n if (!fieldMap[uniqueId]) {\n fieldMap[uniqueId] = {\n key: key,\n kind: inferFieldKind(el),\n group: groupName,\n entryRef: entryRef,\n instances: 1\n };\n } else {\n fieldMap[uniqueId].instances++;\n }\n }\n\n var fields = [];\n for (var k in fieldMap) {\n if (Object.prototype.hasOwnProperty.call(fieldMap, k)) {\n fields.push(fieldMap[k]);\n }\n }\n\n window.__CMS_FIELDS__ = fields;\n window.__CMS_RESCAN__ = scanRenderedFields;\n\n try {\n document.dispatchEvent(new CustomEvent('cms:fields-updated', { detail: fields }));\n } catch (_e) {}\n\n postToEditor({\n source: 'cms-preview',\n v: PROTOCOL_VERSION,\n type: 'rendered-fields',\n fields: fields\n });\n }\n\n function debouncedRescan() {\n if (isPatchingDom) return;\n if (debounceRescanTimer) clearTimeout(debounceRescanTimer);\n debounceRescanTimer = setTimeout(function() {\n scanRenderedFields();\n scheduleRectsUpdate();\n }, 150);\n }\n\n var currentObserver = null;\n function setupMutationObserver() {\n if (typeof MutationObserver === 'undefined' || !document.body) return;\n if (currentObserver) {\n try {\n currentObserver.disconnect();\n } catch (_e) {}\n }\n currentObserver = new MutationObserver(function(mutations) {\n if (isPatchingDom) return;\n hideDevToolbar();\n debouncedRescan();\n });\n currentObserver.observe(document.body, {\n childList: true,\n subtree: true,\n attributeFilter: ['data-cms-field', 'data-cms-entry-field', 'data-cms-group', 'data-cms-collection', 'data-cms-entry']\n });\n }\n\n function buildStableSelector(target) {\n if (!target || !target.tagName) return '';\n if (target === document.documentElement) return 'html';\n if (target === document.body) return 'body';\n\n var parts = [];\n var curr = target;\n var maxLevels = 8;\n\n while (curr && curr !== document.documentElement && parts.length < maxLevels) {\n if (curr === document.body) {\n parts.unshift('body');\n break;\n }\n var id = curr.getAttribute('id');\n if (id && id.trim()) {\n var escapedId = (typeof CSS !== 'undefined' && CSS.escape) ? CSS.escape(id.trim()) : id.trim();\n parts.unshift('#' + escapedId);\n break;\n }\n var tag = curr.tagName ? curr.tagName.toLowerCase() : '';\n if (!tag) break;\n var count = 1;\n var sib = curr.previousElementSibling;\n while (sib) {\n if (sib.tagName && sib.tagName.toLowerCase() === tag) {\n count++;\n }\n sib = sib.previousElementSibling;\n }\n parts.unshift(tag + ':nth-of-type(' + count + ')');\n curr = curr.parentElement;\n }\n\n return parts.join(' > ');\n }\n\n function buildElementLabel(el) {\n if (!el || !el.tagName) return 'element';\n\n var ariaLabel = el.getAttribute('aria-label');\n if (ariaLabel && ariaLabel.trim()) {\n return ariaLabel.trim();\n }\n\n var id = el.getAttribute('id');\n if (id && id.trim()) {\n return '#' + id.trim();\n }\n\n var tag = el.tagName.toLowerCase();\n\n if (tag === 'nav') return 'Navigation';\n if (tag === 'header') return 'Header';\n if (tag === 'footer') return 'Footer';\n if (tag === 'aside') return 'Sidebar';\n if (tag === 'form') return 'Form';\n\n if (tag === 'img') {\n var alt = el.getAttribute('alt');\n if (alt && alt.trim()) return alt.trim();\n return 'img';\n }\n\n if (tag === 'a' || tag === 'button') {\n var text = (el.textContent || '').trim().replace(/\\\\s+/g, ' ');\n if (text) {\n return text.length > 40 ? text.slice(0, 37) + '...' : text;\n }\n return tag;\n }\n\n return tag || 'element';\n }\n\n function buildCandidateEntry(targetEl, clientX, clientY) {\n if (!targetEl || !targetEl.tagName) return null;\n var selector = buildStableSelector(targetEl);\n if (!selector) return null;\n var all = Array.prototype.slice.call(document.querySelectorAll(selector));\n var instance = Math.max(0, all.indexOf(targetEl));\n var hitRect = targetEl.getBoundingClientRect();\n var offsetX = typeof clientX === 'number' ? Math.round(clientX - hitRect.left) : 0;\n var offsetY = typeof clientY === 'number' ? Math.round(clientY - hitRect.top) : 0;\n return {\n selector: selector,\n instance: instance,\n kind: 'element',\n label: buildElementLabel(targetEl),\n offsetX: offsetX,\n offsetY: offsetY,\n rect: getElementRect(targetEl)\n };\n }\n\n function buildAnchorChain(el, clientX, clientY) {\n var chain = [];\n var curr = el;\n while (curr && curr !== document.documentElement && curr !== document.body) {\n var hit = curr.closest('[data-cms-field], [data-cms-entry-field], [data-cms-group], [data-cms-collection][data-cms-entry]');\n if (!hit) break;\n\n var selector = '';\n var kind = 'unknown';\n var label = '';\n\n if (hit.hasAttribute('data-cms-field')) {\n var fieldKey = hit.getAttribute('data-cms-field') || '';\n selector = '[data-cms-field=\"' + fieldKey + '\"]';\n kind = inferFieldKind(hit);\n label = fieldKey;\n } else if (hit.hasAttribute('data-cms-entry-field')) {\n var entryFieldKey = hit.getAttribute('data-cms-entry-field') || '';\n selector = '[data-cms-entry-field=\"' + entryFieldKey + '\"]';\n kind = inferFieldKind(hit);\n label = entryFieldKey;\n } else if (hit.hasAttribute('data-cms-group')) {\n var groupAttr = hit.getAttribute('data-cms-group') || '';\n selector = '[data-cms-group=\"' + groupAttr + '\"]';\n kind = 'group';\n var parsed = parseGroupAttr(groupAttr);\n label = parsed ? parsed.group : groupAttr;\n } else if (hit.hasAttribute('data-cms-collection') && hit.hasAttribute('data-cms-entry')) {\n var col = hit.getAttribute('data-cms-collection') || '';\n var ent = hit.getAttribute('data-cms-entry') || '';\n selector = '[data-cms-collection=\"' + col + '\"][data-cms-entry=\"' + ent + '\"]';\n kind = 'entry';\n label = col + '/' + ent;\n }\n\n if (selector) {\n var all = Array.prototype.slice.call(document.querySelectorAll(selector));\n var instance = Math.max(0, all.indexOf(hit));\n var hitRect = hit.getBoundingClientRect();\n var offsetX = typeof clientX === 'number' ? Math.round(clientX - hitRect.left) : 0;\n var offsetY = typeof clientY === 'number' ? Math.round(clientY - hitRect.top) : 0;\n chain.push({\n selector: selector,\n instance: instance,\n kind: kind,\n label: label,\n offsetX: offsetX,\n offsetY: offsetY,\n rect: getElementRect(hit)\n });\n }\n\n curr = hit.parentElement;\n }\n\n if (chain.length > 0) {\n return chain;\n }\n\n if (!el || !el.tagName) return chain;\n\n var interactiveEl = el.closest ? el.closest('a, button') : null;\n var selfEl = interactiveEl || (el.closest ? el.closest('a, button, nav, header, footer, aside, main, section, article, form, img, svg, [role]') : null) || el;\n var landmarkEl = selfEl.closest ? selfEl.closest('nav, header, footer, aside, main, section, article, form, [role=\"navigation\"], [role=\"banner\"], [role=\"contentinfo\"]') : null;\n\n var selfEntry = buildCandidateEntry(selfEl, clientX, clientY);\n if (selfEntry) {\n chain.push(selfEntry);\n }\n\n if (landmarkEl && landmarkEl !== selfEl) {\n var landmarkEntry = buildCandidateEntry(landmarkEl, clientX, clientY);\n if (landmarkEntry) {\n chain.push(landmarkEntry);\n }\n }\n\n return chain;\n }\n\n function resolveAnchorEl(anchor) {\n if (!anchor || !anchor.selector) return null;\n try {\n var els = document.querySelectorAll(anchor.selector);\n if (!els || els.length === 0) return null;\n var inst = typeof anchor.instance === 'number' ? anchor.instance : 0;\n if (inst >= 0 && inst < els.length) return els[inst];\n return els[0];\n } catch (_e) {\n return null;\n }\n }\n\n function scheduleRectsUpdate() {\n if (rafScheduled) return;\n rafScheduled = true;\n requestAnimationFrame(function() {\n rafScheduled = false;\n var rects = {};\n if (activeKey) {\n var el = document.querySelector('[data-cms-field=\"' + activeKey + '\"], [data-cms-entry-field=\"' + activeKey + '\"]');\n if (el) {\n rects[activeKey] = getElementRect(el);\n }\n }\n postToEditor({\n source: 'cms-preview',\n v: PROTOCOL_VERSION,\n type: 'rects-update',\n rects: rects,\n scrollY: window.scrollY || window.pageYOffset || 0\n });\n\n if (watchedAnchors && watchedAnchors.length > 0) {\n var anchorRects = {};\n for (var a = 0; a < watchedAnchors.length; a++) {\n var wAnchor = watchedAnchors[a];\n var resolvedEl = resolveAnchorEl(wAnchor);\n if (resolvedEl) {\n anchorRects[wAnchor.id] = getElementRect(resolvedEl);\n } else {\n anchorRects[wAnchor.id] = null;\n }\n }\n postToEditor({\n source: 'cms-preview',\n v: PROTOCOL_VERSION,\n type: 'anchor-rects',\n rects: anchorRects\n });\n }\n });\n }\n\n // Click handler\n document.addEventListener('click', function(e) {\n if (document.documentElement.hasAttribute('data-cms-comment-mode')) {\n e.preventDefault();\n e.stopPropagation();\n var target = e.target;\n if (!target || !(target instanceof Element)) return;\n\n var docWidth = Math.max(\n document.documentElement.scrollWidth || 0,\n document.body ? document.body.scrollWidth : 0,\n window.innerWidth || 0\n );\n var docHeight = Math.max(\n document.documentElement.scrollHeight || 0,\n document.body ? document.body.scrollHeight : 0,\n window.innerHeight || 0\n );\n var pageX = e.pageX !== undefined ? e.pageX : (e.clientX + (window.scrollX || window.pageXOffset || 0));\n var pageY = e.pageY !== undefined ? e.pageY : (e.clientY + (window.scrollY || window.pageYOffset || 0));\n var pageXPct = docWidth > 0 ? Math.round((pageX / docWidth) * 10000) / 100 : 0;\n var pageYPct = docHeight > 0 ? Math.round((pageY / docHeight) * 10000) / 100 : 0;\n\n var chain = buildAnchorChain(target, e.clientX, e.clientY);\n var clickRect = chain.length > 0 ? chain[0].rect : {\n top: e.clientY,\n left: e.clientX,\n width: 0,\n height: 0\n };\n\n postToEditor({\n source: 'cms-preview',\n v: PROTOCOL_VERSION,\n type: 'comment-click',\n chain: chain,\n point: { pageXPct: pageXPct, pageYPct: pageYPct },\n rect: clickRect\n });\n return;\n }\n\n if (!document.documentElement.hasAttribute('data-cms-edit-mode')) return;\n var target = e.target;\n if (!target || !(target instanceof Element)) return;\n\n var fieldEl = target.closest('[data-cms-field], [data-cms-entry-field]');\n var groupEl = target.closest('[data-cms-group]');\n\n if (fieldEl) {\n e.preventDefault();\n e.stopPropagation();\n\n var isEntry = fieldEl.hasAttribute('data-cms-entry-field');\n var key = fieldEl.getAttribute('data-cms-field') || fieldEl.getAttribute('data-cms-entry-field') || '';\n var kind = inferFieldKind(fieldEl);\n var rect = getElementRect(fieldEl);\n activeKey = key;\n\n var selector = isEntry ? '[data-cms-entry-field=\"' + key + '\"]' : '[data-cms-field=\"' + key + '\"]';\n var all = Array.prototype.slice.call(document.querySelectorAll(selector));\n var instance = Math.max(0, all.indexOf(fieldEl));\n\n var collectionEl = fieldEl.closest('[data-cms-collection]');\n var entryRef = (isEntry || collectionEl) ? {\n collection: collectionEl ? collectionEl.getAttribute('data-cms-collection') || '' : '',\n slug: collectionEl ? collectionEl.getAttribute('data-cms-entry') || '' : '',\n path: isEntry ? key : key\n } : undefined;\n\n var groupPath = groupEl ? parseGroupAttr(groupEl.getAttribute('data-cms-group')) : undefined;\n\n try {\n document.dispatchEvent(new CustomEvent('cms:field-selected', {\n detail: {\n key: key,\n kind: kind,\n entryRef: entryRef,\n groupPath: groupPath\n }\n }));\n } catch (_e) {}\n\n postToEditor({\n source: 'cms-preview',\n v: PROTOCOL_VERSION,\n type: 'field-click',\n key: key,\n kind: kind,\n rect: rect,\n instance: instance,\n entryRef: entryRef,\n groupPath: groupPath\n });\n return;\n }\n\n if (groupEl) {\n e.preventDefault();\n e.stopPropagation();\n\n var g = parseGroupAttr(groupEl.getAttribute('data-cms-group'));\n if (g) {\n var gRect = getElementRect(groupEl);\n postToEditor({\n source: 'cms-preview',\n v: PROTOCOL_VERSION,\n type: 'group-click',\n group: g.group,\n scope: g.scope,\n rect: gRect\n });\n }\n return;\n }\n\n var collectionEl = target.closest('[data-cms-collection]');\n if (collectionEl) {\n e.preventDefault();\n e.stopPropagation();\n\n var collKey = collectionEl.getAttribute('data-cms-collection') || '';\n var entryEl = target.closest('[data-cms-entry]');\n var slug = collectionEl.getAttribute('data-cms-entry') || (entryEl ? entryEl.getAttribute('data-cms-entry') : null) || undefined;\n var cRect = getElementRect(collectionEl);\n\n postToEditor({\n source: 'cms-preview',\n v: PROTOCOL_VERSION,\n type: 'collection-click',\n collection: collKey,\n slug: slug,\n rect: cRect\n });\n return;\n }\n }, true);\n\n // Message handler\n window.addEventListener('message', function(e) {\n var data = e.data;\n if (!data || typeof data !== 'object') return;\n if (data.source !== 'cms-editor') return;\n\n if (data.type === 'hello') {\n if (!isOriginAllowed(e.origin)) return;\n connectedOrigin = e.origin;\n connectedSource = e.source;\n\n postToEditor({\n source: 'cms-preview',\n v: PROTOCOL_VERSION,\n type: 'ready',\n protocolVersion: PROTOCOL_VERSION,\n capabilities: ['comments', 'collection-click']\n });\n\n scanRenderedFields();\n return;\n }\n\n if (!connectedOrigin || e.origin !== connectedOrigin) return;\n\n if (data.type === 'highlight-mode') {\n if (data.on) {\n document.documentElement.setAttribute('data-cms-edit-mode', 'true');\n } else {\n document.documentElement.removeAttribute('data-cms-edit-mode');\n }\n return;\n }\n\n if (data.type === 'comment-mode') {\n if (data.on) {\n document.documentElement.setAttribute('data-cms-comment-mode', 'true');\n } else {\n document.documentElement.removeAttribute('data-cms-comment-mode');\n }\n return;\n }\n\n if (data.type === 'watch-anchors') {\n watchedAnchors = Array.isArray(data.anchors) ? data.anchors : [];\n scheduleRectsUpdate();\n return;\n }\n\n if (data.type === 'scroll-to-anchor') {\n var sId = data.id;\n var targetItem = null;\n for (var si = 0; si < watchedAnchors.length; si++) {\n if (watchedAnchors[si].id === sId) {\n targetItem = watchedAnchors[si];\n break;\n }\n }\n if (targetItem) {\n var elToScroll = resolveAnchorEl(targetItem);\n if (elToScroll) {\n elToScroll.scrollIntoView({ behavior: 'smooth', block: 'center' });\n scheduleRectsUpdate();\n }\n }\n return;\n }\n\n if (data.type === 'patch') {\n isPatchingDom = true;\n var patchKey = data.key;\n var patchKind = data.kind;\n var patchVal = data.value;\n var patchEntry = data.entryRef;\n\n var patchSelector;\n var fPath = patchEntry && patchEntry.path ? patchEntry.path : patchKey;\n if (patchEntry && (patchEntry.collection || patchEntry.slug)) {\n var colAttr = patchEntry.collection ? '[data-cms-collection=\"' + patchEntry.collection + '\"]' : '';\n var entryAttr = patchEntry.slug ? '[data-cms-entry=\"' + patchEntry.slug + '\"]' : '';\n var scopeSel = colAttr + entryAttr;\n patchSelector = scopeSel + ' [data-cms-entry-field=\"' + fPath + '\"], ' +\n scopeSel + '[data-cms-entry-field=\"' + fPath + '\"]';\n } else if (patchEntry) {\n patchSelector = '[data-cms-entry-field=\"' + fPath + '\"]';\n } else {\n patchSelector = '[data-cms-field=\"' + patchKey + '\"]';\n }\n\n var matchingEls = document.querySelectorAll(patchSelector);\n for (var j = 0; j < matchingEls.length; j++) {\n var mEl = matchingEls[j];\n var isStructured = patchKind === 'geo.area' || patchKind === 'geoArea' ||\n patchKind === 'address' || patchKind === 'address.list' ||\n patchKind === 'media.videoList' || patchKind === 'videoList' ||\n mEl.getAttribute('data-cms-kind') === 'geo.area' ||\n mEl.getAttribute('data-cms-kind') === 'address.list' ||\n mEl.getAttribute('data-cms-kind') === 'media.videoList';\n\n if (patchKind === 'image' || mEl.tagName.toLowerCase() === 'img') {\n if (patchVal && typeof patchVal === 'object') {\n if (patchVal.url) mEl.setAttribute('src', patchVal.url);\n if (patchVal.alt !== undefined) mEl.setAttribute('alt', patchVal.alt);\n } else if (typeof patchVal === 'string') {\n mEl.setAttribute('src', patchVal);\n }\n } else if (patchKind === 'video' || mEl.tagName.toLowerCase() === 'video') {\n if (patchVal && typeof patchVal === 'object') {\n if (patchVal.url) mEl.setAttribute('src', patchVal.url);\n if (patchVal.poster !== undefined) mEl.setAttribute('poster', patchVal.poster);\n } else if (typeof patchVal === 'string') {\n mEl.setAttribute('src', patchVal);\n }\n if (typeof mEl.load === 'function') mEl.load();\n } else if (isStructured || (patchVal && typeof patchVal === 'object')) {\n // Structured non-image field values (e.g. videoList, geoArea, address) cannot be rendered\n // via simple textContent replacement without producing [object Object].\n // Skip the text write and leave server-rendered markup intact; structured fields refresh via reload.\n } else {\n mEl.textContent = patchVal !== null && patchVal !== undefined ? String(patchVal) : '';\n }\n }\n\n isPatchingDom = false;\n scanRenderedFields();\n scheduleRectsUpdate();\n return;\n }\n\n if (data.type === 'scroll-to') {\n var scrollKey = data.key;\n var scrollInstance = typeof data.instance === 'number' ? data.instance : 0;\n var scrollEls = document.querySelectorAll('[data-cms-field=\"' + scrollKey + '\"], [data-cms-entry-field=\"' + scrollKey + '\"]');\n if (scrollEls.length > scrollInstance) {\n scrollEls[scrollInstance].scrollIntoView({ behavior: 'smooth', block: 'center' });\n activeKey = scrollKey;\n scheduleRectsUpdate();\n }\n return;\n }\n\n if (data.type === 'reload') {\n window.location.reload();\n return;\n }\n });\n\n function handlePageTransition() {\n hideDevToolbar();\n scanRenderedFields();\n setupMutationObserver();\n }\n\n window.addEventListener('scroll', scheduleRectsUpdate, { passive: true });\n window.addEventListener('resize', scheduleRectsUpdate, { passive: true });\n\n document.addEventListener('astro:page-load', handlePageTransition);\n document.addEventListener('astro:after-swap', handlePageTransition);\n window.addEventListener('popstate', handlePageTransition);\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', function() {\n handlePageTransition();\n });\n } else {\n handlePageTransition();\n }\n})();`;\n}\n","import { createCmsClient, getClient } from '../client';\nimport { buildBridgeScript } from '../preview/bridge-script';\nimport { isDraftMode, runWithDraftBundle, setActiveDraftBundle } from '../runtime/store';\nimport type { CmsClient, ContentBundle } from '../types';\n\nexport interface PreviewMiddlewareOptions {\n client?: CmsClient;\n siteId?: string;\n contentUrl?: string;\n /** @deprecated Site hosts no longer verify preview tokens. Ignored outside astro dev. */\n previewSecret?: string;\n editorOrigins?: string[];\n}\n\ninterface PreviewContextLocals {\n __cms_is_draft?: boolean;\n __cms_draft_bundle?: ContentBundle;\n [key: string]: unknown;\n}\n\nexport interface PreviewMiddlewareContext {\n request: Request;\n url?: URL;\n locals?: PreviewContextLocals;\n rewrite?: (path: string) => Promise<Response> | undefined;\n}\n\nexport function createPreviewMiddleware(options: PreviewMiddlewareOptions = {}) {\n let client = options.client;\n\n return async (\n context: PreviewMiddlewareContext,\n next: () => Promise<Response>,\n ): Promise<Response> => {\n const globalWithCms = globalThis as typeof globalThis & {\n __CMS_IS_REWRITING__?: boolean;\n };\n\n // If already running within an active draft bundle context or internal rewrite, pass through\n if (\n (typeof globalThis !== 'undefined' && globalWithCms.__CMS_IS_REWRITING__) ||\n isDraftMode() ||\n context.locals?.__cms_is_draft\n ) {\n return next();\n }\n\n const rawUrl = context.url;\n const url =\n rawUrl && typeof rawUrl.href === 'string'\n ? new URL(rawUrl.href)\n : rawUrl && typeof (rawUrl as unknown as { pathname?: string }).pathname === 'string'\n ? rawUrl\n : new URL(context.request?.url || '/', 'http://localhost');\n const pathname = url.pathname || '/';\n const isPreviewRoute = pathname === '/_preview' || pathname.startsWith('/_preview/');\n\n const previewToken =\n (rawUrl?.searchParams?.get ? rawUrl.searchParams.get('preview_token') : null) ||\n (url?.searchParams?.get ? url.searchParams.get('preview_token') : null) ||\n (context.request?.headers?.get ? context.request.headers.get('x-preview-token') : null);\n\n if (!isPreviewRoute && !previewToken) {\n return next();\n }\n\n if (!client) {\n client = getClient() || undefined;\n }\n\n if (!client) {\n const metaEnv = (import.meta as unknown as { env?: Record<string, string | undefined> }).env;\n const siteId =\n options.siteId ||\n (typeof process !== 'undefined' && process.env?.CMS_SITE_ID) ||\n (typeof import.meta !== 'undefined' && metaEnv?.CMS_SITE_ID) ||\n '';\n const contentUrl =\n options.contentUrl ||\n (typeof process !== 'undefined' && process.env?.CMS_CONTENT_URL) ||\n (typeof import.meta !== 'undefined' && metaEnv?.CMS_CONTENT_URL) ||\n '';\n if (siteId && contentUrl) {\n client = createCmsClient({\n siteId,\n contentUrl,\n });\n }\n }\n\n if (!previewToken) {\n return new Response('Preview token is missing', {\n status: 400,\n headers: {\n 'Cache-Control': 'private, no-store',\n 'X-Robots-Tag': 'noindex, nofollow',\n },\n });\n }\n\n if (!client) {\n return new Response('CMS client is missing or not configured', {\n status: 500,\n headers: {\n 'Cache-Control': 'private, no-store',\n 'X-Robots-Tag': 'noindex, nofollow',\n },\n });\n }\n\n let draftBundle: ContentBundle;\n try {\n draftBundle = await client.getBundle({ previewToken });\n } catch (err) {\n const status = (err as { status?: number })?.status;\n if (status === 401 || status === 403 || status === 404) {\n return new Response('Preview token is not valid for this site', {\n status: 404,\n headers: {\n 'Cache-Control': 'private, no-store',\n 'X-Robots-Tag': 'noindex, nofollow',\n },\n });\n }\n\n console.error(err);\n return new Response('Failed to load preview content', {\n status: 502,\n headers: {\n 'Cache-Control': 'private, no-store',\n 'X-Robots-Tag': 'noindex, nofollow',\n },\n });\n }\n\n // Run downstream request within the draft bundle context\n if (context.locals) {\n context.locals.__cms_is_draft = true;\n context.locals.__cms_draft_bundle = draftBundle;\n }\n\n let finalResponse: Response;\n setActiveDraftBundle(draftBundle);\n try {\n finalResponse = await runWithDraftBundle(draftBundle, async () => {\n let response: Response;\n if (isPreviewRoute) {\n const basePath = pathname.replace(/^\\/_preview/, '') || '/';\n if (typeof context.rewrite === 'function') {\n if (typeof globalThis !== 'undefined') {\n globalWithCms.__CMS_IS_REWRITING__ = true;\n }\n try {\n const rewritten = await context.rewrite(basePath);\n if (rewritten) {\n response = rewritten as Response;\n } else {\n response = await next();\n }\n } finally {\n if (typeof globalThis !== 'undefined') {\n globalWithCms.__CMS_IS_REWRITING__ = false;\n }\n }\n } else {\n response = await next();\n }\n } else {\n response = await next();\n }\n\n const contentType = response?.headers?.get ? response.headers.get('content-type') : '';\n const isStaticAsset = Boolean(\n pathname.match(/\\.(js|css|png|jpg|jpeg|gif|svg|ico|webp|woff|woff2|ttf|json|map)$/i),\n );\n const isHtml =\n (typeof contentType === 'string' && contentType.includes('text/html')) ||\n (!contentType && !isStaticAsset);\n\n if (isHtml) {\n const html = await response.text();\n const bridgeScript = buildBridgeScript({\n editorOrigins: options.editorOrigins,\n });\n const scriptTag = `<script>${bridgeScript}</script>`;\n const modifiedHtml = html.includes('</body>')\n ? html.replace('</body>', `${scriptTag}</body>`)\n : `${html}${scriptTag}`;\n\n const newHeaders = new Headers(response.headers);\n if (!newHeaders.has('content-type')) {\n newHeaders.set('content-type', 'text/html; charset=utf-8');\n }\n newHeaders.delete('content-length');\n newHeaders.set('Cache-Control', 'private, no-store, no-cache, must-revalidate');\n newHeaders.set('X-Robots-Tag', 'noindex, nofollow');\n\n return new Response(modifiedHtml, {\n status: response.status,\n statusText: response.statusText,\n headers: newHeaders,\n });\n }\n\n const nonHtmlHeaders = new Headers(response.headers);\n nonHtmlHeaders.set('Cache-Control', 'private, no-store, no-cache, must-revalidate');\n nonHtmlHeaders.set('X-Robots-Tag', 'noindex, nofollow');\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers: nonHtmlHeaders,\n });\n });\n } finally {\n setActiveDraftBundle(null);\n }\n\n return finalResponse;\n };\n}\n"]}
@@ -0,0 +1,18 @@
1
+ declare const CDN_IMAGE_WIDTHS: readonly [320, 400, 640, 800, 1024, 1280, 1600, 1920, 2560];
2
+ type CdnImageWidth = (typeof CDN_IMAGE_WIDTHS)[number];
3
+ declare const ALLOWED_IMAGE_FITS: readonly ["scale-down", "contain", "cover", "crop", "pad"];
4
+ type CdnImageFit = (typeof ALLOWED_IMAGE_FITS)[number];
5
+ declare const ALLOWED_IMAGE_QUALITIES: readonly [60, 75, 80, 85, 90, 100];
6
+ type CdnImageQuality = (typeof ALLOWED_IMAGE_QUALITIES)[number];
7
+ interface ImageTransformOptions {
8
+ width?: number;
9
+ fit?: CdnImageFit;
10
+ quality?: CdnImageQuality | number;
11
+ }
12
+ declare function snapToAllowedWidth(width: number): CdnImageWidth;
13
+ declare function snapToAllowedQuality(quality: number): CdnImageQuality;
14
+ declare function isCdnTransformableUrl(url: string): boolean;
15
+ declare function buildCdnImageUrl(url: string, options?: ImageTransformOptions): string;
16
+ declare function buildSrcSet(url: string, widths?: readonly number[] | number[], options?: Omit<ImageTransformOptions, 'width'>): string;
17
+
18
+ export { ALLOWED_IMAGE_FITS, ALLOWED_IMAGE_QUALITIES, CDN_IMAGE_WIDTHS, type CdnImageFit, type CdnImageQuality, type CdnImageWidth, type ImageTransformOptions, buildCdnImageUrl, buildSrcSet, isCdnTransformableUrl, snapToAllowedQuality, snapToAllowedWidth };
package/dist/image.js ADDED
@@ -0,0 +1,3 @@
1
+ export { ALLOWED_IMAGE_FITS, ALLOWED_IMAGE_QUALITIES, CDN_IMAGE_WIDTHS, buildCdnImageUrl, buildSrcSet, isCdnTransformableUrl, snapToAllowedQuality, snapToAllowedWidth } from './chunk-6FH3C4FF.js';
2
+ //# sourceMappingURL=image.js.map
3
+ //# sourceMappingURL=image.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"image.js"}
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ import { z } from '@407dev/blocks';
4
4
  export { CmsAsset, z } from '@407dev/blocks';
5
5
  import { C as CollectionHandle, a as CollectionEntry, I as InferEntryContent, D as DefineCollectionOptions, b as CollectionStaticPath, c as DualCallableHelper, G as GroupDefinition, F as FieldScope, d as FieldHelpersMap } from './types-CEYS5Fzc.js';
6
6
  export { B as BoundGroupAccessor, e as FieldComponentProps, f as FieldReadOptions, g as GroupAccessor } from './types-CEYS5Fzc.js';
7
+ export { ALLOWED_IMAGE_FITS, ALLOWED_IMAGE_QUALITIES, CDN_IMAGE_WIDTHS, CdnImageFit, CdnImageQuality, CdnImageWidth, ImageTransformOptions, buildCdnImageUrl, buildSrcSet, isCdnTransformableUrl, snapToAllowedQuality, snapToAllowedWidth } from './image.js';
7
8
  import { AstroIntegration } from 'astro';
8
9
  export { P as PreviewMiddlewareContext, a as PreviewMiddlewareOptions, c as createPreviewMiddleware } from './preview-D9yewK8x.js';
9
10
 
@@ -100,28 +101,6 @@ interface HeadRouteInput {
100
101
  */
101
102
  declare function buildHeadTags(route?: HeadRouteInput | null, siteConfig?: CmsSiteConfig | null, options?: BuildHeadTagsOptions): HeadTag[];
102
103
 
103
- interface ImageTransformOptions {
104
- width?: number;
105
- height?: number;
106
- format?: string;
107
- fit?: 'scale-down' | 'contain' | 'cover' | 'crop' | 'pad' | string;
108
- quality?: number;
109
- }
110
- /**
111
- * Determines whether a URL is hosted on a zone domain eligible for /cdn-cgi/image transforms.
112
- * Non-zone URLs (*.r2.dev, localhost, relative paths, data/blob URLs) return false.
113
- */
114
- declare function isCdnTransformableUrl(url: string): boolean;
115
- /**
116
- * Builds a Cloudflare /cdn-cgi/image/... transform URL.
117
- * Automatically degrades to the raw source URL for non-transformable hostnames.
118
- */
119
- declare function buildCdnImageUrl(url: string, options?: ImageTransformOptions): string;
120
- /**
121
- * Generates an HTML srcset string with Cloudflare /cdn-cgi/image transforms for specified widths.
122
- */
123
- declare function buildSrcSet(url: string, widths?: number[], options?: Omit<ImageTransformOptions, 'width'>): string;
124
-
125
104
  declare function cmsAstro(options?: CmsAstroOptions): AstroIntegration;
126
105
  declare const cms: typeof cmsAstro;
127
106
 
@@ -239,4 +218,4 @@ interface SitemapRouteItem {
239
218
  */
240
219
  declare function renderSitemapXml(routes: SitemapRouteItem[], options: RenderSitemapOptions): string;
241
220
 
242
- export { type BuildHeadTagsOptions, CmsAstroOptions, CmsClient, CmsClientConfig, type CmsF, CmsRedirect, CmsSiteConfig, CollectionEntry, CollectionHandle, CollectionStaticPath, ContentBundle, DEFAULT_EDITOR_ORIGINS, DefineCollectionOptions, DualCallableHelper, type EntryScopeAccessor, FieldHelpersMap, FieldScope, type GetPreviewDataOptions, GroupDefinition, type HeadRouteInput, type HeadTag, type ImageTransformOptions, InferEntryContent, KNOWN_NODES, type LinkMarkAttrs, type PreviewBundleResult, type RenderRobotsOptions, type RenderSitemapOptions, type RichTextNodeShape, type RichTextRenderOptions, RouteSeo, type SitemapRouteItem, VerifyTokenResult, buildCdnImageUrl, buildHeadTags, buildSrcSet, bundleReady, clearMissingFieldWarnings, cms, cmsAstro, cmsCollectionAttr, cmsEntryAttr, cmsEntryFieldAttr, cmsFieldAttr, cmsGroupAttr, collectionAttrs, collectionPaths, createCmsClient, createEntryDualCallableHelper, createEntryScope, createScope, defineCollection, defineGroup, entryScope, escapeHtml, f, getActiveBundle, getBuildBundle, getClient, getEntries, getEntry, getLinkMarkAttrs, getMissingFieldWarnings, getPreviewData, initCmsClient, isBundleReady, isCdnTransformableUrl, isDraftMode, markBundleReady, parseRichTextDoc, recordMissingField, renderMarksOnly, renderRedirectsFile, renderRichTextHtml, renderRobotsTxt, renderSitemapXml, resolveEditorOrigins, runWithDraftBundle, setActiveDraftBundle, setBuildBundle, setClient, signPreviewToken, updateBundleFieldValue, verifyPreviewToken };
221
+ export { type BuildHeadTagsOptions, CmsAstroOptions, CmsClient, CmsClientConfig, type CmsF, CmsRedirect, CmsSiteConfig, CollectionEntry, CollectionHandle, CollectionStaticPath, ContentBundle, DEFAULT_EDITOR_ORIGINS, DefineCollectionOptions, DualCallableHelper, type EntryScopeAccessor, FieldHelpersMap, FieldScope, type GetPreviewDataOptions, GroupDefinition, type HeadRouteInput, type HeadTag, InferEntryContent, KNOWN_NODES, type LinkMarkAttrs, type PreviewBundleResult, type RenderRobotsOptions, type RenderSitemapOptions, type RichTextNodeShape, type RichTextRenderOptions, RouteSeo, type SitemapRouteItem, VerifyTokenResult, buildHeadTags, bundleReady, clearMissingFieldWarnings, cms, cmsAstro, cmsCollectionAttr, cmsEntryAttr, cmsEntryFieldAttr, cmsFieldAttr, cmsGroupAttr, collectionAttrs, collectionPaths, createCmsClient, createEntryDualCallableHelper, createEntryScope, createScope, defineCollection, defineGroup, entryScope, escapeHtml, f, getActiveBundle, getBuildBundle, getClient, getEntries, getEntry, getLinkMarkAttrs, getMissingFieldWarnings, getPreviewData, initCmsClient, isBundleReady, isDraftMode, markBundleReady, parseRichTextDoc, recordMissingField, renderMarksOnly, renderRedirectsFile, renderRichTextHtml, renderRobotsTxt, renderSitemapXml, resolveEditorOrigins, runWithDraftBundle, setActiveDraftBundle, setBuildBundle, setClient, signPreviewToken, updateBundleFieldValue, verifyPreviewToken };
package/dist/index.js CHANGED
@@ -1,13 +1,14 @@
1
+ export { ALLOWED_IMAGE_FITS, ALLOWED_IMAGE_QUALITIES, CDN_IMAGE_WIDTHS, buildCdnImageUrl, buildSrcSet, isCdnTransformableUrl, snapToAllowedQuality, snapToAllowedWidth } from './chunk-6FH3C4FF.js';
1
2
  import { mintDevPreviewToken } from './chunk-7LMUFCWX.js';
2
3
  export { signPreviewToken, verifyPreviewToken } from './chunk-7LMUFCWX.js';
3
4
  import { collectionAttrs, collectionPaths, defineCollection, getEntry, getEntries, markBundleReady, cmsEntryAttr, cmsGroupAttr } from './chunk-SGHAANOW.js';
4
5
  export { bundleReady, cmsCollectionAttr, cmsEntryAttr, cmsEntryFieldAttr, cmsFieldAttr, cmsGroupAttr, collectionAttrs, collectionPaths, defineCollection, getEntries, getEntry, isBundleReady, markBundleReady } from './chunk-SGHAANOW.js';
5
- import { initCmsClient, buildBridgeScript, getClient } from './chunk-TT6O4N3H.js';
6
- export { createCmsClient, createPreviewMiddleware, getClient, initCmsClient, setClient } from './chunk-TT6O4N3H.js';
6
+ import { initCmsClient, buildBridgeScript, getClient } from './chunk-ZAAWLJPU.js';
7
+ export { createCmsClient, createPreviewMiddleware, getClient, initCmsClient, setClient } from './chunk-ZAAWLJPU.js';
7
8
  import './chunk-B4YYLS7Y.js';
8
9
  import { getActiveBundle, recordMissingField, getMissingFieldWarnings, clearMissingFieldWarnings } from './chunk-DMLOBKYE.js';
9
10
  export { clearMissingFieldWarnings, getActiveBundle, getBuildBundle, getMissingFieldWarnings, isDraftMode, recordMissingField, runWithDraftBundle, setActiveDraftBundle, setBuildBundle, updateBundleFieldValue } from './chunk-DMLOBKYE.js';
10
- import './chunk-2TKIQIOE.js';
11
+ import './chunk-AIUAT7FF.js';
11
12
  export { DEFAULT_EDITOR_ORIGINS, resolveEditorOrigins } from './chunk-XJPVYMZM.js';
12
13
  import { listFieldTypes, getFieldType, isValidLinkHref } from '@407dev/field-types';
13
14
  import { createComponent, spreadAttributes, renderTemplate, markHTMLString } from 'astro/runtime/server/index.js';
@@ -628,42 +629,6 @@ function buildHeadTags(route, siteConfig, options) {
628
629
  return tags;
629
630
  }
630
631
 
631
- // src/image.ts
632
- function isCdnTransformableUrl(url) {
633
- if (!url || typeof url !== "string") return false;
634
- if (url.startsWith("data:") || url.startsWith("blob:")) return false;
635
- if (url.includes("localhost") || url.includes("127.0.0.1") || url.includes(".r2.dev")) {
636
- return false;
637
- }
638
- return url.startsWith("http://") || url.startsWith("https://");
639
- }
640
- function buildCdnImageUrl(url, options = {}) {
641
- if (!isCdnTransformableUrl(url)) {
642
- return url;
643
- }
644
- const params = [];
645
- if (options.width !== void 0 && options.width !== null) {
646
- params.push(`width=${options.width}`);
647
- }
648
- if (options.height !== void 0 && options.height !== null) {
649
- params.push(`height=${options.height}`);
650
- }
651
- params.push(`format=${options.format || "auto"}`);
652
- if (options.fit) {
653
- params.push(`fit=${options.fit}`);
654
- }
655
- if (options.quality !== void 0 && options.quality !== null) {
656
- params.push(`quality=${options.quality}`);
657
- }
658
- const optionString = params.join(",");
659
- return `/cdn-cgi/image/${optionString}/${url}`;
660
- }
661
- function buildSrcSet(url, widths = [400, 800, 1200, 1600], options = {}) {
662
- if (!url) return "";
663
- if (!isCdnTransformableUrl(url)) return "";
664
- return widths.map((w) => `${buildCdnImageUrl(url, { ...options, width: w })} ${w}w`).join(", ");
665
- }
666
-
667
632
  // src/toolbar/icon.ts
668
633
  var CMS_TOOLBAR_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
669
634
  <path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/>
@@ -952,6 +917,6 @@ ${urlEntries.join("\n")}
952
917
  `;
953
918
  }
954
919
 
955
- export { KNOWN_NODES, buildCdnImageUrl, buildHeadTags, buildSrcSet, cms, cmsAstro, createEntryDualCallableHelper, createEntryScope, createScope, defineGroup, entryScope, escapeHtml, f, getLinkMarkAttrs, getPreviewData, isCdnTransformableUrl, parseRichTextDoc, renderMarksOnly, renderRedirectsFile, renderRichTextHtml, renderRobotsTxt, renderSitemapXml };
920
+ export { KNOWN_NODES, buildHeadTags, cms, cmsAstro, createEntryDualCallableHelper, createEntryScope, createScope, defineGroup, entryScope, escapeHtml, f, getLinkMarkAttrs, getPreviewData, parseRichTextDoc, renderMarksOnly, renderRedirectsFile, renderRichTextHtml, renderRobotsTxt, renderSitemapXml };
956
921
  //# sourceMappingURL=index.js.map
957
922
  //# sourceMappingURL=index.js.map