@sanity/personalization-plugin 2.4.2 → 2.5.0-field-level-personalization.1

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 (34) hide show
  1. package/dist/_chunks-cjs/fieldExperiments.js +507 -0
  2. package/dist/_chunks-cjs/fieldExperiments.js.map +1 -0
  3. package/dist/_chunks-es/fieldExperiments.mjs +511 -0
  4. package/dist/_chunks-es/fieldExperiments.mjs.map +1 -0
  5. package/dist/growthbook/index.js +3 -3
  6. package/dist/growthbook/index.js.map +1 -1
  7. package/dist/growthbook/index.mjs +1 -1
  8. package/dist/index.d.mts +33 -12
  9. package/dist/index.d.ts +33 -12
  10. package/dist/index.js +157 -280
  11. package/dist/index.js.map +1 -1
  12. package/dist/index.mjs +159 -280
  13. package/dist/index.mjs.map +1 -1
  14. package/package.json +1 -1
  15. package/src/components/{ExperimentItem.tsx → ArrayItem.tsx} +1 -2
  16. package/src/components/Select.tsx +1 -1
  17. package/src/components/{Array.tsx → experiment/Array.tsx} +2 -2
  18. package/src/components/{ExperimentContext.tsx → experiment/Context.tsx} +2 -2
  19. package/src/components/{ExperimentField.tsx → experiment/Field.tsx} +11 -8
  20. package/src/components/{ExperimentInput.tsx → experiment/Input.tsx} +4 -4
  21. package/src/components/{VariantPreview.tsx → experiment/VariantPreview.tsx} +2 -2
  22. package/src/components/experiment/index.ts +6 -0
  23. package/src/components/personalization/Array.tsx +59 -0
  24. package/src/components/personalization/Context.tsx +61 -0
  25. package/src/components/personalization/Field.tsx +134 -0
  26. package/src/components/personalization/SegmentInput.tsx +19 -0
  27. package/src/components/personalization/SegmentPreview.tsx +71 -0
  28. package/src/components/personalization/index.ts +5 -0
  29. package/src/fieldExperiments.tsx +43 -13
  30. package/src/fieldPersonalization.tsx +254 -0
  31. package/src/index.ts +1 -0
  32. package/src/types.ts +20 -2
  33. package/src/utils/clearChildGroups.ts +33 -0
  34. /package/src/components/{VariantInput.tsx → experiment/VariantInput.tsx} +0 -0
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: !0 });
3
- var sanity = require("sanity"), index = require("../index.js"), jsxRuntime = require("react/jsx-runtime"), react = require("react"), studioSecrets = require("@sanity/studio-secrets");
3
+ var sanity = require("sanity"), fieldExperiments = require("../_chunks-cjs/fieldExperiments.js"), jsxRuntime = require("react/jsx-runtime"), react = require("react"), studioSecrets = require("@sanity/studio-secrets");
4
4
  const namespace = "growthbook", pluginConfigKeys = [
5
5
  {
6
6
  key: "apiKey",
@@ -91,7 +91,7 @@ const getBooleanConversion = (value) => value === "true" ? "variant" : value ===
91
91
  return {
92
92
  name: "sanity-growthbook-personalistaion-plugin-field-level-experiments",
93
93
  plugins: [
94
- index.fieldLevelExperiments({
94
+ fieldExperiments.fieldLevelExperiments({
95
95
  fields,
96
96
  experiments: (client) => getExperiments({ client, environment, baseUrl, project, convertBooleans, tags })
97
97
  })
@@ -99,7 +99,7 @@ const getBooleanConversion = (value) => value === "true" ? "variant" : value ===
99
99
  form: {
100
100
  components: {
101
101
  input: (props) => {
102
- if (!(props.id === "root" && sanity.isObjectInputProps(props)) || !index.flattenSchemaType(props.schemaType).map(
102
+ if (!(props.id === "root" && sanity.isObjectInputProps(props)) || !fieldExperiments.flattenSchemaType(props.schemaType).map(
103
103
  (field) => field.type.name
104
104
  ).some((name) => name.startsWith("experiment")))
105
105
  return props.renderDefault(props);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/growthbook/Components/Secrets.tsx","../../src/growthbook/Components/GrowthbookContext.tsx","../../src/growthbook/utils.ts","../../src/growthbook/index.ts"],"sourcesContent":["import {SettingsView, useSecrets} from '@sanity/studio-secrets'\nimport {useEffect, useState} from 'react'\nimport {ObjectInputProps} from 'sanity'\n\nimport {useGrowthbookContext} from './GrowthbookContext'\n\nexport const namespace = 'growthbook'\n\nexport const pluginConfigKeys = [\n {\n key: 'apiKey',\n title: 'Your secret API key',\n },\n]\n\nexport const Secrets = (props: ObjectInputProps) => {\n const {secrets, loading} = useSecrets(namespace) as {secrets: {apiKey: string}; loading: boolean}\n const {setSecret} = useGrowthbookContext()\n const [showSettings, setShowSettings] = useState<boolean>(false)\n\n useEffect(() => {\n if (loading) return undefined\n if (!secrets && !loading) {\n setSecret(undefined)\n return setShowSettings(true)\n }\n setSecret(secrets.apiKey)\n return setShowSettings(false)\n }, [secrets, loading, setSecret])\n\n if (!showSettings) {\n return props.renderDefault(props)\n }\n return (\n <>\n <SettingsView\n title={'Growthbook secret'}\n namespace={namespace}\n keys={pluginConfigKeys}\n onClose={() => {\n setShowSettings(false)\n }}\n />\n {props.renderDefault(props)}\n </>\n )\n}\n","import {createContext, useContext, useMemo, useState} from 'react'\nimport {ObjectInputProps} from 'sanity'\n\nimport {GrowthbookContextProps, GrowthbookExperimentFieldPluginConfig} from '../types'\nimport {Secrets} from './Secrets'\n\nexport const GROWTHBOOK_CONFIG_DEFAULT = {\n baseUrl: 'https://api.growthbook.io/api/v1',\n}\n\nexport const GrowthbookContext = createContext<GrowthbookContextProps>({\n setSecret: () => undefined,\n secret: undefined,\n})\n\nexport function useGrowthbookContext() {\n return useContext(GrowthbookContext)\n}\n\ntype GrowthbookProps = ObjectInputProps & {\n growthbookFieldPluginConfig: GrowthbookExperimentFieldPluginConfig\n}\n\nexport function GrowthbookProvider(props: GrowthbookProps) {\n const {growthbookFieldPluginConfig} = props\n const [secret, setSecret] = useState<string | undefined>()\n\n const context = useMemo(\n () => ({...growthbookFieldPluginConfig, secret, setSecret}),\n [growthbookFieldPluginConfig, secret, setSecret],\n )\n\n return (\n <GrowthbookContext.Provider value={context}>\n <Secrets {...props} />\n </GrowthbookContext.Provider>\n )\n}\n","import {SanityClient} from 'sanity'\n\nimport {ExperimentType, GrowthbookFeature, VariantType} from '../types'\nimport {namespace, pluginConfigKeys} from './Components/Secrets'\nimport {GrowthbookExperimentFieldPluginConfig} from './types'\n\nconst getBooleanConversion = (value: string) => {\n // control is false\n if (value === 'true') {\n return 'variant'\n } else if (value === 'false') {\n return 'control'\n }\n return value\n}\n\nexport const getExperiments = async ({\n client,\n environment,\n baseUrl,\n project,\n convertBooleans,\n tags,\n}: Omit<GrowthbookExperimentFieldPluginConfig, 'fields' | 'baseUrl'> & {\n client: SanityClient\n baseUrl: string\n}): Promise<ExperimentType[]> => {\n const query = `*[_id == 'secrets.${namespace}'][0].secrets.${pluginConfigKeys[0].key}`\n\n const secret = await client.fetch(query) // secret is stored in the content lake using @sanity/studio-secrets\n if (!secret) return []\n\n const featureExperiments: ExperimentType[] = []\n let hasMore = true\n let offset = 0\n const url = new URL(`${baseUrl}/features`)\n if (project) {\n url.searchParams.set('projectId', project)\n }\n\n while (hasMore) {\n url.searchParams.set('offset', offset.toString())\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${secret}`,\n },\n })\n\n const {features, hasMore: responseHasMore, nextOffset} = await response.json()\n\n hasMore = responseHasMore\n offset = nextOffset\n if (!features) continue\n\n features.forEach((feature: GrowthbookFeature) => {\n if (feature.archived) {\n return undefined\n }\n if (tags && feature.tags && !feature.tags.some((tag) => tags.includes(tag))) {\n return undefined\n }\n\n const experiments = feature.environments[environment]?.rules.filter(\n (experiment) => experiment.type === 'experiment-ref' || experiment.type === 'experiment',\n )\n\n if (!experiments) {\n return undefined\n }\n\n const variations: VariantType[] = []\n const uniqueValues = new Set<string>()\n\n experiments.forEach((experiment) => {\n experiment?.variations.forEach((variant) => {\n const value = convertBooleans ? getBooleanConversion(variant.value) : variant.value\n if (!uniqueValues.has(value)) {\n uniqueValues.add(value)\n variations.push({\n id: value,\n label: value,\n })\n }\n })\n })\n const value = {id: feature.id, label: feature.id, variants: variations}\n\n featureExperiments.push(value)\n return undefined\n })\n }\n const sortedFeatureExperiments = featureExperiments.sort((a, b) => a.id.localeCompare(b.id))\n return sortedFeatureExperiments\n}\n","import {definePlugin, isObjectInputProps} from 'sanity'\n\nimport {fieldLevelExperiments as baseFieldLevelExperiments} from '../fieldExperiments'\nimport {flattenSchemaType} from '../utils/flattenSchemaType'\nimport {GROWTHBOOK_CONFIG_DEFAULT, GrowthbookProvider} from './Components/GrowthbookContext'\nimport {GrowthbookExperimentFieldPluginConfig} from './types'\nimport {getExperiments} from './utils'\n\nexport const fieldLevelExperiments = definePlugin<GrowthbookExperimentFieldPluginConfig>(\n (config) => {\n const pluginConfig = {...GROWTHBOOK_CONFIG_DEFAULT, ...config}\n const {fields, environment, project, convertBooleans, baseUrl, tags} = pluginConfig\n return {\n name: 'sanity-growthbook-personalistaion-plugin-field-level-experiments',\n plugins: [\n baseFieldLevelExperiments({\n fields,\n experiments: (client) =>\n getExperiments({client, environment, baseUrl, project, convertBooleans, tags}),\n }),\n ],\n\n form: {\n components: {\n input: (props) => {\n const isRootInput = props.id === 'root' && isObjectInputProps(props)\n\n if (!isRootInput) {\n return props.renderDefault(props)\n }\n\n const flatFieldTypeNames = flattenSchemaType(props.schemaType).map(\n (field) => field.type.name,\n )\n\n const hasExperiment = flatFieldTypeNames.some((name) => name.startsWith('experiment'))\n\n if (!hasExperiment) {\n return props.renderDefault(props)\n }\n\n const providerProps = {\n ...props,\n growthbookFieldPluginConfig: {\n ...pluginConfig,\n },\n }\n return GrowthbookProvider(providerProps)\n },\n },\n },\n }\n },\n)\n"],"names":["useSecrets","useState","useEffect","jsxs","Fragment","jsx","SettingsView","createContext","useContext","useMemo","value","definePlugin","baseFieldLevelExperiments","isObjectInputProps","flattenSchemaType"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/growthbook/Components/Secrets.tsx","../../src/growthbook/Components/GrowthbookContext.tsx","../../src/growthbook/utils.ts","../../src/growthbook/index.ts"],"sourcesContent":["import {SettingsView, useSecrets} from '@sanity/studio-secrets'\nimport {useEffect, useState} from 'react'\nimport {ObjectInputProps} from 'sanity'\n\nimport {useGrowthbookContext} from './GrowthbookContext'\n\nexport const namespace = 'growthbook'\n\nexport const pluginConfigKeys = [\n {\n key: 'apiKey',\n title: 'Your secret API key',\n },\n]\n\nexport const Secrets = (props: ObjectInputProps) => {\n const {secrets, loading} = useSecrets(namespace) as {secrets: {apiKey: string}; loading: boolean}\n const {setSecret} = useGrowthbookContext()\n const [showSettings, setShowSettings] = useState<boolean>(false)\n\n useEffect(() => {\n if (loading) return undefined\n if (!secrets && !loading) {\n setSecret(undefined)\n return setShowSettings(true)\n }\n setSecret(secrets.apiKey)\n return setShowSettings(false)\n }, [secrets, loading, setSecret])\n\n if (!showSettings) {\n return props.renderDefault(props)\n }\n return (\n <>\n <SettingsView\n title={'Growthbook secret'}\n namespace={namespace}\n keys={pluginConfigKeys}\n onClose={() => {\n setShowSettings(false)\n }}\n />\n {props.renderDefault(props)}\n </>\n )\n}\n","import {createContext, useContext, useMemo, useState} from 'react'\nimport {ObjectInputProps} from 'sanity'\n\nimport {GrowthbookContextProps, GrowthbookExperimentFieldPluginConfig} from '../types'\nimport {Secrets} from './Secrets'\n\nexport const GROWTHBOOK_CONFIG_DEFAULT = {\n baseUrl: 'https://api.growthbook.io/api/v1',\n}\n\nexport const GrowthbookContext = createContext<GrowthbookContextProps>({\n setSecret: () => undefined,\n secret: undefined,\n})\n\nexport function useGrowthbookContext() {\n return useContext(GrowthbookContext)\n}\n\ntype GrowthbookProps = ObjectInputProps & {\n growthbookFieldPluginConfig: GrowthbookExperimentFieldPluginConfig\n}\n\nexport function GrowthbookProvider(props: GrowthbookProps) {\n const {growthbookFieldPluginConfig} = props\n const [secret, setSecret] = useState<string | undefined>()\n\n const context = useMemo(\n () => ({...growthbookFieldPluginConfig, secret, setSecret}),\n [growthbookFieldPluginConfig, secret, setSecret],\n )\n\n return (\n <GrowthbookContext.Provider value={context}>\n <Secrets {...props} />\n </GrowthbookContext.Provider>\n )\n}\n","import {SanityClient} from 'sanity'\n\nimport {ExperimentType, GrowthbookFeature, VariantType} from '../types'\nimport {namespace, pluginConfigKeys} from './Components/Secrets'\nimport {GrowthbookExperimentFieldPluginConfig} from './types'\n\nconst getBooleanConversion = (value: string) => {\n // control is false\n if (value === 'true') {\n return 'variant'\n } else if (value === 'false') {\n return 'control'\n }\n return value\n}\n\nexport const getExperiments = async ({\n client,\n environment,\n baseUrl,\n project,\n convertBooleans,\n tags,\n}: Omit<GrowthbookExperimentFieldPluginConfig, 'fields' | 'baseUrl'> & {\n client: SanityClient\n baseUrl: string\n}): Promise<ExperimentType[]> => {\n const query = `*[_id == 'secrets.${namespace}'][0].secrets.${pluginConfigKeys[0].key}`\n\n const secret = await client.fetch(query) // secret is stored in the content lake using @sanity/studio-secrets\n if (!secret) return []\n\n const featureExperiments: ExperimentType[] = []\n let hasMore = true\n let offset = 0\n const url = new URL(`${baseUrl}/features`)\n if (project) {\n url.searchParams.set('projectId', project)\n }\n\n while (hasMore) {\n url.searchParams.set('offset', offset.toString())\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${secret}`,\n },\n })\n\n const {features, hasMore: responseHasMore, nextOffset} = await response.json()\n\n hasMore = responseHasMore\n offset = nextOffset\n if (!features) continue\n\n features.forEach((feature: GrowthbookFeature) => {\n if (feature.archived) {\n return undefined\n }\n if (tags && feature.tags && !feature.tags.some((tag) => tags.includes(tag))) {\n return undefined\n }\n\n const experiments = feature.environments[environment]?.rules.filter(\n (experiment) => experiment.type === 'experiment-ref' || experiment.type === 'experiment',\n )\n\n if (!experiments) {\n return undefined\n }\n\n const variations: VariantType[] = []\n const uniqueValues = new Set<string>()\n\n experiments.forEach((experiment) => {\n experiment?.variations.forEach((variant) => {\n const value = convertBooleans ? getBooleanConversion(variant.value) : variant.value\n if (!uniqueValues.has(value)) {\n uniqueValues.add(value)\n variations.push({\n id: value,\n label: value,\n })\n }\n })\n })\n const value = {id: feature.id, label: feature.id, variants: variations}\n\n featureExperiments.push(value)\n return undefined\n })\n }\n const sortedFeatureExperiments = featureExperiments.sort((a, b) => a.id.localeCompare(b.id))\n return sortedFeatureExperiments\n}\n","import {definePlugin, isObjectInputProps} from 'sanity'\n\nimport {fieldLevelExperiments as baseFieldLevelExperiments} from '../fieldExperiments'\nimport {flattenSchemaType} from '../utils/flattenSchemaType'\nimport {GROWTHBOOK_CONFIG_DEFAULT, GrowthbookProvider} from './Components/GrowthbookContext'\nimport {GrowthbookExperimentFieldPluginConfig} from './types'\nimport {getExperiments} from './utils'\n\nexport const fieldLevelExperiments = definePlugin<GrowthbookExperimentFieldPluginConfig>(\n (config) => {\n const pluginConfig = {...GROWTHBOOK_CONFIG_DEFAULT, ...config}\n const {fields, environment, project, convertBooleans, baseUrl, tags} = pluginConfig\n return {\n name: 'sanity-growthbook-personalistaion-plugin-field-level-experiments',\n plugins: [\n baseFieldLevelExperiments({\n fields,\n experiments: (client) =>\n getExperiments({client, environment, baseUrl, project, convertBooleans, tags}),\n }),\n ],\n\n form: {\n components: {\n input: (props) => {\n const isRootInput = props.id === 'root' && isObjectInputProps(props)\n\n if (!isRootInput) {\n return props.renderDefault(props)\n }\n\n const flatFieldTypeNames = flattenSchemaType(props.schemaType).map(\n (field) => field.type.name,\n )\n\n const hasExperiment = flatFieldTypeNames.some((name) => name.startsWith('experiment'))\n\n if (!hasExperiment) {\n return props.renderDefault(props)\n }\n\n const providerProps = {\n ...props,\n growthbookFieldPluginConfig: {\n ...pluginConfig,\n },\n }\n return GrowthbookProvider(providerProps)\n },\n },\n },\n }\n },\n)\n"],"names":["useSecrets","useState","useEffect","jsxs","Fragment","jsx","SettingsView","createContext","useContext","useMemo","value","definePlugin","baseFieldLevelExperiments","isObjectInputProps","flattenSchemaType"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { definePlugin, isObjectInputProps } from "sanity";
2
- import { fieldLevelExperiments as fieldLevelExperiments$1, flattenSchemaType } from "../index.mjs";
2
+ import { fieldLevelExperiments as fieldLevelExperiments$1, flattenSchemaType } from "../_chunks-es/fieldExperiments.mjs";
3
3
  import { jsxs, Fragment, jsx } from "react/jsx-runtime";
4
4
  import { useState, useEffect, createContext, useMemo, useContext } from "react";
5
5
  import { useSecrets, SettingsView } from "@sanity/studio-secrets";
package/dist/index.d.mts CHANGED
@@ -13,10 +13,21 @@ export declare type ArrayInputProps = ArrayOfObjectsInputProps & {
13
13
  experimentId: string
14
14
  }
15
15
 
16
- export declare type ExperimentContextProps = Required<FieldPluginConfig> & {
16
+ export declare type ExperimentContextProps = Required<ExperimentFieldPluginConfig> & {
17
17
  experiments: ExperimentType[]
18
18
  }
19
19
 
20
+ export declare type ExperimentFieldPluginConfig = {
21
+ fields: (string | FieldDefinition)[]
22
+ experiments: ExperimentType[] | ((client: SanityClient) => Promise<ExperimentType[]>)
23
+ apiVersion?: string
24
+ experimentNameOverride?: string
25
+ variantNameOverride?: string
26
+ variantId?: string
27
+ variantArrayName?: string
28
+ experimentId?: string
29
+ }
30
+
20
31
  export declare type ExperimentGeneric<T> = {
21
32
  _type: string
22
33
  default?: T
@@ -38,18 +49,9 @@ export declare type ExperimentType = {
38
49
  variants: VariantType[]
39
50
  }
40
51
 
41
- export declare const fieldLevelExperiments: Plugin_2<FieldPluginConfig>
52
+ export declare const fieldLevelExperiments: Plugin_2<ExperimentFieldPluginConfig>
42
53
 
43
- export declare type FieldPluginConfig = {
44
- fields: (string | FieldDefinition)[]
45
- experiments: ExperimentType[] | ((client: SanityClient) => Promise<ExperimentType[]>)
46
- apiVersion?: string
47
- experimentNameOverride?: string
48
- variantNameOverride?: string
49
- variantId?: string
50
- variantArrayName?: string
51
- experimentId?: string
52
- }
54
+ export declare const fieldLevelPersonalization: Plugin_2<PersonalizationFieldPluginConfig>
53
55
 
54
56
  /**
55
57
  * Flattens a document's schema type into a flat array of fields and includes their path
@@ -248,6 +250,25 @@ export declare type ObjectFieldWithPath = ObjectField<SchemaType> & {
248
250
  path: Path
249
251
  }
250
252
 
253
+ export declare type PersonalizationArrayInputProps = ArrayOfObjectsInputProps & {
254
+ segmentName: string
255
+ segmentId: string
256
+ }
257
+
258
+ export declare type PersonalizationContextProps = Required<PersonalizationFieldPluginConfig> & {
259
+ segments: VariantType[]
260
+ }
261
+
262
+ export declare type PersonalizationFieldPluginConfig = {
263
+ fields: (string | FieldDefinition)[]
264
+ segments: VariantType[] | ((client: SanityClient) => Promise<VariantType[]>)
265
+ apiVersion?: string
266
+ personalizationNameOverride?: string
267
+ segmentNameOverride?: string
268
+ segmentId?: string
269
+ segmentArrayName?: string
270
+ }
271
+
251
272
  export declare type VariantGeneric<T> = {
252
273
  [key: string]: string | T | undefined
253
274
  _type: string
package/dist/index.d.ts CHANGED
@@ -13,10 +13,21 @@ export declare type ArrayInputProps = ArrayOfObjectsInputProps & {
13
13
  experimentId: string
14
14
  }
15
15
 
16
- export declare type ExperimentContextProps = Required<FieldPluginConfig> & {
16
+ export declare type ExperimentContextProps = Required<ExperimentFieldPluginConfig> & {
17
17
  experiments: ExperimentType[]
18
18
  }
19
19
 
20
+ export declare type ExperimentFieldPluginConfig = {
21
+ fields: (string | FieldDefinition)[]
22
+ experiments: ExperimentType[] | ((client: SanityClient) => Promise<ExperimentType[]>)
23
+ apiVersion?: string
24
+ experimentNameOverride?: string
25
+ variantNameOverride?: string
26
+ variantId?: string
27
+ variantArrayName?: string
28
+ experimentId?: string
29
+ }
30
+
20
31
  export declare type ExperimentGeneric<T> = {
21
32
  _type: string
22
33
  default?: T
@@ -38,18 +49,9 @@ export declare type ExperimentType = {
38
49
  variants: VariantType[]
39
50
  }
40
51
 
41
- export declare const fieldLevelExperiments: Plugin_2<FieldPluginConfig>
52
+ export declare const fieldLevelExperiments: Plugin_2<ExperimentFieldPluginConfig>
42
53
 
43
- export declare type FieldPluginConfig = {
44
- fields: (string | FieldDefinition)[]
45
- experiments: ExperimentType[] | ((client: SanityClient) => Promise<ExperimentType[]>)
46
- apiVersion?: string
47
- experimentNameOverride?: string
48
- variantNameOverride?: string
49
- variantId?: string
50
- variantArrayName?: string
51
- experimentId?: string
52
- }
54
+ export declare const fieldLevelPersonalization: Plugin_2<PersonalizationFieldPluginConfig>
53
55
 
54
56
  /**
55
57
  * Flattens a document's schema type into a flat array of fields and includes their path
@@ -248,6 +250,25 @@ export declare type ObjectFieldWithPath = ObjectField<SchemaType> & {
248
250
  path: Path
249
251
  }
250
252
 
253
+ export declare type PersonalizationArrayInputProps = ArrayOfObjectsInputProps & {
254
+ segmentName: string
255
+ segmentId: string
256
+ }
257
+
258
+ export declare type PersonalizationContextProps = Required<PersonalizationFieldPluginConfig> & {
259
+ segments: VariantType[]
260
+ }
261
+
262
+ export declare type PersonalizationFieldPluginConfig = {
263
+ fields: (string | FieldDefinition)[]
264
+ segments: VariantType[] | ((client: SanityClient) => Promise<VariantType[]>)
265
+ apiVersion?: string
266
+ personalizationNameOverride?: string
267
+ segmentNameOverride?: string
268
+ segmentId?: string
269
+ segmentArrayName?: string
270
+ }
271
+
251
272
  export declare type VariantGeneric<T> = {
252
273
  [key: string]: string | T | undefined
253
274
  _type: string