@builder.io/sdk-react-native 0.0.1-44 → 0.0.1-49
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/CHANGELOG.md +13 -0
- package/package.json +1 -1
- package/src/blocks/columns.js +0 -2
- package/src/blocks/columns.lite.tsx +2 -2
- package/src/blocks/custom-code.js +0 -2
- package/src/blocks/custom-code.lite.tsx +1 -9
- package/src/blocks/embed.js +0 -1
- package/src/blocks/embed.lite.tsx +1 -5
- package/src/blocks/form.js +0 -1
- package/src/blocks/form.lite.tsx +1 -1
- package/src/blocks/image.lite.tsx +1 -2
- package/src/blocks/raw-text.js +0 -4
- package/src/blocks/raw-text.lite.tsx +1 -6
- package/src/blocks/symbol.js +1 -3
- package/src/blocks/symbol.lite.tsx +1 -1
- package/src/blocks/text.lite.tsx +1 -6
- package/src/components/render-blocks.js +23 -16
- package/src/components/render-blocks.lite.tsx +9 -3
- package/src/components/render-content.js +24 -23
- package/src/components/render-content.lite.tsx +18 -14
- package/src/functions/get-builder-search-params/fn.test.js +18 -0
- package/src/functions/get-builder-search-params/index.js +20 -0
- package/src/functions/get-content/fn.test.js +34 -0
- package/src/functions/{get-content.js → get-content/index.js} +71 -67
- package/src/functions/get-processed-block.test.js +17 -5
- package/src/index-helpers/blocks-exports.js +19 -0
- package/src/index-helpers/top-of-file.js +2 -0
- package/src/index.js +3 -19
- package/src/functions/get-content.test.js +0 -58
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
### UPCOMING
|
|
2
|
+
|
|
3
|
+
- Add `getBuilderSearchParams` helper export to easily view current drafts on your production site.
|
|
4
|
+
|
|
5
|
+
### 0.0.1-44
|
|
6
|
+
|
|
7
|
+
Changes:
|
|
8
|
+
|
|
9
|
+
- Fixes `getAllContent` to traverse all nested data from symbols/references https://github.com/BuilderIO/builder/pull/718
|
|
10
|
+
- Fixes `getContent` (broken due to missing URL polyfill) https://github.com/BuilderIO/builder/pull/880
|
|
11
|
+
- Strips invalid `this.` left from Mitosis compilation https://github.com/BuilderIO/builder/pull/717/commits/b1947c86db769f74a7408965dac70f22dfcc538d
|
|
12
|
+
- Fix identification of react-native environment https://github.com/BuilderIO/builder/pull/717/commits/9d2a207ceca39bf83d5bbdc4bd67351e86105d78
|
|
13
|
+
- Fix Aspect Ratio handling (this adds support for Pixel Tracking) https://github.com/BuilderIO/builder/pull/749, preceeded by https://github.com/BuilderIO/builder/pull/687
|
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-
|
|
4
|
+
"version": "0.0.1-49",
|
|
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"
|
package/src/blocks/columns.js
CHANGED
|
@@ -54,7 +54,6 @@ function Columns(props) {
|
|
|
54
54
|
return /* @__PURE__ */ React.createElement(
|
|
55
55
|
View,
|
|
56
56
|
{
|
|
57
|
-
className: 'builder-columns',
|
|
58
57
|
style: styles.view1,
|
|
59
58
|
},
|
|
60
59
|
(_a = props.columns) == null
|
|
@@ -63,7 +62,6 @@ function Columns(props) {
|
|
|
63
62
|
/* @__PURE__ */ React.createElement(
|
|
64
63
|
View,
|
|
65
64
|
{
|
|
66
|
-
className: 'builder-column',
|
|
67
65
|
style: styles.view2,
|
|
68
66
|
},
|
|
69
67
|
/* @__PURE__ */ React.createElement(RenderBlocks, {
|
|
@@ -53,9 +53,9 @@ export default function Columns(props) {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
return (
|
|
56
|
-
<View
|
|
56
|
+
<View style={styles.view1}>
|
|
57
57
|
{props.columns?.map((column) => (
|
|
58
|
-
<View
|
|
58
|
+
<View style={styles.view2}>
|
|
59
59
|
<RenderBlocks blocks={column.blocks} />
|
|
60
60
|
</View>
|
|
61
61
|
))}
|
|
@@ -47,8 +47,6 @@ function CustomCode(props) {
|
|
|
47
47
|
}, []);
|
|
48
48
|
return /* @__PURE__ */ React.createElement(View, {
|
|
49
49
|
ref: elem,
|
|
50
|
-
className:
|
|
51
|
-
'builder-custom-code' + (props.replaceNodes ? ' replace-nodes' : ''),
|
|
52
50
|
dangerouslySetInnerHTML: { __html: 'props.code' },
|
|
53
51
|
});
|
|
54
52
|
}
|
|
@@ -55,13 +55,5 @@ export default function CustomCode(props) {
|
|
|
55
55
|
findAndRunScripts();
|
|
56
56
|
}, []);
|
|
57
57
|
|
|
58
|
-
return
|
|
59
|
-
<View
|
|
60
|
-
ref={elem}
|
|
61
|
-
className={
|
|
62
|
-
'builder-custom-code' + (props.replaceNodes ? ' replace-nodes' : '')
|
|
63
|
-
}
|
|
64
|
-
dangerouslySetInnerHTML={{ __html: 'props.code' }}
|
|
65
|
-
/>
|
|
66
|
-
);
|
|
58
|
+
return <View ref={elem} dangerouslySetInnerHTML={{ __html: 'props.code' }} />;
|
|
67
59
|
}
|
package/src/blocks/embed.js
CHANGED
|
@@ -56,10 +56,6 @@ export default function Embed(props) {
|
|
|
56
56
|
}, []);
|
|
57
57
|
|
|
58
58
|
return (
|
|
59
|
-
<View
|
|
60
|
-
className="builder-embed"
|
|
61
|
-
ref={elem}
|
|
62
|
-
dangerouslySetInnerHTML={{ __html: 'props.content' }}
|
|
63
|
-
/>
|
|
59
|
+
<View ref={elem} dangerouslySetInnerHTML={{ __html: 'props.content' }} />
|
|
64
60
|
);
|
|
65
61
|
}
|
package/src/blocks/form.js
CHANGED
package/src/blocks/form.lite.tsx
CHANGED
|
@@ -231,7 +231,7 @@ export default function FormComponent(props) {
|
|
|
231
231
|
) : null}{' '}
|
|
232
232
|
{submissionState() === 'error' && responseData ? (
|
|
233
233
|
<>
|
|
234
|
-
<View
|
|
234
|
+
<View style={styles.view1}>
|
|
235
235
|
{' '}
|
|
236
236
|
<Text>{JSON.stringify(responseData, null, 2)}</Text>{' '}
|
|
237
237
|
</View>
|
|
@@ -10,7 +10,6 @@ export default function Image(props) {
|
|
|
10
10
|
alt={props.altText}
|
|
11
11
|
aria-role={props.altText ? 'presentation' : undefined}
|
|
12
12
|
style={styles.view2}
|
|
13
|
-
className={'builder-image' + (props.class ? ' ' + props.class : '')}
|
|
14
13
|
src={props.image}
|
|
15
14
|
srcset={props.srcset}
|
|
16
15
|
sizes={props.sizes}
|
|
@@ -21,7 +20,7 @@ export default function Image(props) {
|
|
|
21
20
|
|
|
22
21
|
{props.aspectRatio &&
|
|
23
22
|
!(props.fitContent && props.builderBlock?.children?.length) ? (
|
|
24
|
-
<View
|
|
23
|
+
<View style={styles.view3}>
|
|
25
24
|
<Text> </Text>
|
|
26
25
|
</View>
|
|
27
26
|
) : null}
|
package/src/blocks/raw-text.js
CHANGED
|
@@ -3,11 +3,7 @@ import { registerComponent } from '../functions/register-component';
|
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { View } from 'react-native';
|
|
5
5
|
function RawText(props) {
|
|
6
|
-
var _a, _b;
|
|
7
6
|
return /* @__PURE__ */ React.createElement(View, {
|
|
8
|
-
className:
|
|
9
|
-
((_a = props.attributes) == null ? void 0 : _a.class) ||
|
|
10
|
-
((_b = props.attributes) == null ? void 0 : _b.className),
|
|
11
7
|
dangerouslySetInnerHTML: { __html: "props.text || ''" },
|
|
12
8
|
});
|
|
13
9
|
}
|
|
@@ -2,10 +2,5 @@ import * as React from 'react';
|
|
|
2
2
|
import { View, StyleSheet, Image, Text } from 'react-native';
|
|
3
3
|
|
|
4
4
|
export default function RawText(props) {
|
|
5
|
-
return
|
|
6
|
-
<View
|
|
7
|
-
className={props.attributes?.class || props.attributes?.className}
|
|
8
|
-
dangerouslySetInnerHTML={{ __html: "props.text || ''" }}
|
|
9
|
-
/>
|
|
10
|
-
);
|
|
5
|
+
return <View dangerouslySetInnerHTML={{ __html: "props.text || ''" }} />;
|
|
11
6
|
}
|
package/src/blocks/symbol.js
CHANGED
|
@@ -8,9 +8,7 @@ function Symbol(props) {
|
|
|
8
8
|
const builderContext = useContext(BuilderContext);
|
|
9
9
|
return /* @__PURE__ */ React.createElement(
|
|
10
10
|
View,
|
|
11
|
-
|
|
12
|
-
className: 'builder-symbol',
|
|
13
|
-
},
|
|
11
|
+
null,
|
|
14
12
|
/* @__PURE__ */ React.createElement(RenderContent, {
|
|
15
13
|
context: builderContext.context,
|
|
16
14
|
data: (_a = props.symbol) == null ? void 0 : _a.data,
|
package/src/blocks/text.lite.tsx
CHANGED
|
@@ -2,10 +2,5 @@ import * as React from 'react';
|
|
|
2
2
|
import { View, StyleSheet, Image, Text } from 'react-native';
|
|
3
3
|
|
|
4
4
|
export default function Text(props) {
|
|
5
|
-
return
|
|
6
|
-
<View
|
|
7
|
-
className="builder-text"
|
|
8
|
-
dangerouslySetInnerHTML={{ __html: 'props.text' }}
|
|
9
|
-
/>
|
|
10
|
-
);
|
|
5
|
+
return <View dangerouslySetInnerHTML={{ __html: 'props.text' }} />;
|
|
11
6
|
}
|
|
@@ -3,13 +3,22 @@ import { View, StyleSheet } from 'react-native';
|
|
|
3
3
|
import { isEditing } from '../functions/is-editing';
|
|
4
4
|
import RenderBlock from './render-block';
|
|
5
5
|
function RenderBlocks(props) {
|
|
6
|
-
var _a
|
|
6
|
+
var _a;
|
|
7
|
+
function className() {
|
|
8
|
+
var _a2;
|
|
9
|
+
return (
|
|
10
|
+
'builder-blocks' +
|
|
11
|
+
(!((_a2 = props.blocks) == null ? void 0 : _a2.length)
|
|
12
|
+
? ' no-blocks'
|
|
13
|
+
: '')
|
|
14
|
+
);
|
|
15
|
+
}
|
|
7
16
|
function onClick() {
|
|
8
|
-
var _a2,
|
|
17
|
+
var _a2, _b;
|
|
9
18
|
if (isEditing() && !((_a2 = props.blocks) == null ? void 0 : _a2.length)) {
|
|
10
|
-
(
|
|
19
|
+
(_b = window.parent) == null
|
|
11
20
|
? void 0
|
|
12
|
-
:
|
|
21
|
+
: _b.postMessage(
|
|
13
22
|
{
|
|
14
23
|
type: 'builder.clickEmptyBlocks',
|
|
15
24
|
data: {
|
|
@@ -22,11 +31,11 @@ function RenderBlocks(props) {
|
|
|
22
31
|
}
|
|
23
32
|
}
|
|
24
33
|
function onMouseEnter() {
|
|
25
|
-
var _a2,
|
|
34
|
+
var _a2, _b;
|
|
26
35
|
if (isEditing() && !((_a2 = props.blocks) == null ? void 0 : _a2.length)) {
|
|
27
|
-
(
|
|
36
|
+
(_b = window.parent) == null
|
|
28
37
|
? void 0
|
|
29
|
-
:
|
|
38
|
+
: _b.postMessage(
|
|
30
39
|
{
|
|
31
40
|
type: 'builder.hoverEmptyBlocks',
|
|
32
41
|
data: {
|
|
@@ -43,22 +52,20 @@ function RenderBlocks(props) {
|
|
|
43
52
|
{
|
|
44
53
|
'builder-path': props.path,
|
|
45
54
|
'builder-parent-id': props.parent,
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
? ' no-blocks'
|
|
52
|
-
: ''),
|
|
55
|
+
dataSet: {
|
|
56
|
+
class: className(),
|
|
57
|
+
},
|
|
58
|
+
onClick: (event) => onClick(),
|
|
59
|
+
onMouseEnter: (event) => onMouseEnter(),
|
|
53
60
|
style: styles.view1,
|
|
54
61
|
},
|
|
55
62
|
props.blocks
|
|
56
63
|
? /* @__PURE__ */ React.createElement(
|
|
57
64
|
React.Fragment,
|
|
58
65
|
null,
|
|
59
|
-
(
|
|
66
|
+
(_a = props.blocks) == null
|
|
60
67
|
? void 0
|
|
61
|
-
:
|
|
68
|
+
: _a.map((block) =>
|
|
62
69
|
/* @__PURE__ */ React.createElement(RenderBlock, {
|
|
63
70
|
block,
|
|
64
71
|
})
|
|
@@ -4,6 +4,10 @@ import { isEditing } from '../functions/is-editing';
|
|
|
4
4
|
import RenderBlock from './render-block.lite';
|
|
5
5
|
|
|
6
6
|
export default function RenderBlocks(props) {
|
|
7
|
+
function className() {
|
|
8
|
+
return 'builder-blocks' + (!props.blocks?.length ? ' no-blocks' : '');
|
|
9
|
+
}
|
|
10
|
+
|
|
7
11
|
function onClick() {
|
|
8
12
|
if (isEditing() && !props.blocks?.length) {
|
|
9
13
|
window.parent?.postMessage(
|
|
@@ -38,9 +42,11 @@ export default function RenderBlocks(props) {
|
|
|
38
42
|
<View
|
|
39
43
|
builder-path={props.path}
|
|
40
44
|
builder-parent-id={props.parent}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
45
|
+
dataSet={{
|
|
46
|
+
class: className(),
|
|
47
|
+
}}
|
|
48
|
+
onClick={(event) => onClick()}
|
|
49
|
+
onMouseEnter={(event) => onMouseEnter()}
|
|
44
50
|
style={styles.view1}
|
|
45
51
|
>
|
|
46
52
|
{props.blocks ? (
|
|
@@ -2,7 +2,6 @@ import * as React from 'react';
|
|
|
2
2
|
import { View, Text } from 'react-native';
|
|
3
3
|
import { useState, useEffect } from 'react';
|
|
4
4
|
import { isBrowser } from '../functions/is-browser';
|
|
5
|
-
import RenderBlock from './render-block';
|
|
6
5
|
import BuilderContext from '../context/builder.context';
|
|
7
6
|
import { track } from '../functions/track';
|
|
8
7
|
import { isReactNative } from '../functions/is-react-native';
|
|
@@ -10,8 +9,13 @@ import { isEditing } from '../functions/is-editing';
|
|
|
10
9
|
import { isPreviewing } from '../functions/is-previewing';
|
|
11
10
|
import { previewingModelName } from '../functions/previewing-model-name';
|
|
12
11
|
import { getContent } from '../functions/get-content';
|
|
12
|
+
import {
|
|
13
|
+
convertSearchParamsToQueryObject,
|
|
14
|
+
getBuilderSearchParams,
|
|
15
|
+
} from '../functions/get-builder-search-params';
|
|
16
|
+
import RenderBlocks from './render-blocks';
|
|
13
17
|
function RenderContent(props) {
|
|
14
|
-
var _a, _b, _c, _d, _e, _f, _g, _h
|
|
18
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
15
19
|
function useContent() {
|
|
16
20
|
return overrideContent || props.content;
|
|
17
21
|
}
|
|
@@ -108,20 +112,15 @@ function RenderContent(props) {
|
|
|
108
112
|
}
|
|
109
113
|
if (isPreviewing()) {
|
|
110
114
|
if (props.model && previewingModelName() === props.model) {
|
|
111
|
-
const options = {};
|
|
112
115
|
const currentUrl = new URL(location.href);
|
|
113
116
|
const apiKey = currentUrl.searchParams.get('apiKey');
|
|
114
117
|
if (apiKey) {
|
|
115
|
-
const builderPrefix = 'builder.';
|
|
116
|
-
currentUrl.searchParams.forEach((value, key) => {
|
|
117
|
-
if (key.startsWith(builderPrefix)) {
|
|
118
|
-
options[key.replace(builderPrefix, '')] = value;
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
118
|
getContent({
|
|
122
119
|
model: props.model,
|
|
123
120
|
apiKey,
|
|
124
|
-
options
|
|
121
|
+
options: getBuilderSearchParams(
|
|
122
|
+
convertSearchParamsToQueryObject(currentUrl.searchParams)
|
|
123
|
+
),
|
|
125
124
|
}).then((content) => {
|
|
126
125
|
if (content) {
|
|
127
126
|
setOverrideContent(content);
|
|
@@ -132,6 +131,13 @@ function RenderContent(props) {
|
|
|
132
131
|
}
|
|
133
132
|
}
|
|
134
133
|
}, []);
|
|
134
|
+
useEffect(() => {
|
|
135
|
+
return () => {
|
|
136
|
+
if (isBrowser()) {
|
|
137
|
+
window.removeEventListener('message', processMessage);
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}, []);
|
|
135
141
|
return /* @__PURE__ */ React.createElement(
|
|
136
142
|
BuilderContext.Provider,
|
|
137
143
|
{
|
|
@@ -197,20 +203,15 @@ function RenderContent(props) {
|
|
|
197
203
|
)
|
|
198
204
|
)
|
|
199
205
|
: null,
|
|
200
|
-
(
|
|
201
|
-
|
|
202
|
-
(
|
|
206
|
+
/* @__PURE__ */ React.createElement(RenderBlocks, {
|
|
207
|
+
blocks:
|
|
208
|
+
(_h =
|
|
209
|
+
(_g = useContent == null ? void 0 : useContent()) == null
|
|
210
|
+
? void 0
|
|
211
|
+
: _g.data) == null
|
|
203
212
|
? void 0
|
|
204
|
-
:
|
|
205
|
-
|
|
206
|
-
: _h.blocks) == null
|
|
207
|
-
? void 0
|
|
208
|
-
: _i.map((block) =>
|
|
209
|
-
/* @__PURE__ */ React.createElement(RenderBlock, {
|
|
210
|
-
key: block.id,
|
|
211
|
-
block,
|
|
212
|
-
})
|
|
213
|
-
)
|
|
213
|
+
: _h.blocks,
|
|
214
|
+
})
|
|
214
215
|
)
|
|
215
216
|
)
|
|
216
217
|
: null
|
|
@@ -2,7 +2,6 @@ import * as React from 'react';
|
|
|
2
2
|
import { View, StyleSheet, Image, Text } from 'react-native';
|
|
3
3
|
import { useState, useContext, useEffect } from 'react';
|
|
4
4
|
import { isBrowser } from '../functions/is-browser';
|
|
5
|
-
import RenderBlock from './render-block.lite';
|
|
6
5
|
import BuilderContext from '../context/builder.context.lite';
|
|
7
6
|
import { track } from '../functions/track';
|
|
8
7
|
import { ifTarget } from '../functions/if-target';
|
|
@@ -12,6 +11,11 @@ import { isEditing } from '../functions/is-editing';
|
|
|
12
11
|
import { isPreviewing } from '../functions/is-previewing';
|
|
13
12
|
import { previewingModelName } from '../functions/previewing-model-name';
|
|
14
13
|
import { getContent } from '../functions/get-content';
|
|
14
|
+
import {
|
|
15
|
+
convertSearchParamsToQueryObject,
|
|
16
|
+
getBuilderSearchParams,
|
|
17
|
+
} from '../functions/get-builder-search-params';
|
|
18
|
+
import RenderBlocks from './render-blocks.lite';
|
|
15
19
|
|
|
16
20
|
export default function RenderContent(props) {
|
|
17
21
|
function useContent() {
|
|
@@ -126,33 +130,35 @@ export default function RenderContent(props) {
|
|
|
126
130
|
|
|
127
131
|
if (isPreviewing()) {
|
|
128
132
|
if (props.model && previewingModelName() === props.model) {
|
|
129
|
-
const options = {};
|
|
130
133
|
const currentUrl = new URL(location.href);
|
|
131
134
|
const apiKey = currentUrl.searchParams.get('apiKey');
|
|
132
135
|
|
|
133
136
|
if (apiKey) {
|
|
134
|
-
const builderPrefix = 'builder.';
|
|
135
|
-
currentUrl.searchParams.forEach((value, key) => {
|
|
136
|
-
if (key.startsWith(builderPrefix)) {
|
|
137
|
-
options[key.replace(builderPrefix, '')] = value;
|
|
138
|
-
}
|
|
139
|
-
}); // TODO: need access to API key
|
|
140
|
-
|
|
141
137
|
getContent({
|
|
142
138
|
model: props.model,
|
|
143
139
|
apiKey,
|
|
144
|
-
options
|
|
140
|
+
options: getBuilderSearchParams(
|
|
141
|
+
convertSearchParamsToQueryObject(currentUrl.searchParams)
|
|
142
|
+
),
|
|
145
143
|
}).then((content) => {
|
|
146
144
|
if (content) {
|
|
147
145
|
setOverrideContent(content);
|
|
148
146
|
}
|
|
149
147
|
});
|
|
150
|
-
}
|
|
148
|
+
}
|
|
151
149
|
}
|
|
152
150
|
}
|
|
153
151
|
}
|
|
154
152
|
}, []);
|
|
155
153
|
|
|
154
|
+
useEffect(() => {
|
|
155
|
+
return () => {
|
|
156
|
+
if (isBrowser()) {
|
|
157
|
+
window.removeEventListener('message', processMessage);
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
}, []);
|
|
161
|
+
|
|
156
162
|
return (
|
|
157
163
|
<BuilderContext.Provider
|
|
158
164
|
value={{
|
|
@@ -191,9 +197,7 @@ export default function RenderContent(props) {
|
|
|
191
197
|
</View>
|
|
192
198
|
) : null}
|
|
193
199
|
|
|
194
|
-
{useContent?.()?.data?.blocks
|
|
195
|
-
<RenderBlock key={block.id} block={block} />
|
|
196
|
-
))}
|
|
200
|
+
<RenderBlocks blocks={useContent?.()?.data?.blocks} />
|
|
197
201
|
</View>
|
|
198
202
|
</>
|
|
199
203
|
) : null}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { describe, test, expect } from '@jest/globals';
|
|
3
|
+
import { getBuilderSearchParams, convertSearchParamsToQueryObject } from '.';
|
|
4
|
+
const querystring =
|
|
5
|
+
'someotherValue=jklsjfdal&abc=klfdjklgfds&builder.cachebust=true&builder.preview=page&builder.noCache=true&__builder_editing__=true&builder.overrides.page=037948e52eaf4743afed464f02c70da4&builder.overrides.037948e52eaf4743afed464f02c70da4=037948e52eaf4743afed464f02c70da4&builder.overrides.page%3A%2F=037948e52eaf4743afed464f02c70da4&preview_theme_id=128854393017';
|
|
6
|
+
const url = new URL(`localhost:3000/about-us?${querystring}`);
|
|
7
|
+
describe('Get Builder SearchParams', () => {
|
|
8
|
+
test('correctly converts URLSearchParams to object', () => {
|
|
9
|
+
const output = convertSearchParamsToQueryObject(url.searchParams);
|
|
10
|
+
expect(output).toMatchSnapshot();
|
|
11
|
+
});
|
|
12
|
+
test('correctly extracts all builder params from a query object', () => {
|
|
13
|
+
const output = getBuilderSearchParams(
|
|
14
|
+
convertSearchParamsToQueryObject(url.searchParams)
|
|
15
|
+
);
|
|
16
|
+
expect(output).toMatchSnapshot();
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
const BUILDER_SEARCHPARAMS_PREFIX = 'builder.';
|
|
3
|
+
const convertSearchParamsToQueryObject = (searchParams) => {
|
|
4
|
+
const options = {};
|
|
5
|
+
searchParams.forEach((value, key) => {
|
|
6
|
+
options[key] = value;
|
|
7
|
+
});
|
|
8
|
+
return options;
|
|
9
|
+
};
|
|
10
|
+
const getBuilderSearchParams = (options) => {
|
|
11
|
+
const newOptions = {};
|
|
12
|
+
Object.keys(options).forEach((key) => {
|
|
13
|
+
if (key.startsWith(BUILDER_SEARCHPARAMS_PREFIX)) {
|
|
14
|
+
const trimmedKey = key.replace(BUILDER_SEARCHPARAMS_PREFIX, '');
|
|
15
|
+
newOptions[trimmedKey] = options[key];
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
return newOptions;
|
|
19
|
+
};
|
|
20
|
+
export { convertSearchParamsToQueryObject, getBuilderSearchParams };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { describe, test, expect } from '@jest/globals';
|
|
3
|
+
import { generateContentUrl } from '.';
|
|
4
|
+
const testKey = 'YJIGb4i01jvw0SRdL5Bt';
|
|
5
|
+
const testModel = 'page';
|
|
6
|
+
const testId = 'c1b81bab59704599b997574eb0736def';
|
|
7
|
+
const options = {
|
|
8
|
+
cachebust: 'true',
|
|
9
|
+
noCache: 'true',
|
|
10
|
+
'overrides.037948e52eaf4743afed464f02c70da4':
|
|
11
|
+
'037948e52eaf4743afed464f02c70da4',
|
|
12
|
+
'overrides.page': '037948e52eaf4743afed464f02c70da4',
|
|
13
|
+
'overrides.page:/': '037948e52eaf4743afed464f02c70da4',
|
|
14
|
+
preview: 'page',
|
|
15
|
+
};
|
|
16
|
+
describe('Generate Content URL', () => {
|
|
17
|
+
test('generates the proper value for a simple query', () => {
|
|
18
|
+
const output = generateContentUrl({
|
|
19
|
+
apiKey: testKey,
|
|
20
|
+
model: testModel,
|
|
21
|
+
query: { id: testId },
|
|
22
|
+
});
|
|
23
|
+
expect(output).toMatchSnapshot();
|
|
24
|
+
});
|
|
25
|
+
test('Handles overrides correctly', () => {
|
|
26
|
+
const output = generateContentUrl({
|
|
27
|
+
apiKey: testKey,
|
|
28
|
+
model: testModel,
|
|
29
|
+
query: { id: testId },
|
|
30
|
+
options,
|
|
31
|
+
});
|
|
32
|
+
expect(output).toMatchSnapshot();
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -47,7 +47,7 @@ var __async = (__this, __arguments, generator) => {
|
|
|
47
47
|
step((generator = generator.apply(__this, __arguments)).next());
|
|
48
48
|
});
|
|
49
49
|
};
|
|
50
|
-
import { getFetch } from '
|
|
50
|
+
import { getFetch } from '../get-fetch';
|
|
51
51
|
const fetch = getFetch();
|
|
52
52
|
function flatten(object, path = null, separator = '.') {
|
|
53
53
|
return Object.keys(object).reduce((acc, key) => {
|
|
@@ -75,78 +75,82 @@ function getContent(options) {
|
|
|
75
75
|
);
|
|
76
76
|
});
|
|
77
77
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if (options.options) {
|
|
95
|
-
const flattened = flatten(options.options);
|
|
96
|
-
for (const key in flattened) {
|
|
97
|
-
url.searchParams.set(key, String(flattened[key]));
|
|
98
|
-
}
|
|
78
|
+
const generateContentUrl = (options) => {
|
|
79
|
+
const {
|
|
80
|
+
limit = 1,
|
|
81
|
+
userAttributes,
|
|
82
|
+
query,
|
|
83
|
+
noTraverse = false,
|
|
84
|
+
model,
|
|
85
|
+
apiKey,
|
|
86
|
+
} = options;
|
|
87
|
+
const url = new URL(
|
|
88
|
+
`https://cdn.builder.io/api/v2/content/${model}?apiKey=${apiKey}&limit=${limit}&noTraverse=${noTraverse}`
|
|
89
|
+
);
|
|
90
|
+
if (options.options) {
|
|
91
|
+
const flattened = flatten(options.options);
|
|
92
|
+
for (const key in flattened) {
|
|
93
|
+
url.searchParams.set(key, String(flattened[key]));
|
|
99
94
|
}
|
|
100
|
-
|
|
101
|
-
|
|
95
|
+
}
|
|
96
|
+
if (userAttributes) {
|
|
97
|
+
url.searchParams.set('userAttributes', JSON.stringify(userAttributes));
|
|
98
|
+
}
|
|
99
|
+
if (query) {
|
|
100
|
+
const flattened = flatten({ query });
|
|
101
|
+
for (const key in flattened) {
|
|
102
|
+
url.searchParams.set(key, JSON.stringify(flattened[key]));
|
|
102
103
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
data: variation.data,
|
|
134
|
-
testVariationId: variation.id,
|
|
135
|
-
testVariationName: variationName,
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
if (!set) {
|
|
140
|
-
Object.assign(item, {
|
|
141
|
-
testVariationId: item.id,
|
|
142
|
-
testVariationName: 'Default',
|
|
143
|
-
});
|
|
144
|
-
}
|
|
104
|
+
}
|
|
105
|
+
return url;
|
|
106
|
+
};
|
|
107
|
+
const handleABTesting = (content, testGroups) => {
|
|
108
|
+
for (const item of content.results) {
|
|
109
|
+
if (item.variations && Object.keys(item.variations).length) {
|
|
110
|
+
const testGroup = testGroups[item.id];
|
|
111
|
+
const variationValue = item.variations[testGroup];
|
|
112
|
+
if (testGroup && variationValue) {
|
|
113
|
+
item.data = variationValue.data;
|
|
114
|
+
item.testVariationId = variationValue.id;
|
|
115
|
+
item.testVariationName = variationValue.name;
|
|
116
|
+
} else {
|
|
117
|
+
let n = 0;
|
|
118
|
+
const random = Math.random();
|
|
119
|
+
let set = false;
|
|
120
|
+
for (const id in item.variations) {
|
|
121
|
+
const variation = item.variations[id];
|
|
122
|
+
const testRatio = variation.testRatio;
|
|
123
|
+
n += testRatio;
|
|
124
|
+
if (random < n) {
|
|
125
|
+
const variationName =
|
|
126
|
+
variation.name ||
|
|
127
|
+
(variation.id === item.id ? 'Default variation' : '');
|
|
128
|
+
set = true;
|
|
129
|
+
Object.assign(item, {
|
|
130
|
+
data: variation.data,
|
|
131
|
+
testVariationId: variation.id,
|
|
132
|
+
testVariationName: variationName,
|
|
133
|
+
});
|
|
145
134
|
}
|
|
146
135
|
}
|
|
136
|
+
if (!set) {
|
|
137
|
+
Object.assign(item, {
|
|
138
|
+
testVariationId: item.id,
|
|
139
|
+
testVariationName: 'Default',
|
|
140
|
+
});
|
|
141
|
+
}
|
|
147
142
|
}
|
|
148
143
|
}
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
function getAllContent(options) {
|
|
147
|
+
return __async(this, null, function* () {
|
|
148
|
+
const url = generateContentUrl(options);
|
|
149
|
+
const content = yield fetch(url.href).then((res) => res.json());
|
|
150
|
+
if (options.testGroups) {
|
|
151
|
+
handleABTesting(content, options.testGroups);
|
|
152
|
+
}
|
|
149
153
|
return content;
|
|
150
154
|
});
|
|
151
155
|
}
|
|
152
|
-
export { getAllContent, getContent };
|
|
156
|
+
export { generateContentUrl, getAllContent, getContent };
|
|
@@ -2,7 +2,9 @@ import * as React from 'react';
|
|
|
2
2
|
import { expect, test } from '@jest/globals';
|
|
3
3
|
import { getProcessedBlock } from './get-processed-block';
|
|
4
4
|
test('Can process bindings', () => {
|
|
5
|
+
var _a, _b, _c, _d, _e, _f;
|
|
5
6
|
const block = {
|
|
7
|
+
'@type': '@builder.io/sdk:Element',
|
|
6
8
|
properties: {
|
|
7
9
|
foo: 'bar',
|
|
8
10
|
},
|
|
@@ -23,9 +25,19 @@ test('Can process bindings', () => {
|
|
|
23
25
|
state: { test: 'hello' },
|
|
24
26
|
});
|
|
25
27
|
expect(processed).not.toEqual(block);
|
|
26
|
-
expect(processed.properties.foo).toEqual('baz');
|
|
27
|
-
expect(processed.properties.test).toEqual(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
expect(processed.
|
|
28
|
+
expect((_a = processed.properties) == null ? void 0 : _a.foo).toEqual('baz');
|
|
29
|
+
expect((_b = processed.properties) == null ? void 0 : _b.test).toEqual(
|
|
30
|
+
'hello'
|
|
31
|
+
);
|
|
32
|
+
expect((_c = processed.properties) == null ? void 0 : _c.block).toEqual(
|
|
33
|
+
'bar'
|
|
34
|
+
);
|
|
35
|
+
expect((_d = processed.properties) == null ? void 0 : _d.isEditing).toEqual(
|
|
36
|
+
false
|
|
37
|
+
);
|
|
38
|
+
expect(
|
|
39
|
+
(_f = (_e = processed.responsiveStyles) == null ? void 0 : _e.large) == null
|
|
40
|
+
? void 0
|
|
41
|
+
: _f.zIndex
|
|
42
|
+
).toEqual(2);
|
|
31
43
|
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { default as default2 } from '../blocks/columns';
|
|
3
|
+
import { default as default3 } from '../blocks/image';
|
|
4
|
+
import { default as default4 } from '../blocks/text';
|
|
5
|
+
import { default as default5 } from '../blocks/symbol';
|
|
6
|
+
import { default as default6 } from '../blocks/button';
|
|
7
|
+
import { default as default7 } from '../blocks/section';
|
|
8
|
+
import { default as default8 } from '../blocks/fragment';
|
|
9
|
+
import { default as default9 } from '../components/render-content';
|
|
10
|
+
export {
|
|
11
|
+
default6 as Button,
|
|
12
|
+
default2 as Columns,
|
|
13
|
+
default8 as Fragment,
|
|
14
|
+
default3 as Image,
|
|
15
|
+
default9 as RenderContent,
|
|
16
|
+
default7 as Section,
|
|
17
|
+
default5 as Symbol,
|
|
18
|
+
default4 as Text,
|
|
19
|
+
};
|
package/src/index.js
CHANGED
|
@@ -1,29 +1,13 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import
|
|
2
|
+
import('./index-helpers/top-of-file');
|
|
3
3
|
import { isEditing } from './functions/is-editing';
|
|
4
4
|
if (isEditing()) {
|
|
5
5
|
import('./scripts/init-editing');
|
|
6
6
|
}
|
|
7
|
-
|
|
8
|
-
import { default as default3 } from './blocks/image';
|
|
9
|
-
import { default as default4 } from './blocks/text';
|
|
10
|
-
import { default as default5 } from './blocks/symbol';
|
|
11
|
-
import { default as default6 } from './blocks/section';
|
|
12
|
-
import { default as default7 } from './blocks/fragment';
|
|
13
|
-
import { default as default8 } from './components/render-content';
|
|
14
|
-
import { default as default9 } from './blocks/button';
|
|
7
|
+
export * from './index-helpers/blocks-exports';
|
|
15
8
|
export * from './functions/is-editing';
|
|
16
9
|
export * from './functions/register-component';
|
|
17
10
|
export * from './functions/register';
|
|
18
11
|
export * from './functions/set-editor-settings';
|
|
19
12
|
export * from './functions/get-content';
|
|
20
|
-
export
|
|
21
|
-
default9 as Button,
|
|
22
|
-
default2 as Columns,
|
|
23
|
-
default7 as Fragment,
|
|
24
|
-
default3 as Image,
|
|
25
|
-
default8 as RenderContent,
|
|
26
|
-
default6 as Section,
|
|
27
|
-
default5 as Symbol,
|
|
28
|
-
default4 as Text,
|
|
29
|
-
};
|
|
13
|
+
export * from './functions/get-builder-search-params';
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
var __async = (__this, __arguments, generator) => {
|
|
3
|
-
return new Promise((resolve, reject) => {
|
|
4
|
-
var fulfilled = (value) => {
|
|
5
|
-
try {
|
|
6
|
-
step(generator.next(value));
|
|
7
|
-
} catch (e) {
|
|
8
|
-
reject(e);
|
|
9
|
-
}
|
|
10
|
-
};
|
|
11
|
-
var rejected = (value) => {
|
|
12
|
-
try {
|
|
13
|
-
step(generator.throw(value));
|
|
14
|
-
} catch (e) {
|
|
15
|
-
reject(e);
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
var step = (x) =>
|
|
19
|
-
x.done
|
|
20
|
-
? resolve(x.value)
|
|
21
|
-
: Promise.resolve(x.value).then(fulfilled, rejected);
|
|
22
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
23
|
-
});
|
|
24
|
-
};
|
|
25
|
-
import fetchMock from 'jest-fetch-mock';
|
|
26
|
-
fetchMock.enableMocks();
|
|
27
|
-
import { test, beforeEach, expect } from '@jest/globals';
|
|
28
|
-
import { getContent } from './get-content';
|
|
29
|
-
const testKey = 'YJIGb4i01jvw0SRdL5Bt';
|
|
30
|
-
const testModel = 'page';
|
|
31
|
-
const testId = 'c1b81bab59704599b997574eb0736def';
|
|
32
|
-
beforeEach(() => {});
|
|
33
|
-
test.skip('Get content', () =>
|
|
34
|
-
__async(void 0, null, function* () {
|
|
35
|
-
var _a, _b;
|
|
36
|
-
expect(
|
|
37
|
-
(_a = yield getContent({
|
|
38
|
-
apiKey: testKey,
|
|
39
|
-
model: testModel,
|
|
40
|
-
query: {
|
|
41
|
-
id: testId,
|
|
42
|
-
},
|
|
43
|
-
})) == null
|
|
44
|
-
? void 0
|
|
45
|
-
: _a.id
|
|
46
|
-
).toEqual(testId);
|
|
47
|
-
expect(
|
|
48
|
-
(_b = yield getContent({
|
|
49
|
-
apiKey: testKey,
|
|
50
|
-
model: testModel,
|
|
51
|
-
userAttributes: {
|
|
52
|
-
urlPath: '/test-page',
|
|
53
|
-
},
|
|
54
|
-
})) == null
|
|
55
|
-
? void 0
|
|
56
|
-
: _b.id
|
|
57
|
-
).toEqual(testId);
|
|
58
|
-
}));
|