@webiny/website-builder-sdk 0.0.0-unstable.a4f3e4ea8b → 0.0.0-unstable.a85ef555b2

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.
Files changed (117) hide show
  1. package/ComponentInputTraverser.js +4 -0
  2. package/ComponentInputTraverser.js.map +1 -1
  3. package/ComponentResolver.d.ts +3 -1
  4. package/ComponentResolver.js +4 -2
  5. package/ComponentResolver.js.map +1 -1
  6. package/ContentSdk.d.ts +64 -1
  7. package/ContentSdk.js +80 -8
  8. package/ContentSdk.js.map +1 -1
  9. package/DocumentStoreManager.d.ts +9 -2
  10. package/DocumentStoreManager.js +24 -5
  11. package/DocumentStoreManager.js.map +1 -1
  12. package/EditingSdk.d.ts +7 -1
  13. package/EditingSdk.js +5 -3
  14. package/EditingSdk.js.map +1 -1
  15. package/ElementFactory.js +3 -1
  16. package/ElementFactory.js.map +1 -1
  17. package/ElementFactory.test.js +102 -0
  18. package/ElementFactory.test.js.map +1 -1
  19. package/LiveSdk.d.ts +3 -1
  20. package/LiveSdk.js +3 -2
  21. package/LiveSdk.js.map +1 -1
  22. package/PreviewDocument.d.ts +2 -1
  23. package/PreviewDocument.js +2 -2
  24. package/PreviewDocument.js.map +1 -1
  25. package/PreviewSdk.d.ts +3 -1
  26. package/PreviewSdk.js +3 -2
  27. package/PreviewSdk.js.map +1 -1
  28. package/ResizeObserver.js +1 -1
  29. package/ResizeObserver.js.map +1 -1
  30. package/asset/deliveryUrl.test.js +1 -1
  31. package/asset/deliveryUrl.test.js.map +1 -1
  32. package/asset/imageSrcSet.test.js +1 -1
  33. package/asset/imageSrcSet.test.js.map +1 -1
  34. package/asset/normalize.d.ts +1 -1
  35. package/asset/normalize.js +18 -14
  36. package/asset/normalize.js.map +1 -1
  37. package/asset/normalize.test.js +15 -8
  38. package/asset/normalize.test.js.map +1 -1
  39. package/componentLoader/ComponentLoader.d.ts +16 -0
  40. package/componentLoader/ComponentLoader.js +0 -0
  41. package/componentLoader/RegistryOnlyComponentLoader.d.ts +9 -0
  42. package/componentLoader/RegistryOnlyComponentLoader.js +8 -0
  43. package/componentLoader/RegistryOnlyComponentLoader.js.map +1 -0
  44. package/componentLoader/createComponentLoader.d.ts +7 -0
  45. package/componentLoader/createComponentLoader.js +10 -0
  46. package/componentLoader/createComponentLoader.js.map +1 -0
  47. package/componentLoader/defaultComponentLoader.d.ts +7 -0
  48. package/componentLoader/defaultComponentLoader.js +8 -0
  49. package/componentLoader/defaultComponentLoader.js.map +1 -0
  50. package/componentLoader/index.d.ts +3 -0
  51. package/componentLoader/index.js +3 -0
  52. package/contentClientState.test.d.ts +1 -0
  53. package/contentClientState.test.js +384 -0
  54. package/contentClientState.test.js.map +1 -0
  55. package/contentEntry/ContentEntryBindingsResolver.d.ts +8 -5
  56. package/contentEntry/ContentEntryBindingsResolver.js +30 -23
  57. package/contentEntry/ContentEntryBindingsResolver.js.map +1 -1
  58. package/contentEntry/ContentEntryCache.d.ts +7 -4
  59. package/contentEntry/ContentEntryCache.js +10 -9
  60. package/contentEntry/ContentEntryCache.js.map +1 -1
  61. package/createContentClient.d.ts +17 -0
  62. package/createContentClient.js +16 -0
  63. package/createContentClient.js.map +1 -0
  64. package/createContentClient.test.d.ts +1 -0
  65. package/createContentClient.test.js +165 -0
  66. package/createContentClient.test.js.map +1 -0
  67. package/dataProviders/ApiClient.js.map +1 -1
  68. package/dataProviders/DefaultDataProvider.d.ts +4 -0
  69. package/dataProviders/DefaultDataProvider.js +35 -0
  70. package/dataProviders/DefaultDataProvider.js.map +1 -1
  71. package/dataProviders/GET_EXPERIMENT_PAUSED.d.ts +1 -0
  72. package/dataProviders/GET_EXPERIMENT_PAUSED.js +17 -0
  73. package/dataProviders/GET_EXPERIMENT_PAUSED.js.map +1 -0
  74. package/dataProviders/GET_PAGE_BY_ID.d.ts +1 -1
  75. package/dataProviders/GET_PAGE_BY_ID.js +2 -0
  76. package/dataProviders/GET_PAGE_BY_ID.js.map +1 -1
  77. package/dataProviders/GET_PAGE_BY_PATH.d.ts +1 -1
  78. package/dataProviders/GET_PAGE_BY_PATH.js +2 -0
  79. package/dataProviders/GET_PAGE_BY_PATH.js.map +1 -1
  80. package/dataProviders/GET_PAGE_EXPERIMENT.d.ts +1 -0
  81. package/dataProviders/GET_PAGE_EXPERIMENT.js +32 -0
  82. package/dataProviders/GET_PAGE_EXPERIMENT.js.map +1 -0
  83. package/dataProviders/GET_VARIANT_CONTENT.d.ts +1 -0
  84. package/dataProviders/GET_VARIANT_CONTENT.js +24 -0
  85. package/dataProviders/GET_VARIANT_CONTENT.js.map +1 -0
  86. package/dataProviders/NullDataProvider.d.ts +4 -0
  87. package/dataProviders/NullDataProvider.js +9 -0
  88. package/dataProviders/NullDataProvider.js.map +1 -1
  89. package/dataProviders/queries.test.d.ts +1 -0
  90. package/dataProviders/queries.test.js +45 -0
  91. package/dataProviders/queries.test.js.map +1 -0
  92. package/experiments/PostHogAnalyticsProvider.d.ts +31 -0
  93. package/experiments/PostHogAnalyticsProvider.js +28 -0
  94. package/experiments/PostHogAnalyticsProvider.js.map +1 -0
  95. package/experiments/analyticsProvider.d.ts +4 -0
  96. package/experiments/analyticsProvider.js +11 -0
  97. package/experiments/analyticsProvider.js.map +1 -0
  98. package/experiments/bucketing.d.ts +27 -0
  99. package/experiments/bucketing.js +91 -0
  100. package/experiments/bucketing.js.map +1 -0
  101. package/experiments/bucketing.test.d.ts +1 -0
  102. package/experiments/bucketing.test.js +183 -0
  103. package/experiments/bucketing.test.js.map +1 -0
  104. package/experiments/index.d.ts +5 -0
  105. package/experiments/index.js +5 -0
  106. package/experiments/render.d.ts +82 -0
  107. package/experiments/render.js +149 -0
  108. package/experiments/render.js.map +1 -0
  109. package/experiments/types.d.ts +108 -0
  110. package/experiments/types.js +4 -0
  111. package/experiments/types.js.map +1 -0
  112. package/headersProvider.d.ts +1 -2
  113. package/headersProvider.js.map +1 -1
  114. package/index.d.ts +5 -0
  115. package/index.js +5 -0
  116. package/package.json +6 -6
  117. package/types.d.ts +5 -0
