@builder.io/sdk-solid 3.0.0 → 3.0.1

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.
@@ -95,7 +95,8 @@ var builder_context_default = createContext({
95
95
  inheritedStyles: {},
96
96
  BlocksWrapper: "div",
97
97
  BlocksWrapperProps: {},
98
- nonce: ""
98
+ nonce: "",
99
+ model: ""
99
100
  });
100
101
 
101
102
  // src/context/components.context.ts
@@ -394,6 +395,77 @@ function evaluate({
394
395
  }
395
396
  }
396
397
 
398
+ // src/functions/traverse.ts
399
+ function traverse(obj, callback, parent2 = null, key = null, visited = /* @__PURE__ */ new WeakSet()) {
400
+ if (obj == null || typeof obj !== "object") {
401
+ callback(obj, (newValue) => {
402
+ if (parent2 !== null && key !== null) {
403
+ parent2[key] = newValue;
404
+ }
405
+ });
406
+ return;
407
+ }
408
+ if (visited.has(obj)) {
409
+ return;
410
+ }
411
+ visited.add(obj);
412
+ if (Array.isArray(obj)) {
413
+ obj.forEach((item, index) => {
414
+ const update = (newValue) => {
415
+ obj[index] = newValue;
416
+ };
417
+ callback(item, update);
418
+ traverse(item, callback, obj, index, visited);
419
+ });
420
+ } else {
421
+ Object.entries(obj).forEach(([key2, value]) => {
422
+ const update = (newValue) => {
423
+ obj[key2] = newValue;
424
+ };
425
+ callback(value, update);
426
+ traverse(value, callback, obj, key2, visited);
427
+ });
428
+ }
429
+ }
430
+
431
+ // src/functions/extract-localized-values.ts
432
+ function isLocalizedField(value) {
433
+ return value && typeof value === "object" && value["@type"] === "@builder.io/core:LocalizedValue";
434
+ }
435
+ function containsLocalizedValues(data) {
436
+ if (!data || !Object.getOwnPropertyNames(data).length) {
437
+ return false;
438
+ }
439
+ let hasLocalizedValues = false;
440
+ traverse(data, (value) => {
441
+ if (isLocalizedField(value)) {
442
+ hasLocalizedValues = true;
443
+ return;
444
+ }
445
+ });
446
+ return hasLocalizedValues;
447
+ }
448
+ function extractLocalizedValues(data, locale) {
449
+ if (!data || !Object.getOwnPropertyNames(data).length) {
450
+ return {};
451
+ }
452
+ traverse(data, (value, update) => {
453
+ if (isLocalizedField(value)) {
454
+ update(value[locale] ?? void 0);
455
+ }
456
+ });
457
+ return data;
458
+ }
459
+ function resolveLocalizedValues(block, locale) {
460
+ if (block.component?.options && containsLocalizedValues(block.component?.options)) {
461
+ if (!locale) {
462
+ console.warn("[Builder.io] In order to use localized fields in Builder, you must pass a locale prop to the BuilderComponent or to options object while fetching the content to resolve localized fields. Learn more: https://www.builder.io/c/docs/localization-inline#targeting-and-inline-localization");
463
+ }
464
+ block.component.options = extractLocalizedValues(block.component.options, locale ?? "Default");
465
+ }
466
+ return block;
467
+ }
468
+
397
469
  // src/functions/fast-clone.ts
398
470
  var fastClone = (obj) => JSON.parse(JSON.stringify(obj));
399
471
 
