@sanity/personalization-plugin 2.5.0-field-level-personalization.1 → 2.5.0
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/LICENSE +1 -1
- package/README.md +2 -1
- package/dist/growthbook/index.js +3 -3
- package/dist/growthbook/index.js.map +1 -1
- package/dist/growthbook/index.mjs +1 -1
- package/dist/index.d.mts +12 -33
- package/dist/index.d.ts +12 -33
- package/dist/index.js +280 -157
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +280 -159
- package/dist/index.mjs.map +1 -1
- package/dist/launchDarkly/index.d.mts +12 -0
- package/dist/launchDarkly/index.d.ts +12 -0
- package/dist/launchDarkly/index.js +103 -0
- package/dist/launchDarkly/index.js.map +1 -0
- package/dist/launchDarkly/index.mjs +107 -0
- package/dist/launchDarkly/index.mjs.map +1 -0
- package/package.json +10 -5
- package/src/components/{experiment/Array.tsx → Array.tsx} +2 -2
- package/src/components/{experiment/Context.tsx → ExperimentContext.tsx} +2 -2
- package/src/components/{experiment/Field.tsx → ExperimentField.tsx} +8 -11
- package/src/components/{experiment/Input.tsx → ExperimentInput.tsx} +4 -4
- package/src/components/{ArrayItem.tsx → ExperimentItem.tsx} +2 -1
- package/src/components/Select.tsx +1 -1
- package/src/components/{experiment/VariantPreview.tsx → VariantPreview.tsx} +2 -2
- package/src/fieldExperiments.tsx +13 -43
- package/src/index.ts +0 -1
- package/src/launchDarkly/components/LaunchDarklyContext.tsx +36 -0
- package/src/launchDarkly/components/Secrets.tsx +46 -0
- package/src/launchDarkly/index.ts +52 -0
- package/src/launchDarkly/types.ts +193 -0
- package/src/launchDarkly/utils.ts +54 -0
- package/src/types.ts +2 -20
- package/dist/_chunks-cjs/fieldExperiments.js +0 -507
- package/dist/_chunks-cjs/fieldExperiments.js.map +0 -1
- package/dist/_chunks-es/fieldExperiments.mjs +0 -511
- package/dist/_chunks-es/fieldExperiments.mjs.map +0 -1
- package/src/components/experiment/index.ts +0 -6
- package/src/components/personalization/Array.tsx +0 -59
- package/src/components/personalization/Context.tsx +0 -61
- package/src/components/personalization/Field.tsx +0 -134
- package/src/components/personalization/SegmentInput.tsx +0 -19
- package/src/components/personalization/SegmentPreview.tsx +0 -71
- package/src/components/personalization/index.ts +0 -5
- package/src/fieldPersonalization.tsx +0 -254
- package/src/utils/clearChildGroups.ts +0 -33
- /package/src/components/{experiment/VariantInput.tsx → VariantInput.tsx} +0 -0
package/dist/index.mjs
CHANGED
|
@@ -1,82 +1,105 @@
|
|
|
1
|
-
import { clearChildrenGroups, CloseIcon, flattenSchemaType, ArrayItem } from "./_chunks-es/fieldExperiments.mjs";
|
|
2
|
-
import { fieldLevelExperiments } from "./_chunks-es/fieldExperiments.mjs";
|
|
3
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
-
import { useClient, useWorkspace, defineDocumentFieldAction, set, unset,
|
|
5
|
-
import { Stack, Inline, Button } from "@sanity/ui";
|
|
2
|
+
import { useClient, useWorkspace, useFormValue, defineDocumentFieldAction, set, unset, useDocumentOperation, getPublishedId, isReference, isImage, isDocumentSchemaType, definePlugin, isObjectInputProps, defineType, defineField } from "sanity";
|
|
3
|
+
import { Stack, Inline, Button, Select as Select$1, Card, Text } from "@sanity/ui";
|
|
6
4
|
import { uuid } from "@sanity/uuid";
|
|
7
|
-
import { createContext, useMemo, useContext, useCallback, useState, useEffect } from "react";
|
|
5
|
+
import { createContext, useMemo, useContext, useCallback, forwardRef, useState, useEffect } from "react";
|
|
8
6
|
import equal from "fast-deep-equal";
|
|
9
7
|
import { suspend } from "suspend-react";
|
|
10
|
-
import {
|
|
8
|
+
import { GiSoapExperiment } from "react-icons/gi";
|
|
11
9
|
const CONFIG_DEFAULT = {
|
|
12
10
|
fields: [],
|
|
13
11
|
apiVersion: "2024-11-07",
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
experimentNameOverride: "experiment",
|
|
13
|
+
variantNameOverride: "variant",
|
|
14
|
+
variantId: "variantId",
|
|
15
|
+
variantArrayName: "variants",
|
|
16
|
+
experimentId: "experimentId"
|
|
17
|
+
}, ExperimentContext = createContext({
|
|
19
18
|
...CONFIG_DEFAULT,
|
|
20
|
-
|
|
19
|
+
experiments: []
|
|
21
20
|
});
|
|
22
|
-
function
|
|
23
|
-
return useContext(
|
|
21
|
+
function useExperimentContext() {
|
|
22
|
+
return useContext(ExperimentContext);
|
|
24
23
|
}
|
|
25
|
-
function
|
|
26
|
-
const {
|
|
24
|
+
function ExperimentProvider(props) {
|
|
25
|
+
const { experimentFieldPluginConfig } = props, client = useClient({ apiVersion: experimentFieldPluginConfig.apiVersion }), workspace = useWorkspace(), experiments = Array.isArray(experimentFieldPluginConfig.experiments) ? experimentFieldPluginConfig.experiments : suspend(
|
|
27
26
|
// eslint-disable-next-line require-await
|
|
28
|
-
async () => typeof
|
|
27
|
+
async () => typeof experimentFieldPluginConfig.experiments == "function" ? experimentFieldPluginConfig.experiments(client) : experimentFieldPluginConfig.experiments,
|
|
29
28
|
[workspace],
|
|
30
29
|
{ equal }
|
|
31
30
|
), context = useMemo(
|
|
32
|
-
() => ({ ...
|
|
33
|
-
[
|
|
31
|
+
() => ({ ...experimentFieldPluginConfig, experiments }),
|
|
32
|
+
[experimentFieldPluginConfig, experiments]
|
|
34
33
|
);
|
|
35
|
-
return /* @__PURE__ */ jsx(
|
|
34
|
+
return /* @__PURE__ */ jsx(ExperimentContext.Provider, { value: context, children: props.renderDefault(props) });
|
|
36
35
|
}
|
|
37
36
|
const ArrayInput = (props) => {
|
|
38
|
-
const { onItemAppend,
|
|
39
|
-
async (
|
|
37
|
+
const fieldPath = props.path.slice(0, -1), { onItemAppend, variantName, variantId, experimentId } = props, experimentValue = useFormValue([...fieldPath, experimentId]), { experiments } = useExperimentContext(), handleClick = useCallback(
|
|
38
|
+
async (variant) => {
|
|
40
39
|
const item = {
|
|
41
40
|
_key: uuid(),
|
|
42
|
-
[
|
|
43
|
-
|
|
41
|
+
[variantId]: variant.id,
|
|
42
|
+
[experimentId]: experimentValue,
|
|
43
|
+
_type: variantName
|
|
44
44
|
};
|
|
45
45
|
onItemAppend(item);
|
|
46
46
|
},
|
|
47
|
-
[
|
|
48
|
-
),
|
|
47
|
+
[variantId, experimentId, experimentValue, variantName, onItemAppend]
|
|
48
|
+
), filteredVariants = experiments.find((option) => option.id === experimentValue)?.variants || [], usedVariants = (props.value || [])?.map((variant) => variant[variantId]);
|
|
49
49
|
return /* @__PURE__ */ jsxs(Stack, { space: 3, children: [
|
|
50
50
|
props.renderDefault({ ...props, arrayFunctions: () => null }),
|
|
51
|
-
/* @__PURE__ */ jsx(Inline, { space: 1, children:
|
|
51
|
+
/* @__PURE__ */ jsx(Inline, { space: 1, children: filteredVariants.map((variant) => /* @__PURE__ */ jsx(
|
|
52
52
|
Button,
|
|
53
53
|
{
|
|
54
|
-
text: `Add ${
|
|
54
|
+
text: `Add ${variant.label}`,
|
|
55
55
|
mode: "ghost",
|
|
56
|
-
disabled:
|
|
57
|
-
onClick: () => handleClick(
|
|
56
|
+
disabled: usedVariants?.includes(variant.id),
|
|
57
|
+
onClick: () => handleClick(variant)
|
|
58
58
|
},
|
|
59
|
-
`${
|
|
59
|
+
`${experimentValue}-${variant.id}`
|
|
60
60
|
)) })
|
|
61
61
|
] });
|
|
62
|
-
},
|
|
63
|
-
|
|
62
|
+
}, CloseIcon = /* @__PURE__ */ forwardRef(function(props, ref) {
|
|
63
|
+
return /* @__PURE__ */ jsx(
|
|
64
|
+
"svg",
|
|
65
|
+
{
|
|
66
|
+
"data-sanity-icon": "close",
|
|
67
|
+
width: "1em",
|
|
68
|
+
height: "1em",
|
|
69
|
+
viewBox: "0 0 25 25",
|
|
70
|
+
fill: "none",
|
|
71
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
72
|
+
...props,
|
|
73
|
+
ref,
|
|
74
|
+
children: /* @__PURE__ */ jsx(
|
|
75
|
+
"path",
|
|
76
|
+
{
|
|
77
|
+
d: "M18 7L7 18M7 7L18 18",
|
|
78
|
+
stroke: "currentColor",
|
|
79
|
+
strokeWidth: 1.2,
|
|
80
|
+
strokeLinejoin: "round"
|
|
81
|
+
}
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
}), useAddExperimentAction = (props) => {
|
|
86
|
+
const { onChange, active, experimentNameOverride } = props, handleAddAction = useCallback(() => {
|
|
64
87
|
onChange([set(!active, ["active"])]);
|
|
65
88
|
}, [onChange, active]);
|
|
66
89
|
return {
|
|
67
|
-
title: `Add ${
|
|
90
|
+
title: `Add ${experimentNameOverride}`,
|
|
68
91
|
type: "action",
|
|
69
|
-
icon:
|
|
92
|
+
icon: GiSoapExperiment,
|
|
70
93
|
onAction: handleAddAction,
|
|
71
94
|
renderAsButton: !0
|
|
72
95
|
};
|
|
73
96
|
}, useRemoveExperimentAction = (props) => {
|
|
74
|
-
const { onChange, active,
|
|
75
|
-
const activeId = ["active"],
|
|
76
|
-
onChange([set(!active, activeId), unset(
|
|
77
|
-
}, [onChange, active,
|
|
97
|
+
const { onChange, active, experimentId, experimentNameOverride, variantNameOverride } = props, handleClearAction = useCallback(() => {
|
|
98
|
+
const activeId = ["active"], experiment = [experimentId], variants = [`${variantNameOverride}s`];
|
|
99
|
+
onChange([set(!active, activeId), unset(experiment), unset(variants)]);
|
|
100
|
+
}, [onChange, active, experimentId, variantNameOverride]);
|
|
78
101
|
return {
|
|
79
|
-
title: `Remove ${
|
|
102
|
+
title: `Remove ${experimentNameOverride}`,
|
|
80
103
|
type: "action",
|
|
81
104
|
icon: CloseIcon,
|
|
82
105
|
onAction: handleClearAction,
|
|
@@ -86,57 +109,115 @@ const ArrayInput = (props) => {
|
|
|
86
109
|
onChange,
|
|
87
110
|
inputId,
|
|
88
111
|
active,
|
|
89
|
-
|
|
90
|
-
|
|
112
|
+
experimentNameOverride,
|
|
113
|
+
experimentId,
|
|
114
|
+
variantNameOverride
|
|
91
115
|
}) => {
|
|
92
116
|
const removeAction = defineDocumentFieldAction({
|
|
93
|
-
name: `Remove ${
|
|
117
|
+
name: `Remove ${experimentNameOverride}`,
|
|
94
118
|
useAction: (props) => useRemoveExperimentAction({
|
|
95
119
|
active: !0,
|
|
96
120
|
onChange,
|
|
97
|
-
|
|
98
|
-
|
|
121
|
+
experimentNameOverride,
|
|
122
|
+
experimentId,
|
|
123
|
+
variantNameOverride
|
|
99
124
|
})
|
|
100
125
|
}), addAction = defineDocumentFieldAction({
|
|
101
|
-
name: `Add ${
|
|
126
|
+
name: `Add ${experimentNameOverride}`,
|
|
102
127
|
useAction: (props) => useAddExperimentAction({
|
|
103
128
|
active: !1,
|
|
104
129
|
onChange,
|
|
105
|
-
|
|
130
|
+
experimentNameOverride
|
|
106
131
|
})
|
|
107
132
|
});
|
|
108
133
|
return active ? removeAction : addAction;
|
|
109
|
-
},
|
|
110
|
-
const { onChange } = props.inputProps, { inputId,
|
|
134
|
+
}, ExperimentField = (props) => {
|
|
135
|
+
const { onChange } = props.inputProps, { inputId, experimentNameOverride, experimentId, variantNameOverride } = props, active = props.value?.active, actionProps = useMemo(
|
|
111
136
|
() => ({
|
|
112
137
|
onChange,
|
|
113
138
|
inputId,
|
|
114
139
|
active,
|
|
115
|
-
|
|
116
|
-
|
|
140
|
+
experimentNameOverride,
|
|
141
|
+
experimentId,
|
|
142
|
+
variantNameOverride
|
|
117
143
|
}),
|
|
118
|
-
[onChange, inputId, active,
|
|
144
|
+
[onChange, inputId, active, experimentNameOverride, experimentId, variantNameOverride]
|
|
119
145
|
), memoizedActions = useMemo(() => {
|
|
120
146
|
const oldActions = props.actions || [];
|
|
121
147
|
return [createActions(actionProps), ...oldActions];
|
|
122
|
-
}, [actionProps, props.actions]),
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
148
|
+
}, [actionProps, props.actions]), withActionProps = useMemo(
|
|
149
|
+
() => ({
|
|
150
|
+
...props,
|
|
151
|
+
actions: memoizedActions
|
|
152
|
+
}),
|
|
153
|
+
[props, memoizedActions]
|
|
154
|
+
);
|
|
155
|
+
return props.renderDefault(withActionProps);
|
|
156
|
+
}, Select = (props) => {
|
|
157
|
+
const {
|
|
158
|
+
value,
|
|
159
|
+
// Current field value
|
|
160
|
+
onChange,
|
|
161
|
+
// Method to handle patch events,
|
|
162
|
+
elementProps,
|
|
163
|
+
listOptions,
|
|
164
|
+
handleChange
|
|
165
|
+
} = props;
|
|
166
|
+
return /* @__PURE__ */ jsxs(
|
|
167
|
+
Select$1,
|
|
168
|
+
{
|
|
169
|
+
...elementProps,
|
|
170
|
+
fontSize: 2,
|
|
171
|
+
padding: 3,
|
|
172
|
+
space: [3, 3, 4],
|
|
173
|
+
value: value || "",
|
|
174
|
+
onChange: (event) => handleChange(event, onChange),
|
|
175
|
+
children: [
|
|
176
|
+
/* @__PURE__ */ jsx("option", { value: "", children: "Select an option..." }),
|
|
177
|
+
listOptions.map(({ value: optionValue, title }) => /* @__PURE__ */ jsx("option", { value: optionValue, children: title }, optionValue))
|
|
178
|
+
]
|
|
179
|
+
}
|
|
180
|
+
);
|
|
181
|
+
}, formatlistOptions = (experiments) => experiments.map((experiment) => ({
|
|
182
|
+
title: experiment.label,
|
|
183
|
+
value: experiment.id
|
|
184
|
+
})), ExperimentInput = (props) => {
|
|
185
|
+
const { experiments } = useExperimentContext(), id = useFormValue(["_id"]), additionalChangePath = useMemo(
|
|
186
|
+
() => [...props.path.slice(0, -1), `${props.variantNameOverride}s`],
|
|
187
|
+
[props.variantNameOverride, props.path]
|
|
188
|
+
), subValues = useFormValue(additionalChangePath), { patch } = useDocumentOperation(getPublishedId(id), props.schemaType.name), handleChange = useCallback(
|
|
189
|
+
(event, onChange) => {
|
|
190
|
+
const inputValue = event.currentTarget.value;
|
|
191
|
+
if (onChange(inputValue ? set(inputValue) : unset()), subValues) {
|
|
192
|
+
const patchEvent = {
|
|
193
|
+
unset: [additionalChangePath.join(".")]
|
|
194
|
+
};
|
|
195
|
+
patch.execute([patchEvent]);
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
[patch, subValues, additionalChangePath]
|
|
199
|
+
);
|
|
200
|
+
return experiments.length ? /* @__PURE__ */ jsx(Select, { ...props, listOptions: formatlistOptions(experiments), handleChange }) : /* @__PURE__ */ jsx(Card, { padding: [3, 3, 4], radius: 2, shadow: 1, tone: "caution", children: /* @__PURE__ */ jsxs(Text, { align: "center", size: [2, 2, 3], children: [
|
|
201
|
+
"There are no defined ",
|
|
202
|
+
props.experimentNameOverride,
|
|
203
|
+
"s"
|
|
204
|
+
] }) });
|
|
205
|
+
}, ExperimentItem = (props) => {
|
|
206
|
+
const { active } = props.value;
|
|
207
|
+
return active || props.inputProps.onChange(set(!0, ["active"])), props.renderDefault(props);
|
|
208
|
+
}, VariantInput = (props) => {
|
|
209
|
+
const experimentPath = props.path.slice(0, -2), defaultValue = useFormValue([...experimentPath, "default"]), handleClick = () => {
|
|
129
210
|
props.onChange(set(defaultValue, ["value"]));
|
|
130
211
|
};
|
|
131
212
|
return /* @__PURE__ */ jsxs(Stack, { space: 3, children: [
|
|
132
213
|
props.renderDefault(props),
|
|
133
214
|
/* @__PURE__ */ jsx(Inline, { space: 1, children: /* @__PURE__ */ jsx(Button, { text: "Copy default", mode: "ghost", onClick: () => handleClick() }) })
|
|
134
215
|
] });
|
|
135
|
-
},
|
|
136
|
-
const [subtitle, setSubtitle] = useState(void 0), [title, setTitle] = useState(void 0), [media, setMedia] = useState(void 0), client = useClient({ apiVersion: "2025-01-01" }), {
|
|
216
|
+
}, VariantPreview = (props) => {
|
|
217
|
+
const [subtitle, setSubtitle] = useState(void 0), [title, setTitle] = useState(void 0), [media, setMedia] = useState(void 0), client = useClient({ apiVersion: "2025-01-01" }), { experiments } = useExperimentContext(), { experiment, variant, value } = props, selectedExperiment = experiments.find((experimentItem) => experimentItem.id === experiment), selectedVariant = selectedExperiment?.variants.find((variantItem) => variantItem.id === variant);
|
|
137
218
|
useEffect(() => {
|
|
138
219
|
(async () => {
|
|
139
|
-
if (setTitle(`${
|
|
220
|
+
if (setTitle(`${selectedExperiment?.label} - ${selectedVariant?.label}`), typeof value == "string")
|
|
140
221
|
return setSubtitle(value);
|
|
141
222
|
if (isReference(value)) {
|
|
142
223
|
const doc = await client.getDocument(value._ref), referenceType = (props.schemaType.fields.find((field) => field.name === "value")?.type).to.find((field) => field.type?.name === doc?._type), selectFields = {}, previewFields = referenceType?.preview?.select || {};
|
|
@@ -149,7 +230,7 @@ const ArrayInput = (props) => {
|
|
|
149
230
|
}
|
|
150
231
|
return isImage(value) && setMedia(value), "";
|
|
151
232
|
})();
|
|
152
|
-
}, [value, client,
|
|
233
|
+
}, [value, client, selectedExperiment?.label, selectedVariant?.label, props.schemaType]);
|
|
153
234
|
const previewProps = {
|
|
154
235
|
...props,
|
|
155
236
|
title,
|
|
@@ -157,59 +238,65 @@ const ArrayInput = (props) => {
|
|
|
157
238
|
media
|
|
158
239
|
};
|
|
159
240
|
return props.renderDefault(previewProps);
|
|
160
|
-
}
|
|
241
|
+
};
|
|
242
|
+
function flattenSchemaType(schemaType) {
|
|
243
|
+
return isDocumentSchemaType(schemaType) ? extractInnerFields(schemaType.fields, [], 5) : (console.error("Schema type is not a document"), []);
|
|
244
|
+
}
|
|
245
|
+
function extractInnerFields(fields, path, maxDepth) {
|
|
246
|
+
return path.length >= maxDepth ? [] : fields.reduce((acc, field) => {
|
|
247
|
+
const thisFieldWithPath = { path: [...path, field.name], ...field };
|
|
248
|
+
if (field.type.jsonType === "object") {
|
|
249
|
+
const innerFields = extractInnerFields(field.type.fields, [...path, field.name], maxDepth);
|
|
250
|
+
return [...acc, thisFieldWithPath, ...innerFields];
|
|
251
|
+
} else if (field.type.jsonType === "array") {
|
|
252
|
+
const innerFields = (field.type.of || []).reduce((arrayAcc, arrayType) => {
|
|
253
|
+
if ("fields" in arrayType) {
|
|
254
|
+
const typeFields = extractInnerFields(arrayType.fields, [...path, field.name], maxDepth);
|
|
255
|
+
return [...arrayAcc, ...typeFields];
|
|
256
|
+
}
|
|
257
|
+
return arrayAcc;
|
|
258
|
+
}, []);
|
|
259
|
+
return [...acc, thisFieldWithPath, ...innerFields];
|
|
260
|
+
}
|
|
261
|
+
return [...acc, thisFieldWithPath];
|
|
262
|
+
}, []);
|
|
263
|
+
}
|
|
264
|
+
const createExperimentType = ({
|
|
161
265
|
field,
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
266
|
+
experimentNameOverride,
|
|
267
|
+
variantNameOverride,
|
|
268
|
+
variantId,
|
|
269
|
+
variantArrayName,
|
|
270
|
+
experimentId
|
|
166
271
|
}) => {
|
|
167
|
-
const typeName = typeof field == "string" ? field : field.name, usedName = String(typeName[0]).toUpperCase() + String(typeName).slice(1),
|
|
272
|
+
const typeName = typeof field == "string" ? field : field.name, usedName = String(typeName[0]).toUpperCase() + String(typeName).slice(1), variantName = `${variantNameOverride}${usedName}`;
|
|
168
273
|
return defineType({
|
|
169
|
-
name: `${
|
|
274
|
+
name: `${experimentNameOverride}${usedName}`,
|
|
170
275
|
type: "object",
|
|
171
|
-
groups: [
|
|
172
|
-
{
|
|
173
|
-
name: "default",
|
|
174
|
-
title: "Default",
|
|
175
|
-
hidden: ({ parent }) => !Array.isArray(parent)
|
|
176
|
-
},
|
|
177
|
-
{
|
|
178
|
-
name: "personalization",
|
|
179
|
-
title: "Personalization options",
|
|
180
|
-
hidden: ({ parent }) => !Array.isArray(parent)
|
|
181
|
-
},
|
|
182
|
-
{
|
|
183
|
-
name: "all-fields",
|
|
184
|
-
title: "All fields",
|
|
185
|
-
hidden: ({ parent }) => Array.isArray(parent)
|
|
186
|
-
}
|
|
187
|
-
],
|
|
188
276
|
components: {
|
|
189
277
|
field: (props) => /* @__PURE__ */ jsx(
|
|
190
|
-
|
|
278
|
+
ExperimentField,
|
|
191
279
|
{
|
|
192
280
|
...props,
|
|
193
|
-
|
|
194
|
-
|
|
281
|
+
experimentId,
|
|
282
|
+
experimentNameOverride,
|
|
283
|
+
variantNameOverride
|
|
195
284
|
}
|
|
196
285
|
),
|
|
197
|
-
item:
|
|
286
|
+
item: ExperimentItem
|
|
198
287
|
},
|
|
199
288
|
fields: [
|
|
200
289
|
typeof field == "string" ? (
|
|
201
290
|
// Define a simple field if all we have is the name as a string
|
|
202
291
|
defineField({
|
|
203
292
|
name: "default",
|
|
204
|
-
type: field
|
|
205
|
-
group: "default"
|
|
293
|
+
type: field
|
|
206
294
|
})
|
|
207
295
|
) : (
|
|
208
296
|
// Pass in the configured options, but overwrite the name
|
|
209
297
|
{
|
|
210
298
|
...field,
|
|
211
|
-
name: "default"
|
|
212
|
-
group: "default"
|
|
299
|
+
name: "default"
|
|
213
300
|
}
|
|
214
301
|
),
|
|
215
302
|
defineField({
|
|
@@ -219,54 +306,84 @@ const ArrayInput = (props) => {
|
|
|
219
306
|
initialValue: !1
|
|
220
307
|
}),
|
|
221
308
|
defineField({
|
|
222
|
-
name:
|
|
309
|
+
name: experimentId,
|
|
310
|
+
type: "string",
|
|
311
|
+
components: {
|
|
312
|
+
input: (props) => /* @__PURE__ */ jsx(
|
|
313
|
+
ExperimentInput,
|
|
314
|
+
{
|
|
315
|
+
...props,
|
|
316
|
+
experimentNameOverride,
|
|
317
|
+
variantNameOverride
|
|
318
|
+
}
|
|
319
|
+
)
|
|
320
|
+
},
|
|
321
|
+
hidden: ({ parent }) => !parent?.active
|
|
322
|
+
}),
|
|
323
|
+
defineField({
|
|
324
|
+
name: variantArrayName,
|
|
223
325
|
type: "array",
|
|
224
|
-
hidden: ({ parent }) => !parent?.
|
|
225
|
-
group: "personalization",
|
|
326
|
+
hidden: ({ parent }) => !parent?.[experimentId],
|
|
226
327
|
components: {
|
|
227
|
-
input: (props) => /* @__PURE__ */ jsx(
|
|
328
|
+
input: (props) => /* @__PURE__ */ jsx(
|
|
329
|
+
ArrayInput,
|
|
330
|
+
{
|
|
331
|
+
...props,
|
|
332
|
+
variantName,
|
|
333
|
+
variantId,
|
|
334
|
+
experimentId
|
|
335
|
+
}
|
|
336
|
+
)
|
|
228
337
|
},
|
|
229
338
|
of: [
|
|
230
339
|
defineField({
|
|
231
|
-
name:
|
|
232
|
-
type:
|
|
340
|
+
name: variantName,
|
|
341
|
+
type: variantName
|
|
233
342
|
})
|
|
234
343
|
]
|
|
235
344
|
})
|
|
236
345
|
],
|
|
237
346
|
preview: {
|
|
238
347
|
select: {
|
|
239
|
-
base: "default"
|
|
348
|
+
base: "default",
|
|
349
|
+
experiment: experimentId
|
|
240
350
|
},
|
|
241
|
-
prepare: ({ base }) => {
|
|
242
|
-
const title = base?.title || base?.name || typeof base == "string" ? base : "", media = base?.image || base?.photo || base?.media || "";
|
|
351
|
+
prepare: ({ base, experiment }) => {
|
|
352
|
+
const title = base?.title || base?.name || typeof base == "string" ? base : "", experimentTitle = experiment ? `Experiment: ${experiment}` : "", media = base?.image || base?.photo || base?.media || "";
|
|
243
353
|
return {
|
|
244
|
-
title,
|
|
354
|
+
title: title || experimentTitle,
|
|
355
|
+
subtitle: title ? experimentTitle : "",
|
|
245
356
|
media
|
|
246
357
|
};
|
|
247
358
|
}
|
|
248
359
|
}
|
|
249
360
|
});
|
|
250
|
-
},
|
|
361
|
+
}, createVariantType = ({
|
|
251
362
|
field,
|
|
252
|
-
|
|
253
|
-
|
|
363
|
+
variantNameOverride,
|
|
364
|
+
variantId,
|
|
365
|
+
experimentId
|
|
254
366
|
}) => {
|
|
255
367
|
const typeName = typeof field == "string" ? field : field.name, usedName = String(typeName[0]).toUpperCase() + String(typeName).slice(1);
|
|
256
368
|
return defineType({
|
|
257
|
-
name: `${
|
|
258
|
-
title: `${
|
|
369
|
+
name: `${variantNameOverride}${usedName}`,
|
|
370
|
+
title: `${variantNameOverride} array ${usedName}`,
|
|
259
371
|
type: "object",
|
|
260
372
|
components: {
|
|
261
|
-
preview:
|
|
262
|
-
input:
|
|
373
|
+
preview: VariantPreview,
|
|
374
|
+
input: VariantInput
|
|
263
375
|
},
|
|
264
376
|
fields: [
|
|
265
377
|
{
|
|
266
378
|
type: "string",
|
|
267
|
-
name:
|
|
379
|
+
name: variantId,
|
|
268
380
|
readOnly: !0
|
|
269
381
|
},
|
|
382
|
+
{
|
|
383
|
+
type: "string",
|
|
384
|
+
name: experimentId,
|
|
385
|
+
hidden: !0
|
|
386
|
+
},
|
|
270
387
|
typeof field == "string" ? (
|
|
271
388
|
// Define a simple field if all we have is the name as a string
|
|
272
389
|
defineField({
|
|
@@ -285,67 +402,71 @@ const ArrayInput = (props) => {
|
|
|
285
402
|
],
|
|
286
403
|
preview: {
|
|
287
404
|
select: {
|
|
288
|
-
|
|
405
|
+
variant: variantId,
|
|
406
|
+
experiment: experimentId,
|
|
289
407
|
value: "value"
|
|
290
408
|
}
|
|
291
409
|
}
|
|
292
410
|
});
|
|
293
411
|
}, fieldSchema = ({
|
|
294
412
|
fields,
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
413
|
+
experimentNameOverride,
|
|
414
|
+
variantNameOverride,
|
|
415
|
+
variantId,
|
|
416
|
+
variantArrayName,
|
|
417
|
+
experimentId
|
|
299
418
|
}) => [
|
|
300
|
-
...fields.map((field) => createSegmentType({ field, segmentNameOverride, segmentId })),
|
|
301
419
|
...fields.map(
|
|
302
|
-
(field) =>
|
|
420
|
+
(field) => createVariantType({ field, variantNameOverride, variantId, experimentId })
|
|
421
|
+
),
|
|
422
|
+
...fields.map(
|
|
423
|
+
(field) => createExperimentType({
|
|
303
424
|
field,
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
425
|
+
experimentNameOverride,
|
|
426
|
+
variantNameOverride,
|
|
427
|
+
variantId,
|
|
428
|
+
variantArrayName,
|
|
429
|
+
experimentId
|
|
308
430
|
})
|
|
309
431
|
)
|
|
310
|
-
],
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
|
|
432
|
+
], fieldLevelExperiments = definePlugin((config) => {
|
|
433
|
+
const pluginConfig = { ...CONFIG_DEFAULT, ...config }, { fields, experimentNameOverride, variantNameOverride } = pluginConfig, experimentId = `${experimentNameOverride}Id`, variantArrayName = `${variantNameOverride}s`, variantId = `${variantNameOverride}Id`;
|
|
434
|
+
return {
|
|
435
|
+
name: "sanity-personalistaion-plugin-field-level-experiments",
|
|
436
|
+
schema: {
|
|
437
|
+
types: fieldSchema({
|
|
438
|
+
fields,
|
|
439
|
+
experimentNameOverride,
|
|
440
|
+
variantNameOverride,
|
|
441
|
+
variantId,
|
|
442
|
+
variantArrayName,
|
|
443
|
+
experimentId
|
|
444
|
+
})
|
|
445
|
+
},
|
|
446
|
+
form: {
|
|
447
|
+
components: {
|
|
448
|
+
input: (props) => {
|
|
449
|
+
if (!(props.id === "root" && isObjectInputProps(props)) || !flattenSchemaType(props.schemaType).some(
|
|
450
|
+
(field) => field.type.name.startsWith(experimentNameOverride) || field.name.startsWith(experimentNameOverride)
|
|
451
|
+
))
|
|
452
|
+
return props.renderDefault(props);
|
|
453
|
+
const providerProps = {
|
|
454
|
+
...props,
|
|
455
|
+
experimentFieldPluginConfig: {
|
|
456
|
+
...pluginConfig,
|
|
457
|
+
variantId,
|
|
458
|
+
variantArrayName,
|
|
459
|
+
experimentId
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
return ExperimentProvider(providerProps);
|
|
341
463
|
}
|
|
342
464
|
}
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
);
|
|
465
|
+
}
|
|
466
|
+
};
|
|
467
|
+
});
|
|
346
468
|
export {
|
|
347
469
|
fieldLevelExperiments,
|
|
348
|
-
fieldLevelPersonalization,
|
|
349
470
|
flattenSchemaType
|
|
350
471
|
};
|
|
351
472
|
//# sourceMappingURL=index.mjs.map
|