@@ -1 +1 @@
1
- {"version":3,"file":"asset/normalize.js","sources":["../../src/asset/normalize.ts"],"sourcesContent":["import type { Asset, AssetCategory, AssetImage } from \"./types.js\";\n\nexport function getAssetCategory(type?: string | null): AssetCategory {\n if (typeof type === \"string\") {\n if (type.startsWith(\"image/\")) {\n return \"image\";\n }\n if (type.startsWith(\"video/\")) {\n return \"video\";\n }\n }\n return \"document\";\n}\n\nconst isObject = (value: unknown): value is Record<string, unknown> => {\n return typeof value === \"object\" && value !== null;\n};\n\nconst asNumber = (value: unknown): number | undefined => {\n return typeof value === \"number\" && !Number.isNaN(value) ? value : undefined;\n};\n\nconst asString = (value: unknown): string | undefined => {\n return typeof value === \"string\" ? value : undefined;\n};\n\ninterface LegacyImageEdit {\n crop?: { top: number; left: number; bottom: number; right: number };\n hotspot?: { x: number; y: number; width?: number; height?: number };\n alt?: string;\n caption?: string;\n}\n\nexport function assetImageFromLegacyEdit(\n edit?: LegacyImageEdit | null,\n dimensions?: { width?: number | null; height?: number | null }\n): AssetImage | undefined {\n const image: AssetImage = {};\n\n const width = asNumber(dimensions?.width);\n const height = asNumber(dimensions?.height);\n if (width !== undefined) {\n image.width = width;\n }\n if (height !== undefined) {\n image.height = height;\n }\n\n if (edit?.crop) {\n image.crop = {\n top: edit.crop.top ?? 0,\n left: edit.crop.left ?? 0,\n bottom: edit.crop.bottom ?? 0,\n right: edit.crop.right ?? 0\n };\n }\n if (edit?.hotspot) {\n image.focalPoint = { x: edit.hotspot.x, y: edit.hotspot.y };\n }\n if (edit?.alt) {\n image.alt = edit.alt;\n }\n if (edit?.caption) {\n image.caption = edit.caption;\n }\n\n return Object.keys(image).length > 0 ? image : undefined;\n}\n\nconst normalizeAssetImage = (raw: unknown): AssetImage | undefined => {\n if (!isObject(raw)) {\n return undefined;\n }\n const image: AssetImage = {};\n const width = asNumber(raw.width);\n const height = asNumber(raw.height);\n if (width !== undefined) {\n image.width = width;\n }\n if (height !== undefined) {\n image.height = height;\n }\n if (isObject(raw.crop)) {\n image.crop = {\n top: asNumber(raw.crop.top) ?? 0,\n left: asNumber(raw.crop.left) ?? 0,\n bottom: asNumber(raw.crop.bottom) ?? 0,\n right: asNumber(raw.crop.right) ?? 0\n };\n }\n if (isObject(raw.focalPoint)) {\n const x = asNumber(raw.focalPoint.x);\n const y = asNumber(raw.focalPoint.y);\n if (x !== undefined && y !== undefined) {\n image.focalPoint = { x, y };\n }\n }\n const alt = asString(raw.alt);\n if (alt) {\n image.alt = alt;\n }\n const caption = asString(raw.caption);\n if (caption) {\n image.caption = caption;\n }\n return Object.keys(image).length > 0 ? image : undefined;\n};\n\nconst buildBase = (raw: Record<string, unknown>, type: string): Asset => {\n const src = asString(raw.src) ?? \"\";\n return {\n id: asString(raw.id) ?? \"\",\n src,\n url: asString(raw.url) ?? src,\n name: asString(raw.name) ?? \"\",\n type,\n size: asNumber(raw.size) ?? 0\n };\n};\n\nexport function normalizeToAsset(input: unknown): Asset | null {\n if (!isObject(input)) {\n return null;\n }\n\n const hasTypedSubObject =\n isObject(input.image) || isObject(input.document) || isObject(input.video);\n\n if (!hasTypedSubObject) {\n const type = asString(input.mimeType) ?? asString(input.type) ?? \"\";\n const asset = buildBase(input, type);\n if (getAssetCategory(type) === \"image\") {\n const image = assetImageFromLegacyEdit(input.edit as LegacyImageEdit | undefined, {\n width: asNumber(input.width),\n height: asNumber(input.height)\n });\n if (image) {\n asset.image = image;\n }\n }\n return asset;\n }\n\n const type = asString(input.type) ?? asString(input.mimeType) ?? \"\";\n const asset = buildBase(input, type);\n const category = getAssetCategory(type);\n if (category === \"image\") {\n const image = normalizeAssetImage(input.image);\n if (image) {\n asset.image = image;\n }\n } else if (category === \"video\") {\n if (isObject(input.video)) {\n asset.video = {\n autoplay:\n typeof input.video.autoplay === \"boolean\" ? input.video.autoplay : undefined,\n poster: asString(input.video.poster)\n };\n }\n } else if (isObject(input.document)) {\n asset.document = { pages: asNumber(input.document.pages) };\n }\n return asset;\n}\n"],"names":["getAssetCategory","type","isObject","value","asNumber","Number","undefined","asString","assetImageFromLegacyEdit","edit","dimensions","image","width","height","Object","normalizeAssetImage","raw","x","y","alt","caption","buildBase","src","normalizeToAsset","input","hasTypedSubObject","asset","category"],"mappings":"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"}
1
+ {"version":3,"file":"asset/normalize.js","sources":["../../src/asset/normalize.ts"],"sourcesContent":["import type { Asset, AssetCategory, AssetImage } from \"./types.js\";\n\nexport function getAssetCategory(mimeType?: string | null): AssetCategory {\n if (typeof mimeType === \"string\") {\n if (mimeType.startsWith(\"image/\")) {\n return \"image\";\n }\n if (mimeType.startsWith(\"video/\")) {\n return \"video\";\n }\n }\n return \"document\";\n}\n\nconst isObject = (value: unknown): value is Record<string, unknown> => {\n return typeof value === \"object\" && value !== null;\n};\n\nconst asNumber = (value: unknown): number | undefined => {\n return typeof value === \"number\" && !Number.isNaN(value) ? value : undefined;\n};\n\nconst asString = (value: unknown): string | undefined => {\n return typeof value === \"string\" ? value : undefined;\n};\n\ninterface LegacyImageEdit {\n crop?: { top: number; left: number; bottom: number; right: number };\n hotspot?: { x: number; y: number; width?: number; height?: number };\n alt?: string;\n caption?: string;\n}\n\nexport function assetImageFromLegacyEdit(\n edit?: LegacyImageEdit | null,\n dimensions?: { width?: number | null; height?: number | null }\n): AssetImage | undefined {\n const image: AssetImage = {};\n\n const width = asNumber(dimensions?.width);\n const height = asNumber(dimensions?.height);\n if (width !== undefined) {\n image.width = width;\n }\n if (height !== undefined) {\n image.height = height;\n }\n\n if (edit?.crop) {\n image.crop = {\n top: edit.crop.top ?? 0,\n left: edit.crop.left ?? 0,\n bottom: edit.crop.bottom ?? 0,\n right: edit.crop.right ?? 0\n };\n }\n if (edit?.hotspot) {\n image.focalPoint = { x: edit.hotspot.x, y: edit.hotspot.y };\n }\n if (edit?.alt) {\n image.alt = edit.alt;\n }\n if (edit?.caption) {\n image.caption = edit.caption;\n }\n\n return Object.keys(image).length > 0 ? image : undefined;\n}\n\nconst normalizeAssetImage = (raw: unknown): AssetImage | undefined => {\n if (!isObject(raw)) {\n return undefined;\n }\n const image: AssetImage = {};\n const width = asNumber(raw.width);\n const height = asNumber(raw.height);\n if (width !== undefined) {\n image.width = width;\n }\n if (height !== undefined) {\n image.height = height;\n }\n if (isObject(raw.crop)) {\n image.crop = {\n top: asNumber(raw.crop.top) ?? 0,\n left: asNumber(raw.crop.left) ?? 0,\n bottom: asNumber(raw.crop.bottom) ?? 0,\n right: asNumber(raw.crop.right) ?? 0\n };\n }\n if (isObject(raw.focalPoint)) {\n const x = asNumber(raw.focalPoint.x);\n const y = asNumber(raw.focalPoint.y);\n if (x !== undefined && y !== undefined) {\n image.focalPoint = { x, y };\n }\n }\n const alt = asString(raw.alt);\n if (alt) {\n image.alt = alt;\n }\n const caption = asString(raw.caption);\n if (caption) {\n image.caption = caption;\n }\n return Object.keys(image).length > 0 ? image : undefined;\n};\n\nconst buildBase = (raw: Record<string, unknown>, mimeType: string): Asset => {\n const src = asString(raw.src) ?? \"\";\n return {\n id: asString(raw.id) ?? \"\",\n src,\n url: asString(raw.url) ?? src,\n name: asString(raw.name) ?? \"\",\n mimeType,\n size: asNumber(raw.size) ?? 0\n };\n};\n\n/**\n * Keeps the image dimensions in both places: `image.width`/`image.height` for current code,\n * and the root `width`/`height` that 6.4 frontends read.\n */\nconst syncImageDimensions = (asset: Asset): Asset => {\n if (!asset.image) {\n return asset;\n }\n if (asset.image.width !== undefined) {\n asset.width = asset.image.width;\n }\n if (asset.image.height !== undefined) {\n asset.height = asset.image.height;\n }\n return asset;\n};\n\nexport function normalizeToAsset(input: unknown): Asset | null {\n if (!isObject(input)) {\n return null;\n }\n\n const hasTypedSubObject =\n isObject(input.image) || isObject(input.document) || isObject(input.video);\n\n const mimeType = asString(input.mimeType) ?? \"\";\n const asset = buildBase(input, mimeType);\n const category = getAssetCategory(mimeType);\n\n if (!hasTypedSubObject) {\n if (category === \"image\") {\n const image = assetImageFromLegacyEdit(input.edit as LegacyImageEdit | undefined, {\n width: asNumber(input.width),\n height: asNumber(input.height)\n });\n if (image) {\n asset.image = image;\n }\n }\n return syncImageDimensions(asset);\n }\n\n if (category === \"image\") {\n const image = normalizeAssetImage(input.image);\n if (image) {\n asset.image = image;\n }\n } else if (category === \"video\") {\n if (isObject(input.video)) {\n asset.video = {\n autoplay:\n typeof input.video.autoplay === \"boolean\" ? input.video.autoplay : undefined,\n poster: asString(input.video.poster)\n };\n }\n } else if (isObject(input.document)) {\n asset.document = { pages: asNumber(input.document.pages) };\n }\n return syncImageDimensions(asset);\n}\n"],"names":["getAssetCategory","mimeType","isObject","value","asNumber","Number","undefined","asString","assetImageFromLegacyEdit","edit","dimensions","image","width","height","Object","normalizeAssetImage","raw","x","y","alt","caption","buildBase","src","syncImageDimensions","asset","normalizeToAsset","input","hasTypedSubObject","category"],"mappings":"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"}
@@ -95,15 +95,17 @@ describe("normalizeToAsset — legacy Website Builder image value", ()=>{
95
95
  alt: "A cat"
96
96
  }
97
97
  };
