Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix[gen2][builderStudio] ENG-7646 add Builder Studio support for Gen-2 SDK #3794

Merged
merged 9 commits into from
Jan 13, 2025
12 changes: 12 additions & 0 deletions .changeset/fast-jars-kiss.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"@builder.io/sdk-angular": patch
"@builder.io/sdk-react-nextjs": patch
"@builder.io/sdk-qwik": patch
"@builder.io/sdk-react": patch
"@builder.io/sdk-react-native": patch
"@builder.io/sdk-solid": patch
"@builder.io/sdk-svelte": patch
"@builder.io/sdk-vue": patch
---

Fix: previewing Gen2 SDK content within the Studio tab of the Builder Visual Editor.
Original file line number Diff line number Diff line change
Expand Up @@ -315,14 +315,19 @@ export default function EnableEditor(props: BuilderEditorProps) {
* TO-DO: should we only update the state when there is a change?
**/
if (
searchParamPreviewModel === props.model &&
previewApiKey === props.apiKey &&
(!props.content || searchParamPreviewId === props.content.id)
searchParamPreviewModel === 'BUILDER_STUDIO' ||
(searchParamPreviewModel === props.model &&
previewApiKey === props.apiKey &&
(!props.content || searchParamPreviewId === props.content.id))
) {
fetchOneEntry({
model: props.model,
model: props.model || '',
apiKey: props.apiKey,
apiVersion: props.builderContextSignal.value.apiVersion,
...(searchParamPreviewModel === 'BUILDER_STUDIO' &&
props.context?.symbolId
? { query: { id: props.context.symbolId } }
: {}),
}).then((content) => {
if (content) {
state.mergeNewContent(content);
Expand Down
40 changes: 37 additions & 3 deletions packages/sdks/src/functions/get-content/generate-content-url.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { flatten, flattenMongoQuery } from '../../helpers/flatten.js';
import {
flatten,
flattenMongoQuery,
unflatten,
} from '../../helpers/flatten.js';
import { normalizeSearchParams } from '../../helpers/search/search.js';
import { DEFAULT_API_VERSION } from '../../types/api-version.js';
import { getBuilderSearchParamsFromWindow } from '../get-builder-search-params/index.js';
import { isBrowser } from '../is-browser.js';
import type { GetContentOptions } from './types.js';

const isPositiveNumber = (thing: unknown) =>
Expand Down Expand Up @@ -49,7 +54,7 @@ export const generateContentUrl = (options: GetContentOptions): URL => {
url.searchParams.set('includeRefs', String(true));

const finalLocale = locale || userAttributes?.locale;
let finalUserAttributes = userAttributes;
let finalUserAttributes: Record<string, any> = userAttributes || {};

if (finalLocale) {
url.searchParams.set('locale', finalLocale);
Expand Down Expand Up @@ -96,12 +101,17 @@ export const generateContentUrl = (options: GetContentOptions): URL => {
...normalizeSearchParams(options.options || {}),
};

finalUserAttributes = {
...finalUserAttributes,
...getUserAttributesAsJSON(queryOptions),
};

const flattened = flatten(queryOptions);
for (const key in flattened) {
url.searchParams.set(key, String(flattened[key]));
}

if (finalUserAttributes) {
if (Object.keys(finalUserAttributes).length > 0) {
url.searchParams.set('userAttributes', JSON.stringify(finalUserAttributes));
}
if (query) {
Expand All @@ -112,3 +122,27 @@ export const generateContentUrl = (options: GetContentOptions): URL => {
}
return url;
};

const getUserAttributesFromQueryOptions = (queryOptions: any) => {
const newUserAttributes: any = {};
for (const key in queryOptions) {
if (key.startsWith('userAttributes.')) {
newUserAttributes[key] = queryOptions[key];
delete queryOptions[key];
}
}
return newUserAttributes;
};

const getUserAttributesAsJSON = (queryOptions: any) => {
if (isBrowser() && queryOptions['preview'] === 'BUILDER_STUDIO') {
queryOptions['userAttributes.urlPath'] = window.location.pathname;
queryOptions['userAttributes.host'] = window.location.host;

Comment on lines +139 to +140
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this how we handle on gen1 as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's a loom explaining how it's happening on Gen1 SDK https://www.loom.com/share/83bd96e1d6a743639e67165c272765df

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for explaining!

const queryOptionsForUserAttributes =
getUserAttributesFromQueryOptions(queryOptions);
const { userAttributes } = unflatten(queryOptionsForUserAttributes);
return userAttributes;
}
return {};
};
23 changes: 23 additions & 0 deletions packages/sdks/src/helpers/flatten.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,26 @@ export function flattenMongoQuery(
}
return _res;
}

/**
* Unflatten a flat object with dot-separated keys back into a nested object.
*
* { 'foo.bar': 'baz' } -> { foo: { bar: 'baz' }}
*/
export function unflatten(obj: any): any {
const result: any = {};
for (const key in obj) {
const parts = key.split('.');
let current = result;
for (let i = 0; i < parts.length; i++) {
const part = parts[i];
if (i === parts.length - 1) {
current[part] = obj[key];
} else {
current[part] = current[part] || {};
current = current[part];
}
}
}
return result;
}
Loading