@builder.io/sdk-svelte 0.2.1 → 0.2.2

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@builder.io/sdk-svelte",
3
3
  "description": "Builder.io SDK for Svelte",
4
- "version": "0.2.0",
4
+ "version": "0.2.1",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "package",
@@ -128,6 +128,7 @@
128
128
  "./helpers/css": "./helpers/css.js",
129
129
  "./helpers/flatten": "./helpers/flatten.js",
130
130
  "./helpers/localStorage": "./helpers/localStorage.js",
131
+ "./helpers/logger": "./helpers/logger.js",
131
132
  "./helpers/nullable": "./helpers/nullable.js",
132
133
  "./helpers/sessionId": "./helpers/sessionId.js",
133
134
  "./helpers/time": "./helpers/time.js",
@@ -152,7 +153,7 @@
152
153
  "types": "./package/index.d.ts",
153
154
  "devDependencies": {
154
155
  "@sveltejs/adapter-auto": "1.0.0-next.71",
155
- "@sveltejs/kit": "1.0.0-next.474",
156
+ "@sveltejs/kit": "^1.15.2",
156
157
  "@sveltejs/package": "1.0.0-next.1",
157
158
  "svelte": "^3.44.0",
158
159
  "svelte-check": "^2.7.1",
@@ -1,3 +1,9 @@
1
+ ### 0.2.2
2
+
3
+ - Fix: dynamic bindings for Link URLs.
4
+ - Fix: previewing content that includes a symbol whose `model` property is a `page`.
5
+ - Fix: "Show If"/"Hide If" bindings when the initial value is `undefined`.
6
+
1
7
  ### 0.2.1
2
8
 
3
9
  - No Changes.
@@ -7,6 +7,7 @@ import { getContent } from "../../functions/get-content/index.js";
7
7
  import "../../types/builder-content.js";
8
8
  import "../../types/builder-block.js";
9
9
  import { TARGET } from "../../constants/target";
10
+ import { logger } from "../../helpers/logger";
10
11
  const isEvent = (attr) => attr.startsWith("on:");
11
12
  const isNonEvent = (attr) => !attr.startsWith("on:");
12
13
  const filterAttrs = (attrs = {}, filter) => {
@@ -66,7 +67,7 @@ function fetchContent() {
66
67
  }
67
68
  })
68
69
  .catch((err) => {
69
- console.error("[Builder.io]: Could not fetch symbol content: ", err);
70
+ logger.error("Could not fetch symbol content: ", err);
70
71
  });
71
72
  }
72
73
  }
@@ -14,7 +14,6 @@ import { TARGET } from "../../constants/target.js";
14
14
  import { extractTextStyles } from "../../functions/extract-text-styles.js";
15
15
  import RenderComponent from "./render-component.svelte";
16
16
  import { getReactNativeBlockStyles } from "../../functions/get-react-native-block-styles.js";
17
- import { checkIsDefined } from "../../helpers/nullable.js";
18
17
  const setAttrs = (node, attrs = {}) => {
19
18
  const attrKeys = Object.keys(attrs);
20
19
  const setup = (attr) => node.addEventListener(attr.substr(3), attrs[attr]);
@@ -44,10 +43,10 @@ $: useBlock = () => {
44
43
  });
45
44
  };