98
- it("upgrades mimeType -> type and edit -> image", ()=>{
98
+ it("keeps mimeType, maps edit -> image, and mirrors dimensions at the root", ()=>{
99
99
  const asset = normalizeToAsset(legacy);
100
100
  expect(asset).toEqual({
101
101
  id: "file-1",
102
102
  src: "https://cdn/x/cat.jpg",
103
103
  url: "https://cdn/x/cat.jpg",
104
104
  name: "cat.jpg",
105
- type: "image/jpeg",
105
+ mimeType: "image/jpeg",
106
106
  size: 1234,
107
+ width: 800,
108
+ height: 600,
107
109
  image: {
108
110
  width: 800,
109
111
  height: 600,
@@ -131,12 +133,12 @@ describe("normalizeToAsset — legacy Website Builder image value", ()=>{
131
133
  height: 600
132
134
  });
133
135
  });
134
- it("upgrades an original flat WB file value (type + top-level dims, no edit)", ()=>{
136
+ it("upgrades a flat 6.4 file value (mimeType + top-level dims, no edit)", ()=>{
135
137
  const asset = normalizeToAsset({
136
138
  id: "f",
137
139
  src: "https://cdn/x.jpg",
138
140
  name: "x.jpg",
139
- type: "image/jpeg",
141
+ mimeType: "image/jpeg",
140
142
  size: 10,
141
143
  width: 800,
142
144
  height: 600
@@ -146,8 +148,10 @@ describe("normalizeToAsset — legacy Website Builder image value", ()=>{
146
148
  src: "https://cdn/x.jpg",
147
149
  url: "https://cdn/x.jpg",
148
150
  name: "x.jpg",
149
- type: "image/jpeg",
151
+ mimeType: "image/jpeg",
150
152
  size: 10,
153
+ width: 800,
154
+ height: 600,
151
155
  image: {
152
156
  width: 800,
153
157
  height: 600
@@ -162,7 +166,8 @@ describe("normalizeToAsset — legacy Website Builder image value", ()=>{
162
166
  width: void 0,
163
167
  height: void 0
164
168
  });
165
- expect(asset?.type).toBe("application/pdf");
169
+ expect(asset?.mimeType).toBe("application/pdf");
170
+ expect(asset?.width).toBeUndefined();
166
171
  expect(asset?.image).toBeUndefined();
167
172
  });
168
173
  });
@@ -173,8 +178,10 @@ describe("normalizeToAsset — already-unified asset", ()=>{
173
178
  src: "https://cdn/y/pic.png",
174
179
  url: "https://cdn/y/pic.png",
175
180
  name: "pic.png",
176
- type: "image/png",
181
+ mimeType: "image/png",
177
182
  size: 9,
183
+ width: 400,
184
+ height: 300,
178
185
  image: {
179
186
  width: 400,
180
187
  height: 300,
@@ -198,7 +205,7 @@ describe("normalizeToAsset — already-unified asset", ()=>{
198
205
  id: "v1",
199
206
  src: "https://cdn/v/clip.mp4",
200
207
  name: "clip.mp4",
201
- type: "video/mp4",
208
+ mimeType: "video/mp4",
202
209
  size: 42,
203
210
  video: {
204
211
  autoplay: true,
@@ -1 +1 @@
1
- {"version":3,"file":"asset/normalize.test.js","sources":["../../src/asset/normalize.test.ts"],"sourcesContent":["import { describe, it, expect } from \"vitest\";\nimport { assetImageFromLegacyEdit, getAssetCategory, normalizeToAsset } from \"./normalize.js\";\nimport { resolveAssetImage } from \"../image/geometry.js\";\n\ndescribe(\"getAssetCategory\", () => {\n it(\"buckets by MIME prefix\", () => {\n expect(getAssetCategory(\"image/jpeg\")).toBe(\"image\");\n expect(getAssetCategory(\"image/svg+xml\")).toBe(\"image\");\n expect(getAssetCategory(\"video/mp4\")).toBe(\"video\");\n });\n\n it(\"treats everything else as a document\", () => {\n expect(getAssetCategory(\"application/pdf\")).toBe(\"document\");\n expect(getAssetCategory(\"application/zip\")).toBe(\"document\");\n expect(getAssetCategory(\"\")).toBe(\"document\");\n expect(getAssetCategory(undefined)).toBe(\"document\");\n expect(getAssetCategory(null)).toBe(\"document\");\n });\n});\n\ndescribe(\"assetImageFromLegacyEdit\", () => {\n it(\"maps hotspot -> focalPoint and keeps crop/alt/caption\", () => {\n const image = assetImageFromLegacyEdit(\n {\n crop: { top: 0.1, left: 0, bottom: 0.1, right: 0 },\n hotspot: { x: 0.3, y: 0.7, width: 0.5, height: 0.5 },\n alt: \"A cat\",\n caption: \"Meow\"\n },\n { width: 800, height: 600 }\n );\n expect(image).toEqual({\n width: 800,\n height: 600,\n crop: { top: 0.1, left: 0, bottom: 0.1, right: 0 },\n focalPoint: { x: 0.3, y: 0.7 },\n alt: \"A cat\",\n caption: \"Meow\"\n });\n });\n\n it(\"returns undefined when there is nothing to store\", () => {\n expect(assetImageFromLegacyEdit(undefined, {})).toBeUndefined();\n expect(assetImageFromLegacyEdit(null, { width: null, height: undefined })).toBeUndefined();\n });\n\n it(\"keeps dimensions even without an edit\", () => {\n expect(assetImageFromLegacyEdit(undefined, { width: 100, height: 50 })).toEqual({\n width: 100,\n height: 50\n });\n });\n});\n\ndescribe(\"normalizeToAsset — legacy Website Builder image value\", () => {\n const legacy = {\n id: \"file-1\",\n name: \"cat.jpg\",\n size: 1234,\n mimeType: \"image/jpeg\",\n src: \"https://cdn/x/cat.jpg\",\n width: 800,\n height: 600,\n edit: {\n crop: { top: 0.1, left: 0.1, bottom: 0.1, right: 0.1 },\n hotspot: { x: 0.25, y: 0.75, width: 1, height: 1 },\n alt: \"A cat\"\n }\n };\n\n it(\"upgrades mimeType -> type and edit -> image\", () => {\n const asset = normalizeToAsset(legacy);\n expect(asset).toEqual({\n id: \"file-1\",\n src: \"https://cdn/x/cat.jpg\",\n url: \"https://cdn/x/cat.jpg\",\n name: \"cat.jpg\",\n type: \"image/jpeg\",\n size: 1234,\n image: {\n width: 800,\n height: 600,\n crop: { top: 0.1, left: 0.1, bottom: 0.1, right: 0.1 },\n focalPoint: { x: 0.25, y: 0.75 },\n alt: \"A cat\"\n }\n });\n });\n\n it(\"handles a legacy value with no edit (dimensions only)\", () => {\n const asset = normalizeToAsset({ ...legacy, edit: undefined });\n expect(asset?.image).toEqual({ width: 800, height: 600 });\n });\n\n it(\"upgrades an original flat WB file value (type + top-level dims, no edit)\", () => {\n // The shape existing released pages store: flat, uses `type`, no sub-object.\n const asset = normalizeToAsset({\n id: \"f\",\n src: \"https://cdn/x.jpg\",\n name: \"x.jpg\",\n type: \"image/jpeg\",\n size: 10,\n width: 800,\n height: 600\n });\n expect(asset).toEqual({\n id: \"f\",\n src: \"https://cdn/x.jpg\",\n url: \"https://cdn/x.jpg\",\n name: \"x.jpg\",\n type: \"image/jpeg\",\n size: 10,\n image: { width: 800, height: 600 }\n });\n });\n\n it(\"does not attach image data for a non-image legacy value\", () => {\n const asset = normalizeToAsset({\n ...legacy,\n mimeType: \"application/pdf\",\n edit: undefined,\n width: undefined,\n height: undefined\n });\n expect(asset?.type).toBe(\"application/pdf\");\n expect(asset?.image).toBeUndefined();\n });\n});\n\ndescribe(\"normalizeToAsset — already-unified asset\", () => {\n it(\"is idempotent for a well-formed image asset\", () => {\n const asset = {\n id: \"f2\",\n src: \"https://cdn/y/pic.png\",\n url: \"https://cdn/y/pic.png\",\n name: \"pic.png\",\n type: \"image/png\",\n size: 9,\n image: {\n width: 400,\n height: 300,\n crop: { top: 0, left: 0.2, bottom: 0, right: 0.2 },\n focalPoint: { x: 0.5, y: 0.5 },\n alt: \"Pic\"\n }\n };\n expect(normalizeToAsset(asset)).toEqual(asset);\n });\n\n it(\"preserves video data\", () => {\n const asset = normalizeToAsset({\n id: \"v1\",\n src: \"https://cdn/v/clip.mp4\",\n name: \"clip.mp4\",\n type: \"video/mp4\",\n size: 42,\n video: { autoplay: true, poster: \"https://cdn/v/poster.jpg\" }\n });\n expect(asset?.video).toEqual({ autoplay: true, poster: \"https://cdn/v/poster.jpg\" });\n });\n\n it(\"returns null for invalid input\", () => {\n expect(normalizeToAsset(null)).toBeNull();\n expect(normalizeToAsset(undefined)).toBeNull();\n expect(normalizeToAsset(\"nope\")).toBeNull();\n expect(normalizeToAsset(42)).toBeNull();\n });\n});\n\ndescribe(\"resolveAssetImage\", () => {\n it(\"prefers override per property, falling back to base\", () => {\n const merged = resolveAssetImage(\n { crop: { top: 0.1, left: 0, bottom: 0, right: 0 } },\n {\n crop: { top: 0.5, left: 0, bottom: 0, right: 0 },\n focalPoint: { x: 0.2, y: 0.2 },\n alt: \"base\"\n }\n );\n expect(merged.crop).toEqual({ top: 0.1, left: 0, bottom: 0, right: 0 });\n expect(merged.focalPoint).toEqual({ x: 0.2, y: 0.2 });\n expect(merged.alt).toBe(\"base\");\n });\n});\n"],"names":["describe","it","expect","getAssetCategory","undefined","image","assetImageFromLegacyEdit","legacy","asset","normalizeToAsset","merged","resolveAssetImage"],"mappings":"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"}
1
+ {"version":3,"file":"asset/normalize.test.js","sources":["../../src/asset/normalize.test.ts"],"sourcesContent":["import { describe, it, expect } from \"vitest\";\nimport { assetImageFromLegacyEdit, getAssetCategory, normalizeToAsset } from \"./normalize.js\";\nimport { resolveAssetImage } from \"../image/geometry.js\";\n\ndescribe(\"getAssetCategory\", () => {\n it(\"buckets by MIME prefix\", () => {\n expect(getAssetCategory(\"image/jpeg\")).toBe(\"image\");\n expect(getAssetCategory(\"image/svg+xml\")).toBe(\"image\");\n expect(getAssetCategory(\"video/mp4\")).toBe(\"video\");\n });\n\n it(\"treats everything else as a document\", () => {\n expect(getAssetCategory(\"application/pdf\")).toBe(\"document\");\n expect(getAssetCategory(\"application/zip\")).toBe(\"document\");\n expect(getAssetCategory(\"\")).toBe(\"document\");\n expect(getAssetCategory(undefined)).toBe(\"document\");\n expect(getAssetCategory(null)).toBe(\"document\");\n });\n});\n\ndescribe(\"assetImageFromLegacyEdit\", () => {\n it(\"maps hotspot -> focalPoint and keeps crop/alt/caption\", () => {\n const image = assetImageFromLegacyEdit(\n {\n crop: { top: 0.1, left: 0, bottom: 0.1, right: 0 },\n hotspot: { x: 0.3, y: 0.7, width: 0.5, height: 0.5 },\n alt: \"A cat\",\n caption: \"Meow\"\n },\n { width: 800, height: 600 }\n );\n expect(image).toEqual({\n width: 800,\n height: 600,\n crop: { top: 0.1, left: 0, bottom: 0.1, right: 0 },\n focalPoint: { x: 0.3, y: 0.7 },\n alt: \"A cat\",\n caption: \"Meow\"\n });\n });\n\n it(\"returns undefined when there is nothing to store\", () => {\n expect(assetImageFromLegacyEdit(undefined, {})).toBeUndefined();\n expect(assetImageFromLegacyEdit(null, { width: null, height: undefined })).toBeUndefined();\n });\n\n it(\"keeps dimensions even without an edit\", () => {\n expect(assetImageFromLegacyEdit(undefined, { width: 100, height: 50 })).toEqual({\n width: 100,\n height: 50\n });\n });\n});\n\ndescribe(\"normalizeToAsset — legacy Website Builder image value\", () => {\n const legacy = {\n id: \"file-1\",\n name: \"cat.jpg\",\n size: 1234,\n mimeType: \"image/jpeg\",\n src: \"https://cdn/x/cat.jpg\",\n width: 800,\n height: 600,\n edit: {\n crop: { top: 0.1, left: 0.1, bottom: 0.1, right: 0.1 },\n hotspot: { x: 0.25, y: 0.75, width: 1, height: 1 },\n alt: \"A cat\"\n }\n };\n\n it(\"keeps mimeType, maps edit -> image, and mirrors dimensions at the root\", () => {\n const asset = normalizeToAsset(legacy);\n expect(asset).toEqual({\n id: \"file-1\",\n src: \"https://cdn/x/cat.jpg\",\n url: \"https://cdn/x/cat.jpg\",\n name: \"cat.jpg\",\n mimeType: \"image/jpeg\",\n size: 1234,\n width: 800,\n height: 600,\n image: {\n width: 800,\n height: 600,\n crop: { top: 0.1, left: 0.1, bottom: 0.1, right: 0.1 },\n focalPoint: { x: 0.25, y: 0.75 },\n alt: \"A cat\"\n }\n });\n });\n\n it(\"handles a legacy value with no edit (dimensions only)\", () => {\n const asset = normalizeToAsset({ ...legacy, edit: undefined });\n expect(asset?.image).toEqual({ width: 800, height: 600 });\n });\n\n it(\"upgrades a flat 6.4 file value (mimeType + top-level dims, no edit)\", () => {\n // The shape released 6.x versions store: flat, no image sub-object.\n const asset = normalizeToAsset({\n id: \"f\",\n src: \"https://cdn/x.jpg\",\n name: \"x.jpg\",\n mimeType: \"image/jpeg\",\n size: 10,\n width: 800,\n height: 600\n });\n expect(asset).toEqual({\n id: \"f\",\n src: \"https://cdn/x.jpg\",\n url: \"https://cdn/x.jpg\",\n name: \"x.jpg\",\n mimeType: \"image/jpeg\",\n size: 10,\n width: 800,\n height: 600,\n image: { width: 800, height: 600 }\n });\n });\n\n it(\"does not attach image data for a non-image legacy value\", () => {\n const asset = normalizeToAsset({\n ...legacy,\n mimeType: \"application/pdf\",\n edit: undefined,\n width: undefined,\n height: undefined\n });\n expect(asset?.mimeType).toBe(\"application/pdf\");\n expect(asset?.width).toBeUndefined();\n expect(asset?.image).toBeUndefined();\n });\n});\n\ndescribe(\"normalizeToAsset — already-unified asset\", () => {\n it(\"is idempotent for a well-formed image asset\", () => {\n const asset = {\n id: \"f2\",\n src: \"https://cdn/y/pic.png\",\n url: \"https://cdn/y/pic.png\",\n name: \"pic.png\",\n mimeType: \"image/png\",\n size: 9,\n width: 400,\n height: 300,\n image: {\n width: 400,\n height: 300,\n crop: { top: 0, left: 0.2, bottom: 0, right: 0.2 },\n focalPoint: { x: 0.5, y: 0.5 },\n alt: \"Pic\"\n }\n };\n expect(normalizeToAsset(asset)).toEqual(asset);\n });\n\n it(\"preserves video data\", () => {\n const asset = normalizeToAsset({\n id: \"v1\",\n src: \"https://cdn/v/clip.mp4\",\n name: \"clip.mp4\",\n mimeType: \"video/mp4\",\n size: 42,\n video: { autoplay: true, poster: \"https://cdn/v/poster.jpg\" }\n });\n expect(asset?.video).toEqual({ autoplay: true, poster: \"https://cdn/v/poster.jpg\" });\n });\n\n it(\"returns null for invalid input\", () => {\n expect(normalizeToAsset(null)).toBeNull();\n expect(normalizeToAsset(undefined)).toBeNull();\n expect(normalizeToAsset(\"nope\")).toBeNull();\n expect(normalizeToAsset(42)).toBeNull();\n });\n});\n\ndescribe(\"resolveAssetImage\", () => {\n it(\"prefers override per property, falling back to base\", () => {\n const merged = resolveAssetImage(\n { crop: { top: 0.1, left: 0, bottom: 0, right: 0 } },\n {\n crop: { top: 0.5, left: 0, bottom: 0, right: 0 },\n focalPoint: { x: 0.2, y: 0.2 },\n alt: \"base\"\n }\n );\n expect(merged.crop).toEqual({ top: 0.1, left: 0, bottom: 0, right: 0 });\n expect(merged.focalPoint).toEqual({ x: 0.2, y: 0.2 });\n expect(merged.alt).toBe(\"base\");\n });\n});\n"],"names":["describe","it","expect","getAssetCategory","undefined","image","assetImageFromLegacyEdit","legacy","asset","normalizeToAsset","merged","resolveAssetImage"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { Component, ElementComponent } from "../types.js";
2
+ import type { ApiClient } from "../dataProviders/ApiClient.js";
3
+ import type { ApiConfig } from "../ContentSdk.js";
4
+ /**
5
+ * Loads a component that a document references but the content client has no registration for.
6
+ * This is the seam for fetching components per tenant and for caching them. The content client
7
+ * creates one loader per client and caches nothing itself.
8
+ */
9
+ export interface ComponentLoader {
10
+ loadComponent(ref: ElementComponent): Promise<Component | null>;
11
+ }
12
+ export type ComponentLoaderFactoryParams = {
13
+ apiClient: ApiClient;
14
+ config: ApiConfig;
15
+ };
16
+ export type ComponentLoaderFactory = (params: ComponentLoaderFactoryParams) => ComponentLoader;
File without changes
@@ -0,0 +1,9 @@
1
+ import type { Component } from "../types.js";
2
+ import type { ComponentLoader } from "./ComponentLoader.js";
3
+ /**
4
+ * The loader used when neither the config nor a framework integration provides one. It loads
5
+ * nothing, so only components registered with `registerComponent` render.
6
+ */
7
+ export declare class RegistryOnlyComponentLoader implements ComponentLoader {
8
+ loadComponent(): Promise<Component | null>;
9
+ }
@@ -0,0 +1,8 @@
1
+ class RegistryOnlyComponentLoader {
2
+ async loadComponent() {
3
+ return null;
4
+ }
5
+ }
6
+ export { RegistryOnlyComponentLoader };
7
+
8
+ //# sourceMappingURL=RegistryOnlyComponentLoader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"componentLoader/RegistryOnlyComponentLoader.js","sources":["../../src/componentLoader/RegistryOnlyComponentLoader.ts"],"sourcesContent":["import type { Component } from \"~/types.js\";\nimport type { ComponentLoader } from \"./ComponentLoader.js\";\n\n/**\n * The loader used when neither the config nor a framework integration provides one. It loads\n * nothing, so only components registered with `registerComponent` render.\n */\nexport class RegistryOnlyComponentLoader implements ComponentLoader {\n async loadComponent(): Promise<Component | null> {\n return null;\n }\n}\n"],"names":["RegistryOnlyComponentLoader"],"mappings":"AAOO,MAAMA;IACT,MAAM,gBAA2C;QAC7C,OAAO;IACX;AACJ"}
@@ -0,0 +1,7 @@
1
+ import type { ComponentLoader, ComponentLoaderFactory } from "./ComponentLoader.js";
2
+ import type { ComponentLoaderFactoryParams } from "./ComponentLoader.js";
3
+ /**
4
+ * Create a content client's loader: its own factory if it has one, else the default set with
5
+ * `setDefaultComponentLoader`, else a loader that loads nothing.
6
+ */
7
+ export declare function createComponentLoader(factory: ComponentLoaderFactory | undefined, params: ComponentLoaderFactoryParams): ComponentLoader;
@@ -0,0 +1,10 @@
1
+ import { getDefaultComponentLoader } from "./defaultComponentLoader.js";
2
+ import { RegistryOnlyComponentLoader } from "./RegistryOnlyComponentLoader.js";
3
+ function createComponentLoader(factory, params) {
4
+ const resolved = factory ?? getDefaultComponentLoader();
5
+ if (!resolved) return new RegistryOnlyComponentLoader();
6
+ return resolved(params);
7
+ }
8
+ export { createComponentLoader };
9
+
10
+ //# sourceMappingURL=createComponentLoader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"componentLoader/createComponentLoader.js","sources":["../../src/componentLoader/createComponentLoader.ts"],"sourcesContent":["import type { ComponentLoader, ComponentLoaderFactory } from \"./ComponentLoader.js\";\nimport type { ComponentLoaderFactoryParams } from \"./ComponentLoader.js\";\nimport { getDefaultComponentLoader } from \"./defaultComponentLoader.js\";\nimport { RegistryOnlyComponentLoader } from \"./RegistryOnlyComponentLoader.js\";\n\n/**\n * Create a content client's loader: its own factory if it has one, else the default set with\n * `setDefaultComponentLoader`, else a loader that loads nothing.\n */\nexport function createComponentLoader(\n factory: ComponentLoaderFactory | undefined,\n params: ComponentLoaderFactoryParams\n): ComponentLoader {\n const resolved = factory ?? getDefaultComponentLoader();\n if (!resolved) {\n return new RegistryOnlyComponentLoader();\n }\n return resolved(params);\n}\n"],"names":["createComponentLoader","factory","params","resolved","getDefaultComponentLoader","RegistryOnlyComponentLoader"],"mappings":";;AASO,SAASA,sBACZC,OAA2C,EAC3CC,MAAoC;IAEpC,MAAMC,WAAWF,WAAWG;IAC5B,IAAI,CAACD,UACD,OAAO,IAAIE;IAEf,OAAOF,SAASD;AACpB"}
@@ -0,0 +1,7 @@
1
+ import type { ComponentLoaderFactory } from "./ComponentLoader.js";
2
+ /**
3
+ * Set the component loader that content clients use when their config has none. A framework
4
+ * integration sets it on import, the way it sets the headers provider.
5
+ */
6
+ export declare const setDefaultComponentLoader: (factory: ComponentLoaderFactory | undefined) => void;
7
+ export declare const getDefaultComponentLoader: () => ComponentLoaderFactory | undefined;
@@ -0,0 +1,8 @@
1
+ let defaultComponentLoader;
2
+ const setDefaultComponentLoader = (factory)=>{
3
+ defaultComponentLoader = factory;
4
+ };
5
+ const getDefaultComponentLoader = ()=>defaultComponentLoader;
6
+ export { getDefaultComponentLoader, setDefaultComponentLoader };
7
+
8
+ //# sourceMappingURL=defaultComponentLoader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"componentLoader/defaultComponentLoader.js","sources":["../../src/componentLoader/defaultComponentLoader.ts"],"sourcesContent":["import type { ComponentLoaderFactory } from \"./ComponentLoader.js\";\n\nlet defaultComponentLoader: ComponentLoaderFactory | undefined;\n\n/**\n * Set the component loader that content clients use when their config has none. A framework\n * integration sets it on import, the way it sets the headers provider.\n */\nexport const setDefaultComponentLoader = (factory: ComponentLoaderFactory | undefined) => {\n defaultComponentLoader = factory;\n};\n\nexport const getDefaultComponentLoader = () => defaultComponentLoader;\n"],"names":["defaultComponentLoader","setDefaultComponentLoader","factory","getDefaultComponentLoader"],"mappings":"AAEA,IAAIA;AAMG,MAAMC,4BAA4B,CAACC;IACtCF,yBAAyBE;AAC7B;AAEO,MAAMC,4BAA4B,IAAMH"}
@@ -0,0 +1,3 @@
1
+ export * from "./ComponentLoader.js";
2
+ export * from "./RegistryOnlyComponentLoader.js";
3
+ export * from "./defaultComponentLoader.js";
@@ -0,0 +1,3 @@
1
+ export * from "./ComponentLoader.js";
2
+ export * from "./RegistryOnlyComponentLoader.js";
3
+ export * from "./defaultComponentLoader.js";
@@ -0,0 +1 @@
1
+ export {};