@uniformdev/canvas-next-rsc 19.173.1-alpha.17 → 19.173.2-alpha.210
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/dist/UniformComposition-0pvEHduc.d.mts +64 -0
- package/dist/UniformComposition-0pvEHduc.d.ts +77 -0
- package/dist/UniformComposition-38e22896.d.ts +74 -0
- package/dist/UniformComposition-B-Z17dUt.d.ts +56 -43
- package/dist/UniformComposition-D4tBQ2U4.d.mts +64 -0
- package/dist/UniformComposition-D4tBQ2U4.d.ts +77 -0
- package/dist/UniformComposition-Dw55RFP6.d.mts +67 -0
- package/dist/UniformComposition-Dw55RFP6.d.ts +67 -0
- package/dist/UniformComposition-d178d865.d.ts +77 -0
- package/dist/actions/updateContext.d.ts +2 -0
- package/dist/actions/updateContext.js +17 -0
- package/dist/client/canvasClient.d.ts +5 -0
- package/dist/client/canvasClient.js +53 -0
- package/dist/client/manifestClient.d.ts +209 -0
- package/dist/client/manifestClient.js +33 -0
- package/dist/client/projectMapClient.d.ts +5 -0
- package/dist/client/projectMapClient.js +17 -0
- package/dist/client/routeClient.d.ts +5 -0
- package/dist/client/routeClient.js +68 -0
- package/dist/component.d.mts +23 -5
- package/dist/component.d.ts +23 -5
- package/dist/component.js +67 -25
- package/dist/component.mjs +66 -23
- package/dist/components/DefaultNotImplementedComponent.d.ts +4 -0
- package/dist/components/DefaultNotImplementedComponent.js +45 -0
- package/dist/components/GoogleTagManagerAnalytics.d.ts +3 -0
- package/dist/components/GoogleTagManagerAnalytics.js +44 -0
- package/dist/components/UniformComponent.d.ts +35 -0
- package/dist/components/UniformComponent.js +14 -0
- package/dist/components/UniformComposition.d.ts +47 -0
- package/dist/components/UniformComposition.js +35 -0
- package/dist/components/UniformContext.d.ts +13 -0
- package/dist/components/UniformContext.js +19 -0
- package/dist/components/UniformRichText.d.ts +42 -0
- package/dist/components/UniformRichText.js +15 -0
- package/dist/components/UniformRichTextNode.d.ts +14 -0
- package/dist/components/UniformRichTextNode.js +49 -0
- package/dist/components/UniformScript.d.ts +5 -0
- package/dist/components/UniformScript.js +49 -0
- package/dist/components/UniformSlot.d.ts +48 -0
- package/dist/components/UniformSlot.js +38 -0
- package/dist/components/UniformText.d.ts +10 -0
- package/dist/components/UniformText.js +5 -0
- package/dist/components/__tests__/evaluateComposition.spec.d.ts +1 -0
- package/dist/components/__tests__/evaluateComposition.spec.js +80 -0
- package/dist/components/convertComponentToProps.d.ts +18 -0
- package/dist/components/convertComponentToProps.js +22 -0
- package/dist/components/evaluateComposition.d.ts +32 -0
- package/dist/components/evaluateComposition.js +183 -0
- package/dist/components/getEnrichmentTags.d.ts +5 -0
- package/dist/components/getEnrichmentTags.js +13 -0
- package/dist/components/getUniformContext.d.ts +10 -0
- package/dist/components/getUniformContext.js +17 -0
- package/dist/components/nodes/HeadingRichTextNode.d.ts +2 -0
- package/dist/components/nodes/HeadingRichTextNode.js +6 -0
- package/dist/components/nodes/LinebreakRichTextNode.d.ts +2 -0
- package/dist/components/nodes/LinebreakRichTextNode.js +4 -0
- package/dist/components/nodes/LinkRichTextNode.d.ts +2 -0
- package/dist/components/nodes/LinkRichTextNode.js +6 -0
- package/dist/components/nodes/ListItemRichTextNode.d.ts +2 -0
- package/dist/components/nodes/ListItemRichTextNode.js +5 -0
- package/dist/components/nodes/ListRichTextNode.d.ts +2 -0
- package/dist/components/nodes/ListRichTextNode.js +6 -0
- package/dist/components/nodes/ParagraphRichTextNode.d.ts +2 -0
- package/dist/components/nodes/ParagraphRichTextNode.js +6 -0
- package/dist/components/nodes/TabRichTextNode.d.ts +2 -0
- package/dist/components/nodes/TabRichTextNode.js +4 -0
- package/dist/components/nodes/TextRichTextNode.d.ts +2 -0
- package/dist/components/nodes/TextRichTextNode.js +9 -0
- package/dist/components/renderComponent.d.ts +26 -0
- package/dist/components/renderComponent.js +52 -0
- package/dist/components/resolvePath.d.ts +5 -0
- package/dist/components/resolvePath.js +34 -0
- package/dist/components/retrieveRoute.d.ts +198 -0
- package/dist/components/retrieveRoute.js +146 -0
- package/dist/components/types.d.ts +15 -0
- package/dist/components/types.js +1 -0
- package/dist/config/helpers.d.ts +23 -0
- package/dist/config/helpers.js +34 -0
- package/dist/config/models.d.ts +51 -0
- package/dist/config/models.js +1 -0
- package/dist/config/uniform.server.config.d.ts +3 -0
- package/dist/config/uniform.server.config.js +4 -0
- package/dist/cookie/index.d.ts +12 -0
- package/dist/cookie/index.js +21 -0
- package/dist/handler/createPreviewGETRouteHandler.d.ts +1 -0
- package/dist/handler/createPreviewGETRouteHandler.js +43 -0
- package/dist/handler/createPreviewPOSTRouteHandler.d.ts +1 -0
- package/dist/handler/createPreviewPOSTRouteHandler.js +88 -0
- package/dist/handler/createUniformRouteHandler.d.ts +4 -0
- package/dist/handler/createUniformRouteHandler.js +10 -0
- package/dist/handler/helpers.d.ts +17 -0
- package/dist/handler/helpers.js +148 -0
- package/dist/handler/messages/handleCompositionChanged.d.ts +2 -0
- package/dist/handler/messages/handleCompositionChanged.js +9 -0
- package/dist/handler/messages/handleCompositionDeleted.d.ts +2 -0
- package/dist/handler/messages/handleCompositionDeleted.js +9 -0
- package/dist/handler/messages/handleCompositionPublished.d.ts +2 -0
- package/dist/handler/messages/handleCompositionPublished.js +9 -0
- package/dist/handler/messages/handleManifestPublished.d.ts +2 -0
- package/dist/handler/messages/handleManifestPublished.js +10 -0
- package/dist/handler/messages/handleProjectMapNodeDelete.d.ts +2 -0
- package/dist/handler/messages/handleProjectMapNodeDelete.js +21 -0
- package/dist/handler/messages/handleProjectMapNodeInsert.d.ts +2 -0
- package/dist/handler/messages/handleProjectMapNodeInsert.js +21 -0
- package/dist/handler/messages/handleProjectMapNodeUpdate.d.ts +2 -0
- package/dist/handler/messages/handleProjectMapNodeUpdate.js +22 -0
- package/dist/handler/messages/handleRedirectDelete.d.ts +2 -0
- package/dist/handler/messages/handleRedirectDelete.js +15 -0
- package/dist/handler/messages/handleRedirectInsert.d.ts +2 -0
- package/dist/handler/messages/handleRedirectInsert.js +15 -0
- package/dist/handler/messages/handleRedirectUpdate.d.ts +2 -0
- package/dist/handler/messages/handleRedirectUpdate.js +15 -0
- package/dist/handler.js +2 -1
- package/dist/handler.mjs +2 -1
- package/dist/hooks/useForgetMe.d.ts +4 -0
- package/dist/hooks/useForgetMe.js +10 -0
- package/dist/hooks/useToggleConsent.d.ts +7 -0
- package/dist/hooks/useToggleConsent.js +22 -0
- package/dist/hooks/useUniformContext.d.ts +1 -0
- package/dist/hooks/useUniformContext.js +3 -0
- package/dist/index.d.mts +38 -38
- package/dist/index.d.ts +38 -38
- package/dist/index.esm.js +51 -19
- package/dist/index.js +78 -50
- package/dist/index.mjs +51 -19
- package/dist/models/index.d.ts +30 -0
- package/dist/models/index.js +1 -0
- package/dist/register/componentStore.d.ts +1 -0
- package/dist/register/componentStore.js +2 -0
- package/dist/register/componentStoreResolver.d.ts +4 -0
- package/dist/register/componentStoreResolver.js +5 -0
- package/dist/register/createComponentStore.d.ts +12 -0
- package/dist/register/createComponentStore.js +13 -0
- package/dist/register/createComponentStoreResolver.d.ts +12 -0
- package/dist/register/createComponentStoreResolver.js +9 -0
- package/dist/register/getTypeWithVariant.d.ts +1 -0
- package/dist/register/getTypeWithVariant.js +1 -0
- package/dist/register/registerUniformComponent.d.ts +10 -0
- package/dist/register/registerUniformComponent.js +8 -0
- package/dist/resolve/resolveChildren.d.ts +17 -0
- package/dist/resolve/resolveChildren.js +20 -0
- package/dist/score/index.d.ts +3 -0
- package/dist/score/index.js +114 -0
- package/dist/utils/__tests__/apply.spec.d.ts +1 -0
- package/dist/utils/__tests__/apply.spec.js +358 -0
- package/dist/utils/__tests__/diff.spec.d.ts +1 -0
- package/dist/utils/__tests__/diff.spec.js +394 -0
- package/dist/utils/apply.d.ts +10 -0
- package/dist/utils/apply.js +124 -0
- package/dist/utils/comp.d.ts +25 -0
- package/dist/utils/comp.js +65 -0
- package/dist/utils/diff.d.ts +58 -0
- package/dist/utils/diff.js +144 -0
- package/dist/utils/draft.d.ts +20 -0
- package/dist/utils/draft.js +22 -0
- package/dist/utils/tag.d.ts +2 -0
- package/dist/utils/tag.js +7 -0
- package/dist/utils/url.d.ts +1 -0
- package/dist/utils/url.js +10 -0
- package/package.json +20 -20
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { createElement as _createElement } from "react";
|
|
3
|
+
import { isRichTextNode } from '@uniformdev/richtext';
|
|
4
|
+
import { HeadingRichTextNode } from './nodes/HeadingRichTextNode';
|
|
5
|
+
import { LinebreakRichTextNode } from './nodes/LinebreakRichTextNode';
|
|
6
|
+
import { LinkRichTextNode } from './nodes/LinkRichTextNode';
|
|
7
|
+
import { ListItemRichTextNode } from './nodes/ListItemRichTextNode';
|
|
8
|
+
import { ListRichTextNode } from './nodes/ListRichTextNode';
|
|
9
|
+
import { ParagraphRichTextNode } from './nodes/ParagraphRichTextNode';
|
|
10
|
+
import { TabRichTextNode } from './nodes/TabRichTextNode';
|
|
11
|
+
import { TextRichTextNode } from './nodes/TextRichTextNode';
|
|
12
|
+
/**
|
|
13
|
+
* Render a single RichText node
|
|
14
|
+
*/
|
|
15
|
+
export function UniformRichTextNode({ node, ...props }) {
|
|
16
|
+
var _a;
|
|
17
|
+
if (!isRichTextNode(node))
|
|
18
|
+
return null;
|
|
19
|
+
let NodeRenderer = (_a = props.resolveRichTextRenderer) === null || _a === void 0 ? void 0 : _a.call(props, node);
|
|
20
|
+
if (typeof NodeRenderer === 'undefined') {
|
|
21
|
+
NodeRenderer = resolveRichTextDefaultRenderer(node);
|
|
22
|
+
}
|
|
23
|
+
if (!NodeRenderer) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
const children = node.children
|
|
27
|
+
? node.children.map((childNode, i) => _createElement(UniformRichTextNode, { ...props, key: i, node: childNode }))
|
|
28
|
+
: null;
|
|
29
|
+
return _jsx(NodeRenderer, { node: node, children: children });
|
|
30
|
+
}
|
|
31
|
+
const rendererMap = new Map([
|
|
32
|
+
['heading', HeadingRichTextNode],
|
|
33
|
+
['linebreak', LinebreakRichTextNode],
|
|
34
|
+
['link', LinkRichTextNode],
|
|
35
|
+
['list', ListRichTextNode],
|
|
36
|
+
['listitem', ListItemRichTextNode],
|
|
37
|
+
['paragraph', ParagraphRichTextNode],
|
|
38
|
+
['quote', ({ children }) => _jsx("blockquote", { children: children })],
|
|
39
|
+
[
|
|
40
|
+
'code',
|
|
41
|
+
({ children }) => (_jsx("pre", { children: _jsx("code", { children: children }) })),
|
|
42
|
+
],
|
|
43
|
+
['root', ({ children }) => _jsx(_Fragment, { children: children })],
|
|
44
|
+
['text', TextRichTextNode],
|
|
45
|
+
['tab', TabRichTextNode],
|
|
46
|
+
]);
|
|
47
|
+
const resolveRichTextDefaultRenderer = (node) => {
|
|
48
|
+
return rendererMap.get(node.type);
|
|
49
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { createCanvasChannel } from '@uniformdev/canvas';
|
|
4
|
+
import { useRouter } from 'next/navigation';
|
|
5
|
+
import { useEffect, useMemo } from 'react';
|
|
6
|
+
export const UniformScript = ({ enabled }) => {
|
|
7
|
+
const router = useRouter();
|
|
8
|
+
const channel = useMemo(() => {
|
|
9
|
+
var _a;
|
|
10
|
+
if (typeof window === 'undefined') {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const instance = createCanvasChannel({
|
|
14
|
+
broadcastTo: [(_a = window.opener) !== null && _a !== void 0 ? _a : window.top],
|
|
15
|
+
listenTo: [window],
|
|
16
|
+
});
|
|
17
|
+
return instance;
|
|
18
|
+
}, []);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (!channel) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const unsubscribeFromEditorUpdates = channel.on('editor-state-updated', () => {
|
|
24
|
+
router.refresh();
|
|
25
|
+
});
|
|
26
|
+
return () => {
|
|
27
|
+
unsubscribeFromEditorUpdates();
|
|
28
|
+
};
|
|
29
|
+
}, [channel, router]);
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
if (typeof window === 'undefined') {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const existing = document.getElementById('uniform-script');
|
|
35
|
+
if (enabled) {
|
|
36
|
+
if (!existing) {
|
|
37
|
+
const script = document.createElement('script');
|
|
38
|
+
script.id = 'uniform-script';
|
|
39
|
+
script.src = `https://uniform.app/files/canvas-in-context-embed/index.js`;
|
|
40
|
+
script.async = true;
|
|
41
|
+
document.head.appendChild(script);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else if (existing) {
|
|
45
|
+
existing.remove();
|
|
46
|
+
}
|
|
47
|
+
}, [enabled]);
|
|
48
|
+
return _jsx(_Fragment, {});
|
|
49
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { ComponentInstance } from '@uniformdev/canvas';
|
|
2
|
+
import React, { Key, ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
import { CompositionContext } from './UniformComponent';
|
|
5
|
+
export type CustomSlotChildRenderFunc = (options: {
|
|
6
|
+
child: ReactNode;
|
|
7
|
+
component: ComponentInstance;
|
|
8
|
+
key: Key;
|
|
9
|
+
}) => JSX.Element;
|
|
10
|
+
export type UniformSlotWrapperComponentProps = {
|
|
11
|
+
items: ReactNode[];
|
|
12
|
+
slotName: string;
|
|
13
|
+
};
|
|
14
|
+
export type UniformSlotProps<TSlotNames extends string> = {
|
|
15
|
+
/** Name of the slot to render */
|
|
16
|
+
name: TSlotNames;
|
|
17
|
+
/** The composition that is being rendered */
|
|
18
|
+
data: ComponentInstance;
|
|
19
|
+
/** The context of the composition that is being rendered */
|
|
20
|
+
context: CompositionContext;
|
|
21
|
+
/**
|
|
22
|
+
* Optional render props enables wrapping all child components in the slot with some markup
|
|
23
|
+
*
|
|
24
|
+
* @deprecated Use `wrapperComponent` instead and define wrapping component for slot children inside.
|
|
25
|
+
*/
|
|
26
|
+
children?: CustomSlotChildRenderFunc;
|
|
27
|
+
/**
|
|
28
|
+
* Optional wrapper component around list of slot items that allows to control
|
|
29
|
+
* exactly how to render slot items, otherwise React.Fragment is being used
|
|
30
|
+
*/
|
|
31
|
+
wrapperComponent?: React.ComponentType<UniformSlotWrapperComponentProps>;
|
|
32
|
+
/**
|
|
33
|
+
* Optional ReactNode to use as a placeholder in Canvas editor when the slot is empty.
|
|
34
|
+
* The node is used to render a placeholder with realistic dimensions and it's never shown to users.
|
|
35
|
+
* Pass `null` to disable the placeholder.
|
|
36
|
+
*/
|
|
37
|
+
emptyPlaceholder?: ReactNode;
|
|
38
|
+
};
|
|
39
|
+
export declare function UniformSlot<TSlotNames extends string = string>({
|
|
40
|
+
name,
|
|
41
|
+
children,
|
|
42
|
+
emptyPlaceholder,
|
|
43
|
+
data: parentData,
|
|
44
|
+
wrapperComponent,
|
|
45
|
+
context,
|
|
46
|
+
}: UniformSlotProps<TSlotNames> & {
|
|
47
|
+
data: ComponentInstance;
|
|
48
|
+
}): JSX.Element | null;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React, { createElement, Fragment } from 'react';
|
|
3
|
+
import { renderComponent } from './renderComponent';
|
|
4
|
+
export function UniformSlot({ name, children, emptyPlaceholder, data: parentData, wrapperComponent, context, }) {
|
|
5
|
+
var _a;
|
|
6
|
+
const slot = (_a = parentData.slots) === null || _a === void 0 ? void 0 : _a[name];
|
|
7
|
+
if (!slot || !Array.isArray(slot)) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
const finalChildren = slot.map((component, index) => {
|
|
11
|
+
const child = renderComponent({
|
|
12
|
+
component,
|
|
13
|
+
context,
|
|
14
|
+
resolveSystem: {
|
|
15
|
+
test: () => {
|
|
16
|
+
// https://www.youtube.com/watch?v=G3AfIvJBcGo
|
|
17
|
+
return null;
|
|
18
|
+
},
|
|
19
|
+
personalization: () => {
|
|
20
|
+
return null;
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
key: `inner-${index}`,
|
|
24
|
+
indexInSlot: index,
|
|
25
|
+
slotName: name,
|
|
26
|
+
parentComponent: parentData,
|
|
27
|
+
slotChildrenCount: slot.length,
|
|
28
|
+
emptyPlaceholder,
|
|
29
|
+
});
|
|
30
|
+
const elements = children ? children({ child, component, key: `wrapped-inner-${index}` }) : child;
|
|
31
|
+
return createElement(Fragment, { key: `wrapped-${index}` }, elements);
|
|
32
|
+
});
|
|
33
|
+
if (!wrapperComponent) {
|
|
34
|
+
return React.createElement(React.Fragment, undefined, finalChildren);
|
|
35
|
+
}
|
|
36
|
+
const Wrapper = wrapperComponent;
|
|
37
|
+
return _jsx(Wrapper, { items: finalChildren, slotName: name });
|
|
38
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type PureUniformTextProps } from '@uniformdev/canvas-react/core';
|
|
2
|
+
|
|
3
|
+
import { CompositionContext } from './UniformComponent';
|
|
4
|
+
export type UniformTextProps = {
|
|
5
|
+
context: CompositionContext;
|
|
6
|
+
} & Omit<PureUniformTextProps, 'skipCustomRendering' | 'isContextualEditing'>;
|
|
7
|
+
export declare const UniformText: ({
|
|
8
|
+
context,
|
|
9
|
+
...rest
|
|
10
|
+
}: UniformTextProps) => import('react/jsx-runtime').JSX.Element;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { PureUniformText } from '@uniformdev/canvas-react/core';
|
|
3
|
+
export const UniformText = ({ context, ...rest }) => {
|
|
4
|
+
return (_jsx(PureUniformText, { ...rest, isContextualEditing: context.isContextualEditing, skipCustomRendering: context.isContextualEditing }));
|
|
5
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { CANVAS_LOCALE_TAG_PARAM, CANVAS_LOCALIZATION_SLOT, CANVAS_LOCALIZATION_TYPE, } from '@uniformdev/canvas';
|
|
2
|
+
import { Context } from '@uniformdev/context';
|
|
3
|
+
import { evaluateComposition } from '../evaluateComposition';
|
|
4
|
+
jest.mock('../getUniformContext', () => ({
|
|
5
|
+
getUniformContext: () => {
|
|
6
|
+
return new Context({
|
|
7
|
+
manifest: {
|
|
8
|
+
project: {},
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
},
|
|
12
|
+
}));
|
|
13
|
+
describe('evaluateComposition', () => {
|
|
14
|
+
it('should localize a composition when dynmaic inputs include locale token', async () => {
|
|
15
|
+
var _a, _b;
|
|
16
|
+
const root = {
|
|
17
|
+
_id: 'root',
|
|
18
|
+
_name: 'root',
|
|
19
|
+
type: 'root',
|
|
20
|
+
slots: {
|
|
21
|
+
content: [
|
|
22
|
+
{
|
|
23
|
+
type: CANVAS_LOCALIZATION_TYPE,
|
|
24
|
+
slots: {
|
|
25
|
+
[CANVAS_LOCALIZATION_SLOT]: [
|
|
26
|
+
{
|
|
27
|
+
type: 'hero',
|
|
28
|
+
parameters: {
|
|
29
|
+
[CANVAS_LOCALE_TAG_PARAM]: {
|
|
30
|
+
type: CANVAS_LOCALE_TAG_PARAM,
|
|
31
|
+
value: 'fr',
|
|
32
|
+
},
|
|
33
|
+
title: {
|
|
34
|
+
type: 'text',
|
|
35
|
+
value: 'This is the french title!',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
type: 'hero',
|
|
41
|
+
parameters: {
|
|
42
|
+
[CANVAS_LOCALE_TAG_PARAM]: {
|
|
43
|
+
type: CANVAS_LOCALE_TAG_PARAM,
|
|
44
|
+
value: 'en',
|
|
45
|
+
},
|
|
46
|
+
title: {
|
|
47
|
+
type: 'text',
|
|
48
|
+
value: 'This is the english title!',
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
await evaluateComposition({
|
|
59
|
+
root,
|
|
60
|
+
dynamicInputs: {
|
|
61
|
+
lang: 'en',
|
|
62
|
+
},
|
|
63
|
+
cookies: {},
|
|
64
|
+
headers: new Headers(),
|
|
65
|
+
params: {
|
|
66
|
+
slug: 'whatever',
|
|
67
|
+
},
|
|
68
|
+
searchParams: {},
|
|
69
|
+
config: {
|
|
70
|
+
experimental: {
|
|
71
|
+
localeDynamicInputs: ['lang'],
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
update: undefined,
|
|
75
|
+
});
|
|
76
|
+
const localizedHero = (_a = root.slots) === null || _a === void 0 ? void 0 : _a['content'][0];
|
|
77
|
+
expect(localizedHero).toBeDefined();
|
|
78
|
+
expect((_b = localizedHero === null || localizedHero === void 0 ? void 0 : localizedHero.parameters) === null || _b === void 0 ? void 0 : _b[CANVAS_LOCALE_TAG_PARAM].value).toBe('en');
|
|
79
|
+
});
|
|
80
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ComponentInstance } from '@uniformdev/canvas';
|
|
2
|
+
|
|
3
|
+
import { ComponentProps, CompositionContext } from './UniformComponent';
|
|
4
|
+
/**
|
|
5
|
+
* Extracts parameters from a component instance and returns them as a props object.
|
|
6
|
+
*
|
|
7
|
+
* @param component The component instance to extract parameters from.
|
|
8
|
+
*
|
|
9
|
+
* @returns The parameters as a props object.
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
export declare function convertComponentToProps<T = unknown>({
|
|
13
|
+
component,
|
|
14
|
+
context,
|
|
15
|
+
}: {
|
|
16
|
+
component: ComponentInstance;
|
|
17
|
+
context: CompositionContext;
|
|
18
|
+
}): ComponentProps<T>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracts parameters from a component instance and returns them as a props object.
|
|
3
|
+
*
|
|
4
|
+
* @param component The component instance to extract parameters from.
|
|
5
|
+
*
|
|
6
|
+
* @returns The parameters as a props object.
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
export function convertComponentToProps({ component, context, }) {
|
|
10
|
+
var _a;
|
|
11
|
+
const parameters = (_a = component.parameters) !== null && _a !== void 0 ? _a : {};
|
|
12
|
+
const renderComponentProps = {
|
|
13
|
+
...Object.keys(parameters).reduce((acc, cur) => {
|
|
14
|
+
acc[cur] = parameters[cur].value;
|
|
15
|
+
return acc;
|
|
16
|
+
}, {}),
|
|
17
|
+
...component.data,
|
|
18
|
+
component,
|
|
19
|
+
context,
|
|
20
|
+
};
|
|
21
|
+
return renderComponentProps;
|
|
22
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { RootComponentInstance, RouteGetResponseComposition } from '@uniformdev/canvas';
|
|
2
|
+
import { ContextState } from '@uniformdev/context';
|
|
3
|
+
|
|
4
|
+
import { UniformServerConfig } from '../config';
|
|
5
|
+
import { SeenUniformComponent } from '../models';
|
|
6
|
+
export declare const evaluateComposition: ({
|
|
7
|
+
root,
|
|
8
|
+
params,
|
|
9
|
+
searchParams,
|
|
10
|
+
dynamicInputs,
|
|
11
|
+
headers,
|
|
12
|
+
cookies,
|
|
13
|
+
update,
|
|
14
|
+
config,
|
|
15
|
+
}: {
|
|
16
|
+
root: RootComponentInstance;
|
|
17
|
+
params: {
|
|
18
|
+
slug: string | string[];
|
|
19
|
+
};
|
|
20
|
+
searchParams: {
|
|
21
|
+
[key: string]: string | undefined;
|
|
22
|
+
};
|
|
23
|
+
dynamicInputs: RouteGetResponseComposition['dynamicInputs'];
|
|
24
|
+
headers: Headers;
|
|
25
|
+
cookies: Record<string, string>;
|
|
26
|
+
update: Partial<ContextState> | undefined;
|
|
27
|
+
config?: UniformServerConfig | undefined;
|
|
28
|
+
}) => Promise<{
|
|
29
|
+
composition: RootComponentInstance;
|
|
30
|
+
cookieValue: string | undefined;
|
|
31
|
+
seenComponents: SeenUniformComponent[];
|
|
32
|
+
}>;
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { CANVAS_PERSONALIZATION_PARAM, CANVAS_PERSONALIZE_TYPE, CANVAS_TEST_TYPE, localize, mapSlotToPersonalizedVariations, mapSlotToTestVariations, walkNodeTree, } from '@uniformdev/canvas';
|
|
2
|
+
import { UNIFORM_DEFAULT_COOKIE_NAME } from '@uniformdev/context';
|
|
3
|
+
import { getServerConfig } from '../config/helpers';
|
|
4
|
+
import { serializeCookie } from '../score';
|
|
5
|
+
import { isIncontextEditingEnabled } from '../utils/draft';
|
|
6
|
+
import { getBaseUrl } from '../utils/url';
|
|
7
|
+
import { getEnrichmentTags } from './getEnrichmentTags';
|
|
8
|
+
import { getUniformContext } from './getUniformContext';
|
|
9
|
+
import { resolvePath } from './resolvePath';
|
|
10
|
+
export const evaluateComposition = async ({ root, params, searchParams, dynamicInputs, headers, cookies, update, config = getServerConfig(), }) => {
|
|
11
|
+
// resolve the path from route params
|
|
12
|
+
const path = resolvePath({
|
|
13
|
+
params,
|
|
14
|
+
});
|
|
15
|
+
const context = await getUniformContext({
|
|
16
|
+
searchParams,
|
|
17
|
+
cookieValue: cookies[UNIFORM_DEFAULT_COOKIE_NAME] || undefined,
|
|
18
|
+
});
|
|
19
|
+
// generate the current URL for the request
|
|
20
|
+
const url = new URL(`${getBaseUrl()}${path}`);
|
|
21
|
+
for (const [key, value] of Object.entries(searchParams)) {
|
|
22
|
+
if (value) {
|
|
23
|
+
url.searchParams.set(key, value);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const missingQuirkValue = 'unknown';
|
|
27
|
+
const { cookies: updateCookies, quirks: updateQuirks, ...restOfUpdate } = update || {};
|
|
28
|
+
// update context to update scores
|
|
29
|
+
await context.update({
|
|
30
|
+
cookies: {
|
|
31
|
+
...cookies,
|
|
32
|
+
...(updateCookies || {}),
|
|
33
|
+
},
|
|
34
|
+
url,
|
|
35
|
+
quirks: {
|
|
36
|
+
'vc-country': headers.get('x-vercel-ip-country') || missingQuirkValue,
|
|
37
|
+
'vc-region': headers.get('x-vercel-ip-country-region') || missingQuirkValue,
|
|
38
|
+
'vc-city': headers.get('x-vercel-ip-city') || missingQuirkValue,
|
|
39
|
+
...(updateQuirks || {}),
|
|
40
|
+
},
|
|
41
|
+
...restOfUpdate,
|
|
42
|
+
});
|
|
43
|
+
const composition = root;
|
|
44
|
+
const resolvedLocaleKey = Object.keys(dynamicInputs || {}).find((key) => {
|
|
45
|
+
var _a, _b;
|
|
46
|
+
return (_b = (_a = config.experimental) === null || _a === void 0 ? void 0 : _a.localeDynamicInputs) === null || _b === void 0 ? void 0 : _b.includes(key);
|
|
47
|
+
});
|
|
48
|
+
const resolvedLocale = resolvedLocaleKey
|
|
49
|
+
? dynamicInputs[resolvedLocaleKey]
|
|
50
|
+
: undefined;
|
|
51
|
+
if (typeof resolvedLocale !== 'undefined') {
|
|
52
|
+
localize({
|
|
53
|
+
composition,
|
|
54
|
+
locale: resolvedLocale,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
const enrichmentTags = [];
|
|
58
|
+
const seenComponents = [];
|
|
59
|
+
walkNodeTree(composition, ({ type, node: component, actions }) => {
|
|
60
|
+
var _a, _b, _c, _d, _e, _f;
|
|
61
|
+
if (type !== 'component') {
|
|
62
|
+
// we ignore blocks for now
|
|
63
|
+
actions.stopProcessingDescendants();
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
let replacementComponents;
|
|
67
|
+
// evaluate personalization components
|
|
68
|
+
if (component.type === CANVAS_PERSONALIZE_TYPE) {
|
|
69
|
+
const pzComponent = component;
|
|
70
|
+
// extract the personalized variations from the pz component slot
|
|
71
|
+
const processedVariants = mapSlotToPersonalizedVariations((_a = pzComponent === null || pzComponent === void 0 ? void 0 : pzComponent.slots) === null || _a === void 0 ? void 0 : _a.pz);
|
|
72
|
+
// extract the number of variations to take from the pz component, defaulting to 1
|
|
73
|
+
const take = Number((_b = pzComponent.parameters.count) === null || _b === void 0 ? void 0 : _b.value) || 1;
|
|
74
|
+
// determine the personalization name
|
|
75
|
+
const personalizationName = ((_c = pzComponent.parameters.trackingEventName) === null || _c === void 0 ? void 0 : _c.value) || 'Unknown';
|
|
76
|
+
// personalize the component
|
|
77
|
+
const { variations: personalized } = context.personalize({
|
|
78
|
+
name: personalizationName,
|
|
79
|
+
variations: processedVariants,
|
|
80
|
+
take,
|
|
81
|
+
});
|
|
82
|
+
// if personalized variations were returned, remove the the criteria parameter
|
|
83
|
+
if (personalized) {
|
|
84
|
+
for (let i = 0; i < personalized.length; i++) {
|
|
85
|
+
(_d = personalized[i].parameters) === null || _d === void 0 ? true : delete _d[CANVAS_PERSONALIZATION_PARAM];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// record that we have selected these variations for this personalization
|
|
89
|
+
seenComponents.push({
|
|
90
|
+
id: personalizationName,
|
|
91
|
+
type: 'personalization',
|
|
92
|
+
variants: personalized.map((p) => p.id),
|
|
93
|
+
control: context.storage.data.controlGroup || false,
|
|
94
|
+
});
|
|
95
|
+
// set the replacement components to the personalized variations
|
|
96
|
+
replacementComponents = personalized;
|
|
97
|
+
}
|
|
98
|
+
// evaluate test component
|
|
99
|
+
if (component.type === CANVAS_TEST_TYPE) {
|
|
100
|
+
const testComponent = component;
|
|
101
|
+
// extract the test variations from the test component slot
|
|
102
|
+
const processedVariants = mapSlotToTestVariations((_e = testComponent === null || testComponent === void 0 ? void 0 : testComponent.slots) === null || _e === void 0 ? void 0 : _e.test);
|
|
103
|
+
const testName = ((_f = testComponent.parameters.test) === null || _f === void 0 ? void 0 : _f.value) || 'Unknown';
|
|
104
|
+
// evaluate the test
|
|
105
|
+
const testResult = context.test({
|
|
106
|
+
name: testName,
|
|
107
|
+
variations: processedVariants,
|
|
108
|
+
});
|
|
109
|
+
// record that we have selected this variation for this test
|
|
110
|
+
seenComponents.push({
|
|
111
|
+
id: testName,
|
|
112
|
+
type: 'test',
|
|
113
|
+
variant: testResult.result ? testResult.result.id : undefined,
|
|
114
|
+
});
|
|
115
|
+
// set the replacement components to the test variation
|
|
116
|
+
if (testResult.result) {
|
|
117
|
+
replacementComponents = [testResult.result];
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
replacementComponents = [];
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// if we replacement components is defined, process replacements
|
|
124
|
+
if (typeof replacementComponents !== 'undefined') {
|
|
125
|
+
// if no variants were selected, just remove the current component. no matches.
|
|
126
|
+
if (replacementComponents.length === 0) {
|
|
127
|
+
actions.remove();
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
const [first, ...rest] = replacementComponents;
|
|
131
|
+
// replace the first component
|
|
132
|
+
actions.replace(first);
|
|
133
|
+
// if there are other components, insert them after the first
|
|
134
|
+
if (rest.length) {
|
|
135
|
+
actions.insertAfter(rest);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
// check to see if this component has any enrichment tags assigned
|
|
141
|
+
const tags = getEnrichmentTags(component);
|
|
142
|
+
// if so, add them to the enrichment tags
|
|
143
|
+
if (tags === null || tags === void 0 ? void 0 : tags.length) {
|
|
144
|
+
enrichmentTags.push(...tags);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
// when we post compositions to CANVAS_EDITOR_STATE, we have to remove all
|
|
149
|
+
// contextual editing objects that have been attached to parameters in order
|
|
150
|
+
// to pass API validation. walk the composition and add them back in, assume
|
|
151
|
+
// everything is editable.
|
|
152
|
+
if (isIncontextEditingEnabled({ searchParams })) {
|
|
153
|
+
walkNodeTree(composition, ({ node: component, actions, type }) => {
|
|
154
|
+
if (type !== 'component') {
|
|
155
|
+
actions.stopProcessingDescendants();
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
if (component.parameters) {
|
|
159
|
+
const params = Object.keys(component.parameters);
|
|
160
|
+
params.forEach((key) => {
|
|
161
|
+
const param = component.parameters[key];
|
|
162
|
+
if (param.type === 'text' && typeof param._contextualEditing === 'undefined') {
|
|
163
|
+
param._contextualEditing = {
|
|
164
|
+
isEditable: true,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
// if we've seen any enrichment tags, update the context with them
|
|
172
|
+
if (enrichmentTags.length) {
|
|
173
|
+
await context.update({
|
|
174
|
+
enrichments: enrichmentTags,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
// return the updated cookie value and any seen components
|
|
178
|
+
return {
|
|
179
|
+
cookieValue: context.storage.data.consent ? serializeCookie(context.storage.data) : undefined,
|
|
180
|
+
composition,
|
|
181
|
+
seenComponents,
|
|
182
|
+
};
|
|
183
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { CANVAS_ENRICHMENT_TAG_PARAM } from '@uniformdev/canvas';
|
|
2
|
+
export const getEnrichmentTags = (targets) => {
|
|
3
|
+
const targetsArray = Array.isArray(targets) ? targets : [targets];
|
|
4
|
+
const tags = [];
|
|
5
|
+
targetsArray.forEach((target) => {
|
|
6
|
+
var _a, _b;
|
|
7
|
+
const enrichmentTags = (_b = (_a = target.parameters) === null || _a === void 0 ? void 0 : _a[CANVAS_ENRICHMENT_TAG_PARAM]) === null || _b === void 0 ? void 0 : _b.value;
|
|
8
|
+
if (enrichmentTags) {
|
|
9
|
+
tags.push(...enrichmentTags);
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
return tags;
|
|
13
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Context } from '@uniformdev/context';
|
|
2
|
+
|
|
3
|
+
import { UniformCompositionProps } from './UniformComposition';
|
|
4
|
+
export declare const getUniformContext: ({
|
|
5
|
+
searchParams,
|
|
6
|
+
cookieValue,
|
|
7
|
+
}: {
|
|
8
|
+
searchParams?: UniformCompositionProps['searchParams'];
|
|
9
|
+
cookieValue: string | undefined;
|
|
10
|
+
}) => Promise<Context>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Context, CookieTransitionDataStore } from '@uniformdev/context';
|
|
2
|
+
import { getManifestFromApi } from '../client/manifestClient';
|
|
3
|
+
import { getServerConfig } from '../config/helpers';
|
|
4
|
+
export const getUniformContext = async ({ searchParams, cookieValue, }) => {
|
|
5
|
+
const manifest = await getManifestFromApi({
|
|
6
|
+
searchParams,
|
|
7
|
+
});
|
|
8
|
+
const config = getServerConfig();
|
|
9
|
+
const context = new Context({
|
|
10
|
+
manifest,
|
|
11
|
+
defaultConsent: config.defaultConsent,
|
|
12
|
+
transitionStore: new CookieTransitionDataStore({
|
|
13
|
+
serverCookieValue: cookieValue,
|
|
14
|
+
}),
|
|
15
|
+
});
|
|
16
|
+
return context;
|
|
17
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { linkParamValueToHref } from '@uniformdev/richtext';
|
|
3
|
+
export const LinkRichTextNode = ({ children, node }) => {
|
|
4
|
+
const { link } = node;
|
|
5
|
+
return _jsx("a", { href: linkParamValueToHref(link), children: children });
|
|
6
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
export const ListRichTextNode = ({ children, node }) => {
|
|
3
|
+
const { tag, start } = node;
|
|
4
|
+
const ListTag = (tag !== null && tag !== void 0 ? tag : 'ul');
|
|
5
|
+
return _jsx(ListTag, { start: Number.isFinite(start) && start > 0 ? start : undefined, children: children });
|
|
6
|
+
};
|