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