@builder.io/sdk-svelte 0.0.2 → 0.0.4
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/--package.json +159 -0
- package/package/blocks/BaseText.svelte +19 -0
- package/package/blocks/BaseText.svelte.d.ts +19 -0
- package/package/blocks/columns/columns.svelte +13 -4
- package/package/blocks/columns/columns.svelte.d.ts +1 -1
- package/package/blocks/custom-code/custom-code.svelte +1 -1
- package/package/blocks/embed/embed.svelte +2 -0
- package/package/blocks/form/form.svelte +7 -5
- package/package/blocks/image/image.svelte +48 -46
- package/package/blocks/image/image.svelte.d.ts +1 -1
- package/package/blocks/img/img.svelte +7 -2
- package/package/blocks/section/section.svelte +7 -2
- package/package/blocks/symbol/symbol.svelte +13 -13
- package/package/blocks/symbol/symbol.svelte.d.ts +3 -3
- package/package/blocks/video/video.svelte +14 -3
- package/package/components/render-block/block-styles.svelte +24 -19
- package/package/components/render-block/block-styles.svelte.d.ts +2 -2
- package/package/components/render-block/render-block.svelte +81 -58
- package/package/components/render-block/render-block.svelte.d.ts +2 -2
- package/package/components/render-block/render-component-with-context.svelte +32 -0
- package/package/components/render-block/render-component-with-context.svelte.d.ts +19 -0
- package/package/components/render-block/render-component.svelte +1 -3
- package/package/components/render-block/render-component.svelte.d.ts +2 -2
- package/package/components/render-block/render-repeated-block.svelte +3 -0
- package/package/components/render-block/types.d.ts +2 -2
- package/package/components/render-block/types.js +1 -2
- package/package/components/render-blocks.svelte +12 -1
- package/package/components/render-blocks.svelte.d.ts +3 -1
- package/package/components/render-content/components/render-styles.svelte +2 -1
- package/package/components/render-content/render-content.svelte +24 -8
- package/package/components/render-content/render-content.svelte.d.ts +2 -2
- package/package/constants/builder-registered-components.js +3 -0
- package/package/context/builder.context.d.ts +1 -0
- package/package/context/builder.context.js +1 -0
- package/package/context/types.d.ts +4 -3
- package/package/context/types.js +1 -3
- package/package/functions/extract-text-styles.d.ts +4 -0
- package/package/functions/extract-text-styles.js +34 -0
- package/package/functions/fast-clone.d.ts +4 -0
- package/package/functions/fast-clone.js +4 -0
- package/package/functions/get-block-actions-handler.d.ts +5 -0
- package/package/functions/get-block-actions-handler.js +9 -0
- package/package/functions/get-block-actions.d.ts +1 -1
- package/package/functions/get-block-actions.js +2 -8
- package/package/functions/get-block-component-options.d.ts +1 -1
- package/package/functions/get-block-component-options.js +0 -1
- package/package/functions/get-block-properties.d.ts +1 -1
- package/package/functions/get-block-properties.js +0 -1
- package/package/functions/get-block-tag.d.ts +1 -1
- package/package/functions/get-block-tag.js +0 -1
- package/package/functions/get-builder-search-params/index.d.ts +1 -1
- package/package/functions/get-builder-search-params/index.js +6 -2
- package/package/functions/get-content/ab-testing.d.ts +5 -3
- package/package/functions/get-content/ab-testing.js +75 -37
- package/package/functions/get-content/index.d.ts +1 -1
- package/package/functions/get-content/index.js +4 -5
- package/package/functions/get-content/types.d.ts +7 -2
- package/package/functions/get-processed-block.d.ts +1 -1
- package/package/functions/get-processed-block.js +5 -4
- package/package/functions/get-processed-block.test.js +0 -1
- package/package/functions/get-react-native-block-styles.d.ts +6 -0
- package/package/functions/get-react-native-block-styles.js +16 -0
- package/package/functions/register-component.d.ts +2 -2
- package/package/functions/register-component.js +1 -5
- package/package/functions/register.d.ts +2 -2
- package/package/functions/register.js +0 -2
- package/package/functions/sanitize-react-native-block-styles.d.ts +3 -0
- package/package/functions/sanitize-react-native-block-styles.js +53 -0
- package/package/functions/track.d.ts +1 -1
- package/package/functions/track.js +5 -6
- package/package/functions/transform-block.d.ts +1 -1
- package/package/functions/transform-block.js +0 -1
- package/package/helpers/ab-tests.d.ts +8 -0
- package/package/helpers/ab-tests.js +5 -0
- package/package/helpers/cookie.d.ts +9 -3
- package/package/helpers/cookie.js +8 -3
- package/package/helpers/css.d.ts +5 -1
- package/package/helpers/css.js +14 -1
- package/package/helpers/localStorage.d.ts +3 -4
- package/package/helpers/sessionId.d.ts +3 -4
- package/package/helpers/sessionId.js +5 -3
- package/package/helpers/visitorId.d.ts +3 -5
- package/package/scripts/init-editing.js +42 -38
- package/package/types/builder-content.d.ts +1 -1
- package/package/types/builder-content.js +1 -1
- package/package/types/targets.d.ts +1 -1
- package/package/types/typescript.d.ts +1 -0
- package/package.json +8 -3
- package/package/blocks/button/button.lite.d.ts +0 -0
- package/package/blocks/button/button.lite.tsx +0 -36
- package/package/blocks/columns/columns.lite.d.ts +0 -0
- package/package/blocks/columns/columns.lite.tsx +0 -139
- package/package/blocks/custom-code/custom-code.lite.d.ts +0 -0
- package/package/blocks/custom-code/custom-code.lite.tsx +0 -70
- package/package/blocks/embed/embed.lite.d.ts +0 -0
- package/package/blocks/embed/embed.lite.tsx +0 -52
- package/package/blocks/form/form.lite.d.ts +0 -0
- package/package/blocks/form/form.lite.tsx +0 -351
- package/package/blocks/fragment/fragment.lite.d.ts +0 -0
- package/package/blocks/fragment/fragment.lite.tsx +0 -12
- package/package/blocks/image/image.lite.d.ts +0 -0
- package/package/blocks/image/image.lite.tsx +0 -148
- package/package/blocks/img/img.lite.d.ts +0 -0
- package/package/blocks/img/img.lite.tsx +0 -48
- package/package/blocks/input/input.lite.d.ts +0 -0
- package/package/blocks/input/input.lite.tsx +0 -34
- package/package/blocks/raw-text/raw-text.lite.d.ts +0 -0
- package/package/blocks/raw-text/raw-text.lite.tsx +0 -15
- package/package/blocks/section/section.lite.d.ts +0 -0
- package/package/blocks/section/section.lite.tsx +0 -30
- package/package/blocks/select/select.lite.d.ts +0 -0
- package/package/blocks/select/select.lite.tsx +0 -34
- package/package/blocks/submit-button/submit-button.lite.d.ts +0 -0
- package/package/blocks/submit-button/submit-button.lite.tsx +0 -15
- package/package/blocks/symbol/symbol.lite.d.ts +0 -0
- package/package/blocks/symbol/symbol.lite.tsx +0 -92
- package/package/blocks/text/text.lite.d.ts +0 -0
- package/package/blocks/text/text.lite.tsx +0 -11
- package/package/blocks/textarea/textarea.lite.d.ts +0 -0
- package/package/blocks/textarea/textarea.lite.tsx +0 -19
- package/package/blocks/video/video.lite.d.ts +0 -0
- package/package/blocks/video/video.lite.tsx +0 -92
- package/package/components/render-block/block-styles.lite.d.ts +0 -0
- package/package/components/render-block/block-styles.lite.tsx +0 -60
- package/package/components/render-block/render-block.lite.d.ts +0 -0
- package/package/components/render-block/render-block.lite.tsx +0 -216
- package/package/components/render-block/render-component.lite.d.ts +0 -0
- package/package/components/render-block/render-component.lite.tsx +0 -33
- package/package/components/render-block/render-repeated-block.lite.d.ts +0 -0
- package/package/components/render-block/render-repeated-block.lite.tsx +0 -49
- package/package/components/render-blocks.lite.d.ts +0 -0
- package/package/components/render-blocks.lite.tsx +0 -91
- package/package/components/render-content/components/render-styles.lite.d.ts +0 -0
- package/package/components/render-content/components/render-styles.lite.tsx +0 -86
- package/package/components/render-content/render-content.lite.d.ts +0 -0
- package/package/components/render-content/render-content.lite.tsx +0 -356
- package/package/components/render-inlined-styles.lite.d.ts +0 -0
- package/package/components/render-inlined-styles.lite.tsx +0 -27
- package/package/functions/convert-style-object.d.ts +0 -1
- package/package/functions/convert-style-object.js +0 -3
- package/package/functions/get-block-styles.d.ts +0 -2
- package/package/functions/get-block-styles.js +0 -21
- package/package/functions/sanitize-styles.d.ts +0 -4
- package/package/functions/sanitize-styles.js +0 -6
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const TEXT_STYLE_KEYS = [
|
|
2
|
+
'color',
|
|
3
|
+
'whiteSpace',
|
|
4
|
+
'direction',
|
|
5
|
+
'hyphens',
|
|
6
|
+
'overflowWrap',
|
|
7
|
+
];
|
|
8
|
+
/**
|
|
9
|
+
* Check if the key represent a CSS style property that applies to text
|
|
10
|
+
* See MDN docs for refrence of what properties apply to text.
|
|
11
|
+
* https://developer.mozilla.org/en-US/docs/Learn/CSS/Styling_text/Fundamentals#summary
|
|
12
|
+
*/
|
|
13
|
+
const isTextStyle = (key) => {
|
|
14
|
+
return (TEXT_STYLE_KEYS.includes(key) ||
|
|
15
|
+
key.startsWith('font') ||
|
|
16
|
+
key.startsWith('text') ||
|
|
17
|
+
key.startsWith('letter') ||
|
|
18
|
+
key.startsWith('line') ||
|
|
19
|
+
key.startsWith('word') ||
|
|
20
|
+
key.startsWith('writing'));
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Extract styles that apply to text from a style object.
|
|
24
|
+
*/
|
|
25
|
+
export const extractTextStyles = (styles) => {
|
|
26
|
+
const textStyles = {};
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
28
|
+
Object.entries(styles).forEach(([key, value]) => {
|
|
29
|
+
if (isTextStyle(key)) {
|
|
30
|
+
textStyles[key] = value;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
return textStyles;
|
|
34
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { BuilderContextInterface } from '../context/types.js';
|
|
2
|
+
import type { BuilderBlock } from '../types/builder-block.js';
|
|
3
|
+
export declare function crateEventHandler(value: string, options: {
|
|
4
|
+
block: BuilderBlock;
|
|
5
|
+
} & Pick<BuilderContextInterface, 'state' | 'context'>): (event: Event) => any;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import '../types/builder-block.js';
|
|
2
|
-
import { evaluate } from './evaluate.js';
|
|
3
1
|
import { getEventHandlerName } from './event-handler-name.js';
|
|
2
|
+
import { crateEventHandler } from './get-block-actions-handler.js';
|
|
4
3
|
export function getBlockActions(options) {
|
|
5
4
|
const obj = {};
|
|
6
5
|
const optionActions = options.block.actions ?? {};
|
|
@@ -10,12 +9,7 @@ export function getBlockActions(options) {
|
|
|
10
9
|
continue;
|
|
11
10
|
}
|
|
12
11
|
const value = optionActions[key];
|
|
13
|
-
obj[getEventHandlerName(key)] = (
|
|
14
|
-
code: value,
|
|
15
|
-
context: options.context,
|
|
16
|
-
state: options.state,
|
|
17
|
-
event,
|
|
18
|
-
});
|
|
12
|
+
obj[getEventHandlerName(key)] = crateEventHandler(value, options);
|
|
19
13
|
}
|
|
20
14
|
return obj;
|
|
21
15
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { BuilderBlock } from '../types/builder-block.js';
|
|
1
|
+
import type { BuilderBlock } from '../types/builder-block.js';
|
|
2
2
|
export declare function getBlockComponentOptions(block: BuilderBlock): any;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
declare type QueryObject = Record<string, string>;
|
|
2
2
|
export declare const convertSearchParamsToQueryObject: (searchParams: URLSearchParams) => QueryObject;
|
|
3
|
-
export declare const getBuilderSearchParams: (
|
|
3
|
+
export declare const getBuilderSearchParams: (_options: QueryObject | URLSearchParams | undefined) => QueryObject;
|
|
4
4
|
export declare const getBuilderSearchParamsFromWindow: () => QueryObject;
|
|
5
5
|
export declare const normalizeSearchParams: (searchParams: QueryObject | URLSearchParams) => QueryObject;
|
|
6
6
|
export {};
|
|
@@ -7,7 +7,11 @@ export const convertSearchParamsToQueryObject = (searchParams) => {
|
|
|
7
7
|
});
|
|
8
8
|
return options;
|
|
9
9
|
};
|
|
10
|
-
export const getBuilderSearchParams = (
|
|
10
|
+
export const getBuilderSearchParams = (_options) => {
|
|
11
|
+
if (!_options) {
|
|
12
|
+
return {};
|
|
13
|
+
}
|
|
14
|
+
const options = normalizeSearchParams(_options);
|
|
11
15
|
const newOptions = {};
|
|
12
16
|
Object.keys(options).forEach((key) => {
|
|
13
17
|
if (key.startsWith(BUILDER_SEARCHPARAMS_PREFIX)) {
|
|
@@ -22,7 +26,7 @@ export const getBuilderSearchParamsFromWindow = () => {
|
|
|
22
26
|
return {};
|
|
23
27
|
}
|
|
24
28
|
const searchParams = new URLSearchParams(window.location.search);
|
|
25
|
-
return getBuilderSearchParams(
|
|
29
|
+
return getBuilderSearchParams(searchParams);
|
|
26
30
|
};
|
|
27
31
|
export const normalizeSearchParams = (searchParams) => searchParams instanceof URLSearchParams
|
|
28
32
|
? convertSearchParamsToQueryObject(searchParams)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
export declare const handleABTesting: (item
|
|
1
|
+
import type { BuilderContent } from '../../types/builder-content.js';
|
|
2
|
+
import type { CanTrack } from '../../types/can-track.js';
|
|
3
|
+
export declare const handleABTesting: ({ item, canTrack, }: {
|
|
4
|
+
item: BuilderContent;
|
|
5
|
+
} & CanTrack) => Promise<void>;
|
|
@@ -1,40 +1,78 @@
|
|
|
1
|
-
import '
|
|
2
|
-
import '../../
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const testRatio = variation.testRatio;
|
|
20
|
-
n += testRatio;
|
|
21
|
-
if (random < n) {
|
|
22
|
-
const variationName = variation.name ||
|
|
23
|
-
(variation.id === item.id ? 'Default variation' : '');
|
|
24
|
-
set = true;
|
|
25
|
-
Object.assign(item, {
|
|
26
|
-
data: variation.data,
|
|
27
|
-
testVariationId: variation.id,
|
|
28
|
-
testVariationName: variationName,
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
if (!set) {
|
|
33
|
-
Object.assign(item, {
|
|
34
|
-
testVariationId: item.id,
|
|
35
|
-
testVariationName: 'Default',
|
|
36
|
-
});
|
|
37
|
-
}
|
|
1
|
+
import { getContentVariationCookie, setContentVariationCookie, } from '../../helpers/ab-tests.js';
|
|
2
|
+
import { checkIsDefined } from '../../helpers/nullable.js';
|
|
3
|
+
const checkIsBuilderContentWithVariations = (item) => checkIsDefined(item.id) &&
|
|
4
|
+
checkIsDefined(item.variations) &&
|
|
5
|
+
Object.keys(item.variations).length > 0;
|
|
6
|
+
/**
|
|
7
|
+
* Randomly assign a variation to this user and store it in cookies/storage
|
|
8
|
+
*/
|
|
9
|
+
const getRandomVariationId = ({ id, variations, }) => {
|
|
10
|
+
let n = 0;
|
|
11
|
+
const random = Math.random();
|
|
12
|
+
// loop over variations test ratios, incrementing a counter,
|
|
13
|
+
// until we find the variation that this user should be assigned to
|
|
14
|
+
for (const id in variations) {
|
|
15
|
+
const testRatio = variations[id]?.testRatio;
|
|
16
|
+
n += testRatio;
|
|
17
|
+
if (random < n) {
|
|
18
|
+
return id;
|
|
38
19
|
}
|
|
39
20
|
}
|
|
21
|
+
// `item.variations` does not include the default variation
|
|
22
|
+
// if we arrive here, then it means that the random number fits in the default variation bucket
|
|
23
|
+
return id;
|
|
24
|
+
};
|
|
25
|
+
const getTestFields = ({ item, testGroupId, }) => {
|
|
26
|
+
const variationValue = item.variations[testGroupId];
|
|
27
|
+
if (testGroupId === item.id ||
|
|
28
|
+
// handle edge-case where `testGroupId` points to non-existing variation
|
|
29
|
+
!variationValue) {
|
|
30
|
+
return {
|
|
31
|
+
testVariationId: item.id,
|
|
32
|
+
testVariationName: 'Default',
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
return {
|
|
37
|
+
data: variationValue.data,
|
|
38
|
+
testVariationId: variationValue.id,
|
|
39
|
+
testVariationName: variationValue.name || (variationValue.id === item.id ? 'Default' : ''),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const getContentVariation = async ({ item, canTrack, }) => {
|
|
44
|
+
// try to find test variation in cookies/storage
|
|
45
|
+
const testGroupId = await getContentVariationCookie({
|
|
46
|
+
canTrack,
|
|
47
|
+
contentId: item.id,
|
|
48
|
+
});
|
|
49
|
+
const testFields = testGroupId
|
|
50
|
+
? getTestFields({ item, testGroupId })
|
|
51
|
+
: undefined;
|
|
52
|
+
if (testFields) {
|
|
53
|
+
return testFields;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
// if variation not found in storage, assign a random variation to this user
|
|
57
|
+
const randomVariationId = getRandomVariationId({
|
|
58
|
+
variations: item.variations,
|
|
59
|
+
id: item.id,
|
|
60
|
+
});
|
|
61
|
+
// store variation in cookies/storage
|
|
62
|
+
setContentVariationCookie({
|
|
63
|
+
contentId: item.id,
|
|
64
|
+
value: randomVariationId,
|
|
65
|
+
canTrack,
|
|
66
|
+
}).catch((err) => {
|
|
67
|
+
console.error('could not store A/B test variation: ', err);
|
|
68
|
+
});
|
|
69
|
+
return getTestFields({ item, testGroupId: randomVariationId });
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
export const handleABTesting = async ({ item, canTrack, }) => {
|
|
73
|
+
if (!checkIsBuilderContentWithVariations(item)) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const variationValue = await getContentVariation({ item, canTrack });
|
|
77
|
+
Object.assign(item, variationValue);
|
|
40
78
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BuilderContent } from '../../types/builder-content.js';
|
|
1
|
+
import type { BuilderContent } from '../../types/builder-content.js';
|
|
2
2
|
export declare type GetContentOptions = import('./types.js').GetContentOptions;
|
|
3
3
|
export declare function getContent(options: GetContentOptions): Promise<BuilderContent | null>;
|
|
4
4
|
export declare const generateContentUrl: (options: GetContentOptions) => URL;
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { flatten } from '../../helpers/flatten.js';
|
|
2
|
-
import '../../types/builder-content.js';
|
|
3
2
|
import { getBuilderSearchParamsFromWindow, normalizeSearchParams, } from '../get-builder-search-params/index.js';
|
|
4
3
|
import { getFetch } from '../get-fetch.js';
|
|
5
4
|
import { handleABTesting } from './ab-testing.js';
|
|
6
|
-
const fetch$ = getFetch();
|
|
7
5
|
export async function getContent(options) {
|
|
8
6
|
return (await getAllContent({ ...options, limit: 1 })).results[0] || null;
|
|
9
7
|
}
|
|
@@ -31,11 +29,12 @@ export const generateContentUrl = (options) => {
|
|
|
31
29
|
};
|
|
32
30
|
export async function getAllContent(options) {
|
|
33
31
|
const url = generateContentUrl(options);
|
|
34
|
-
const fetch = await
|
|
32
|
+
const fetch = await getFetch();
|
|
35
33
|
const content = await fetch(url.href).then((res) => res.json());
|
|
36
|
-
|
|
34
|
+
const canTrack = options.canTrack !== false;
|
|
35
|
+
if (canTrack) {
|
|
37
36
|
for (const item of content.results) {
|
|
38
|
-
handleABTesting(item,
|
|
37
|
+
await handleABTesting({ item, canTrack });
|
|
39
38
|
}
|
|
40
39
|
}
|
|
41
40
|
return content;
|
|
@@ -3,8 +3,6 @@ export interface GetContentOptions {
|
|
|
3
3
|
model: string;
|
|
4
4
|
/** Your public API key */
|
|
5
5
|
apiKey: string;
|
|
6
|
-
/** A/B test groups the current visitor is in. Key is the content ID, value is the variation ID */
|
|
7
|
-
testGroups?: Record<string, string> | null;
|
|
8
6
|
/** Number of items to fetch. Default is 1 */
|
|
9
7
|
limit?: number;
|
|
10
8
|
/** User attributes to target on, such as { urlPath: '/foo', device: 'mobile', ...etc } */
|
|
@@ -23,4 +21,11 @@ export interface GetContentOptions {
|
|
|
23
21
|
* If set to `false`, it will render the entire content tree eagerly.
|
|
24
22
|
*/
|
|
25
23
|
noTraverse?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* If set to `false`, it will not use cookies to target content. Therefore, A/B Testing will be disabled and
|
|
26
|
+
* only the default variation will be returned to every user.
|
|
27
|
+
*
|
|
28
|
+
* Defaults to `true`.
|
|
29
|
+
*/
|
|
30
|
+
canTrack?: boolean;
|
|
26
31
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { BuilderContextInterface } from '../context/types.js';
|
|
2
|
-
import { BuilderBlock } from '../types/builder-block.js';
|
|
2
|
+
import type { BuilderBlock } from '../types/builder-block.js';
|
|
3
3
|
export declare function getProcessedBlock({ block, context, shouldEvaluateBindings, state, }: {
|
|
4
4
|
block: BuilderBlock;
|
|
5
5
|
/**
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import '../types/builder-block.js';
|
|
2
1
|
import { evaluate } from './evaluate.js';
|
|
2
|
+
import { fastClone } from './fast-clone.js';
|
|
3
3
|
import { set } from './set.js';
|
|
4
4
|
import { transformBlock } from './transform-block.js';
|
|
5
5
|
const evaluateBindings = ({ block, context, state, }) => {
|
|
6
6
|
if (!block.bindings) {
|
|
7
7
|
return block;
|
|
8
8
|
}
|
|
9
|
+
const copy = fastClone(block);
|
|
9
10
|
const copied = {
|
|
10
|
-
...
|
|
11
|
-
properties: { ...
|
|
12
|
-
actions: { ...
|
|
11
|
+
...copy,
|
|
12
|
+
properties: { ...copy.properties },
|
|
13
|
+
actions: { ...copy.actions },
|
|
13
14
|
};
|
|
14
15
|
for (const binding in block.bindings) {
|
|
15
16
|
const expression = block.bindings[binding];
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { BuilderContextInterface } from '../context/types.js';
|
|
2
|
+
import type { BuilderBlock } from '../types/builder-block.js';
|
|
3
|
+
export declare function getReactNativeBlockStyles({ block, context, }: {
|
|
4
|
+
block: BuilderBlock;
|
|
5
|
+
context: BuilderContextInterface;
|
|
6
|
+
}): CSSStyleDeclaration | Record<string, string | undefined>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { sanitizeReactNativeBlockStyles } from './sanitize-react-native-block-styles.js';
|
|
2
|
+
export function getReactNativeBlockStyles({ block, context, }) {
|
|
3
|
+
const responsiveStyles = block.responsiveStyles;
|
|
4
|
+
if (!responsiveStyles) {
|
|
5
|
+
return {};
|
|
6
|
+
}
|
|
7
|
+
const styles = {
|
|
8
|
+
// recursively apply inherited styles so that they can be passed down to children `Text` blocks
|
|
9
|
+
...context.inheritedStyles,
|
|
10
|
+
...(responsiveStyles.large || {}),
|
|
11
|
+
...(responsiveStyles.medium || {}),
|
|
12
|
+
...(responsiveStyles.small || {}),
|
|
13
|
+
};
|
|
14
|
+
const newStyles = sanitizeReactNativeBlockStyles(styles);
|
|
15
|
+
return newStyles;
|
|
16
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RegisteredComponent } from '../context/types.js';
|
|
1
|
+
import type { RegisteredComponent } from '../context/types.js';
|
|
2
2
|
import type { ComponentInfo } from '../types/components.js';
|
|
3
3
|
/**
|
|
4
4
|
* @deprecated. Use the `customComponents` prop in RenderContent instead to provide your custom components to the builder SDK.
|
|
@@ -8,7 +8,7 @@ export declare const components: RegisteredComponent[];
|
|
|
8
8
|
* @deprecated. Use the `customComponents` prop in RenderContent instead to provide your custom components to the builder SDK.
|
|
9
9
|
*/
|
|
10
10
|
export declare function registerComponent(component: any, info: ComponentInfo): void;
|
|
11
|
-
export declare const createRegisterComponentMessage: ({ component, ...info }: RegisteredComponent) => {
|
|
11
|
+
export declare const createRegisterComponentMessage: ({ component: _, ...info }: RegisteredComponent) => {
|
|
12
12
|
type: string;
|
|
13
13
|
data: ComponentInfo;
|
|
14
14
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import '
|
|
1
|
+
import { fastClone } from './fast-clone.js';
|
|
2
2
|
/**
|
|
3
3
|
* @deprecated. Use the `customComponents` prop in RenderContent instead to provide your custom components to the builder SDK.
|
|
4
4
|
*/
|
|
@@ -15,10 +15,6 @@ export const createRegisterComponentMessage = ({ component: _, ...info }) => ({
|
|
|
15
15
|
type: 'builder.registerComponent',
|
|
16
16
|
data: prepareComponentInfoToSend(info),
|
|
17
17
|
});
|
|
18
|
-
/**
|
|
19
|
-
* We need to serialize values to a string in case there are Proxy values, as is the case with SolidJS etc.
|
|
20
|
-
*/
|
|
21
|
-
const fastClone = (obj) => JSON.parse(JSON.stringify(obj));
|
|
22
18
|
const serializeValue = (value) => typeof value === 'function' ? serializeFn(value) : fastClone(value);
|
|
23
19
|
/**
|
|
24
20
|
* Input attributes that are functions must be converted to strings before being serialized to JSON.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { BuilderBlock } from '../types/builder-block.js';
|
|
2
|
-
import { DeepPartial } from '../types/deep-partial.js';
|
|
1
|
+
import type { BuilderBlock } from '../types/builder-block.js';
|
|
2
|
+
import type { DeepPartial } from '../types/deep-partial.js';
|
|
3
3
|
export interface InsertMenuItem {
|
|
4
4
|
name: string;
|
|
5
5
|
icon?: string;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const propertiesThatMustBeNumber = new Set(['lineHeight']);
|
|
2
|
+
const displayValues = new Set(['flex', 'none']);
|
|
3
|
+
const SHOW_WARNINGS = false;
|
|
4
|
+
const normalizeNumber = (value) => {
|
|
5
|
+
if (Number.isNaN(value)) {
|
|
6
|
+
return undefined;
|
|
7
|
+
}
|
|
8
|
+
else if (value < 0) {
|
|
9
|
+
// TODO: why are negative values not allowed?
|
|
10
|
+
return 0;
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
export const sanitizeReactNativeBlockStyles = (styles) => {
|
|
17
|
+
return Object.keys(styles).reduce((acc, key) => {
|
|
18
|
+
const propertyValue = styles[key];
|
|
19
|
+
if (key === 'display' && !displayValues.has(propertyValue)) {
|
|
20
|
+
if (SHOW_WARNINGS) {
|
|
21
|
+
console.warn(`Style value for key "display" must be "flex" or "none" but had ${propertyValue}`);
|
|
22
|
+
}
|
|
23
|
+
return acc;
|
|
24
|
+
}
|
|
25
|
+
if (propertiesThatMustBeNumber.has(key) &&
|
|
26
|
+
typeof propertyValue !== 'number') {
|
|
27
|
+
if (SHOW_WARNINGS) {
|
|
28
|
+
console.warn(`Style key ${key} must be a number, but had value \`${styles[key]}\``);
|
|
29
|
+
}
|
|
30
|
+
return acc;
|
|
31
|
+
}
|
|
32
|
+
if (typeof propertyValue === 'string') {
|
|
33
|
+
// `px` units need to be stripped and replaced with numbers
|
|
34
|
+
// https://regexr.com/6ualn
|
|
35
|
+
const isPixelUnit = propertyValue.match(/^-?(\d*)(\.?)(\d*)*px$/);
|
|
36
|
+
if (isPixelUnit) {
|
|
37
|
+
const newValue = parseFloat(propertyValue);
|
|
38
|
+
const normalizedValue = normalizeNumber(newValue);
|
|
39
|
+
if (normalizedValue) {
|
|
40
|
+
return { ...acc, [key]: normalizedValue };
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
return acc;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
else if (propertyValue === '0') {
|
|
47
|
+
// 0 edge case needs to be handled
|
|
48
|
+
return { ...acc, [key]: 0 };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return { ...acc, [key]: propertyValue };
|
|
52
|
+
}, {});
|
|
53
|
+
};
|
|
@@ -1,25 +1,24 @@
|
|
|
1
1
|
import { TARGET } from '../constants/target.js';
|
|
2
2
|
import { getSessionId } from '../helpers/sessionId.js';
|
|
3
3
|
import { getVisitorId } from '../helpers/visitorId.js';
|
|
4
|
-
import '../types/can-track.js';
|
|
5
4
|
import { isBrowser } from './is-browser.js';
|
|
6
5
|
import { isEditing } from './is-editing.js';
|
|
7
|
-
const getTrackingEventData = ({ canTrack }) => {
|
|
6
|
+
const getTrackingEventData = async ({ canTrack, }) => {
|
|
8
7
|
if (!canTrack) {
|
|
9
8
|
return { visitorId: undefined, sessionId: undefined };
|
|
10
9
|
}
|
|
11
|
-
const sessionId = getSessionId({ canTrack });
|
|
10
|
+
const sessionId = await getSessionId({ canTrack });
|
|
12
11
|
const visitorId = getVisitorId({ canTrack });
|
|
13
12
|
return {
|
|
14
13
|
sessionId,
|
|
15
14
|
visitorId,
|
|
16
15
|
};
|
|
17
16
|
};
|
|
18
|
-
const createEvent = ({ type: eventType, canTrack, orgId, contentId, ...properties }) => ({
|
|
17
|
+
const createEvent = async ({ type: eventType, canTrack, orgId, contentId, ...properties }) => ({
|
|
19
18
|
type: eventType,
|
|
20
19
|
data: {
|
|
21
20
|
...properties,
|
|
22
|
-
...getTrackingEventData({ canTrack }),
|
|
21
|
+
...(await getTrackingEventData({ canTrack })),
|
|
23
22
|
ownerId: orgId,
|
|
24
23
|
contentId,
|
|
25
24
|
},
|
|
@@ -37,7 +36,7 @@ export async function track(eventProps) {
|
|
|
37
36
|
return fetch(`https://builder.io/api/v1/track`, {
|
|
38
37
|
method: 'POST',
|
|
39
38
|
body: JSON.stringify({
|
|
40
|
-
events: [createEvent(eventProps)],
|
|
39
|
+
events: [await createEvent(eventProps)],
|
|
41
40
|
}),
|
|
42
41
|
headers: {
|
|
43
42
|
'content-type': 'application/json',
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { BuilderBlock } from '../types/builder-block.js';
|
|
1
|
+
import type { BuilderBlock } from '../types/builder-block.js';
|
|
2
2
|
export declare function transformBlock(block: BuilderBlock): BuilderBlock;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CanTrack } from '../types/can-track.js';
|
|
2
|
+
export declare const getContentVariationCookie: ({ contentId, canTrack, }: {
|
|
3
|
+
contentId: string;
|
|
4
|
+
} & CanTrack) => Promise<string | undefined>;
|
|
5
|
+
export declare const setContentVariationCookie: ({ contentId, canTrack, value, }: {
|
|
6
|
+
contentId: string;
|
|
7
|
+
value: string;
|
|
8
|
+
} & CanTrack) => Promise<undefined>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { getCookie, setCookie } from './cookie.js';
|
|
2
|
+
const BUILDER_STORE_PREFIX = 'builderio.variations';
|
|
3
|
+
const getContentTestKey = (id) => `${BUILDER_STORE_PREFIX}.${id}`;
|
|
4
|
+
export const getContentVariationCookie = ({ contentId, canTrack, }) => getCookie({ name: getContentTestKey(contentId), canTrack });
|
|
5
|
+
export const setContentVariationCookie = ({ contentId, canTrack, value, }) => setCookie({ name: getContentTestKey(contentId), value, canTrack });
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
import { CanTrack } from '../types/can-track.js';
|
|
1
|
+
import type { CanTrack } from '../types/can-track.js';
|
|
2
|
+
/**
|
|
3
|
+
* NOTE: This function is `async` because its react-native override is async. Do not remove the `async` keyword!
|
|
4
|
+
*/
|
|
2
5
|
export declare const getCookie: ({ name, canTrack, }: {
|
|
3
6
|
name: string;
|
|
4
|
-
} & CanTrack) => string | undefined
|
|
7
|
+
} & CanTrack) => Promise<string | undefined>;
|
|
8
|
+
/**
|
|
9
|
+
* NOTE: This function is `async` because its react-native override is async. Do not remove the `async` keyword!
|
|
10
|
+
*/
|
|
5
11
|
export declare const setCookie: ({ name, value, expires, canTrack, }: {
|
|
6
12
|
name: string;
|
|
7
13
|
value: string;
|
|
8
14
|
expires?: Date | undefined;
|
|
9
|
-
} & CanTrack) => undefined
|
|
15
|
+
} & CanTrack) => Promise<undefined>;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { isBrowser } from '../functions/is-browser.js';
|
|
2
|
-
import '../types/can-track.js';
|
|
3
2
|
import { getTopLevelDomain } from './url.js';
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* NOTE: This function is `async` because its react-native override is async. Do not remove the `async` keyword!
|
|
5
|
+
*/
|
|
6
|
+
export const getCookie = async ({ name, canTrack, }) => {
|
|
5
7
|
try {
|
|
6
8
|
if (!canTrack) {
|
|
7
9
|
return undefined;
|
|
@@ -41,7 +43,10 @@ const createCookieString = ({ name, value, expires, }) => {
|
|
|
41
43
|
const cookie = stringifyCookie(cookieValue);
|
|
42
44
|
return cookie;
|
|
43
45
|
};
|
|
44
|
-
|
|
46
|
+
/**
|
|
47
|
+
* NOTE: This function is `async` because its react-native override is async. Do not remove the `async` keyword!
|
|
48
|
+
*/
|
|
49
|
+
export const setCookie = async ({ name, value, expires, canTrack, }) => {
|
|
45
50
|
try {
|
|
46
51
|
if (!canTrack) {
|
|
47
52
|
return undefined;
|