@builder.io/sdk-react-native 0.0.1-60 → 0.0.1-63

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@builder.io/sdk-react-native",
3
3
  "description": "Builder.io SDK for React Native",
4
- "version": "0.0.1-60",
4
+ "version": "0.0.1-63",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
7
7
  "release:dev": "npm version prerelease --no-git-tag-version && npm publish --tag dev --access public"
@@ -187,7 +187,31 @@ const componentInfo = {
187
187
  ]
188
188
  }
189
189
  ],
190
- onChange: " function clearWidths() { columns.forEach(col => { col.delete('width'); }); } const columns = options.get('columns') as Array<Map<String, any>>; if (Array.isArray(columns)) { const containsColumnWithWidth = !!columns.find(col => col.get('width')); if (containsColumnWithWidth) { const containsColumnWithoutWidth = !!columns.find(col => !col.get('width')); if (containsColumnWithoutWidth) { clearWidths(); } else { const sumWidths = columns.reduce((memo, col) => { return memo + col.get('width'); }, 0); const widthsDontAddUp = sumWidths !== 100; if (widthsDontAddUp) { clearWidths(); } } } } "
190
+ onChange(options) {
191
+ function clearWidths() {
192
+ columns.forEach((col) => {
193
+ col.delete("width");
194
+ });
195
+ }
196
+ const columns = options.get("columns");
197
+ if (Array.isArray(columns)) {
198
+ const containsColumnWithWidth = !!columns.find((col) => col.get("width"));
199
+ if (containsColumnWithWidth) {
200
+ const containsColumnWithoutWidth = !!columns.find((col) => !col.get("width"));
201
+ if (containsColumnWithoutWidth) {
202
+ clearWidths();
203
+ } else {
204
+ const sumWidths = columns.reduce((memo, col) => {
205
+ return memo + col.get("width");
206
+ }, 0);
207
+ const widthsDontAddUp = sumWidths !== 100;
208
+ if (widthsDontAddUp) {
209
+ clearWidths();
210
+ }
211
+ }
212
+ }
213
+ }
214
+ }
191
215
  },