@@ -492,7 +564,8 @@ function getProcessedBlock({
492
564
  rootState,
493
565
  rootSetState
494
566
  }) {
495
- const transformedBlock = transformBlock(block);
567
+ let transformedBlock = resolveLocalizedValues(block, rootState.locale);
568
+ transformedBlock = transformBlock(transformedBlock);
496
569
  if (shouldEvaluateBindings) {
497
570
  return evaluateBindings({
498
571
  block: transformedBlock,
@@ -750,16 +823,24 @@ function mapStyleObjToStrIfNeeded(style) {
750
823
  }
751
824
 
752
825
  // src/components/block/block.helpers.ts
826
+ var checkIsComponentRestricted = (component, model) => {
827
+ if (!component)
828
+ return true;
829
+ if (!model)
830
+ return false;
831
+ return component.models && component.models.length > 0 && !component.models.includes(model);
832
+ };
753
833
  var getComponent = ({
754
834
  block,
755
- registeredComponents
835
+ registeredComponents,
836
+ model
756
837
  }) => {
757
838
  const componentName = block.component?.name;
758
839
  if (!componentName) {
759
840
  return null;
760
841
  }
761
842
  const ref = registeredComponents[componentName];
762
- if (!ref) {
843
+ if (!ref || checkIsComponentRestricted(ref, model)) {
763
844
  console.warn(`
764
845
  Could not find a registered component named "${componentName}".
765
846
  If you registered it, is the file that registered it imported by the file that needs to render it?`);
@@ -813,11 +894,15 @@ var provideLinkComponent = (block, linkComponent) => {
813
894
  };
814
895
  return {};
815
896
  };
816
- var provideRegisteredComponents = (block, registeredComponents) => {
817
- if (block?.shouldReceiveBuilderProps?.builderComponents)
897
+ var provideRegisteredComponents = (block, registeredComponents, model) => {
898
+ if (block?.shouldReceiveBuilderProps?.builderComponents) {
899
+ const filteredRegisteredComponents = Object.fromEntries(Object.entries(registeredComponents).filter(([_, component]) => {
900
+ return !checkIsComponentRestricted(component, model);
901
+ }));
818
902
  return {
819
- builderComponents: registeredComponents
903
+ builderComponents: filteredRegisteredComponents
820
904
  };
905
+ }
821
906
  return {};
822
907
  };
823
908
  var provideBuilderBlock = (block, builderBlock) => {
@@ -1221,7 +1306,8 @@ function Block(props) {
1221
1306
  const blockComponent = createMemo5(() => {
1222
1307
  return getComponent({
1223
1308
  block: processedBlock(),
1224
- registeredComponents: props.registeredComponents
1309
+ registeredComponents: props.registeredComponents,
1310
+ model: props.context.model
1225
1311
  });
1226
1312
  });
1227
1313
  const Tag = createMemo5(() => {
@@ -1256,7 +1342,8 @@ function Block(props) {
1256
1342
  ...provideLinkComponent(blockComponent(), props.linkComponent),
1257
1343
  ...provideRegisteredComponents(
1258
1344
  blockComponent(),
1259
- props.registeredComponents
1345
+ props.registeredComponents,
1346
+ props.context.model
1260
1347
  )
1261
1348
  },
1262
1349
  context: props.context,
@@ -1680,7 +1767,7 @@ function Image(props) {
1680
1767
  const url = imageToUse;
1681
1768
  if (!url || // We can auto add srcset for cdn.builder.io and shopify
1682
1769
  // images, otherwise you can supply this prop manually
1683
- !(url.match(/builder\.io/) || url.match(/cdn\.shopify\.com/))) {
1770
+ !(typeof url === "string" && (url.match(/builder\.io/) || url.match(/cdn\.shopify\.com/)))) {
1684
1771
  return props.srcset;
1685
1772
  }
1686
1773
  if (props.noWebp) {
@@ -1721,7 +1808,7 @@ function Image(props) {
1721
1808
  <picture>
1722
1809
  <Show8 when={webpSrcSet()}><source type="image/webp" srcset={webpSrcSet()} /></Show8>
1723
1810
  <img
1724
- class={"builder-image" + (props.className ? " " + props.className : "") + " img-7e6ffddc"}
1811
+ class={"builder-image" + (props.className ? " " + props.className : "") + " img-070d7e88"}
1725
1812
  loading={props.highPriority ? "eager" : "lazy"}
1726
1813
  fetchpriority={props.highPriority ? "high" : "auto"}
1727
1814
  alt={props.altText}
@@ -1739,22 +1826,22 @@ function Image(props) {
1739
1826
  <Show8
1740
1827
  when={props.aspectRatio && !(props.builderBlock?.children?.length && props.fitContent)}
1741
1828
  ><div
1742
- class="builder-image-sizer div-7e6ffddc"
1829
+ class="builder-image-sizer div-070d7e88"
1743
1830
  style={{
1744
1831
  "padding-top": props.aspectRatio * 100 + "%"
1745
1832
  }}
1746
1833
  /></Show8>
1747
1834
  <Show8 when={props.builderBlock?.children?.length && props.fitContent}>{props.children}</Show8>
1748
- <Show8 when={!props.fitContent && props.builderBlock?.children?.length}><div class="div-7e6ffddc-2">{props.children}</div></Show8>
1835
+ <Show8 when={!props.fitContent && props.builderBlock?.children?.length}><div class="div-070d7e88-2">{props.children}</div></Show8>
1749
1836
  </>
1750
- <style>{`.img-7e6ffddc {
1837
+ <style>{`.img-070d7e88 {
1751
1838
  opacity: 1;
1752
1839
  transition: opacity 0.2s ease-in-out;
1753
- }.div-7e6ffddc {
1840
+ }.div-070d7e88 {
1754
1841
  width: 100%;
1755
1842
  pointer-events: none;
1756
1843
  font-size: 0;
1757
- }.div-7e6ffddc-2 {
1844
+ }.div-070d7e88-2 {
1758
1845
  display: flex;
1759
1846
  flex-direction: column;
1760
1847
  align-items: stretch;
@@ -2547,6 +2634,10 @@ var componentInfo4 = {
2547
2634
  noWrap: true
2548
2635
  };
2549
2636
 
2637
+ // src/constants/file-types.ts
2638
+ var IMAGE_FILE_TYPES = ["jpeg", "jpg", "png", "svg", "webp", "gif", "jfif", "pjpeg", "pjp", "apng", "avif", "tif", "tiff", "heif", "bmp", "eps", "raw", "cr2", "nef", "orf", "sr2", "psd", "heic", "dib", "ai"];
2639
+ var VIDEO_FILE_TYPES = ["mp4", "webm", "mkv", "flv", "vob", "ogv", "ogg", "drc", "gif", "gifv", "mng", "avi", "mov", "qt", "mts", "m2ts", "ts", "wmv", "yuv", "rm", "rmvb", "viv", "asf", "amv", "m4p", "mpeg", "mpe", "m2v", "m4v", "svi", "3gp", "3g2", "mxf", "roq", "nsv", "f4v", "f4p", "f4a", "f4b"];
2640
+
2550
2641
  // src/blocks/image/component-info.ts
2551
2642
  var componentInfo5 = {
2552
2643
  name: "Image",
@@ -2563,7 +2654,7 @@ var componentInfo5 = {
2563
2654
  name: "image",
2564
2655
  type: "file",
2565
2656
  bubble: true,
2566
- allowedFileTypes: ["jpeg", "jpg", "png", "svg", "webp"],
2657
+ allowedFileTypes: IMAGE_FILE_TYPES,
2567
2658
  required: true,
2568
2659
  defaultValue: "https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F72c80f114dc149019051b6852a9e3b7a",
2569
2660
  onChange: (options) => {
@@ -3923,7 +4014,7 @@ var componentInfo18 = {
3923
4014
  name: "image",
3924
4015
  bubble: true,
3925
4016
  type: "file",
3926
- allowedFileTypes: ["jpeg", "jpg", "png", "svg", "gif", "webp"],
4017
+ allowedFileTypes: IMAGE_FILE_TYPES,
3927
4018
  required: true
3928
4019
  }],
3929
4020
  noWrap: true,
@@ -3958,14 +4049,14 @@ var componentInfo19 = {
3958
4049
  inputs: [{
3959
4050
  name: "video",
3960
4051
  type: "file",
3961
- allowedFileTypes: ["mp4"],
4052
+ allowedFileTypes: VIDEO_FILE_TYPES,
3962
4053
  bubble: true,
3963
4054
  defaultValue: "https://cdn.builder.io/o/assets%2FYJIGb4i01jvw0SRdL5Bt%2Fd27731a526464deba0016216f5f9e570%2Fcompressed?apiKey=YJIGb4i01jvw0SRdL5Bt&token=d27731a526464deba0016216f5f9e570&alt=media&optimized=true",
3964
4055
  required: true
3965
4056
  }, {
3966
4057
  name: "posterImage",
3967
4058
  type: "file",
3968
- allowedFileTypes: ["jpeg", "png"],
4059
+ allowedFileTypes: IMAGE_FILE_TYPES,
3969
4060
  helperText: "Image to show before the video plays"
3970
4061
  }, {
3971
4062
  name: "autoPlay",
@@ -4191,7 +4282,7 @@ var createRegisterComponentMessage = (info) => ({
4191
4282
  var serializeFn = (fnValue) => {
4192
4283
  const fnStr = fnValue.toString().trim();
4193
4284
  const isArrowWithoutParens = /^[a-zA-Z0-9_]+\s*=>/i.test(fnStr);
4194
- const appendFunction = !fnStr.startsWith("function") && !fnStr.startsWith("(") && !isArrowWithoutParens;
4285
+ const appendFunction = !fnStr.startsWith("function") && !fnStr.startsWith("async") && !fnStr.startsWith("(") && !isArrowWithoutParens;
4195
4286
  return `return (${appendFunction ? "function " : ""}${fnStr}).apply(this, arguments)`;
4196
4287
  };
4197
4288
  function serializeIncludingFunctions(info) {
@@ -4276,7 +4367,7 @@ function getPreviewContent(_searchParams) {
4276
4367
  }
4277
4368
 
4278
4369
  // src/constants/sdk-version.ts
4279
- var SDK_VERSION = "3.0.0";
4370
+ var SDK_VERSION = "3.0.1";
4280
4371
 
4281
4372
  // src/helpers/sdk-headers.ts
4282
4373
  var getSdkHeaders = () => ({
@@ -4994,6 +5085,12 @@ var subscribeToEditor = (model, callback, options) => {
4994
5085
  };
4995
5086
  };
4996
5087
 
5088
+ // src/components/content/components/enable-editor.helpers.ts
5089
+ var SDKS_USING_ELEMENT_REF_APPROACH = ["svelte", "qwik", "vue"];
5090
+ var needsElementRefDivForEditing = () => {
5091
+ return SDKS_USING_ELEMENT_REF_APPROACH.includes(TARGET) && (isEditing() || isPreviewing());
5092
+ };
5093
+
4997
5094
  // src/components/content/components/styles.helpers.ts
4998
5095
  var getCssFromFont = (font) => {
4999
5096
  const family = font.family + (font.kind && !font.kind.includes("#") ? ", " + font.kind : "");
@@ -5240,8 +5337,10 @@ function EnableEditor(props) {
5240
5337
  Object.values(
5241
5338
  props.builderContextSignal.componentInfos
5242
5339
  ).forEach((registeredComponent) => {
5243
- const message = createRegisterComponentMessage(registeredComponent);
5244
- window.parent?.postMessage(message, "*");
5340
+ if (!props.model || !registeredComponent.models?.length || registeredComponent.models.includes(props.model)) {
5341
+ const message = createRegisterComponentMessage(registeredComponent);
5342
+ window.parent?.postMessage(message, "*");
5343
+ }
5245
5344
  });
5246
5345
  window.addEventListener(
5247
5346
  "builder:component:stateChangeListenerActivated",
@@ -5318,7 +5417,9 @@ function EnableEditor(props) {
5318
5417
  }
5319
5418
  }
5320
5419
  createEffect3(on3(() => [onUpdateFn_3_props_locale()], onUpdateFn_3));
5321
- return <><builder_context_default.Provider value={props.builderContextSignal}><Show13 when={props.builderContextSignal.content}><Dynamic5
5420
+ return <><builder_context_default.Provider value={props.builderContextSignal}><Show13
5421
+ when={props.builderContextSignal.content || needsElementRefDivForEditing()}
5422
+ ><Dynamic5
5322
5423
  class={getWrapperClassName(
5323
5424
  props.content?.testVariationId || props.content?.id
5324
5425
  )}
@@ -5327,6 +5428,9 @@ function EnableEditor(props) {
5327
5428
  onClick={(event) => onClick(event)}
5328
5429
  builder-content-id={props.builderContextSignal.content?.id}
5329
5430
  builder-model={props.model}
5431
+ style={{
5432
+ display: !props.builderContextSignal.content && needsElementRefDivForEditing() ? "none" : void 0
5433
+ }}
5330
5434
  {...{}}
5331
5435
  {...showContentProps()}
5332
5436
  {...props.contentWrapperProps}
@@ -5407,13 +5511,7 @@ function ContentComponent(props) {
5407
5511
  const [registeredComponents, setRegisteredComponents] = createSignal18(
5408
5512
  [
5409
5513
  ...getDefaultRegisteredComponents(),
5410
- ...props.customComponents?.filter(({ models }) => {
5411
- if (!models?.length)
5412
- return true;
5413
- if (!props.model)
5414
- return true;
5415
- return models.includes(props.model);
5416
- }) || []
5514
+ ...props.customComponents || []
5417
5515
  ].reduce(
5418
5516
  (acc, { component, ...info }) => ({
5419
5517
  ...acc,
@@ -5443,13 +5541,7 @@ function ContentComponent(props) {
5443
5541
  apiVersion: props.apiVersion,
5444
5542
  componentInfos: [
5445
5543
  ...getDefaultRegisteredComponents(),
5446
- ...props.customComponents?.filter(({ models }) => {
5447
- if (!models?.length)
5448
- return true;
5449
- if (!props.model)
5450
- return true;
5451
- return models.includes(props.model);
5452
- }) || []
5544
+ ...props.customComponents || []
5453
5545
  ].reduce(
5454
5546
  (acc, { component: _, ...info }) => ({
5455
5547
  ...acc,
@@ -5460,7 +5552,8 @@ function ContentComponent(props) {
5460
5552
  inheritedStyles: {},
5461
5553
  BlocksWrapper: props.blocksWrapper || "div",
5462
5554
  BlocksWrapperProps: props.blocksWrapperProps || {},
5463
- nonce: props.nonce || ""
5555
+ nonce: props.nonce || "",
5556
+ model: props.model || ""
5464
5557
  });
5465
5558
  function contentSetState(newRootState) {
5466
5559
  setBuilderContextSignal((PREVIOUS_VALUE) => ({