46
45
  $: canShowBlock = () => {
47
- if (checkIsDefined(useBlock().hide)) {
46
+ if ("hide" in useBlock()) {
48
47
  return !useBlock().hide;
49
48
  }
50
- if (checkIsDefined(useBlock().show)) {
49
+ if ("show" in useBlock()) {
51
50
  return useBlock().show;
52
51
  }
53
52
  return true;
@@ -20,6 +20,7 @@ import { getInteractionPropertiesForEvent } from "../../functions/track/interact
20
20
  import "./render-content.types.js";
21
21
  import { getContentInitialValue, getContextStateInitialValue, } from "./render-content.helpers.js";
22
22
  import { TARGET } from "../../constants/target.js";
23
+ import { logger } from "../../helpers/logger.js";
23
24
  export let content;
24
25
  export let data;
25
26
  export let canTrack;
@@ -198,7 +199,7 @@ let httpReqsData = {};
198
199
  let clicked = false;
199
200
  onMount(() => {
200
201
  if (!apiKey) {
201
- console.error("[Builder.io]: No API key provided to `RenderContent` component. This can cause issues. Please provide an API key using the `apiKey` prop.");
202
+ logger.error("No API key provided to `RenderContent` component. This can cause issues. Please provide an API key using the `apiKey` prop.");
202
203
  }
203
204
  if (isBrowser()) {
204
205
  if (isEditing()) {
@@ -237,20 +238,21 @@ onMount(() => {
237
238
  // override normal content in preview mode
238
239
  if (isPreviewing()) {
239
240
  const searchParams = new URL(location.href).searchParams;
240
- const searchParamPreview = searchParams.get("builder.preview");
241
+ const searchParamPreviewModel = searchParams.get("builder.preview");
242
+ const searchParamPreviewId = searchParams.get(`builder.preview.${searchParamPreviewModel}`);
241
243
  const previewApiKey = searchParams.get("apiKey") || searchParams.get("builder.space");
242
244
  /**
243
245
  * Make sure that:
244
246
  * - the preview model name is the same as the one we're rendering, since there can be multiple models rendered
245
247
  * at the same time, e.g. header/page/footer.
246
248
  * - the API key is the same, since we don't want to preview content from other organizations.
247
- *
248
- * TO-DO: should we check that the preview item ID is the same as the initial one being rendered? Or would
249
- * this break scenarios where the item is not published yet?
249
+ * - if there is content, that the preview ID is the same as that of the one we receive.
250
250
  *
251
251
  * TO-DO: should we only update the state when there is a change?
252
252
  **/
253
- if (searchParamPreview === model && previewApiKey === apiKey) {
253
+ if (searchParamPreviewModel === model &&
254
+ previewApiKey === apiKey &&
255
+ (!content || searchParamPreviewId === content.id)) {
254
256
  getContent({
255
257
  model: model,
256
258
  apiKey: apiKey,
@@ -3,4 +3,5 @@ export declare function getBlockProperties(block: BuilderBlock): {
3
3
  'builder-id': string | undefined;
4
4
  style: string | Partial<CSSStyleDeclaration> | undefined;
5
5
  class: string;
6
+ href: any;
6
7
  };
@@ -1,8 +1,39 @@
1
1
  import { TARGET } from '../constants/target.js';
2
2
  import { convertStyleMapToCSSArray } from '../helpers/css.js';
3
3
  import { transformBlockProperties } from './transform-block-properties.js';
4
+ const extractRelevantRootBlockProperties = (block) => {
5
+ // currently we are only spreading the `href` property
6
+ // TO-DO: potentially spread all properties from block, but only if they are not already defined by BuilderBlock
7
+ // const {
8
+ // '@type': _type,
9
+ // '@version': _version,
10
+ // id: _id,
11
+ // tagName: _tagName,
12
+ // layerName: _layerName,
13
+ // groupLocked: _groupLocked,
14
+ // layerLocked: _layerLocked,
15
+ // class: _class,
16
+ // children: _children,
17
+ // responsiveStyles: _responsiveStyles,
18
+ // component: _component,
19
+ // bindings: _bindings,
20
+ // meta: _meta,
21
+ // actions: _actions,
22
+ // properties: _properties,
23
+ // code: _code,
24
+ // repeat: _repeat,
25
+ // animations: _animations,
26
+ // style: _style,
27
+ // hide: _hide,
28
+ // show: _show,
29
+ // // anything set by dynamic bindings outside of predefined `BuilderBlock` properties
30
+ // ...remainingBlockProperties
31
+ // } = block;
32
+ return { href: block.href };
33
+ };
4
34
  export function getBlockProperties(block) {
5
35
  const properties = {
36
+ ...extractRelevantRootBlockProperties(block),
6
37
  ...block.properties,
7
38
  'builder-id': block.id,
8
39
  style: getStyleAttribute(block.style),
@@ -7,5 +7,5 @@ type ContentResponse = {
7
7
  status: number;
8
8
  message: string;
9
9
  };
10
- export declare function getAllContent(options: GetContentOptions): Promise<ContentResponse>;
10
+ export declare function getAllContent(options: GetContentOptions): Promise<ContentResponse | null>;
11
11
  export {};
@@ -1,33 +1,40 @@
1
+ import { logger } from '../../helpers/logger.js';
1
2
  import { fetch } from '../get-fetch.js';
2
3
  import { handleABTesting } from './ab-testing.js';
3
4
  import { generateContentUrl } from './generate-content-url.js';
4
5
  export async function getContent(options) {
5
6
  const allContent = await getAllContent({ ...options, limit: 1 });
6
- if ('results' in allContent) {
7
+ if (allContent && 'results' in allContent) {
7
8
  return allContent?.results[0] || null;
8
9
  }
9
10
  return null;
10
11
  }
11
12
  export async function getAllContent(options) {
12
- const url = generateContentUrl(options);
13
- const res = await fetch(url.href);
14
- const content = await res.json();
15
- if ('status' in content && !('results' in content)) {
16
- console.error('[Builder.io]: Error fetching data. ', content, options);
17
- return content;
18
- }
19
- const canTrack = options.canTrack !== false;
20
13
  try {
21
- if (canTrack &&
22
- // This makes sure we have a non-error response with the results array.
23
- Array.isArray(content.results)) {
24
- for (const item of content.results) {
25
- await handleABTesting({ item, canTrack });
14
+ const url = generateContentUrl(options);
15
+ const res = await fetch(url.href);
16
+ const content = await res.json();
17
+ if ('status' in content && !('results' in content)) {
18
+ logger.error('Error fetching data. ', content, options);
19
+ return content;
20
+ }
21
+ const canTrack = options.canTrack !== false;
22
+ try {
23
+ if (canTrack &&
24
+ // This makes sure we have a non-error response with the results array.
25
+ Array.isArray(content.results)) {
26
+ for (const item of content.results) {
27
+ await handleABTesting({ item, canTrack });
28
+ }
26
29
  }
27
30
  }
31
+ catch (e) {
32
+ logger.error('Could not setup A/B testing. ', e);
33
+ }
34
+ return content;
28
35
  }
29
- catch (e) {
30
- console.error('[Builder.io]: Could not setup A/B testing. ', e);
36
+ catch (error) {
37
+ logger.error('Error fetching data. ', error);
38
+ return null;
31
39
  }
32
- return content;
33
40
  }
@@ -1,4 +1,5 @@
1
1
  import { TARGET } from '../../constants/target.js';
2
+ import { logger } from '../../helpers/logger.js';
2
3
  import { getSessionId } from '../../helpers/sessionId.js';
3
4
  import { getVisitorId } from '../../helpers/visitorId.js';
4
5
  import { isBrowser } from '../is-browser.js';
@@ -30,7 +31,7 @@ const createEvent = async ({ type: eventType, canTrack, apiKey, metadata, ...pro
30
31
  });
31
32
  export async function _track(eventProps) {
32
33
  if (!eventProps.apiKey) {
33
- console.error('[Builder.io]: Missing API key for track call. Please provide your API key.');
34
+ logger.error('Missing API key for track call. Please provide your API key.');
34
35
  return;
35
36
  }
36
37
  if (!eventProps.canTrack) {
@@ -0,0 +1,5 @@
1
+ export declare const logger: {
2
+ log: (...message: any[]) => void;
3
+ error: (...message: any[]) => void;
4
+ warn: (...message: any[]) => void;
5
+ };
@@ -0,0 +1,6 @@
1
+ const MSG_PREFIX = '[Builder.io]: ';
2
+ export const logger = {
3
+ log: (...message) => console.log(MSG_PREFIX, ...message),
4
+ error: (...message) => console.error(MSG_PREFIX, ...message),
5
+ warn: (...message) => console.warn(MSG_PREFIX, ...message),
6
+ };
@@ -1,5 +1,5 @@
1
1
  import type { BuilderBlock } from './builder-block.js';
2
- import type { Input } from './components.js';
2
+ import type { Input } from './input.js';
3
3
  import type { Nullable } from './typescript.js';
4
4
  export interface Breakpoints {
5
5
  small: number;
@@ -1,76 +1,5 @@
1
1
  import type { BuilderElement } from './element';
2
- export interface Input {
3
- name: string;
4
- friendlyName?: string;
5
- description?: string;
6
- defaultValue?: any;
7
- type: string;
8
- valueType?: {
9
- type?: string;
10
- };
11
- required?: boolean;
12
- autoFocus?: boolean;
13
- subFields?: Input[];
14
- helperText?: string;
15
- allowedFileTypes?: string[];
16
- imageHeight?: number;
17
- imageWidth?: number;
18
- mediaHeight?: number;
19
- mediaWidth?: number;
20
- hideFromUI?: boolean;
21
- modelId?: string;
22
- /**
23
- * Number field type validation maximum accepted input
24
- */
25
- max?: number;
26
- /**
27
- * Number field type validation minimum accepted input
28
- */
29
- min?: number;
30
- /**
31
- * Number field type step size when using arrows
32
- */
33
- step?: number;
34
- /**
35
- * Set this to `true` to show the editor for this input when
36
- * children of this component are selected. This is useful for things
37
- * like Tabs, such that users may not always select the Tabs component
38
- * directly but will still be looking for how to add additional tabs
39
- */
40
- broadcast?: boolean;
41
- /**
42
- * Set this to `true` to show the editor for this input when
43
- * group locked parents of this component are selected. This is useful
44
- * to bubble up important inputs for locked groups, like text and images
45
- */
46
- bubble?: boolean;
47
- options?: {
48
- [key: string]: any;
49
- };
50
- enum?: string[] | {
51
- label: string;
52
- value: any;
53
- helperText?: string;
54
- }[];
55
- /** Regex field validation for all string types (text, longText, html, url, etc) */
56
- regex?: {
57
- /** pattern to test, like "^\/[a-z]$" */
58
- pattern: string;
59
- /** flags for the RegExp constructor, e.g. "gi" */
60
- options?: string;
61
- /**
62
- * Friendly message to display to end-users if the regex fails, e.g.
63
- * "You must use a relative url starting with '/...' "
64
- */
65
- message: string;
66
- };
67
- advanced?: boolean;
68
- onChange?: ((options: Map<string, any>) => void | Promise<void>) | string;
69
- code?: boolean;
70
- richText?: boolean;
71
- showIf?: ((options: Map<string, any>) => boolean) | string;
72
- copyOnAdd?: boolean;
73
- }
2
+ import type { Input } from './input';
74
3
  export interface ComponentInfo {
75
4
  /**
76
5
  * Name your component something unique, e.g. 'MyButton'. You can override built-in components
@@ -114,4 +114,8 @@ export interface Input {
114
114
  * Use optionally with inputs of type `reference`. Restricts the content entry picker to a specific model by name.
115
115
  */
116
116
  model?: string;
117
+ valueType?: {
118
+ type?: string;
119
+ };
120
+ onChange?: ((options: Map<string, any>) => void | Promise<void>) | string;
117
121
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@builder.io/sdk-svelte",
3
3
  "description": "Builder.io SDK for Svelte",
4
- "version": "0.2.1",
4
+ "version": "0.2.2",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "package",
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "devDependencies": {
41
41
  "@sveltejs/adapter-auto": "1.0.0-next.71",
42
- "@sveltejs/kit": "1.0.0-next.474",
42
+ "@sveltejs/kit": "^1.15.2",
43
43
  "@sveltejs/package": "1.0.0-next.1",
44
44
  "svelte": "^3.44.0",
45
45
  "svelte-check": "^2.7.1",
@@ -27,6 +27,7 @@
27
27
  import { BuilderContent } from "../../types/builder-content.js";
28
28
  import { BuilderBlock } from "../../types/builder-block.js";
29
29
  import { TARGET } from "../../constants/target";
30
+ import { logger } from "../../helpers/logger";
30
31
 
31
32
  const isEvent = (attr) => attr.startsWith("on:");
32
33
  const isNonEvent = (attr) => !attr.startsWith("on:");
@@ -93,7 +94,7 @@
93
94
  }
94
95
  })
95
96
  .catch((err) => {
96
- console.error("[Builder.io]: Could not fetch symbol content: ", err);
97
+ logger.error("Could not fetch symbol content: ", err);
97
98
  });
98
99
  }
99
100
  }
@@ -25,7 +25,6 @@
25
25
  import { extractTextStyles } from "../../functions/extract-text-styles.js";
26
26
  import RenderComponent from "./render-component.svelte";
27
27
  import { getReactNativeBlockStyles } from "../../functions/get-react-native-block-styles.js";
28
- import { checkIsDefined } from "../../helpers/nullable.js";
29
28
 
30
29
  const setAttrs = (node, attrs = {}) => {
31
30
  const attrKeys = Object.keys(attrs);
@@ -59,10 +58,10 @@
59
58
  });
60
59
  };
61
60
  $: canShowBlock = () => {
62
- if (checkIsDefined(useBlock().hide)) {
61
+ if ("hide" in useBlock()) {
63
62
  return !useBlock().hide;
64
63
  }
65
- if (checkIsDefined(useBlock().show)) {
64
+ if ("show" in useBlock()) {
66
65
  return useBlock().show;
67
66
  }
68
67
  return true;
@@ -38,6 +38,7 @@
38
38
  getContextStateInitialValue,
39
39
  } from "./render-content.helpers.js";
40
40
  import { TARGET } from "../../constants/target.js";
41
+ import { logger } from "../../helpers/logger.js";
41
42
 
42
43
  export let content: RenderContentProps["content"];
43
44
  export let data: RenderContentProps["data"];
@@ -236,8 +237,8 @@
236
237
 
237
238
  onMount(() => {
238
239
  if (!apiKey) {
239
- console.error(
240
- "[Builder.io]: No API key provided to `RenderContent` component. This can cause issues. Please provide an API key using the `apiKey` prop."
240
+ logger.error(
241
+ "No API key provided to `RenderContent` component. This can cause issues. Please provide an API key using the `apiKey` prop."
241
242
  );
242
243
  }
243
244
  if (isBrowser()) {
@@ -283,7 +284,10 @@
283
284
  // override normal content in preview mode
284
285
  if (isPreviewing()) {
285
286
  const searchParams = new URL(location.href).searchParams;
286
- const searchParamPreview = searchParams.get("builder.preview");
287
+ const searchParamPreviewModel = searchParams.get("builder.preview");
288
+ const searchParamPreviewId = searchParams.get(
289
+ `builder.preview.${searchParamPreviewModel}`
290
+ );
287
291
  const previewApiKey =
288
292
  searchParams.get("apiKey") || searchParams.get("builder.space");
289
293
 
@@ -292,13 +296,15 @@
292
296
  * - the preview model name is the same as the one we're rendering, since there can be multiple models rendered
293
297
  * at the same time, e.g. header/page/footer.
294
298
  * - the API key is the same, since we don't want to preview content from other organizations.
295
- *
296
- * TO-DO: should we check that the preview item ID is the same as the initial one being rendered? Or would
297
- * this break scenarios where the item is not published yet?
299
+ * - if there is content, that the preview ID is the same as that of the one we receive.
298
300
  *
299
301
  * TO-DO: should we only update the state when there is a change?
300
302
  **/
301
- if (searchParamPreview === model && previewApiKey === apiKey) {
303
+ if (
304
+ searchParamPreviewModel === model &&
305
+ previewApiKey === apiKey &&
306
+ (!content || searchParamPreviewId === content.id)
307
+ ) {
302
308
  getContent({
303
309
  model: model,
304
310
  apiKey: apiKey,
@@ -3,8 +3,42 @@ import { convertStyleMapToCSSArray } from '../helpers/css.js';
3
3
  import type { BuilderBlock } from '../types/builder-block.js';
4
4
  import { transformBlockProperties } from './transform-block-properties.js';
5
5
 
6
+ const extractRelevantRootBlockProperties = (block: BuilderBlock) => {
7
+ // currently we are only spreading the `href` property
8
+ // TO-DO: potentially spread all properties from block, but only if they are not already defined by BuilderBlock
9
+
10
+ // const {
11
+ // '@type': _type,
12
+ // '@version': _version,
13
+ // id: _id,
14
+ // tagName: _tagName,
15
+ // layerName: _layerName,
16
+ // groupLocked: _groupLocked,
17
+ // layerLocked: _layerLocked,
18
+ // class: _class,
19
+ // children: _children,
20
+ // responsiveStyles: _responsiveStyles,
21
+ // component: _component,
22
+ // bindings: _bindings,
23
+ // meta: _meta,
24
+ // actions: _actions,
25
+ // properties: _properties,
26
+ // code: _code,
27
+ // repeat: _repeat,
28
+ // animations: _animations,
29
+ // style: _style,
30
+ // hide: _hide,
31
+ // show: _show,
32
+ // // anything set by dynamic bindings outside of predefined `BuilderBlock` properties
33
+ // ...remainingBlockProperties
34
+ // } = block;
35
+
36
+ return { href: (block as any).href };
37
+ };
38
+
6
39
  export function getBlockProperties(block: BuilderBlock) {
7
40
  const properties = {
41
+ ...extractRelevantRootBlockProperties(block),
8
42
  ...block.properties,
9
43
  'builder-id': block.id,
10
44
  style: getStyleAttribute(block.style),
@@ -1,3 +1,4 @@
1
+ import { logger } from '../../helpers/logger.js';
1
2
  import type { BuilderContent } from '../../types/builder-content.js';
2
3
  import { fetch } from '../get-fetch.js';
3
4
  import { handleABTesting } from './ab-testing.js';
@@ -8,7 +9,7 @@ export async function getContent(
8
9
  options: GetContentOptions
9
10
  ): Promise<BuilderContent | null> {
10
11
  const allContent = await getAllContent({ ...options, limit: 1 });
11
- if ('results' in allContent) {
12
+ if (allContent && 'results' in allContent) {
12
13
  return allContent?.results[0] || null;
13
14
  }
14
15
 
@@ -26,31 +27,36 @@ type ContentResponse =
26
27
 
27
28
  export async function getAllContent(
28
29
  options: GetContentOptions
29
- ): Promise<ContentResponse> {
30
- const url = generateContentUrl(options);
30
+ ): Promise<ContentResponse | null> {
31
+ try {
32
+ const url = generateContentUrl(options);
31
33
 
32
- const res = await fetch(url.href);
33
- const content = await (res.json() as Promise<ContentResponse>);
34
+ const res = await fetch(url.href);
35
+ const content = await (res.json() as Promise<ContentResponse>);
34
36
 
35
- if ('status' in content && !('results' in content)) {
36
- console.error('[Builder.io]: Error fetching data. ', content, options);
37
- return content;
38
- }
37
+ if ('status' in content && !('results' in content)) {
38
+ logger.error('Error fetching data. ', content, options);
39
+ return content;
40
+ }
39
41
 
40
- const canTrack = options.canTrack !== false;
41
- try {
42
- if (
43
- canTrack &&
44
- // This makes sure we have a non-error response with the results array.
45
- Array.isArray(content.results)
46
- ) {
47
- for (const item of content.results) {
48
- await handleABTesting({ item, canTrack });
42
+ const canTrack = options.canTrack !== false;
43
+ try {
44
+ if (
45
+ canTrack &&
46
+ // This makes sure we have a non-error response with the results array.
47
+ Array.isArray(content.results)
48
+ ) {
49
+ for (const item of content.results) {
50
+ await handleABTesting({ item, canTrack });
51
+ }
49
52
  }
53
+ } catch (e) {
54
+ logger.error('Could not setup A/B testing. ', e);
50
55
  }
51
- } catch (e) {
52
- console.error('[Builder.io]: Could not setup A/B testing. ', e);
53
- }
54
56
 
55
- return content;
57
+ return content;
58
+ } catch (error) {
59
+ logger.error('Error fetching data. ', error);
60
+ return null;
61
+ }
56
62
  }
@@ -1,6 +1,7 @@
1
1
  import { serializeFn } from '../blocks/util.js';
2
2
  import type { RegisteredComponent } from '../context/types.js';
3
- import type { ComponentInfo, Input } from '../types/components.js';
3
+ import type { ComponentInfo } from '../types/components.js';
4
+ import type { Input } from '../types/input.js';
4
5
  import { fastClone } from './fast-clone.js';
5
6
 
6
7
  /**
@@ -37,14 +38,13 @@ const prepareComponentInfoToSend = ({
37
38
  ...info
38
39
  }: ComponentInfo): ComponentInfo => ({
39
40
  ...fastClone(info),
40
- inputs: inputs?.map(
41
- (input): Input =>
42
- Object.entries(input).reduce(
43
- (acc, [key, value]) => ({
44
- ...acc,
45
- [key]: serializeValue(value),
46
- }),
47
- {} as Input
48
- )
41
+ inputs: inputs?.map((input) =>
42
+ Object.entries(input).reduce(
43
+ (acc, [key, value]) => ({
44
+ ...acc,
45
+ [key]: serializeValue(value),
46
+ }),
47
+ {} as Input
48
+ )
49
49
  ),
50
50
  });
@@ -1,4 +1,5 @@
1
1
  import { TARGET } from '../../constants/target.js';
2
+ import { logger } from '../../helpers/logger.js';
2
3
  import { getSessionId } from '../../helpers/sessionId.js';
3
4
  import { getVisitorId } from '../../helpers/visitorId.js';
4
5
  import type { CanTrack } from '../../types/can-track.js';
@@ -100,8 +101,8 @@ const createEvent = async ({
100
101
 
101
102
  export async function _track(eventProps: EventProps) {
102
103
  if (!eventProps.apiKey) {
103
- console.error(
104
- '[Builder.io]: Missing API key for track call. Please provide your API key.'
104
+ logger.error(
105
+ 'Missing API key for track call. Please provide your API key.'
105
106
  );
106
107
  return;
107
108
  }
@@ -0,0 +1,6 @@
1
+ const MSG_PREFIX = '[Builder.io]: ';
2
+ export const logger = {
3
+ log: (...message: any[]) => console.log(MSG_PREFIX, ...message),
4
+ error: (...message: any[]) => console.error(MSG_PREFIX, ...message),
5
+ warn: (...message: any[]) => console.warn(MSG_PREFIX, ...message),
6
+ };
@@ -1,5 +1,5 @@
1
1
  import type { BuilderBlock } from './builder-block.js';
2
- import type { Input } from './components.js';
2
+ import type { Input } from './input.js';
3
3
  import type { Nullable } from './typescript.js';
4
4
 
5
5
  export interface Breakpoints {
@@ -1,72 +1,5 @@
1
1
  import type { BuilderElement } from './element';
2
-
3
- export interface Input {
4
- name: string;
5
- friendlyName?: string;
6
- description?: string;
7
- defaultValue?: any;
8
- type: string;
9
- valueType?: {
10
- type?: string;
11
- };
12
- required?: boolean;
13
- autoFocus?: boolean;
14
- subFields?: Input[];
15
- helperText?: string;
16
- allowedFileTypes?: string[];
17
- imageHeight?: number;
18
- imageWidth?: number;
19
- mediaHeight?: number;
20
- mediaWidth?: number;
21
- hideFromUI?: boolean;
22
- modelId?: string;
23
- /**
24
- * Number field type validation maximum accepted input
25
- */
26
- max?: number;
27
- /**
28
- * Number field type validation minimum accepted input
29
- */
30
- min?: number;
31
- /**
32
- * Number field type step size when using arrows
33
- */
34
- step?: number;
35
-
36
- /**
37
- * Set this to `true` to show the editor for this input when
38
- * children of this component are selected. This is useful for things
39
- * like Tabs, such that users may not always select the Tabs component
40
- * directly but will still be looking for how to add additional tabs
41
- */
42
- broadcast?: boolean;
43
- /**
44
- * Set this to `true` to show the editor for this input when
45
- * group locked parents of this component are selected. This is useful
46
- * to bubble up important inputs for locked groups, like text and images
47
- */
48
- bubble?: boolean;
49
- options?: { [key: string]: any };
50
- enum?: string[] | { label: string; value: any; helperText?: string }[];
51
- /** Regex field validation for all string types (text, longText, html, url, etc) */
52
- regex?: {
53
- /** pattern to test, like "^\/[a-z]$" */
54
- pattern: string;
55
- /** flags for the RegExp constructor, e.g. "gi" */
56
- options?: string;
57
- /**
58
- * Friendly message to display to end-users if the regex fails, e.g.
59
- * "You must use a relative url starting with '/...' "
60
- */
61
- message: string;
62
- };
63
- advanced?: boolean;
64
- onChange?: ((options: Map<string, any>) => void | Promise<void>) | string;
65
- code?: boolean;
66
- richText?: boolean;
67
- showIf?: ((options: Map<string, any>) => boolean) | string;
68
- copyOnAdd?: boolean;
69
- }
2
+ import type { Input } from './input';
70
3
 
71
4
  export interface ComponentInfo {
72
5
  /**
@@ -117,4 +117,9 @@ export interface Input {
117
117
  * Use optionally with inputs of type `reference`. Restricts the content entry picker to a specific model by name.
118
118
  */
119
119
  model?: string;
120
+
121
+ valueType?: {
122
+ type?: string;
123
+ };
124
+ onChange?: ((options: Map<string, any>) => void | Promise<void>) | string;
120
125
  }