192
216
  {
193
217
  name: "space",
@@ -10,7 +10,26 @@ const componentInfo = {
10
10
  required: true,
11
11
  defaultValue: "",
12
12
  helperText: "e.g. enter a youtube url, google map, etc",
13
- onChange: " const url = options.get('url'); if (url) { options.set('content', 'Loading...'); // TODO: get this out of here! const apiKey = 'ae0e60e78201a3f2b0de4b'; return fetch(`https://iframe.ly/api/iframely?url=${url}&api_key=${apiKey}`) .then(res => res.json()) .then(data => { if (options.get('url') === url) { if (data.html) { options.set('content', data.html); } else { options.set('content', 'Invalid url, please try another'); } } }) .catch(err => { options.set( 'content', 'There was an error embedding this URL, please try again or another URL' ); }); } else { options.delete('content'); } "
13
+ onChange(options) {
14
+ const url = options.get("url");
15
+ if (url) {
16
+ options.set("content", "Loading...");
17
+ const apiKey = "ae0e60e78201a3f2b0de4b";
18
+ return fetch(`https://iframe.ly/api/iframely?url=${url}&api_key=${apiKey}`).then((res) => res.json()).then((data) => {
19
+ if (options.get("url") === url) {
20
+ if (data.html) {
21
+ options.set("content", data.html);
22
+ } else {
23
+ options.set("content", "Invalid url, please try another");
24
+ }
25
+ }
26
+ }).catch((_err) => {
27
+ options.set("content", "There was an error embedding this URL, please try again or another URL");
28
+ });
29
+ } else {
30
+ options.delete("content");
31
+ }
32
+ }
14
33
  },
15
34
  {
16
35
  name: "content",
@@ -1,45 +1,38 @@
1
1
  import * as React from "react";
2
2
  import { View } from "react-native";
3
3
  import { useState, useRef, useEffect } from "react";
4
+ import { isJsScript } from "./helpers";
4
5
  function Embed(props) {
5
6
  const elem = useRef(null);
6
7
  const [scriptsInserted, setScriptsInserted] = useState(() => []);
7
8
  const [scriptsRun, setScriptsRun] = useState(() => []);
9
+ const [ranInitFn, setRanInitFn] = useState(() => false);
8
10
  function findAndRunScripts() {
9
- if (elem.current && typeof window !== "undefined") {
10
- const scripts = elem.current.getElementsByTagName("script");
11
- for (let i = 0; i < scripts.length; i++) {
12
- const script = scripts[i];
13
- if (script.src) {
14
- if (scriptsInserted.includes(script.src)) {
15
- continue;
16
- }
17
- scriptsInserted.push(script.src);
18
- const newScript = document.createElement("script");
19
- newScript.async = true;
20
- newScript.src = script.src;
21
- document.head.appendChild(newScript);
22
- } else if (!script.type || [
23
- "text/javascript",
24
- "application/javascript",
25
- "application/ecmascript"
26
- ].includes(script.type)) {
27
- if (scriptsRun.includes(script.innerText)) {
28
- continue;
29
- }
30
- try {
31
- scriptsRun.push(script.innerText);
32
- new Function(script.innerText)();
33
- } catch (error) {
34
- console.warn("`Embed`: Error running script:", error);
35
- }
11
+ const scripts = elem.current.getElementsByTagName("script");
12
+ for (let i = 0; i < scripts.length; i++) {
13
+ const script = scripts[i];
14
+ if (script.src && !scriptsInserted.includes(script.src)) {
15
+ scriptsInserted.push(script.src);
16
+ const newScript = document.createElement("script");
17
+ newScript.async = true;
18
+ newScript.src = script.src;
19
+ document.head.appendChild(newScript);
20
+ } else if (isJsScript(script) && !scriptsRun.includes(script.innerText)) {
21
+ try {
22
+ scriptsRun.push(script.innerText);
23
+ new Function(script.innerText)();
24
+ } catch (error) {
25
+ console.warn("`Embed`: Error running script:", error);
36
26
  }
37
27
  }
38
28
  }
39
29
  }
40
30
  useEffect(() => {
41
- findAndRunScripts();
42
- }, []);
31
+ if (elem.current && !ranInitFn) {
32
+ setRanInitFn(true);
33
+ findAndRunScripts();
34
+ }
35
+ }, [elem, ranInitFn]);
43
36
  return /* @__PURE__ */ React.createElement(View, {
44
37
  ref: elem,
45
38
  dangerouslySetInnerHTML: { __html: props.content }
@@ -0,0 +1,10 @@
1
+ import * as React from 'react';
2
+ const SCRIPT_MIME_TYPES = [
3
+ "text/javascript",
4
+ "application/javascript",
5
+ "application/ecmascript"
6
+ ];
7
+ const isJsScript = (script) => SCRIPT_MIME_TYPES.includes(script.type);
8
+ export {
9
+ isJsScript
10
+ };
@@ -19,7 +19,53 @@ const componentInfo = {
19
19
  allowedFileTypes: ["jpeg", "jpg", "png", "svg"],
20
20
  required: true,
21
21
  defaultValue: "https://cdn.builder.io/api/v1/image/assets%2Fpwgjf0RoYWbdnJSbpBAjXNRMe9F2%2Ffb27a7c790324294af8be1c35fe30f4d",
22
- onChange: " const DEFAULT_ASPECT_RATIO = 0.7041; options.delete('srcset'); options.delete('noWebp'); function loadImage(url, timeout) { return new Promise((resolve, reject) => { const img = document.createElement('img'); let loaded = false; img.onload = () => { loaded = true; resolve(img); }; img.addEventListener('error', event => { console.warn('Image load failed', event.error); reject(event.error); }); img.src = url; setTimeout(() => { if (!loaded) { reject(new Error('Image load timed out')); } }, timeout); }); } function round(num) { return Math.round(num * 1000) / 1000; } const value = options.get('image'); const aspectRatio = options.get('aspectRatio'); // For SVG images - don't render as webp, keep them as SVG fetch(value) .then(res => res.blob()) .then(blob => { if (blob.type.includes('svg')) { options.set('noWebp', true); } }); if (value && (!aspectRatio || aspectRatio === DEFAULT_ASPECT_RATIO)) { return loadImage(value).then(img => { const possiblyUpdatedAspectRatio = options.get('aspectRatio'); if ( options.get('image') === value && (!possiblyUpdatedAspectRatio || possiblyUpdatedAspectRatio === DEFAULT_ASPECT_RATIO) ) { if (img.width && img.height) { options.set('aspectRatio', round(img.height / img.width)); options.set('height', img.height); options.set('width', img.width); } } }); }"
22
+ onChange(options) {
23
+ const DEFAULT_ASPECT_RATIO = 0.7041;
24
+ options.delete("srcset");
25
+ options.delete("noWebp");
26
+ function loadImage(url, timeout = 6e4) {
27
+ return new Promise((resolve, reject) => {
28
+ const img = document.createElement("img");
29
+ let loaded = false;
30
+ img.onload = () => {
31
+ loaded = true;
32
+ resolve(img);
33
+ };
34
+ img.addEventListener("error", (event) => {
35
+ console.warn("Image load failed", event.error);
36
+ reject(event.error);
37
+ });
38
+ img.src = url;
39
+ setTimeout(() => {
40
+ if (!loaded) {
41
+ reject(new Error("Image load timed out"));
42
+ }
43
+ }, timeout);
44
+ });
45
+ }
46
+ function round(num) {
47
+ return Math.round(num * 1e3) / 1e3;
48
+ }
49
+ const value = options.get("image");
50
+ const aspectRatio = options.get("aspectRatio");
51
+ fetch(value).then((res) => res.blob()).then((blob) => {
52
+ if (blob.type.includes("svg")) {
53
+ options.set("noWebp", true);
54
+ }
55
+ });
56
+ if (value && (!aspectRatio || aspectRatio === DEFAULT_ASPECT_RATIO)) {
57
+ return loadImage(value).then((img) => {
58
+ const possiblyUpdatedAspectRatio = options.get("aspectRatio");
59
+ if (options.get("image") === value && (!possiblyUpdatedAspectRatio || possiblyUpdatedAspectRatio === DEFAULT_ASPECT_RATIO)) {
60
+ if (img.width && img.height) {
61
+ options.set("aspectRatio", round(img.height / img.width));
62
+ options.set("height", img.height);
63
+ options.set("width", img.width);
64
+ }
65
+ }
66
+ });
67
+ }
68
+ }
23
69
  },
24
70
  {
25
71
  name: "backgroundSize",
@@ -0,0 +1,49 @@
1
+ import * as React from 'react';
2
+ function removeProtocol(path) {
3
+ return path.replace(/http(s)?:/, "");
4
+ }
5
+ function updateQueryParam(uri = "", key, value) {
6
+ const re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
7
+ const separator = uri.indexOf("?") !== -1 ? "&" : "?";
8
+ if (uri.match(re)) {
9
+ return uri.replace(re, "$1" + key + "=" + encodeURIComponent(value) + "$2");
10
+ }
11
+ return uri + separator + key + "=" + encodeURIComponent(value);
12
+ }
13
+ function getShopifyImageUrl(src, size) {
14
+ if (!src || !(src == null ? void 0 : src.match(/cdn\.shopify\.com/)) || !size) {
15
+ return src;
16
+ }
17
+ if (size === "master") {
18
+ return removeProtocol(src);
19
+ }
20
+ const match = src.match(/(_\d+x(\d+)?)?(\.(jpg|jpeg|gif|png|bmp|bitmap|tiff|tif)(\?v=\d+)?)/i);
21
+ if (match) {
22
+ const prefix = src.split(match[0]);
23
+ const suffix = match[3];
24
+ const useSize = size.match("x") ? size : `${size}x`;
25
+ return removeProtocol(`${prefix[0]}_${useSize}${suffix}`);
26
+ }
27
+ return null;
28
+ }
29
+ function getSrcSet(url) {
30
+ if (!url) {
31
+ return url;
32
+ }
33
+ const sizes = [100, 200, 400, 800, 1200, 1600, 2e3];
34
+ if (url.match(/builder\.io/)) {
35
+ let srcUrl = url;
36
+ const widthInSrc = Number(url.split("?width=")[1]);
37
+ if (!isNaN(widthInSrc)) {
38
+ srcUrl = `${srcUrl} ${widthInSrc}w`;
39
+ }
40
+ return sizes.filter((size) => size !== widthInSrc).map((size) => `${updateQueryParam(url, "width", size)} ${size}w`).concat([srcUrl]).join(", ");
41
+ }
42
+ if (url.match(/cdn\.shopify\.com/)) {
43
+ return sizes.map((size) => [getShopifyImageUrl(url, `${size}x${size}`), size]).filter(([sizeUrl]) => !!sizeUrl).map(([sizeUrl, size]) => `${sizeUrl} ${size}w`).concat([url]).join(", ");
44
+ }
45
+ return url;
46
+ }
47
+ export {
48
+ getSrcSet
49
+ };
@@ -38,8 +38,8 @@ function Symbol(props) {
38
38
  getContent({
39
39
  model: symbolToUse.model,
40
40
  apiKey: builderContext.apiKey,
41
- options: {
42
- entry: symbolToUse.entry
41
+ query: {
42
+ id: symbolToUse.entry
43
43
  }
44
44
  }).then((response) => {
45
45
  setContent(response);
@@ -58,6 +58,7 @@ function Symbol(props) {
58
58
  }), /* @__PURE__ */ React.createElement(RenderContent, {
59
59
  apiKey: builderContext.apiKey,
60
60
  context: builderContext.context,
61
+ customComponents: Object.values(builderContext.registeredComponents),
61
62
  data: __spreadValues(__spreadValues(__spreadValues({}, (_d = props.symbol) == null ? void 0 : _d.data), builderContext.state), (_g = (_f = (_e = props.symbol) == null ? void 0 : _e.content) == null ? void 0 : _f.data) == null ? void 0 : _g.state),
62
63
  model: (_h = props.symbol) == null ? void 0 : _h.model,
63
64
  content
@@ -127,30 +127,28 @@ function RenderBlock(props) {
127
127
  if (!(repeat == null ? void 0 : repeat.collection)) {
128
128
  return void 0;
129
129
  }
130
- const { collection, itemName } = repeat;
131
130
  const itemsArray = evaluate({
132
- code: collection,
131
+ code: repeat.collection,
133
132
  state: builderContext.state,
134
133
  context: builderContext.context
135
134
  });
136
- if (Array.isArray(itemsArray)) {
137
- const collectionName = collection.split(".").pop();
138
- const itemNameToUse = itemName || (collectionName ? collectionName + "Item" : "item");
139
- const repeatArray = itemsArray.map((item, index) => ({
140
- context: __spreadProps(__spreadValues({}, builderContext), {
141
- state: __spreadProps(__spreadValues({}, builderContext.state), {
142
- $index: index,
143
- $item: item,
144
- [itemNameToUse]: item,
145
- [`$${itemNameToUse}Index`]: index
146
- })
147
- }),
148
- block: blockWithoutRepeat
149
- }));
150
- return repeatArray;
151
- } else {
135
+ if (!Array.isArray(itemsArray)) {
152
136
  return void 0;
153
137
  }
138
+ const collectionName = repeat.collection.split(".").pop();
139
+ const itemNameToUse = repeat.itemName || (collectionName ? collectionName + "Item" : "item");
140
+ const repeatArray = itemsArray.map((item, index) => ({
141
+ context: __spreadProps(__spreadValues({}, builderContext), {
142
+ state: __spreadProps(__spreadValues({}, builderContext.state), {
143
+ $index: index,
144
+ $item: item,
145
+ [itemNameToUse]: item,
146
+ [`$${itemNameToUse}Index`]: index
147
+ })
148
+ }),
149
+ block: blockWithoutRepeat
150
+ }));
151
+ return repeatArray;
154
152
  }
155
153
  const builderContext = useContext(BuilderContext);
156
154
  const TagNameRef = tagName();
@@ -158,7 +156,7 @@ function RenderBlock(props) {
158
156
  key: index,
159
157
  repeatContext: data.context,
160
158
  block: data.block
161
- }))) : /* @__PURE__ */ React.createElement(RenderComponent, __spreadValues({}, renderComponentProps())), (_b = childrenWithoutParentComponent()) == null ? void 0 : _b.map((child) => /* @__PURE__ */ React.createElement(RenderBlock, {
159
+ }))) : null, !repeatItemData() ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(RenderComponent, __spreadValues({}, renderComponentProps()))) : null, (_b = childrenWithoutParentComponent()) == null ? void 0 : _b.map((child) => /* @__PURE__ */ React.createElement(RenderBlock, {
162
160
  key: "render-block-" + child.id,
163
161
  block: child
164
162
  })), (_c = childrenWithoutParentComponent()) == null ? void 0 : _c.map((child) => /* @__PURE__ */ React.createElement(BlockStyles, {
@@ -0,0 +1 @@
1
+ import * as React from 'react';
@@ -44,16 +44,11 @@ import { getDefaultRegisteredComponents } from "../../constants/builder-register
44
44
  import { TARGET } from "../../constants/target.js";
45
45
  import BuilderContext from "../../context/builder.context";
46
46
  import { evaluate } from "../../functions/evaluate.js";
47
- import {
48
- convertSearchParamsToQueryObject,
49
- getBuilderSearchParams
50
- } from "../../functions/get-builder-search-params/index.js";
51
47
  import { getContent } from "../../functions/get-content/index.js";
52
48
  import { getFetch } from "../../functions/get-fetch.js";
53
49
  import { isBrowser } from "../../functions/is-browser.js";
54
50
  import { isEditing } from "../../functions/is-editing.js";
55
51
  import { isPreviewing } from "../../functions/is-previewing.js";
56
- import { previewingModelName } from "../../functions/previewing-model-name.js";
57
52
  import {
58
53
  components,
59
54
  createRegisterComponentMessage
@@ -62,7 +57,7 @@ import { track } from "../../functions/track.js";
62
57
  import RenderBlocks from "../render-blocks.js";
63
58
  import RenderContentStyles from "./components/render-styles.js";
64
59
  function RenderContent(props) {
65
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
60
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
66
61
  function useContent() {
67
62
  var _a2;
68
63
  const mergedContent = __spreadProps(__spreadValues(__spreadValues({}, props.content), overrideContent), {
@@ -164,6 +159,10 @@ function RenderContent(props) {
164
159
  }));
165
160
  }
166
161
  }
162
+ function shouldRenderContentStyles() {
163
+ var _a2, _b2, _c2, _d2, _e2;
164
+ return Boolean((((_b2 = (_a2 = useContent == null ? void 0 : useContent()) == null ? void 0 : _a2.data) == null ? void 0 : _b2.cssCode) || ((_e2 = (_d2 = (_c2 = useContent == null ? void 0 : useContent()) == null ? void 0 : _c2.data) == null ? void 0 : _d2.customFonts) == null ? void 0 : _e2.length)) && TARGET !== "reactNative");
165
+ }
167
166
  useEffect(() => {
168
167
  if (isBrowser()) {
169
168
  if (isEditing()) {
@@ -181,14 +180,13 @@ function RenderContent(props) {
181
180
  });
182
181
  }
183
182
  if (isPreviewing()) {
184
- if (props.model && previewingModelName() === props.model) {
185
- const currentUrl = new URL(location.href);
186
- const previewApiKey = currentUrl.searchParams.get("apiKey");
183
+ const searchParams = new URL(location.href).searchParams;
184
+ if (props.model && searchParams.get("builder.preview") === props.model) {
185
+ const previewApiKey = searchParams.get("apiKey") || searchParams.get("builder.space");
187
186
  if (previewApiKey) {
188
187
  getContent({
189
188
  model: props.model,
190
- apiKey: previewApiKey,
191
- options: getBuilderSearchParams(convertSearchParamsToQueryObject(currentUrl.searchParams))
189
+ apiKey: previewApiKey
192
190
  }).then((content) => {
193
191
  if (content) {
194
192
  setOverrideContent(content);
@@ -242,11 +240,11 @@ function RenderContent(props) {
242
240
  contentId: useContent().id
243
241
  }),
244
242
  "data-builder-content-id": (_e = useContent == null ? void 0 : useContent()) == null ? void 0 : _e.id
245
- }, (((_g = (_f = useContent == null ? void 0 : useContent()) == null ? void 0 : _f.data) == null ? void 0 : _g.cssCode) || ((_j = (_i = (_h = useContent == null ? void 0 : useContent()) == null ? void 0 : _h.data) == null ? void 0 : _i.customFonts) == null ? void 0 : _j.length)) && TARGET !== "reactNative" ? /* @__PURE__ */ React.createElement(RenderContentStyles, {
246
- cssCode: useContent().data.cssCode,
247
- customFonts: useContent().data.customFonts
243
+ }, shouldRenderContentStyles() ? /* @__PURE__ */ React.createElement(RenderContentStyles, {
244
+ cssCode: (_g = (_f = useContent == null ? void 0 : useContent()) == null ? void 0 : _f.data) == null ? void 0 : _g.cssCode,
245
+ customFonts: (_i = (_h = useContent == null ? void 0 : useContent()) == null ? void 0 : _h.data) == null ? void 0 : _i.customFonts
248
246
  }) : null, /* @__PURE__ */ React.createElement(RenderBlocks, {
249
- blocks: (_l = (_k = useContent == null ? void 0 : useContent()) == null ? void 0 : _k.data) == null ? void 0 : _l.blocks
247
+ blocks: (_k = (_j = useContent == null ? void 0 : useContent()) == null ? void 0 : _j.data) == null ? void 0 : _k.blocks
250
248
  }))) : null);
251
249
  }
252
250
  export {
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { View } from "react-native";
3
- function getBlockTag(block) {
3
+ function getBlockTag(_block) {
4
4
  return View;
5
5
  }
6
6
  export {
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import { isBrowser } from "../is-browser";
2
3
  const BUILDER_SEARCHPARAMS_PREFIX = "builder.";
3
4
  const convertSearchParamsToQueryObject = (searchParams) => {
4
5
  const options = {};
@@ -17,7 +18,17 @@ const getBuilderSearchParams = (options) => {
17
18
  });
18
19
  return newOptions;
19
20
  };
21
+ const getBuilderSearchParamsFromWindow = () => {
22
+ if (!isBrowser()) {
23
+ return {};
24
+ }
25
+ const searchParams = new URLSearchParams(window.location.search);
26
+ return getBuilderSearchParams(convertSearchParamsToQueryObject(searchParams));
27
+ };
28
+ const normalizeSearchParams = (searchParams) => searchParams instanceof URLSearchParams ? convertSearchParamsToQueryObject(searchParams) : searchParams;
20
29
  export {
21
30
  convertSearchParamsToQueryObject,
22
- getBuilderSearchParams
31
+ getBuilderSearchParams,
32
+ getBuilderSearchParamsFromWindow,
33
+ normalizeSearchParams
23
34
  };
@@ -0,0 +1,39 @@
1
+ import * as React from 'react';
2
+ const handleABTesting = (item, testGroups) => {
3
+ if (item.variations && Object.keys(item.variations).length) {
4
+ const testGroup = item.id ? testGroups[item.id] : void 0;
5
+ const variationValue = testGroup ? item.variations[testGroup] : void 0;
6
+ if (testGroup && variationValue) {
7
+ item.data = variationValue.data;
8
+ item.testVariationId = variationValue.id;
9
+ item.testVariationName = variationValue.name;
10
+ } else {
11
+ let n = 0;
12
+ const random = Math.random();
13
+ let set = false;
14
+ for (const id in item.variations) {
15
+ const variation = item.variations[id];
16
+ const testRatio = variation.testRatio;
17
+ n += testRatio;
18
+ if (random < n) {
19
+ const variationName = variation.name || (variation.id === item.id ? "Default variation" : "");
20
+ set = true;
21
+ Object.assign(item, {
22
+ data: variation.data,
23
+ testVariationId: variation.id,
24
+ testVariationName: variationName
25
+ });
26
+ }
27
+ }
28
+ if (!set) {
29
+ Object.assign(item, {
30
+ testVariationId: item.id,
31
+ testVariationName: "Default"
32
+ });
33
+ }
34
+ }
35
+ }
36
+ };
37
+ export {
38
+ handleABTesting
39
+ };
@@ -38,20 +38,14 @@ var __async = (__this, __arguments, generator) => {
38
38
  step((generator = generator.apply(__this, __arguments)).next());
39
39
  });
40
40
  };
41
+ import { flatten } from "../../helpers/flatten.js";
42
+ import {
43
+ getBuilderSearchParamsFromWindow,
44
+ normalizeSearchParams
45
+ } from "../get-builder-search-params/index.js";
41
46
  import { getFetch } from "../get-fetch.js";
47
+ import { handleABTesting } from "./ab-testing.js";
42
48
  const fetch$ = getFetch();
43
- function flatten(object, path = null, separator = ".") {
44
- return Object.keys(object).reduce((acc, key) => {
45
- const value = object[key];
46
- const newPath = [path, key].filter(Boolean).join(separator);
47
- const isObject = [
48
- typeof value === "object",
49
- value !== null,
50
- !(Array.isArray(value) && value.length === 0)
51
- ].every(Boolean);
52
- return isObject ? __spreadValues(__spreadValues({}, acc), flatten(value, newPath, separator)) : __spreadProps(__spreadValues({}, acc), { [newPath]: value });
53
- }, {});
54
- }
55
49
  function getContent(options) {
56
50
  return __async(this, null, function* () {
57
51
  return (yield getAllContent(__spreadProps(__spreadValues({}, options), { limit: 1 }))).results[0] || null;
@@ -67,67 +61,31 @@ const generateContentUrl = (options) => {
67
61
  apiKey
68
62
  } = options;
69
63
  const url = new URL(`https://cdn.builder.io/api/v2/content/${model}?apiKey=${apiKey}&limit=${limit}&noTraverse=${noTraverse}`);
70
- if (options.options) {
71
- const flattened = flatten(options.options);
72
- for (const key in flattened) {
73
- url.searchParams.set(key, String(flattened[key]));
74
- }
64
+ const queryOptions = __spreadValues(__spreadValues({}, getBuilderSearchParamsFromWindow()), normalizeSearchParams(options.options || {}));
65
+ const flattened = flatten(queryOptions);
66
+ for (const key in flattened) {
67
+ url.searchParams.set(key, String(flattened[key]));
75
68
  }
76
69
  if (userAttributes) {
77
70
  url.searchParams.set("userAttributes", JSON.stringify(userAttributes));
78
71
  }
79
72
  if (query) {
80
- const flattened = flatten({ query });
81
- for (const key in flattened) {
82
- url.searchParams.set(key, JSON.stringify(flattened[key]));
73
+ const flattened2 = flatten({ query });
74
+ for (const key in flattened2) {
75
+ url.searchParams.set(key, JSON.stringify(flattened2[key]));
83
76
  }
84
77
  }
85
78
  return url;
86
79
  };
87
- const handleABTesting = (content, testGroups) => {
88
- for (const item of content.results) {
89
- if (item.variations && Object.keys(item.variations).length) {
90
- const testGroup = testGroups[item.id];
91
- const variationValue = item.variations[testGroup];
92
- if (testGroup && variationValue) {
93
- item.data = variationValue.data;
94
- item.testVariationId = variationValue.id;
95
- item.testVariationName = variationValue.name;
96
- } else {
97
- let n = 0;
98
- const random = Math.random();
99
- let set = false;
100
- for (const id in item.variations) {
101
- const variation = item.variations[id];
102
- const testRatio = variation.testRatio;
103
- n += testRatio;
104
- if (random < n) {
105
- const variationName = variation.name || (variation.id === item.id ? "Default variation" : "");
106
- set = true;
107
- Object.assign(item, {
108
- data: variation.data,
109
- testVariationId: variation.id,
110
- testVariationName: variationName
111
- });
112
- }
113
- }
114
- if (!set) {
115
- Object.assign(item, {
116
- testVariationId: item.id,
117
- testVariationName: "Default"
118
- });
119
- }
120
- }
121
- }
122
- }
123
- };
124
80
  function getAllContent(options) {
125
81
  return __async(this, null, function* () {
126
82
  const url = generateContentUrl(options);
127
83
  const fetch = yield fetch$;
128
84
  const content = yield fetch(url.href).then((res) => res.json());
129
85
  if (options.testGroups) {
130
- handleABTesting(content, options.testGroups);
86
+ for (const item of content.results) {
87
+ handleABTesting(item, options.testGroups);
88
+ }
131
89
  }
132
90
  return content;
133
91
  });
@@ -0,0 +1 @@
1
+ import * as React from 'react';
@@ -30,7 +30,6 @@ var __objRest = (source, exclude) => {
30
30
  }
31
31
  return target;
32
32
  };
33
- import { fastClone } from "./fast-clone.js";
34
33
  const components = [];
35
34
  function registerComponent(component, info) {
36
35
  components.push(__spreadValues({ component }, info));
@@ -39,31 +38,34 @@ function registerComponent(component, info) {
39
38
  }
40
39
  const createRegisterComponentMessage = (_a) => {
41
40
  var _b = _a, {
42
- component
41
+ component: _
43
42
  } = _b, info = __objRest(_b, [
44
43
  "component"
45
44
  ]);
46
45
  return {
47
46
  type: "builder.registerComponent",
48
- data: prepareComponentInfoToSend(fastClone(info))
47
+ data: prepareComponentInfoToSend(info)
49
48
  };
50
49
  };
51
- function prepareComponentInfoToSend(info) {
52
- return __spreadValues(__spreadValues({}, info), info.inputs && {
53
- inputs: info.inputs.map((input) => {
54
- const keysToConvertFnToString = ["onChange", "showIf"];
55
- for (const key of keysToConvertFnToString) {
56
- const fn = input[key];
57
- if (fn && typeof fn === "function") {
58
- input = __spreadProps(__spreadValues({}, input), {
59
- [key]: `return (${fn.toString()}).apply(this, arguments)`
60
- });
61
- }
62
- }
63
- return input;
64
- })
50
+ const fastClone = (obj) => JSON.parse(JSON.stringify(obj));
51
+ const serializeValue = (value) => typeof value === "function" ? serializeFn(value) : fastClone(value);
52
+ const serializeFn = (fnValue) => {
53
+ const fnStr = fnValue.toString().trim();
54
+ const appendFunction = !fnStr.startsWith("function") && !fnStr.startsWith("(");
55
+ return `return (${appendFunction ? "function " : ""}${fnStr}).apply(this, arguments)`;
56
+ };
57
+ const prepareComponentInfoToSend = (_c) => {
58
+ var _d = _c, {
59
+ inputs
60
+ } = _d, info = __objRest(_d, [
61
+ "inputs"
62
+ ]);
63
+ return __spreadProps(__spreadValues({}, fastClone(info)), {
64
+ inputs: inputs == null ? void 0 : inputs.map((input) => Object.entries(input).reduce((acc, [key, value]) => __spreadProps(__spreadValues({}, acc), {
65
+ [key]: serializeValue(value)
66
+ }), {}))
65
67
  });
66
- }
68
+ };
67
69
  export {
68
70
  components,
69
71
  createRegisterComponentMessage,
@@ -0,0 +1,35 @@
1
+ import * as React from 'react';
2
+ var __defProp = Object.defineProperty;
3
+ var __defProps = Object.defineProperties;
4
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
5
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __spreadValues = (a, b) => {
10
+ for (var prop in b || (b = {}))
11
+ if (__hasOwnProp.call(b, prop))
12
+ __defNormalProp(a, prop, b[prop]);
13
+ if (__getOwnPropSymbols)
14
+ for (var prop of __getOwnPropSymbols(b)) {
15
+ if (__propIsEnum.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ }
18
+ return a;
19
+ };
20
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
21
+ function flatten(object, path = null, separator = ".") {
22
+ return Object.keys(object).reduce((acc, key) => {
23
+ const value = object[key];
24
+ const newPath = [path, key].filter(Boolean).join(separator);
25
+ const isObject = [
26
+ typeof value === "object",
27
+ value !== null,
28
+ !(Array.isArray(value) && value.length === 0)
29
+ ].every(Boolean);
30
+ return isObject ? __spreadValues(__spreadValues({}, acc), flatten(value, newPath, separator)) : __spreadProps(__spreadValues({}, acc), { [newPath]: value });
31
+ }, {});
32
+ }
33
+ export {
34
+ flatten
35
+ };
@@ -1,5 +0,0 @@
1
- import * as React from 'react';
2
- const fastClone = (obj) => JSON.parse(JSON.stringify(obj));
3
- export {
4
- fastClone
5
- };
@@ -1,12 +0,0 @@
1
- import * as React from 'react';
2
- import { isPreviewing } from "./is-previewing.js";
3
- function previewingModelName() {
4
- if (!isPreviewing()) {
5
- return null;
6
- }
7
- const url = new URL(location.href);
8
- return url.searchParams.get("builder.preview");
9
- }
10
- export {
11
- previewingModelName
12
- };