sanity-plugin-internationalized-array 3.2.1 → 3.2.2

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/lib/index.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/cache.ts","../src/constants.ts","../src/utils/getDocumentsToTranslate.ts","../src/utils/getLanguageDisplay.ts","../src/components/AddButtons.tsx","../src/components/DocumentAddButtons.tsx","../src/components/getSelectedValue.ts","../src/components/InternationalizedArrayContext.tsx","../src/components/InternationalizedField.tsx","../src/components/Preload.tsx","../src/utils/checkAllLanguagesArePresent.ts","../src/utils/createAddAllTitle.ts","../src/utils/createValueSchemaTypeName.ts","../src/utils/createAddLanguagePatches.ts","../src/fieldActions/index.ts","../src/components/createFieldName.ts","../src/components/Feedback.tsx","../src/components/InternationalizedArray.tsx","../src/utils/getLanguagesFieldOption.ts","../src/schema/array.ts","../src/components/getToneFromValidation.ts","../src/components/InternationalizedInput.tsx","../src/schema/object.ts","../src/utils/flattenSchemaType.ts","../src/plugin.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/explicit-module-boundary-types */\n\nimport * as suspend from 'suspend-react'\n\nimport type {Language, LanguageCallback} from './types'\n\nexport const namespace = 'sanity-plugin-internationalized-array'\n\nexport const version = 'v1'\n\n// Simple in-memory cache for validation functions that run outside React context\nconst validationCache = new Map<string, Language[]>()\n\n// Cache for function references to enable sharing between same functions\nconst functionCache = new Map<string, Language[]>()\n\n// Cache for function keys to avoid recalculating them\nconst functionKeyCache = new WeakMap<LanguageCallback, string>()\n\n// https://github.com/pmndrs/suspend-react#preloading\nexport const preload = (fn: () => Promise<Language[]>) =>\n suspend.preload(() => fn(), [version, namespace])\n\n// Enhanced preload function that can use custom cache keys\nexport const preloadWithKey = (\n fn: () => Promise<Language[]>,\n key: (string | number)[]\n) => suspend.preload(() => fn(), key)\n\n// https://github.com/pmndrs/suspend-react#cache-busting\nexport const clear = () => suspend.clear([version, namespace])\n\n// https://github.com/pmndrs/suspend-react#peeking-into-entries-outside-of-suspense\nexport const peek = (selectedValue: Record<string, unknown>) =>\n suspend.peek([version, namespace, selectedValue]) as Language[] | undefined\n\n// Helper function to create a stable cache key that matches the component's key structure\nexport const createCacheKey = (\n selectedValue: Record<string, unknown>,\n workspaceId?: string\n) => {\n const selectedValueHash = JSON.stringify(selectedValue)\n return workspaceId\n ? [version, namespace, selectedValueHash, workspaceId]\n : [version, namespace, selectedValueHash]\n}\n\n// Enhanced peek function that can work with workspace context\nexport const peekWithWorkspace = (\n selectedValue: Record<string, unknown>,\n workspaceId?: string\n) =>\n suspend.peek(createCacheKey(selectedValue, workspaceId)) as\n | Language[]\n | undefined\n\n// Generate a unique key for a function reference (cached for performance)\nexport const getFunctionKey = (fn: LanguageCallback): string => {\n // Check if we already have a cached key for this function\n const cachedKey = functionKeyCache.get(fn)\n if (cachedKey) {\n return cachedKey\n }\n\n // Create a hash for functions (only when needed)\n const fnStr = fn.toString()\n let hash = 0\n // Only hash the first 100 characters for performance\n const maxLength = Math.min(fnStr.length, 100)\n for (let i = 0; i < maxLength; i++) {\n const char = fnStr.charCodeAt(i)\n // eslint-disable-next-line no-bitwise\n hash = (hash << 5) - hash + char\n // eslint-disable-next-line no-bitwise\n hash &= hash // Convert to 32-bit integer\n }\n const key = `anonymous_${Math.abs(hash)}`\n functionKeyCache.set(fn, key)\n return key\n}\n\n// Create a cache key that includes function identity\nexport const createFunctionCacheKey = (\n fn: LanguageCallback,\n selectedValue: Record<string, unknown>,\n workspaceId?: string\n): string => {\n const functionKey = getFunctionKey(fn)\n const selectedValueHash = JSON.stringify(selectedValue)\n return workspaceId\n ? `${functionKey}:${selectedValueHash}:${workspaceId}`\n : `${functionKey}:${selectedValueHash}`\n}\n\n// Cache for validation functions with function awareness\nexport const getValidationCache = (key: string): Language[] | undefined => {\n return validationCache.get(key)\n}\n\nexport const setValidationCache = (\n key: string,\n languages: Language[]\n): void => {\n validationCache.set(key, languages)\n}\n\nexport const clearValidationCache = (): void => {\n validationCache.clear()\n}\n\n// Function-aware cache operations\nexport const getFunctionCache = (\n fn: LanguageCallback,\n selectedValue: Record<string, unknown>,\n workspaceId?: string\n): Language[] | undefined => {\n const key = createFunctionCacheKey(fn, selectedValue, workspaceId)\n return functionCache.get(key)\n}\n\nexport const setFunctionCache = (\n fn: LanguageCallback,\n selectedValue: Record<string, unknown>,\n languages: Language[],\n workspaceId?: string\n): void => {\n const key = createFunctionCacheKey(fn, selectedValue, workspaceId)\n functionCache.set(key, languages)\n}\n\nexport const clearFunctionCache = (): void => {\n functionCache.clear()\n}\n\n// Clear function key cache as well\nexport const clearAllCaches = (): void => {\n functionCache.clear()\n // Note: WeakMap doesn't have a clear method, but it will be garbage collected\n // when the function references are no longer held\n}\n\n// Check if two functions are the same reference\nexport const isSameFunction = (\n fn1: LanguageCallback,\n fn2: LanguageCallback\n): boolean => {\n return fn1 === fn2 || getFunctionKey(fn1) === getFunctionKey(fn2)\n}\n","import {PluginConfig} from './types'\n\nexport const MAX_COLUMNS = {\n codeOnly: 5,\n titleOnly: 4,\n titleAndCode: 3,\n}\n\nexport const CONFIG_DEFAULT: Required<PluginConfig> = {\n languages: [],\n select: {},\n defaultLanguages: [],\n fieldTypes: [],\n apiVersion: '2025-10-15',\n buttonLocations: ['field'],\n buttonAddAll: true,\n languageDisplay: 'codeOnly',\n}\n","import {SanityDocument} from 'sanity'\n\nexport interface DocumentsToTranslate {\n path: (string | number)[]\n pathString: string\n _key: string\n _type: string\n [key: string]: unknown\n}\n\nexport const getDocumentsToTranslate = (\n value: SanityDocument | unknown,\n rootPath: (string | number)[] = []\n): DocumentsToTranslate[] => {\n if (Array.isArray(value)) {\n const arrayRootPath = [...rootPath]\n\n // if item contains internationalized return array\n const internationalizedValues = value.filter((item) => {\n if (Array.isArray(item)) return false\n\n if (typeof item === 'object') {\n const type = item?._type as string | undefined\n return (\n type?.startsWith('internationalizedArray') && type?.endsWith('Value')\n )\n }\n return false\n })\n\n if (internationalizedValues.length > 0) {\n return internationalizedValues.map((internationalizedValue) => {\n return {\n ...internationalizedValue,\n path: arrayRootPath,\n pathString: arrayRootPath.join('.'),\n }\n })\n }\n\n if (value.length > 0) {\n return value\n .map((item, index) =>\n getDocumentsToTranslate(item, [...arrayRootPath, index])\n )\n .flat()\n }\n\n return []\n }\n if (typeof value === 'object' && value) {\n const startsWithUnderscoreRegex = /^_/\n const itemKeys = Object.keys(value).filter(\n (key) => !key.match(startsWithUnderscoreRegex)\n ) as (keyof typeof value)[]\n\n return itemKeys\n .map((item) => {\n const selectedValue = value[item] as unknown\n const path = [...rootPath, item]\n return getDocumentsToTranslate(selectedValue, path)\n })\n .flat()\n }\n return []\n}\n","import {LanguageDisplay} from '../types'\n\nexport function getLanguageDisplay(\n languageDisplay: LanguageDisplay,\n title: string,\n code: string\n): string {\n if (languageDisplay === 'codeOnly') return code.toUpperCase()\n if (languageDisplay === 'titleOnly') return title\n if (languageDisplay === 'titleAndCode')\n return `${title} (${code.toUpperCase()})`\n return title\n}\n","import {AddIcon} from '@sanity/icons'\nimport {Button, Grid} from '@sanity/ui'\nimport type React from 'react'\nimport {memo} from 'react'\n\nimport {MAX_COLUMNS} from '../constants'\nimport type {Language, Value} from '../types'\nimport {getLanguageDisplay} from '../utils/getLanguageDisplay'\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\ntype AddButtonsProps = {\n languages: Language[]\n readOnly: boolean\n value: Value[] | undefined\n onClick: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void\n}\n\nfunction AddButtons(props: AddButtonsProps) {\n const {languages, readOnly, value, onClick} = props\n const {languageDisplay} = useInternationalizedArrayContext()\n\n return languages.length > 0 ? (\n <Grid\n columns={Math.min(languages.length, MAX_COLUMNS[languageDisplay])}\n gap={2}\n >\n {languages.map((language) => {\n const languageTitle: string = getLanguageDisplay(\n languageDisplay,\n language.title,\n language.id\n )\n return (\n <Button\n key={language.id}\n tone=\"primary\"\n mode=\"ghost\"\n fontSize={1}\n disabled={\n readOnly ||\n Boolean(value?.find((item) => item._key === language.id))\n }\n text={languageTitle}\n // Only show plus icon if there's one row or less AND only showing codes\n icon={\n languages.length > MAX_COLUMNS[languageDisplay] &&\n languageDisplay === 'codeOnly'\n ? undefined\n : AddIcon\n }\n value={language.id}\n onClick={onClick}\n />\n )\n })}\n </Grid>\n ) : null\n}\n\nexport default memo(AddButtons)\n","import {Box, Stack, Text, useToast} from '@sanity/ui'\nimport React, {useCallback} from 'react'\nimport {\n FormInsertPatch,\n FormSetIfMissingPatch,\n insert,\n isSanityDocument,\n PatchEvent,\n setIfMissing,\n useSchema,\n} from 'sanity'\nimport {useDocumentPane} from 'sanity/structure'\n\nimport {\n DocumentsToTranslate,\n getDocumentsToTranslate,\n} from '../utils/getDocumentsToTranslate'\nimport AddButtons from './AddButtons'\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\ntype DocumentAddButtonsProps = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n value: Record<string, any> | undefined\n}\nexport default function DocumentAddButtons(\n props: DocumentAddButtonsProps\n): React.ReactElement {\n const {filteredLanguages} = useInternationalizedArrayContext()\n const value = isSanityDocument(props.value) ? props.value : undefined\n\n const toast = useToast()\n const {onChange} = useDocumentPane()\n const schema = useSchema()\n\n const documentsToTranslation = getDocumentsToTranslate(value, [])\n\n // Helper function to determine if a field should be initialized as an array\n const getInitialValueForType = useCallback(\n (typeName: string): unknown => {\n if (!typeName) return undefined\n\n // Extract the base type name from internationalized array type\n // e.g., \"internationalizedArrayBodyValue\" -> \"body\"\n const match = typeName.match(/^internationalizedArray(.+)Value$/)\n if (!match) return undefined\n\n const baseTypeName = match[1].charAt(0).toLowerCase() + match[1].slice(1)\n\n // Check if it's a known array-based type (Portable Text fields)\n const arrayBasedTypes = [\n 'body',\n 'htmlContent',\n 'blockContent',\n 'portableText',\n ]\n if (arrayBasedTypes.includes(baseTypeName)) {\n return []\n }\n\n // Try to look up the schema type to determine if it's an array\n try {\n const schemaType = schema.get(typeName)\n if (schemaType) {\n // Check if this is an object type with a 'value' field\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const valueField = (schemaType as any)?.fields?.find(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (f: any) => f.name === 'value'\n )\n if (valueField) {\n const fieldType = valueField.type\n // Check if the value field is an array type\n if (\n fieldType?.jsonType === 'array' ||\n fieldType?.name === 'array' ||\n fieldType?.type === 'array' ||\n fieldType?.of !== undefined ||\n arrayBasedTypes.includes(fieldType?.name)\n ) {\n return []\n }\n }\n }\n } catch (error) {\n // If we can't determine from schema, fall back to undefined\n console.warn(\n 'Could not determine field type from schema:',\n typeName,\n error\n )\n }\n\n return undefined\n },\n [schema]\n )\n\n const handleDocumentButtonClick = useCallback(\n async (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {\n const languageId = event.currentTarget.value\n if (!languageId) {\n toast.push({\n status: 'error',\n title: 'No language selected',\n })\n return\n }\n const alreadyTranslated = documentsToTranslation.filter(\n (translation) => translation?._key === languageId\n )\n const removeDuplicates = documentsToTranslation.reduce<\n DocumentsToTranslate[]\n >((filteredTranslations, translation) => {\n if (\n alreadyTranslated.filter(\n (alreadyTranslation) =>\n alreadyTranslation.pathString === translation.pathString\n ).length > 0\n ) {\n return filteredTranslations\n }\n const translationAlreadyExists = filteredTranslations.filter(\n (filteredTranslation) => filteredTranslation.path === translation.path\n )\n\n if (translationAlreadyExists.length > 0) {\n return filteredTranslations\n }\n return [...filteredTranslations, translation]\n }, [])\n if (removeDuplicates.length === 0) {\n toast.push({\n status: 'error',\n title: 'No internationalizedArray fields found in document root',\n })\n return\n }\n\n // Write a new patch for each empty field\n const patches: (FormSetIfMissingPatch | FormInsertPatch)[] = []\n\n for (const toTranslate of removeDuplicates) {\n const path = toTranslate.path\n\n // Get the appropriate initial value for this field type\n const initialValue = getInitialValueForType(toTranslate._type)\n\n const ifMissing = setIfMissing([], path)\n const insertValue = insert(\n [\n {\n _key: languageId,\n _type: toTranslate._type,\n value: initialValue, // Use the determined initial value instead of undefined\n },\n ],\n 'after',\n [...path, -1]\n )\n patches.push(ifMissing)\n patches.push(insertValue)\n }\n\n onChange(PatchEvent.from(patches.flat()))\n },\n [documentsToTranslation, getInitialValueForType, onChange, toast]\n )\n return (\n <Stack space={3}>\n <Box>\n <Text size={1} weight=\"semibold\">\n Add translation to internationalized fields\n </Text>\n </Box>\n <AddButtons\n languages={filteredLanguages}\n readOnly={false}\n value={undefined}\n onClick={handleDocumentButtonClick}\n />\n </Stack>\n )\n}\n","import {get} from 'lodash'\n\nexport const getSelectedValue = (\n select: Record<string, string> | undefined,\n document:\n | {\n [x: string]: unknown\n }\n | undefined\n): Record<string, unknown> => {\n if (!select || !document) {\n return {}\n }\n\n const selection: Record<string, string> = select || {}\n const selectedValue: Record<string, unknown> = {}\n for (const [key, path] of Object.entries(selection)) {\n let value = get(document, path)\n if (Array.isArray(value)) {\n // If there are references in the array, ensure they have `_ref` set, otherwise they are considered empty and can safely be ignored\n value = value.filter((item) =>\n typeof item === 'object'\n ? item?._type === 'reference' && '_ref' in item\n : true\n )\n }\n selectedValue[key] = value\n }\n\n return selectedValue\n}\n","import {useLanguageFilterStudioContext} from '@sanity/language-filter'\nimport {Stack} from '@sanity/ui'\nimport equal from 'fast-deep-equal'\nimport type React from 'react'\nimport {createContext, useContext, useDeferredValue, useMemo} from 'react'\nimport {type ObjectInputProps, useClient, useWorkspace} from 'sanity'\nimport {useDocumentPane} from 'sanity/structure'\nimport {suspend} from 'suspend-react'\n\nimport {createCacheKey, setFunctionCache} from '../cache'\nimport {CONFIG_DEFAULT} from '../constants'\nimport type {Language, PluginConfig} from '../types'\nimport DocumentAddButtons from './DocumentAddButtons'\nimport {getSelectedValue} from './getSelectedValue'\n\n// This provider makes the plugin config available to all components in the document form\n// But with languages resolved and filtered languages updated base on @sanity/language-filter\n\ntype InternationalizedArrayContextProps = Required<PluginConfig> & {\n languages: Language[]\n filteredLanguages: Language[]\n}\n\nexport const InternationalizedArrayContext =\n createContext<InternationalizedArrayContextProps>({\n ...CONFIG_DEFAULT,\n languages: [],\n filteredLanguages: [],\n })\n\nexport function useInternationalizedArrayContext(): InternationalizedArrayContextProps {\n return useContext(InternationalizedArrayContext)\n}\n\ntype InternationalizedArrayProviderProps = ObjectInputProps & {\n internationalizedArray: Required<PluginConfig>\n}\n\nexport function InternationalizedArrayProvider(\n props: InternationalizedArrayProviderProps\n): React.ReactElement {\n const {internationalizedArray} = props\n\n const client = useClient({apiVersion: internationalizedArray.apiVersion})\n const workspace = useWorkspace()\n const {formState} = useDocumentPane()\n const deferredDocument = useDeferredValue(formState?.value)\n const selectedValue = useMemo(\n () => getSelectedValue(internationalizedArray.select, deferredDocument),\n [internationalizedArray.select, deferredDocument]\n )\n\n // Use a stable workspace identifier to prevent unnecessary re-renders\n const workspaceId = useMemo(() => {\n // Use workspace name if available, otherwise create a stable hash\n if (workspace?.name) {\n return workspace.name\n }\n // Create a stable hash from workspace properties that matter for caching\n const workspaceKey = {\n name: workspace?.name,\n title: workspace?.title,\n // Add other stable properties as needed\n }\n return JSON.stringify(workspaceKey)\n }, [workspace])\n\n // Memoize the cache key to prevent expensive JSON.stringify calls\n const cacheKey = useMemo(\n () => createCacheKey(selectedValue, workspaceId),\n [selectedValue, workspaceId]\n )\n\n // Fetch or return languages\n const languages = Array.isArray(internationalizedArray.languages)\n ? internationalizedArray.languages\n : suspend(\n // eslint-disable-next-line require-await\n async () => {\n if (typeof internationalizedArray.languages === 'function') {\n const result = await internationalizedArray.languages(\n client,\n selectedValue\n )\n // Populate function cache for use outside React context\n setFunctionCache(\n internationalizedArray.languages,\n selectedValue,\n result,\n workspaceId\n )\n return result\n }\n return internationalizedArray.languages\n },\n cacheKey,\n {equal}\n )\n\n // Filter out some languages if language filter is enabled\n const {selectedLanguageIds, options: languageFilterOptions} =\n useLanguageFilterStudioContext()\n\n const filteredLanguages = useMemo(() => {\n const documentType = deferredDocument ? deferredDocument._type : undefined\n const languageFilterEnabled =\n typeof documentType === 'string' &&\n languageFilterOptions.documentTypes.includes(documentType)\n\n return languageFilterEnabled\n ? languages.filter((language) =>\n selectedLanguageIds.includes(language.id)\n )\n : languages\n }, [deferredDocument, languageFilterOptions, languages, selectedLanguageIds])\n\n const showDocumentButtons =\n internationalizedArray.buttonLocations.includes('document')\n const context = useMemo(\n () => ({...internationalizedArray, languages, filteredLanguages}),\n [filteredLanguages, internationalizedArray, languages]\n )\n\n return (\n <InternationalizedArrayContext.Provider value={context}>\n {showDocumentButtons ? (\n <Stack space={5}>\n <DocumentAddButtons value={props.value} />\n {props.renderDefault(props)}\n </Stack>\n ) : (\n props.renderDefault(props)\n )}\n </InternationalizedArrayContext.Provider>\n )\n}\n","import type {ReactNode} from 'react'\nimport {useMemo} from 'react'\nimport {type FieldProps} from 'sanity'\n\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\nexport default function InternationalizedField(props: FieldProps): ReactNode {\n const {languages} = useInternationalizedArrayContext()\n\n // hide titles for 'value' fields within valid language entries\n const customProps = useMemo(() => {\n const pathSegment = props.path.slice(0, -1)[1]\n const languageId =\n typeof pathSegment === 'object' && '_key' in pathSegment\n ? pathSegment._key\n : undefined\n const hasValidLanguageId = languageId\n ? languages.some((l) => l.id === languageId)\n : false\n const shouldHideTitle =\n props.title?.toLowerCase() === 'value' && hasValidLanguageId\n\n return {\n ...props,\n title: shouldHideTitle ? '' : props.title,\n }\n }, [props, languages])\n\n if (!customProps.schemaType.name.startsWith('internationalizedArray')) {\n return customProps.renderDefault(customProps)\n }\n\n // Show reference field selector if there's a value\n if (customProps.schemaType.name === 'reference' && customProps.value) {\n return customProps.renderDefault({\n ...customProps,\n title: '',\n level: 0, // Reset the level to avoid nested styling\n })\n }\n\n // For basic field types, we can use children to keep the simple input\n if (\n customProps.schemaType.name === 'string' ||\n customProps.schemaType.name === 'number' ||\n customProps.schemaType.name === 'text'\n ) {\n return customProps.children\n }\n\n // For complex fields (like markdown), we need to use renderDefault\n // to get all the field's functionality\n return customProps.renderDefault({\n ...customProps,\n level: 0, // Reset the level to avoid nested styling\n })\n}\n","import {memo} from 'react'\nimport {useClient} from 'sanity'\n\nimport {createCacheKey, peek, preloadWithKey, setFunctionCache} from '../cache'\nimport type {PluginConfig} from '../types'\n\nexport default memo(function Preload(\n props: Required<Pick<PluginConfig, 'apiVersion' | 'languages'>>\n) {\n const client = useClient({apiVersion: props.apiVersion})\n\n // Use the same cache key structure as the main component\n // This should match the main component when selectedValue is empty\n const cacheKey = createCacheKey({})\n\n if (!Array.isArray(peek({}))) {\n // eslint-disable-next-line require-await\n preloadWithKey(async () => {\n if (Array.isArray(props.languages)) {\n return props.languages\n }\n const result = await props.languages(client, {})\n // Populate function cache for sharing with other components\n // Use the same key structure as the main component\n setFunctionCache(props.languages, {}, result)\n return result\n }, cacheKey)\n }\n\n return null\n})\n","import {Language, Value} from '../types'\n\nexport function checkAllLanguagesArePresent(\n languages: Language[],\n value: Value[] | undefined\n): boolean {\n const filteredLanguageIds = languages.map((l) => l.id)\n const languagesInUseIds = value ? value.map((v) => v._key) : []\n\n return (\n languagesInUseIds.length === filteredLanguageIds.length &&\n languagesInUseIds.every((l) => filteredLanguageIds.includes(l))\n )\n}\n","import {Language, Value} from '../types'\n\nexport function createAddAllTitle(\n value: Value[] | undefined,\n languages: Language[]\n): string {\n if (value?.length) {\n return `Add missing ${\n languages.length - value.length === 1 ? `language` : `languages`\n }`\n }\n\n return languages.length === 1\n ? `Add ${languages[0].title} Field`\n : `Add all languages`\n}\n","import {SchemaType} from 'sanity'\n\nexport function createValueSchemaTypeName(schemaType: SchemaType): string {\n return `${schemaType.name}Value`\n}\n","import {FormInsertPatch, insert, Path, SchemaType} from 'sanity'\n\nimport {Language, Value} from '../types'\nimport {createValueSchemaTypeName} from './createValueSchemaTypeName'\n\ntype AddConfig = {\n // New keys to add to the field\n addLanguageKeys: string[]\n // Schema of the current field\n schemaType: SchemaType\n // All languages registered in the plugin\n languages: Language[]\n // Languages that are currently visible\n filteredLanguages: Language[]\n // Current value of the internationalizedArray field\n value?: Value[]\n // Path to this item\n path?: Path\n}\n\nexport function createAddLanguagePatches(config: AddConfig): FormInsertPatch[] {\n const {\n addLanguageKeys,\n schemaType,\n languages,\n filteredLanguages,\n value,\n path = [],\n } = config\n\n const itemBase = {_type: createValueSchemaTypeName(schemaType)}\n\n // Create new items\n const getNewItems = () => {\n if (Array.isArray(addLanguageKeys) && addLanguageKeys.length > 0) {\n return addLanguageKeys.map((id) => ({\n ...itemBase,\n _key: id,\n }))\n }\n\n return filteredLanguages\n .filter((language) =>\n value?.length ? !value.find((v) => v._key === language.id) : true\n )\n .map((language) => ({\n ...itemBase,\n _key: language.id,\n }))\n }\n const newItems = getNewItems()\n\n // Insert new items in the correct order\n const languagesInUse = value?.length ? value.map((v) => v) : []\n\n const insertions = newItems.map((item) => {\n // What's the original index of this language?\n const languageIndex = languages.findIndex((l) => item._key === l.id)\n\n // What languages are there beyond that index?\n const remainingLanguages = languages.slice(languageIndex + 1)\n\n // So what is the index in the current value array of the next language in the language array?\n const nextLanguageIndex = languagesInUse.findIndex((l) =>\n // eslint-disable-next-line max-nested-callbacks\n remainingLanguages.find((r) => r.id === l._key)\n )\n\n // Keep local state up to date incase multiple insertions are being made\n if (nextLanguageIndex < 0) {\n languagesInUse.push(item)\n } else {\n languagesInUse.splice(nextLanguageIndex, 0, item)\n }\n\n return nextLanguageIndex < 0\n ? // No next language (-1), add to end of array\n insert([item], 'after', [...path, nextLanguageIndex])\n : // Next language found, insert before that\n insert([item], 'before', [...path, nextLanguageIndex])\n })\n\n return insertions\n}\n","import {AddIcon, TranslateIcon} from '@sanity/icons'\nimport {useCallback} from 'react'\nimport {\n defineDocumentFieldAction,\n type DocumentFieldActionItem,\n type DocumentFieldActionProps,\n PatchEvent,\n setIfMissing,\n useFormValue,\n} from 'sanity'\nimport {useDocumentPane} from 'sanity/structure'\n\nimport {useInternationalizedArrayContext} from '../components/InternationalizedArrayContext'\nimport type {Language, Value} from '../types'\nimport {checkAllLanguagesArePresent} from '../utils/checkAllLanguagesArePresent'\nimport {createAddAllTitle} from '../utils/createAddAllTitle'\nimport {createAddLanguagePatches} from '../utils/createAddLanguagePatches'\n\nconst createTranslateFieldActions: (\n fieldActionProps: DocumentFieldActionProps,\n context: {\n languages: Language[]\n filteredLanguages: Language[]\n }\n) => DocumentFieldActionItem[] = (\n fieldActionProps,\n {languages, filteredLanguages}\n) =>\n languages.map((language) => {\n const value = useFormValue(fieldActionProps.path) as Value[]\n const disabled =\n value && Array.isArray(value)\n ? Boolean(value?.find((item) => item._key === language.id))\n : false\n const hidden = !filteredLanguages.some((f) => f.id === language.id)\n\n const {onChange} = useDocumentPane()\n\n const onAction = useCallback(() => {\n const {schemaType, path} = fieldActionProps\n\n const addLanguageKeys = [language.id]\n const patches = createAddLanguagePatches({\n addLanguageKeys,\n schemaType,\n languages,\n filteredLanguages,\n value,\n path,\n })\n\n onChange(PatchEvent.from([setIfMissing([], path), ...patches]))\n }, [language.id, value, onChange])\n\n return {\n type: 'action',\n icon: AddIcon,\n onAction,\n title: language.title,\n hidden,\n disabled,\n }\n })\n\nconst AddMissingTranslationsFieldAction: (\n fieldActionProps: DocumentFieldActionProps,\n context: {\n languages: Language[]\n filteredLanguages: Language[]\n }\n) => DocumentFieldActionItem = (\n fieldActionProps,\n {languages, filteredLanguages}\n) => {\n const value = useFormValue(fieldActionProps.path) as Value[]\n const disabled = value && value.length === filteredLanguages.length\n const hidden = checkAllLanguagesArePresent(filteredLanguages, value)\n\n const {onChange} = useDocumentPane()\n\n const onAction = useCallback(() => {\n const {schemaType, path} = fieldActionProps\n\n const addLanguageKeys: string[] = []\n const patches = createAddLanguagePatches({\n addLanguageKeys,\n schemaType,\n languages,\n filteredLanguages,\n value,\n path,\n })\n\n onChange(PatchEvent.from([setIfMissing([], path), ...patches]))\n }, [fieldActionProps, filteredLanguages, languages, onChange, value])\n\n return {\n type: 'action',\n icon: AddIcon,\n onAction,\n title: createAddAllTitle(value, filteredLanguages),\n disabled,\n hidden,\n }\n}\n\nexport const internationalizedArrayFieldAction = defineDocumentFieldAction({\n name: 'internationalizedArray',\n useAction(fieldActionProps) {\n const isInternationalizedArrayField =\n fieldActionProps?.schemaType?.type?.name.startsWith(\n 'internationalizedArray'\n )\n const {languages, filteredLanguages} = useInternationalizedArrayContext()\n\n const translateFieldActions = createTranslateFieldActions(\n fieldActionProps,\n {languages, filteredLanguages}\n )\n\n return {\n type: 'group',\n icon: TranslateIcon,\n title: 'Add Translation',\n renderAsButton: true,\n children: isInternationalizedArrayField\n ? [\n ...translateFieldActions,\n AddMissingTranslationsFieldAction(fieldActionProps, {\n languages,\n filteredLanguages,\n }),\n ]\n : [],\n hidden: !isInternationalizedArrayField,\n }\n },\n})\n","export function camelCase(string: string): string {\n return string.replace(/-([a-z])/g, (g) => g[1].toUpperCase())\n}\n\nexport function titleCase(string: string): string {\n return string\n .split(` `)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(` `)\n}\n\nexport function pascalCase(string: string): string {\n return titleCase(camelCase(string))\n}\n\nexport function createFieldName(name: string, addValue = false): string {\n return addValue\n ? [`internationalizedArray`, pascalCase(name), `Value`].join(``)\n : [`internationalizedArray`, pascalCase(name)].join(``)\n}\n","import {Card, Code, Stack, Text} from '@sanity/ui'\nimport type React from 'react'\n\nconst schemaExample = {\n languages: [\n {id: 'en', title: 'English'},\n {id: 'no', title: 'Norsk'},\n ],\n}\n\nexport default function Feedback(): React.ReactElement {\n return (\n <Card tone=\"caution\" border radius={2} padding={3}>\n <Stack space={4}>\n <Text>\n An array of language objects must be passed into the{' '}\n <code>internationalizedArray</code> helper function, each with an{' '}\n <code>id</code> and <code>title</code> field. Example:\n </Text>\n <Card padding={2} border radius={2}>\n <Code size={1} language=\"javascript\">\n {JSON.stringify(schemaExample, null, 2)}\n </Code>\n </Card>\n </Stack>\n </Card>\n )\n}\n","import {AddIcon} from '@sanity/icons'\nimport {useLanguageFilterStudioContext} from '@sanity/language-filter'\nimport {Button, Card, Stack, Text, useToast} from '@sanity/ui'\nimport type React from 'react'\nimport {useCallback, useEffect, useMemo} from 'react'\nimport {\n type ArrayOfObjectsInputProps,\n ArrayOfObjectsItem,\n type ArraySchemaType,\n MemberItemError,\n set,\n setIfMissing,\n useFormValue,\n} from 'sanity'\nimport {useDocumentPane} from 'sanity/structure'\n\nimport type {Value} from '../types'\nimport {checkAllLanguagesArePresent} from '../utils/checkAllLanguagesArePresent'\nimport {createAddAllTitle} from '../utils/createAddAllTitle'\nimport {createAddLanguagePatches} from '../utils/createAddLanguagePatches'\nimport AddButtons from './AddButtons'\nimport Feedback from './Feedback'\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\nexport type InternationalizedArrayProps = ArrayOfObjectsInputProps<\n Value,\n ArraySchemaType\n>\n\nexport default function InternationalizedArray(\n props: InternationalizedArrayProps\n): React.ReactElement {\n const {\n members,\n value,\n schemaType,\n onChange,\n readOnly: documentReadOnly,\n } = props\n\n const readOnly =\n typeof schemaType.readOnly === 'boolean' ? schemaType.readOnly : false\n const toast = useToast()\n\n const {\n languages,\n filteredLanguages,\n defaultLanguages,\n buttonAddAll,\n buttonLocations,\n } = useInternationalizedArrayContext()\n\n // Support updating the UI if languageFilter is installed\n const {selectedLanguageIds, options: languageFilterOptions} =\n useLanguageFilterStudioContext()\n const documentType = useFormValue(['_type'])\n const languageFilterEnabled =\n typeof documentType === 'string' &&\n languageFilterOptions.documentTypes.includes(documentType)\n\n const filteredMembers = useMemo(\n () =>\n languageFilterEnabled\n ? members.filter((member) => {\n // This member is the outer object created by the plugin\n // Satisfy TS\n if (member.kind !== 'item') {\n return false\n }\n\n // This is the inner \"value\" field member created by this plugin\n const valueMember = member.item.members[0]\n\n // Satisfy TS\n if (valueMember.kind !== 'field') {\n return false\n }\n\n return languageFilterOptions.filterField(\n member.item.schemaType,\n valueMember,\n selectedLanguageIds\n )\n })\n : members,\n [languageFilterEnabled, members, languageFilterOptions, selectedLanguageIds]\n )\n\n const handleAddLanguage = useCallback(\n async (\n param?: React.MouseEvent<HTMLButtonElement, MouseEvent> | string[]\n ) => {\n if (!filteredLanguages?.length) {\n return\n }\n\n const addLanguageKeys: string[] = Array.isArray(param)\n ? param\n : ([param?.currentTarget?.value].filter(Boolean) as string[])\n\n const patches = createAddLanguagePatches({\n addLanguageKeys,\n schemaType,\n languages,\n filteredLanguages,\n value,\n })\n\n onChange([setIfMissing([]), ...patches])\n },\n [filteredLanguages, languages, onChange, schemaType, value]\n )\n\n const {isDeleting} = useDocumentPane()\n\n const addedLanguages = members.map(({key}) => key)\n const hasAddedDefaultLanguages = defaultLanguages\n .filter((language) => languages.find((l) => l.id === language))\n .every((language) => addedLanguages.includes(language))\n\n useEffect(() => {\n if (!isDeleting && !hasAddedDefaultLanguages) {\n const languagesToAdd = defaultLanguages\n .filter((language) => !addedLanguages.includes(language))\n .filter((language) => languages.find((l) => l.id === language))\n // Account for strict mode by scheduling the update\n const timeout = setTimeout(() => {\n if (!documentReadOnly) handleAddLanguage(languagesToAdd)\n })\n return () => clearTimeout(timeout)\n }\n return undefined\n }, [\n isDeleting,\n hasAddedDefaultLanguages,\n handleAddLanguage,\n defaultLanguages,\n addedLanguages,\n languages,\n documentReadOnly,\n ])\n\n // NOTE: This is reordering and re-setting the whole array, it could be surgical\n const handleRestoreOrder = useCallback(() => {\n if (!value?.length || !languages?.length) {\n return\n }\n\n // Create a new value array in the correct order\n // This would also strip out values that don't have a language as the key\n const updatedValue = value\n .reduce((acc, v) => {\n const newIndex = languages.findIndex((l) => l.id === v?._key)\n\n if (newIndex > -1) {\n acc[newIndex] = v\n }\n\n return acc\n }, [] as Value[])\n .filter(Boolean)\n\n if (value?.length !== updatedValue.length) {\n toast.push({\n title: 'There was an error reordering languages',\n status: 'warning',\n })\n }\n\n onChange(set(updatedValue))\n }, [toast, languages, onChange, value])\n\n const allKeysAreLanguages = useMemo(() => {\n if (!value?.length || !languages?.length) {\n return true\n }\n\n return value?.every((v) => languages.find((l) => l?.id === v?._key))\n }, [value, languages])\n\n // Check languages are in the correct order\n const languagesInUse = useMemo(\n () =>\n languages && languages.length > 1\n ? languages.filter((l) => value?.find((v) => v._key === l.id))\n : [],\n [languages, value]\n )\n\n const languagesOutOfOrder = useMemo(() => {\n if (!value?.length || !languagesInUse.length) {\n return []\n }\n\n return value\n .map((v, vIndex) =>\n vIndex === languagesInUse.findIndex((l) => l.id === v._key) ? null : v\n )\n .filter(Boolean)\n }, [value, languagesInUse])\n\n const languagesAreValid = useMemo(\n () =>\n !languages?.length ||\n (languages?.length && languages.every((item) => item.id && item.title)),\n [languages]\n )\n\n // Automatically restore order of fields\n useEffect(() => {\n if (languagesOutOfOrder.length > 0 && allKeysAreLanguages) {\n handleRestoreOrder()\n }\n }, [languagesOutOfOrder, allKeysAreLanguages, handleRestoreOrder])\n\n // compare value keys with possible languages\n const allLanguagesArePresent = useMemo(\n () => checkAllLanguagesArePresent(filteredLanguages, value),\n [filteredLanguages, value]\n )\n\n if (!languagesAreValid) {\n return <Feedback />\n }\n\n const addButtonsAreVisible =\n // Plugin was configured to display buttons here (default!)\n buttonLocations.includes('field') &&\n // There's at least one language visible\n filteredLanguages?.length > 0 &&\n // Not every language has a value yet\n !allLanguagesArePresent\n const fieldHasMembers = members?.length > 0\n\n return (\n <Stack space={2}>\n {fieldHasMembers ? (\n <>\n {filteredMembers.map((member) => {\n if (member.kind === 'item') {\n return (\n <ArrayOfObjectsItem\n {...props}\n key={member.key}\n member={member}\n />\n )\n }\n\n return <MemberItemError key={member.key} member={member} />\n })}\n </>\n ) : null}\n\n {/* Give some feedback in the UI so the field doesn't look \"missing\" */}\n {!addButtonsAreVisible && !fieldHasMembers ? (\n <Card border tone=\"transparent\" padding={3} radius={2}>\n <Text size={1}>\n This internationalized field currently has no translations.\n </Text>\n </Card>\n ) : null}\n\n {addButtonsAreVisible ? (\n <Stack space={2}>\n <AddButtons\n languages={filteredLanguages}\n value={value}\n readOnly={readOnly}\n onClick={handleAddLanguage}\n />\n {buttonAddAll ? (\n <Button\n tone=\"primary\"\n mode=\"ghost\"\n disabled={readOnly || allLanguagesArePresent}\n icon={AddIcon}\n text={createAddAllTitle(value, filteredLanguages)}\n onClick={handleAddLanguage}\n />\n ) : null}\n </Stack>\n ) : null}\n </Stack>\n )\n}\n","import {SchemaType} from 'sanity'\n\nimport {ArrayFieldOptions} from '../schema/array'\n\nexport function getLanguagesFieldOption(\n schemaType: SchemaType | undefined\n): ArrayFieldOptions['languages'] | undefined {\n if (!schemaType) {\n return undefined\n }\n const languagesOption = (schemaType.options as ArrayFieldOptions)?.languages\n if (languagesOption) {\n return languagesOption\n }\n return getLanguagesFieldOption(schemaType.type)\n}\n","/* eslint-disable no-nested-ternary */\nimport {defineField, type FieldDefinition, type Rule} from 'sanity'\n\nimport {getFunctionCache, peek, setFunctionCache} from '../cache'\nimport {createFieldName} from '../components/createFieldName'\nimport {getSelectedValue} from '../components/getSelectedValue'\nimport InternationalizedArray from '../components/InternationalizedArray'\nimport type {Language, LanguageCallback, Value} from '../types'\nimport {getLanguagesFieldOption} from '../utils/getLanguagesFieldOption'\n\ntype ArrayFactoryConfig = {\n apiVersion: string\n select?: Record<string, string>\n languages: Language[] | LanguageCallback\n defaultLanguages?: string[]\n type: string | FieldDefinition\n}\n\nexport type ArrayFieldOptions = Pick<\n ArrayFactoryConfig,\n 'apiVersion' | 'select' | 'languages'\n>\n\nexport default (config: ArrayFactoryConfig): FieldDefinition<'array'> => {\n const {apiVersion, select, languages, type} = config\n const typeName = typeof type === `string` ? type : type.name\n const arrayName = createFieldName(typeName)\n const objectName = createFieldName(typeName, true)\n\n return defineField({\n name: arrayName,\n title: 'Internationalized array',\n type: 'array',\n components: {\n input: InternationalizedArray,\n },\n options: {\n // @ts-expect-error - these options are required for validation rules – not the custom input component\n apiVersion,\n select,\n languages,\n },\n of: [\n defineField({\n ...(typeof type === 'string' ? {} : type),\n name: objectName,\n type: objectName,\n }),\n ],\n // @ts-expect-error - fix typings\n validation: (rule: Rule) =>\n rule.custom<Value[]>(async (value, context) => {\n if (!value || value.length === 0) {\n return true\n }\n\n // Early return for simple cases to avoid expensive operations\n if (value.length === 1 && !value[0]?._key) {\n return true\n }\n\n const selectedValue = getSelectedValue(select, context.document)\n const client = context.getClient({apiVersion})\n\n let contextLanguages: Language[] = []\n const languagesFieldOption = getLanguagesFieldOption(context?.type)\n\n if (Array.isArray(languagesFieldOption)) {\n contextLanguages = languagesFieldOption\n } else if (Array.isArray(peek(selectedValue))) {\n contextLanguages = peek(selectedValue) || []\n } else if (typeof languagesFieldOption === 'function') {\n // Try to get from function cache first (if it's the same function as the component)\n const cachedLanguages = getFunctionCache(\n languagesFieldOption,\n selectedValue\n )\n\n if (Array.isArray(cachedLanguages)) {\n contextLanguages = cachedLanguages\n } else {\n // Try suspend cache as fallback\n const suspendCachedLanguages = peek(selectedValue)\n if (Array.isArray(suspendCachedLanguages)) {\n contextLanguages = suspendCachedLanguages\n } else {\n // Only make the async call if we don't have cached data\n contextLanguages = await languagesFieldOption(\n client,\n selectedValue\n )\n // Cache the result for future validation calls\n setFunctionCache(\n languagesFieldOption,\n selectedValue,\n contextLanguages\n )\n }\n }\n }\n\n if (value && value.length > contextLanguages.length) {\n return `Cannot be more than ${\n contextLanguages.length === 1\n ? `1 item`\n : `${contextLanguages.length} items`\n }`\n }\n\n // Create a Set for faster language ID lookups\n const languageIds = new Set(contextLanguages.map((lang) => lang.id))\n\n // Check for invalid language keys\n const nonLanguageKeys = value.filter(\n (item) => item?._key && !languageIds.has(item._key)\n )\n if (nonLanguageKeys.length) {\n return {\n message: `Array item keys must be valid languages registered to the field type`,\n paths: nonLanguageKeys.map((item) => [{_key: item._key}]),\n }\n }\n\n // Check for duplicate language keys (more efficient)\n const seenKeys = new Set<string>()\n const duplicateValues: Value[] = []\n\n for (const item of value) {\n if (item?._key) {\n if (seenKeys.has(item._key)) {\n duplicateValues.push(item)\n } else {\n seenKeys.add(item._key)\n }\n }\n }\n\n if (duplicateValues.length) {\n return {\n message: 'There can only be one field per language',\n paths: duplicateValues.map((item) => [{_key: item._key}]),\n }\n }\n\n return true\n }),\n })\n}\n","import type {CardTone} from '@sanity/ui'\nimport type {FormNodeValidation} from 'sanity'\n\nexport function getToneFromValidation(\n validations: FormNodeValidation[]\n): CardTone | undefined {\n if (!validations?.length) {\n return undefined\n }\n\n const validationLevels = validations.map((v) => v.level)\n\n if (validationLevels.includes('error')) {\n return `critical`\n } else if (validationLevels.includes('warning')) {\n return `caution`\n }\n\n return undefined\n}\n","import {RemoveCircleIcon} from '@sanity/icons'\nimport {\n Button,\n Card,\n Flex,\n Label,\n Menu,\n MenuButton,\n MenuItem,\n Spinner,\n Stack,\n Text,\n Tooltip,\n} from '@sanity/ui'\nimport type React from 'react'\nimport {ReactNode, useCallback, useMemo} from 'react'\nimport {type ObjectItemProps, useFormValue} from 'sanity'\nimport {set, unset} from 'sanity'\n\nimport {getLanguageDisplay} from '../utils/getLanguageDisplay'\nimport {getToneFromValidation} from './getToneFromValidation'\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\nexport type InternationalizedValue = {\n _type: string\n _key: string\n value: string\n}\n\nexport default function InternationalizedInput(\n props: ObjectItemProps<InternationalizedValue>\n): ReactNode {\n const parentValue = useFormValue(\n props.path.slice(0, -1)\n ) as InternationalizedValue[]\n\n // Extract the original onChange to avoid dependency issues\n const originalOnChange = props.inputProps.onChange\n\n // Create a wrapped onChange handler to intercept patches for paste operations\n const wrappedOnChange = useCallback(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (patches: any) => {\n // Ensure patches is an array before proceeding with paste logic\n // For single patch operations (like unset), pass through directly\n if (!Array.isArray(patches)) {\n return originalOnChange(patches)\n }\n\n // Check if this is a paste operation into an empty or uninitialized Portable Text field\n const valueField = props.value?.value\n const isEmptyOrUndefined =\n valueField === undefined ||\n valueField === null ||\n (Array.isArray(valueField) && valueField.length === 0)\n\n if (isEmptyOrUndefined) {\n // Check for insert patches that are trying to operate on a non-existent structure\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const hasProblematicInsert = patches.some((patch: any) => {\n // Ensure patch exists and has required properties\n if (!patch || typeof patch !== 'object') {\n return false\n }\n\n // Look for insert patches targeting the value field or direct array index\n if (\n patch.type === 'insert' &&\n patch.path &&\n Array.isArray(patch.path) &&\n patch.path.length > 0\n ) {\n // The path might be ['value', index] or just [index] depending on context\n const isTargetingValue =\n patch.path[0] === 'value' || typeof patch.path[0] === 'number'\n return isTargetingValue\n }\n return false\n })\n\n if (hasProblematicInsert) {\n // First, ensure the value field exists as an empty array if it doesn't\n const initPatch =\n valueField === undefined\n ? {type: 'setIfMissing', path: ['value'], value: []}\n : null\n\n // Transform the patches to ensure they work with the nested structure\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const fixedPatches = patches.map((patch: any) => {\n // Ensure patch exists and has required properties\n if (!patch || typeof patch !== 'object') {\n return patch\n }\n\n if (\n patch.type === 'insert' &&\n patch.path &&\n Array.isArray(patch.path)\n ) {\n // Ensure the path is correct for the nested structure\n const fixedPath =\n patch.path[0] === 'value'\n ? patch.path\n : ['value', ...patch.path]\n const fixedPatch = {...patch, path: fixedPath}\n return fixedPatch\n }\n return patch\n })\n\n // If we need to initialize the field, include that patch first\n const allPatches = initPatch\n ? [initPatch, ...fixedPatches]\n : fixedPatches\n\n return originalOnChange(allPatches)\n }\n }\n\n // For all other cases, pass through unchanged\n return originalOnChange(patches)\n },\n [props.value, originalOnChange]\n )\n\n const inlineProps = {\n ...props.inputProps,\n // This is the magic that makes inline editing work?\n members: props.inputProps.members.filter(\n (m) => m.kind === 'field' && m.name === 'value'\n ),\n // This just overrides the type\n // Remove this as it shouldn't be necessary?\n value: props.value as InternationalizedValue,\n // Use our wrapped onChange handler\n onChange: wrappedOnChange,\n }\n\n const {validation, value, onChange, readOnly} = inlineProps\n\n // The parent array contains the languages from the plugin config\n const {languages, languageDisplay, defaultLanguages} =\n useInternationalizedArrayContext()\n\n const languageKeysInUse = useMemo(\n () => parentValue?.map((v) => v._key) ?? [],\n [parentValue]\n )\n const keyIsValid = languages?.length\n ? languages.find((l) => l.id === value._key)\n : false\n\n // Changes the key of this item, ideally to a valid language\n const handleKeyChange = useCallback(\n (event: React.MouseEvent<HTMLButtonElement, MouseEvent>): void => {\n const languageId = event?.currentTarget?.value\n\n if (\n !value ||\n !languages?.length ||\n !languages.find((l) => l.id === languageId)\n ) {\n return\n }\n\n onChange([set(languageId, ['_key'])])\n },\n [onChange, value, languages]\n )\n\n // Removes this item from the array\n const handleUnset = useCallback((): void => {\n onChange(unset())\n }, [onChange])\n\n if (!languages) {\n return <Spinner />\n }\n\n const language = languages.find((l) => l.id === value._key)\n const languageTitle: string =\n keyIsValid && language\n ? getLanguageDisplay(languageDisplay, language.title, language.id)\n : ''\n\n const isDefault = defaultLanguages.includes(value._key)\n\n const removeButton = (\n <Button\n mode=\"bleed\"\n icon={RemoveCircleIcon}\n tone=\"critical\"\n disabled={readOnly || isDefault}\n onClick={handleUnset}\n />\n )\n\n return (\n <Card paddingTop={2} tone={getToneFromValidation(validation)}>\n <Stack space={2}>\n <Card tone=\"inherit\">\n {keyIsValid ? (\n <Label muted size={1}>\n {languageTitle}\n </Label>\n ) : (\n <MenuButton\n button={<Button fontSize={1} text={`Change \"${value._key}\"`} />}\n id={`${value._key}-change-key`}\n menu={\n <Menu>\n {languages.map((lang) => (\n <MenuItem\n disabled={languageKeysInUse.includes(lang.id)}\n fontSize={1}\n key={lang.id}\n text={lang.id.toLocaleUpperCase()}\n value={lang.id}\n // @ts-expect-error - fix typings\n onClick={handleKeyChange}\n />\n ))}\n </Menu>\n }\n popover={{portal: true}}\n />\n )}\n </Card>\n <Flex align=\"center\" gap={2}>\n <Card flex={1} tone=\"inherit\">\n {props.inputProps.renderInput(inlineProps)}\n </Card>\n\n <Card tone=\"inherit\">\n {isDefault ? (\n <Tooltip\n content={\n <Text muted size={1}>\n Can&apos;t remove default language\n </Text>\n }\n fallbackPlacements={['right', 'left']}\n placement=\"top\"\n portal\n >\n <span>{removeButton}</span>\n </Tooltip>\n ) : (\n removeButton\n )}\n </Card>\n </Flex>\n </Stack>\n </Card>\n )\n}\n","import {defineField, FieldDefinition} from 'sanity'\n\nimport {createFieldName} from '../components/createFieldName'\nimport InternationalizedInput from '../components/InternationalizedInput'\n\ntype ObjectFactoryConfig = {\n type: string | FieldDefinition\n}\n\nexport default (config: ObjectFactoryConfig): FieldDefinition<'object'> => {\n const {type} = config\n const typeName = typeof type === `string` ? type : type.name\n const objectName = createFieldName(typeName, true)\n\n return defineField({\n name: objectName,\n title: `Internationalized array ${type}`,\n type: 'object',\n components: {\n // @ts-expect-error - fix typings\n item: InternationalizedInput,\n },\n fields: [\n defineField({\n ...(typeof type === 'string' ? {type} : type),\n name: 'value',\n }),\n ],\n preview: {\n select: {\n title: 'value',\n subtitle: '_key',\n },\n },\n })\n}\n","import {\n isDocumentSchemaType,\n type ObjectField,\n type Path,\n type SchemaType,\n} from 'sanity'\n\ntype ObjectFieldWithPath = ObjectField<SchemaType> & {path: Path}\n\n/**\n * Flattens a document's schema type into a flat array of fields and includes their path\n */\nexport function flattenSchemaType(\n schemaType: SchemaType\n): ObjectFieldWithPath[] {\n if (!isDocumentSchemaType(schemaType)) {\n console.error(`Schema type is not a document`)\n return []\n }\n\n return extractInnerFields(schemaType.fields, [], 3)\n}\n\nfunction extractInnerFields(\n fields: ObjectField<SchemaType>[],\n path: Path,\n maxDepth: number\n): ObjectFieldWithPath[] {\n if (path.length >= maxDepth) {\n return []\n }\n\n return fields.reduce<ObjectFieldWithPath[]>((acc, field) => {\n const thisFieldWithPath = {path: [...path, field.name], ...field}\n\n if (field.type.jsonType === 'object') {\n const innerFields = extractInnerFields(\n field.type.fields,\n [...path, field.name],\n maxDepth\n )\n\n return [...acc, thisFieldWithPath, ...innerFields]\n } else if (\n field.type.jsonType === 'array' &&\n field.type.of.length &&\n field.type.of.some((item) => 'fields' in item)\n ) {\n const innerFields = field.type.of.flatMap((innerField) =>\n extractInnerFields(\n // @ts-expect-error - Fix TS assertion for array fields\n innerField.fields,\n [...path, field.name],\n maxDepth\n )\n )\n\n return [...acc, thisFieldWithPath, ...innerFields]\n }\n\n return [...acc, thisFieldWithPath]\n }, [])\n}\n","import {definePlugin, isObjectInputProps} from 'sanity'\n\nimport {InternationalizedArrayProvider} from './components/InternationalizedArrayContext'\nimport InternationalizedField from './components/InternationalizedField'\nimport Preload from './components/Preload'\nimport {CONFIG_DEFAULT} from './constants'\nimport {internationalizedArrayFieldAction} from './fieldActions'\nimport array from './schema/array'\nimport object from './schema/object'\nimport {PluginConfig} from './types'\nimport {flattenSchemaType} from './utils/flattenSchemaType'\n\nexport const internationalizedArray = definePlugin<PluginConfig>((config) => {\n const pluginConfig = {...CONFIG_DEFAULT, ...config}\n const {\n apiVersion = '2025-10-15',\n select,\n languages,\n fieldTypes,\n defaultLanguages,\n buttonLocations,\n } = pluginConfig\n\n return {\n name: 'sanity-plugin-internationalized-array',\n // Preload languages for use throughout the Studio\n studio: Array.isArray(languages)\n ? undefined\n : {\n components: {\n layout: (props) => (\n <>\n <Preload apiVersion={apiVersion} languages={languages} />\n {props.renderDefault(props)}\n </>\n ),\n },\n },\n // Optional: render \"add language\" buttons as field actions\n document: {\n unstable_fieldActions: buttonLocations.includes('unstable__fieldAction')\n ? (prev) => [...prev, internationalizedArrayFieldAction]\n : undefined,\n },\n // Wrap document editor with a language provider\n form: {\n components: {\n field: (props) => <InternationalizedField {...props} />,\n\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 const hasInternationalizedArray = flatFieldTypeNames.some((name) =>\n name.startsWith('internationalizedArray')\n )\n\n if (!hasInternationalizedArray) {\n return props.renderDefault(props)\n }\n\n return (\n <InternationalizedArrayProvider\n {...props}\n internationalizedArray={pluginConfig}\n />\n )\n },\n },\n },\n // Register custom schema types for the outer array and the inner object\n schema: {\n types: [\n ...fieldTypes.map((type) =>\n array({type, apiVersion, select, languages, defaultLanguages})\n ),\n ...fieldTypes.map((type) => object({type})),\n ],\n },\n }\n})\n"],"names":["__spreadProps","AddButtons","__spreadValues","internationalizedArray","suspend"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/cache.ts","../src/constants.ts","../src/utils/getDocumentsToTranslate.ts","../src/utils/getLanguageDisplay.ts","../src/components/AddButtons.tsx","../src/components/DocumentAddButtons.tsx","../src/components/getSelectedValue.ts","../src/components/InternationalizedArrayContext.tsx","../src/components/InternationalizedField.tsx","../src/components/Preload.tsx","../src/utils/checkAllLanguagesArePresent.ts","../src/utils/createAddAllTitle.ts","../src/utils/createValueSchemaTypeName.ts","../src/utils/createAddLanguagePatches.ts","../src/fieldActions/index.ts","../src/components/createFieldName.ts","../src/components/Feedback.tsx","../src/components/InternationalizedArray.tsx","../src/utils/getLanguagesFieldOption.ts","../src/schema/array.ts","../src/components/getToneFromValidation.ts","../src/components/InternationalizedInput.tsx","../src/schema/object.ts","../src/utils/flattenSchemaType.ts","../src/plugin.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/explicit-module-boundary-types */\n\nimport * as suspend from 'suspend-react'\n\nimport type {Language, LanguageCallback} from './types'\n\nexport const namespace = 'sanity-plugin-internationalized-array'\n\nexport const version = 'v1'\n\n// Simple in-memory cache for validation functions that run outside React context\nconst validationCache = new Map<string, Language[]>()\n\n// Cache for function references to enable sharing between same functions\nconst functionCache = new Map<string, Language[]>()\n\n// Cache for function keys to avoid recalculating them\nconst functionKeyCache = new WeakMap<LanguageCallback, string>()\n\n// https://github.com/pmndrs/suspend-react#preloading\nexport const preload = (fn: () => Promise<Language[]>) =>\n suspend.preload(() => fn(), [version, namespace])\n\n// Enhanced preload function that can use custom cache keys\nexport const preloadWithKey = (\n fn: () => Promise<Language[]>,\n key: (string | number)[]\n) => suspend.preload(() => fn(), key)\n\n// https://github.com/pmndrs/suspend-react#cache-busting\nexport const clear = () => suspend.clear([version, namespace])\n\n// https://github.com/pmndrs/suspend-react#peeking-into-entries-outside-of-suspense\nexport const peek = (selectedValue: Record<string, unknown>) =>\n suspend.peek([version, namespace, selectedValue]) as Language[] | undefined\n\n// Helper function to create a stable cache key that matches the component's key structure\nexport const createCacheKey = (\n selectedValue: Record<string, unknown>,\n workspaceId?: string\n) => {\n const selectedValueHash = JSON.stringify(selectedValue)\n return workspaceId\n ? [version, namespace, selectedValueHash, workspaceId]\n : [version, namespace, selectedValueHash]\n}\n\n// Enhanced peek function that can work with workspace context\nexport const peekWithWorkspace = (\n selectedValue: Record<string, unknown>,\n workspaceId?: string\n) =>\n suspend.peek(createCacheKey(selectedValue, workspaceId)) as\n | Language[]\n | undefined\n\n// Generate a unique key for a function reference (cached for performance)\nexport const getFunctionKey = (fn: LanguageCallback): string => {\n // Check if we already have a cached key for this function\n const cachedKey = functionKeyCache.get(fn)\n if (cachedKey) {\n return cachedKey\n }\n\n // Create a hash for functions (only when needed)\n const fnStr = fn.toString()\n let hash = 0\n // Only hash the first 100 characters for performance\n const maxLength = Math.min(fnStr.length, 100)\n for (let i = 0; i < maxLength; i++) {\n const char = fnStr.charCodeAt(i)\n // eslint-disable-next-line no-bitwise\n hash = (hash << 5) - hash + char\n // eslint-disable-next-line no-bitwise\n hash &= hash // Convert to 32-bit integer\n }\n const key = `anonymous_${Math.abs(hash)}`\n functionKeyCache.set(fn, key)\n return key\n}\n\n// Create a cache key that includes function identity\nexport const createFunctionCacheKey = (\n fn: LanguageCallback,\n selectedValue: Record<string, unknown>,\n workspaceId?: string\n): string => {\n const functionKey = getFunctionKey(fn)\n const selectedValueHash = JSON.stringify(selectedValue)\n return workspaceId\n ? `${functionKey}:${selectedValueHash}:${workspaceId}`\n : `${functionKey}:${selectedValueHash}`\n}\n\n// Cache for validation functions with function awareness\nexport const getValidationCache = (key: string): Language[] | undefined => {\n return validationCache.get(key)\n}\n\nexport const setValidationCache = (\n key: string,\n languages: Language[]\n): void => {\n validationCache.set(key, languages)\n}\n\nexport const clearValidationCache = (): void => {\n validationCache.clear()\n}\n\n// Function-aware cache operations\nexport const getFunctionCache = (\n fn: LanguageCallback,\n selectedValue: Record<string, unknown>,\n workspaceId?: string\n): Language[] | undefined => {\n const key = createFunctionCacheKey(fn, selectedValue, workspaceId)\n return functionCache.get(key)\n}\n\nexport const setFunctionCache = (\n fn: LanguageCallback,\n selectedValue: Record<string, unknown>,\n languages: Language[],\n workspaceId?: string\n): void => {\n const key = createFunctionCacheKey(fn, selectedValue, workspaceId)\n functionCache.set(key, languages)\n}\n\nexport const clearFunctionCache = (): void => {\n functionCache.clear()\n}\n\n// Clear function key cache as well\nexport const clearAllCaches = (): void => {\n functionCache.clear()\n // Note: WeakMap doesn't have a clear method, but it will be garbage collected\n // when the function references are no longer held\n}\n\n// Check if two functions are the same reference\nexport const isSameFunction = (\n fn1: LanguageCallback,\n fn2: LanguageCallback\n): boolean => {\n return fn1 === fn2 || getFunctionKey(fn1) === getFunctionKey(fn2)\n}\n","import {PluginConfig} from './types'\n\nexport const MAX_COLUMNS = {\n codeOnly: 5,\n titleOnly: 4,\n titleAndCode: 3,\n}\n\nexport const CONFIG_DEFAULT: Required<PluginConfig> = {\n languages: [],\n select: {},\n defaultLanguages: [],\n fieldTypes: [],\n apiVersion: '2025-10-15',\n buttonLocations: ['field'],\n buttonAddAll: true,\n languageDisplay: 'codeOnly',\n}\n","import {SanityDocument} from 'sanity'\n\nexport interface DocumentsToTranslate {\n path: (string | number)[]\n pathString: string\n _key: string\n _type: string\n [key: string]: unknown\n}\n\nexport const getDocumentsToTranslate = (\n value: SanityDocument | unknown,\n rootPath: (string | number)[] = []\n): DocumentsToTranslate[] => {\n if (Array.isArray(value)) {\n const arrayRootPath = [...rootPath]\n\n // if item contains internationalized return array\n const internationalizedValues = value.filter((item) => {\n if (Array.isArray(item)) return false\n\n if (typeof item === 'object') {\n const type = item?._type as string | undefined\n return (\n type?.startsWith('internationalizedArray') && type?.endsWith('Value')\n )\n }\n return false\n })\n\n if (internationalizedValues.length > 0) {\n return internationalizedValues.map((internationalizedValue) => {\n return {\n ...internationalizedValue,\n path: arrayRootPath,\n pathString: arrayRootPath.join('.'),\n }\n })\n }\n\n if (value.length > 0) {\n return value\n .map((item, index) =>\n getDocumentsToTranslate(item, [...arrayRootPath, index])\n )\n .flat()\n }\n\n return []\n }\n if (typeof value === 'object' && value) {\n const startsWithUnderscoreRegex = /^_/\n const itemKeys = Object.keys(value).filter(\n (key) => !key.match(startsWithUnderscoreRegex)\n ) as (keyof typeof value)[]\n\n return itemKeys\n .map((item) => {\n const selectedValue = value[item] as unknown\n const path = [...rootPath, item]\n return getDocumentsToTranslate(selectedValue, path)\n })\n .flat()\n }\n return []\n}\n","import {LanguageDisplay} from '../types'\n\nexport function getLanguageDisplay(\n languageDisplay: LanguageDisplay,\n title: string,\n code: string\n): string {\n if (languageDisplay === 'codeOnly') return code.toUpperCase()\n if (languageDisplay === 'titleOnly') return title\n if (languageDisplay === 'titleAndCode')\n return `${title} (${code.toUpperCase()})`\n return title\n}\n","import {AddIcon} from '@sanity/icons'\nimport {Button, Grid} from '@sanity/ui'\nimport type React from 'react'\nimport {memo} from 'react'\n\nimport {MAX_COLUMNS} from '../constants'\nimport type {Language, Value} from '../types'\nimport {getLanguageDisplay} from '../utils/getLanguageDisplay'\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\ntype AddButtonsProps = {\n languages: Language[]\n readOnly: boolean\n value: Value[] | undefined\n onClick: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void\n}\n\nfunction AddButtons(props: AddButtonsProps) {\n const {languages, readOnly, value, onClick} = props\n const {languageDisplay} = useInternationalizedArrayContext()\n\n return languages.length > 0 ? (\n <Grid\n columns={Math.min(languages.length, MAX_COLUMNS[languageDisplay])}\n gap={2}\n >\n {languages.map((language) => {\n const languageTitle: string = getLanguageDisplay(\n languageDisplay,\n language.title,\n language.id\n )\n return (\n <Button\n key={language.id}\n tone=\"primary\"\n mode=\"ghost\"\n fontSize={1}\n disabled={\n readOnly ||\n Boolean(value?.find((item) => item._key === language.id))\n }\n text={languageTitle}\n // Only show plus icon if there's one row or less AND only showing codes\n icon={\n languages.length > MAX_COLUMNS[languageDisplay] &&\n languageDisplay === 'codeOnly'\n ? undefined\n : AddIcon\n }\n value={language.id}\n onClick={onClick}\n />\n )\n })}\n </Grid>\n ) : null\n}\n\nexport default memo(AddButtons)\n","import {Box, Stack, Text, useToast} from '@sanity/ui'\nimport React, {useCallback} from 'react'\nimport {\n FormInsertPatch,\n FormSetIfMissingPatch,\n insert,\n isSanityDocument,\n PatchEvent,\n setIfMissing,\n useSchema,\n} from 'sanity'\nimport {useDocumentPane} from 'sanity/structure'\n\nimport {\n DocumentsToTranslate,\n getDocumentsToTranslate,\n} from '../utils/getDocumentsToTranslate'\nimport AddButtons from './AddButtons'\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\ntype DocumentAddButtonsProps = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n value: Record<string, any> | undefined\n}\nexport default function DocumentAddButtons(\n props: DocumentAddButtonsProps\n): React.ReactElement {\n const {filteredLanguages} = useInternationalizedArrayContext()\n const value = isSanityDocument(props.value) ? props.value : undefined\n\n const toast = useToast()\n const {onChange} = useDocumentPane()\n const schema = useSchema()\n\n const documentsToTranslation = getDocumentsToTranslate(value, [])\n\n // Helper function to determine if a field should be initialized as an array\n const getInitialValueForType = useCallback(\n (typeName: string): unknown => {\n if (!typeName) return undefined\n\n // Extract the base type name from internationalized array type\n // e.g., \"internationalizedArrayBodyValue\" -> \"body\"\n const match = typeName.match(/^internationalizedArray(.+)Value$/)\n if (!match) return undefined\n\n const baseTypeName = match[1].charAt(0).toLowerCase() + match[1].slice(1)\n\n // Check if it's a known array-based type (Portable Text fields)\n const arrayBasedTypes = [\n 'body',\n 'htmlContent',\n 'blockContent',\n 'portableText',\n ]\n if (arrayBasedTypes.includes(baseTypeName)) {\n return []\n }\n\n // Try to look up the schema type to determine if it's an array\n try {\n const schemaType = schema.get(typeName)\n if (schemaType) {\n // Check if this is an object type with a 'value' field\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const valueField = (schemaType as any)?.fields?.find(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (f: any) => f.name === 'value'\n )\n if (valueField) {\n const fieldType = valueField.type\n // Check if the value field is an array type\n if (\n fieldType?.jsonType === 'array' ||\n fieldType?.name === 'array' ||\n fieldType?.type === 'array' ||\n fieldType?.of !== undefined ||\n arrayBasedTypes.includes(fieldType?.name)\n ) {\n return []\n }\n }\n }\n } catch (error) {\n // If we can't determine from schema, fall back to undefined\n console.warn(\n 'Could not determine field type from schema:',\n typeName,\n error\n )\n }\n\n return undefined\n },\n [schema]\n )\n\n const handleDocumentButtonClick = useCallback(\n async (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {\n const languageId = event.currentTarget.value\n if (!languageId) {\n toast.push({\n status: 'error',\n title: 'No language selected',\n })\n return\n }\n const alreadyTranslated = documentsToTranslation.filter(\n (translation) => translation?._key === languageId\n )\n const removeDuplicates = documentsToTranslation.reduce<\n DocumentsToTranslate[]\n >((filteredTranslations, translation) => {\n if (\n alreadyTranslated.filter(\n (alreadyTranslation) =>\n alreadyTranslation.pathString === translation.pathString\n ).length > 0\n ) {\n return filteredTranslations\n }\n const translationAlreadyExists = filteredTranslations.filter(\n (filteredTranslation) => filteredTranslation.path === translation.path\n )\n\n if (translationAlreadyExists.length > 0) {\n return filteredTranslations\n }\n return [...filteredTranslations, translation]\n }, [])\n if (removeDuplicates.length === 0) {\n toast.push({\n status: 'error',\n title: 'No internationalizedArray fields found in document root',\n })\n return\n }\n\n // Write a new patch for each empty field\n const patches: (FormSetIfMissingPatch | FormInsertPatch)[] = []\n\n for (const toTranslate of removeDuplicates) {\n const path = toTranslate.path\n\n // Get the appropriate initial value for this field type\n const initialValue = getInitialValueForType(toTranslate._type)\n\n const ifMissing = setIfMissing([], path)\n const insertValue = insert(\n [\n {\n _key: languageId,\n _type: toTranslate._type,\n value: initialValue, // Use the determined initial value instead of undefined\n },\n ],\n 'after',\n [...path, -1]\n )\n patches.push(ifMissing)\n patches.push(insertValue)\n }\n\n onChange(PatchEvent.from(patches.flat()))\n },\n [documentsToTranslation, getInitialValueForType, onChange, toast]\n )\n return (\n <Stack space={3}>\n <Box>\n <Text size={1} weight=\"semibold\">\n Add translation to internationalized fields\n </Text>\n </Box>\n <AddButtons\n languages={filteredLanguages}\n readOnly={false}\n value={undefined}\n onClick={handleDocumentButtonClick}\n />\n </Stack>\n )\n}\n","import {get} from 'lodash'\n\nexport const getSelectedValue = (\n select: Record<string, string> | undefined,\n document:\n | {\n [x: string]: unknown\n }\n | undefined\n): Record<string, unknown> => {\n if (!select || !document) {\n return {}\n }\n\n const selection: Record<string, string> = select || {}\n const selectedValue: Record<string, unknown> = {}\n for (const [key, path] of Object.entries(selection)) {\n let value = get(document, path)\n if (Array.isArray(value)) {\n // If there are references in the array, ensure they have `_ref` set, otherwise they are considered empty and can safely be ignored\n value = value.filter((item) =>\n typeof item === 'object'\n ? item?._type === 'reference' && '_ref' in item\n : true\n )\n }\n selectedValue[key] = value\n }\n\n return selectedValue\n}\n","import {useLanguageFilterStudioContext} from '@sanity/language-filter'\nimport {Stack} from '@sanity/ui'\nimport equal from 'fast-deep-equal'\nimport type React from 'react'\nimport {createContext, useContext, useDeferredValue, useMemo} from 'react'\nimport {type ObjectInputProps, useClient, useWorkspace} from 'sanity'\nimport {useDocumentPane} from 'sanity/structure'\nimport {suspend} from 'suspend-react'\n\nimport {createCacheKey, setFunctionCache} from '../cache'\nimport {CONFIG_DEFAULT} from '../constants'\nimport type {Language, PluginConfig} from '../types'\nimport DocumentAddButtons from './DocumentAddButtons'\nimport {getSelectedValue} from './getSelectedValue'\n\n// This provider makes the plugin config available to all components in the document form\n// But with languages resolved and filtered languages updated base on @sanity/language-filter\n\ntype InternationalizedArrayContextProps = Required<PluginConfig> & {\n languages: Language[]\n filteredLanguages: Language[]\n}\n\nexport const InternationalizedArrayContext =\n createContext<InternationalizedArrayContextProps>({\n ...CONFIG_DEFAULT,\n languages: [],\n filteredLanguages: [],\n })\n\nexport function useInternationalizedArrayContext(): InternationalizedArrayContextProps {\n return useContext(InternationalizedArrayContext)\n}\n\ntype InternationalizedArrayProviderProps = ObjectInputProps & {\n internationalizedArray: Required<PluginConfig>\n}\n\nexport function InternationalizedArrayProvider(\n props: InternationalizedArrayProviderProps\n): React.ReactElement {\n const {internationalizedArray} = props\n\n const client = useClient({apiVersion: internationalizedArray.apiVersion})\n const workspace = useWorkspace()\n const {formState} = useDocumentPane()\n const deferredDocument = useDeferredValue(formState?.value)\n const selectedValue = useMemo(\n () => getSelectedValue(internationalizedArray.select, deferredDocument),\n [internationalizedArray.select, deferredDocument]\n )\n\n // Use a stable workspace identifier to prevent unnecessary re-renders\n const workspaceId = useMemo(() => {\n // Use workspace name if available, otherwise create a stable hash\n if (workspace?.name) {\n return workspace.name\n }\n // Create a stable hash from workspace properties that matter for caching\n const workspaceKey = {\n name: workspace?.name,\n title: workspace?.title,\n // Add other stable properties as needed\n }\n return JSON.stringify(workspaceKey)\n }, [workspace])\n\n // Memoize the cache key to prevent expensive JSON.stringify calls\n const cacheKey = useMemo(\n () => createCacheKey(selectedValue, workspaceId),\n [selectedValue, workspaceId]\n )\n\n // Fetch or return languages\n const languages = Array.isArray(internationalizedArray.languages)\n ? internationalizedArray.languages\n : suspend(\n // eslint-disable-next-line require-await\n async () => {\n if (typeof internationalizedArray.languages === 'function') {\n const result = await internationalizedArray.languages(\n client,\n selectedValue\n )\n // Populate function cache for use outside React context\n setFunctionCache(\n internationalizedArray.languages,\n selectedValue,\n result,\n workspaceId\n )\n return result\n }\n return internationalizedArray.languages\n },\n cacheKey,\n {equal}\n )\n\n // Filter out some languages if language filter is enabled\n const {selectedLanguageIds, options: languageFilterOptions} =\n useLanguageFilterStudioContext()\n\n const filteredLanguages = useMemo(() => {\n const documentType = deferredDocument ? deferredDocument._type : undefined\n const languageFilterEnabled =\n typeof documentType === 'string' &&\n languageFilterOptions.documentTypes.includes(documentType)\n\n return languageFilterEnabled\n ? languages.filter((language) =>\n selectedLanguageIds.includes(language.id)\n )\n : languages\n }, [deferredDocument, languageFilterOptions, languages, selectedLanguageIds])\n\n const showDocumentButtons =\n internationalizedArray.buttonLocations.includes('document')\n const context = useMemo(\n () => ({...internationalizedArray, languages, filteredLanguages}),\n [filteredLanguages, internationalizedArray, languages]\n )\n\n return (\n <InternationalizedArrayContext.Provider value={context}>\n {showDocumentButtons ? (\n <Stack space={5}>\n <DocumentAddButtons value={props.value} />\n {props.renderDefault(props)}\n </Stack>\n ) : (\n props.renderDefault(props)\n )}\n </InternationalizedArrayContext.Provider>\n )\n}\n","import type {ReactNode} from 'react'\nimport {useMemo} from 'react'\nimport {type FieldProps} from 'sanity'\n\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\nexport default function InternationalizedField(props: FieldProps): ReactNode {\n const {languages} = useInternationalizedArrayContext()\n\n // hide titles for 'value' fields within valid language entries\n const customProps = useMemo(() => {\n const pathSegment = props.path.slice(0, -1)[1]\n const languageId =\n typeof pathSegment === 'object' && '_key' in pathSegment\n ? pathSegment._key\n : undefined\n const hasValidLanguageId = languageId\n ? languages.some((l) => l.id === languageId)\n : false\n const shouldHideTitle =\n props.title?.toLowerCase() === 'value' && hasValidLanguageId\n\n return {\n ...props,\n title: shouldHideTitle ? '' : props.title,\n }\n }, [props, languages])\n\n if (!customProps.schemaType.name.startsWith('internationalizedArray')) {\n return customProps.renderDefault(customProps)\n }\n\n // Show reference field selector if there's a value\n if (customProps.schemaType.name === 'reference' && customProps.value) {\n return customProps.renderDefault({\n ...customProps,\n title: '',\n level: 0, // Reset the level to avoid nested styling\n })\n }\n\n // For basic field types, we can use children to keep the simple input\n if (\n customProps.schemaType.name === 'string' ||\n customProps.schemaType.name === 'number' ||\n customProps.schemaType.name === 'text'\n ) {\n return customProps.children\n }\n\n // For complex fields (like markdown), we need to use renderDefault\n // to get all the field's functionality\n return customProps.renderDefault({\n ...customProps,\n level: 0, // Reset the level to avoid nested styling\n })\n}\n","import {memo} from 'react'\nimport {useClient} from 'sanity'\n\nimport {createCacheKey, peek, preloadWithKey, setFunctionCache} from '../cache'\nimport type {PluginConfig} from '../types'\n\nexport default memo(function Preload(\n props: Required<Pick<PluginConfig, 'apiVersion' | 'languages'>>\n) {\n const client = useClient({apiVersion: props.apiVersion})\n\n // Use the same cache key structure as the main component\n // This should match the main component when selectedValue is empty\n const cacheKey = createCacheKey({})\n\n if (!Array.isArray(peek({}))) {\n // eslint-disable-next-line require-await\n preloadWithKey(async () => {\n if (Array.isArray(props.languages)) {\n return props.languages\n }\n const result = await props.languages(client, {})\n // Populate function cache for sharing with other components\n // Use the same key structure as the main component\n setFunctionCache(props.languages, {}, result)\n return result\n }, cacheKey)\n }\n\n return null\n})\n","import {Language, Value} from '../types'\n\nexport function checkAllLanguagesArePresent(\n languages: Language[],\n value: Value[] | undefined\n): boolean {\n const filteredLanguageIds = languages.map((l) => l.id)\n const languagesInUseIds = value ? value.map((v) => v._key) : []\n\n return (\n languagesInUseIds.length === filteredLanguageIds.length &&\n languagesInUseIds.every((l) => filteredLanguageIds.includes(l))\n )\n}\n","import {Language, Value} from '../types'\n\nexport function createAddAllTitle(\n value: Value[] | undefined,\n languages: Language[]\n): string {\n if (value?.length) {\n return `Add missing ${\n languages.length - value.length === 1 ? `language` : `languages`\n }`\n }\n\n return languages.length === 1\n ? `Add ${languages[0].title} Field`\n : `Add all languages`\n}\n","import {SchemaType} from 'sanity'\n\nexport function createValueSchemaTypeName(schemaType: SchemaType): string {\n return `${schemaType.name}Value`\n}\n","import {FormInsertPatch, insert, Path, SchemaType} from 'sanity'\n\nimport {Language, Value} from '../types'\nimport {createValueSchemaTypeName} from './createValueSchemaTypeName'\n\ntype AddConfig = {\n // New keys to add to the field\n addLanguageKeys: string[]\n // Schema of the current field\n schemaType: SchemaType\n // All languages registered in the plugin\n languages: Language[]\n // Languages that are currently visible\n filteredLanguages: Language[]\n // Current value of the internationalizedArray field\n value?: Value[]\n // Path to this item\n path?: Path\n}\n\nexport function createAddLanguagePatches(config: AddConfig): FormInsertPatch[] {\n const {\n addLanguageKeys,\n schemaType,\n languages,\n filteredLanguages,\n value,\n path = [],\n } = config\n\n const itemBase = {_type: createValueSchemaTypeName(schemaType)}\n\n // Create new items\n const getNewItems = () => {\n if (Array.isArray(addLanguageKeys) && addLanguageKeys.length > 0) {\n return addLanguageKeys.map((id) => ({\n ...itemBase,\n _key: id,\n }))\n }\n\n return filteredLanguages\n .filter((language) =>\n value?.length ? !value.find((v) => v._key === language.id) : true\n )\n .map((language) => ({\n ...itemBase,\n _key: language.id,\n }))\n }\n const newItems = getNewItems()\n\n // Insert new items in the correct order\n const languagesInUse = value?.length ? value.map((v) => v) : []\n\n const insertions = newItems.map((item) => {\n // What's the original index of this language?\n const languageIndex = languages.findIndex((l) => item._key === l.id)\n\n // What languages are there beyond that index?\n const remainingLanguages = languages.slice(languageIndex + 1)\n\n // So what is the index in the current value array of the next language in the language array?\n const nextLanguageIndex = languagesInUse.findIndex((l) =>\n // eslint-disable-next-line max-nested-callbacks\n remainingLanguages.find((r) => r.id === l._key)\n )\n\n // Keep local state up to date incase multiple insertions are being made\n if (nextLanguageIndex < 0) {\n languagesInUse.push(item)\n } else {\n languagesInUse.splice(nextLanguageIndex, 0, item)\n }\n\n return nextLanguageIndex < 0\n ? // No next language (-1), add to end of array\n insert([item], 'after', [...path, nextLanguageIndex])\n : // Next language found, insert before that\n insert([item], 'before', [...path, nextLanguageIndex])\n })\n\n return insertions\n}\n","import {AddIcon, TranslateIcon} from '@sanity/icons'\nimport {useCallback} from 'react'\nimport {\n defineDocumentFieldAction,\n type DocumentFieldActionItem,\n type DocumentFieldActionProps,\n PatchEvent,\n setIfMissing,\n useFormValue,\n} from 'sanity'\nimport {useDocumentPane} from 'sanity/structure'\n\nimport {useInternationalizedArrayContext} from '../components/InternationalizedArrayContext'\nimport type {Language, Value} from '../types'\nimport {checkAllLanguagesArePresent} from '../utils/checkAllLanguagesArePresent'\nimport {createAddAllTitle} from '../utils/createAddAllTitle'\nimport {createAddLanguagePatches} from '../utils/createAddLanguagePatches'\n\nconst createTranslateFieldActions: (\n fieldActionProps: DocumentFieldActionProps,\n context: {\n languages: Language[]\n filteredLanguages: Language[]\n }\n) => DocumentFieldActionItem[] = (\n fieldActionProps,\n {languages, filteredLanguages}\n) =>\n languages.map((language) => {\n const value = useFormValue(fieldActionProps.path) as Value[]\n const disabled =\n value && Array.isArray(value)\n ? Boolean(value?.find((item) => item._key === language.id))\n : false\n const hidden = !filteredLanguages.some((f) => f.id === language.id)\n\n const {onChange} = useDocumentPane()\n\n const onAction = useCallback(() => {\n const {schemaType, path} = fieldActionProps\n\n const addLanguageKeys = [language.id]\n const patches = createAddLanguagePatches({\n addLanguageKeys,\n schemaType,\n languages,\n filteredLanguages,\n value,\n path,\n })\n\n onChange(PatchEvent.from([setIfMissing([], path), ...patches]))\n }, [language.id, value, onChange])\n\n return {\n type: 'action',\n icon: AddIcon,\n onAction,\n title: language.title,\n hidden,\n disabled,\n }\n })\n\nconst AddMissingTranslationsFieldAction: (\n fieldActionProps: DocumentFieldActionProps,\n context: {\n languages: Language[]\n filteredLanguages: Language[]\n }\n) => DocumentFieldActionItem = (\n fieldActionProps,\n {languages, filteredLanguages}\n) => {\n const value = useFormValue(fieldActionProps.path) as Value[]\n const disabled = value && value.length === filteredLanguages.length\n const hidden = checkAllLanguagesArePresent(filteredLanguages, value)\n\n const {onChange} = useDocumentPane()\n\n const onAction = useCallback(() => {\n const {schemaType, path} = fieldActionProps\n\n const addLanguageKeys: string[] = []\n const patches = createAddLanguagePatches({\n addLanguageKeys,\n schemaType,\n languages,\n filteredLanguages,\n value,\n path,\n })\n\n onChange(PatchEvent.from([setIfMissing([], path), ...patches]))\n }, [fieldActionProps, filteredLanguages, languages, onChange, value])\n\n return {\n type: 'action',\n icon: AddIcon,\n onAction,\n title: createAddAllTitle(value, filteredLanguages),\n disabled,\n hidden,\n }\n}\n\nexport const internationalizedArrayFieldAction = defineDocumentFieldAction({\n name: 'internationalizedArray',\n useAction(fieldActionProps) {\n const isInternationalizedArrayField =\n fieldActionProps?.schemaType?.type?.name.startsWith(\n 'internationalizedArray'\n )\n const {languages, filteredLanguages} = useInternationalizedArrayContext()\n\n const translateFieldActions = createTranslateFieldActions(\n fieldActionProps,\n {languages, filteredLanguages}\n )\n\n return {\n type: 'group',\n icon: TranslateIcon,\n title: 'Add Translation',\n renderAsButton: true,\n children: isInternationalizedArrayField\n ? [\n ...translateFieldActions,\n AddMissingTranslationsFieldAction(fieldActionProps, {\n languages,\n filteredLanguages,\n }),\n ]\n : [],\n hidden: !isInternationalizedArrayField,\n }\n },\n})\n","export function camelCase(string: string): string {\n return string.replace(/-([a-z])/g, (g) => g[1].toUpperCase())\n}\n\nexport function titleCase(string: string): string {\n return string\n .split(` `)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(` `)\n}\n\nexport function pascalCase(string: string): string {\n return titleCase(camelCase(string))\n}\n\nexport function createFieldName(name: string, addValue = false): string {\n return addValue\n ? [`internationalizedArray`, pascalCase(name), `Value`].join(``)\n : [`internationalizedArray`, pascalCase(name)].join(``)\n}\n","import {Card, Code, Stack, Text} from '@sanity/ui'\nimport type React from 'react'\n\nconst schemaExample = {\n languages: [\n {id: 'en', title: 'English'},\n {id: 'no', title: 'Norsk'},\n ],\n}\n\nexport default function Feedback(): React.ReactElement {\n return (\n <Card tone=\"caution\" border radius={2} padding={3}>\n <Stack space={4}>\n <Text>\n An array of language objects must be passed into the{' '}\n <code>internationalizedArray</code> helper function, each with an{' '}\n <code>id</code> and <code>title</code> field. Example:\n </Text>\n <Card padding={2} border radius={2}>\n <Code size={1} language=\"javascript\">\n {JSON.stringify(schemaExample, null, 2)}\n </Code>\n </Card>\n </Stack>\n </Card>\n )\n}\n","import {AddIcon} from '@sanity/icons'\nimport {useLanguageFilterStudioContext} from '@sanity/language-filter'\nimport {Button, Card, Stack, Text, useToast} from '@sanity/ui'\nimport type React from 'react'\nimport {useCallback, useEffect, useMemo} from 'react'\nimport {\n type ArrayOfObjectsInputProps,\n ArrayOfObjectsItem,\n type ArraySchemaType,\n MemberItemError,\n set,\n setIfMissing,\n useFormValue,\n} from 'sanity'\nimport {useDocumentPane} from 'sanity/structure'\n\nimport type {Value} from '../types'\nimport {checkAllLanguagesArePresent} from '../utils/checkAllLanguagesArePresent'\nimport {createAddAllTitle} from '../utils/createAddAllTitle'\nimport {createAddLanguagePatches} from '../utils/createAddLanguagePatches'\nimport AddButtons from './AddButtons'\nimport Feedback from './Feedback'\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\nexport type InternationalizedArrayProps = ArrayOfObjectsInputProps<\n Value,\n ArraySchemaType\n>\n\nexport default function InternationalizedArray(\n props: InternationalizedArrayProps\n): React.ReactElement {\n const {\n members,\n value,\n schemaType,\n onChange,\n readOnly: documentReadOnly,\n } = props\n\n const readOnly =\n typeof schemaType.readOnly === 'boolean' ? schemaType.readOnly : false\n const toast = useToast()\n\n const {\n languages,\n filteredLanguages,\n defaultLanguages,\n buttonAddAll,\n buttonLocations,\n } = useInternationalizedArrayContext()\n\n // Support updating the UI if languageFilter is installed\n const {selectedLanguageIds, options: languageFilterOptions} =\n useLanguageFilterStudioContext()\n const documentType = useFormValue(['_type'])\n const languageFilterEnabled =\n typeof documentType === 'string' &&\n languageFilterOptions.documentTypes.includes(documentType)\n\n const filteredMembers = useMemo(\n () =>\n languageFilterEnabled\n ? members.filter((member) => {\n // This member is the outer object created by the plugin\n // Satisfy TS\n if (member.kind !== 'item') {\n return false\n }\n\n // This is the inner \"value\" field member created by this plugin\n const valueMember = member.item.members[0]\n\n // Satisfy TS\n if (valueMember.kind !== 'field') {\n return false\n }\n\n return languageFilterOptions.filterField(\n member.item.schemaType,\n valueMember,\n selectedLanguageIds\n )\n })\n : members,\n [languageFilterEnabled, members, languageFilterOptions, selectedLanguageIds]\n )\n\n const handleAddLanguage = useCallback(\n async (\n param?: React.MouseEvent<HTMLButtonElement, MouseEvent> | string[]\n ) => {\n if (!filteredLanguages?.length) {\n return\n }\n\n const addLanguageKeys: string[] = Array.isArray(param)\n ? param\n : ([param?.currentTarget?.value].filter(Boolean) as string[])\n\n const patches = createAddLanguagePatches({\n addLanguageKeys,\n schemaType,\n languages,\n filteredLanguages,\n value,\n })\n\n onChange([setIfMissing([]), ...patches])\n },\n [filteredLanguages, languages, onChange, schemaType, value]\n )\n\n const {isDeleting} = useDocumentPane()\n\n const addedLanguages = members.map(({key}) => key)\n const hasAddedDefaultLanguages = defaultLanguages\n .filter((language) => languages.find((l) => l.id === language))\n .every((language) => addedLanguages.includes(language))\n\n useEffect(() => {\n if (!isDeleting && !hasAddedDefaultLanguages) {\n const languagesToAdd = defaultLanguages\n .filter((language) => !addedLanguages.includes(language))\n .filter((language) => languages.find((l) => l.id === language))\n // Account for strict mode by scheduling the update\n const timeout = setTimeout(() => {\n if (!documentReadOnly) handleAddLanguage(languagesToAdd)\n })\n return () => clearTimeout(timeout)\n }\n return undefined\n }, [\n isDeleting,\n hasAddedDefaultLanguages,\n handleAddLanguage,\n defaultLanguages,\n addedLanguages,\n languages,\n documentReadOnly,\n ])\n\n // NOTE: This is reordering and re-setting the whole array, it could be surgical\n const handleRestoreOrder = useCallback(() => {\n if (!value?.length || !languages?.length) {\n return\n }\n\n // Create a new value array in the correct order\n // This would also strip out values that don't have a language as the key\n const updatedValue = value\n .reduce((acc, v) => {\n const newIndex = languages.findIndex((l) => l.id === v?._key)\n\n if (newIndex > -1) {\n acc[newIndex] = v\n }\n\n return acc\n }, [] as Value[])\n .filter(Boolean)\n\n if (value?.length !== updatedValue.length) {\n toast.push({\n title: 'There was an error reordering languages',\n status: 'warning',\n })\n }\n\n onChange(set(updatedValue))\n }, [toast, languages, onChange, value])\n\n const allKeysAreLanguages = useMemo(() => {\n if (!value?.length || !languages?.length) {\n return true\n }\n\n return value?.every((v) => languages.find((l) => l?.id === v?._key))\n }, [value, languages])\n\n // Check languages are in the correct order\n const languagesInUse = useMemo(\n () =>\n languages && languages.length > 1\n ? languages.filter((l) => value?.find((v) => v._key === l.id))\n : [],\n [languages, value]\n )\n\n const languagesOutOfOrder = useMemo(() => {\n if (!value?.length || !languagesInUse.length) {\n return []\n }\n\n return value\n .map((v, vIndex) =>\n vIndex === languagesInUse.findIndex((l) => l.id === v._key) ? null : v\n )\n .filter(Boolean)\n }, [value, languagesInUse])\n\n const languagesAreValid = useMemo(\n () =>\n !languages?.length ||\n (languages?.length && languages.every((item) => item.id && item.title)),\n [languages]\n )\n\n // Automatically restore order of fields\n useEffect(() => {\n if (languagesOutOfOrder.length > 0 && allKeysAreLanguages) {\n handleRestoreOrder()\n }\n }, [languagesOutOfOrder, allKeysAreLanguages, handleRestoreOrder])\n\n // compare value keys with possible languages\n const allLanguagesArePresent = useMemo(\n () => checkAllLanguagesArePresent(filteredLanguages, value),\n [filteredLanguages, value]\n )\n\n if (!languagesAreValid) {\n return <Feedback />\n }\n\n const addButtonsAreVisible =\n // Plugin was configured to display buttons here (default!)\n buttonLocations.includes('field') &&\n // There's at least one language visible\n filteredLanguages?.length > 0 &&\n // Not every language has a value yet\n !allLanguagesArePresent\n const fieldHasMembers = members?.length > 0\n\n return (\n <Stack space={2}>\n {fieldHasMembers ? (\n <>\n {filteredMembers.map((member) => {\n if (member.kind === 'item') {\n return (\n <ArrayOfObjectsItem\n {...props}\n key={member.key}\n member={member}\n />\n )\n }\n\n return <MemberItemError key={member.key} member={member} />\n })}\n </>\n ) : null}\n\n {/* Give some feedback in the UI so the field doesn't look \"missing\" */}\n {!addButtonsAreVisible && !fieldHasMembers ? (\n <Card border tone=\"transparent\" padding={3} radius={2}>\n <Text size={1}>\n This internationalized field currently has no translations.\n </Text>\n </Card>\n ) : null}\n\n {addButtonsAreVisible ? (\n <Stack space={2}>\n <AddButtons\n languages={filteredLanguages}\n value={value}\n readOnly={readOnly}\n onClick={handleAddLanguage}\n />\n {buttonAddAll ? (\n <Button\n tone=\"primary\"\n mode=\"ghost\"\n disabled={readOnly || allLanguagesArePresent}\n icon={AddIcon}\n text={createAddAllTitle(value, filteredLanguages)}\n onClick={handleAddLanguage}\n />\n ) : null}\n </Stack>\n ) : null}\n </Stack>\n )\n}\n","import {SchemaType} from 'sanity'\n\nimport {ArrayFieldOptions} from '../schema/array'\n\nexport function getLanguagesFieldOption(\n schemaType: SchemaType | undefined\n): ArrayFieldOptions['languages'] | undefined {\n if (!schemaType) {\n return undefined\n }\n const languagesOption = (schemaType.options as ArrayFieldOptions)?.languages\n if (languagesOption) {\n return languagesOption\n }\n return getLanguagesFieldOption(schemaType.type)\n}\n","/* eslint-disable no-nested-ternary */\nimport {defineField, type FieldDefinition, type Rule} from 'sanity'\n\nimport {getFunctionCache, peek, setFunctionCache} from '../cache'\nimport {createFieldName} from '../components/createFieldName'\nimport {getSelectedValue} from '../components/getSelectedValue'\nimport InternationalizedArray from '../components/InternationalizedArray'\nimport type {Language, LanguageCallback, Value} from '../types'\nimport {getLanguagesFieldOption} from '../utils/getLanguagesFieldOption'\n\ntype ArrayFactoryConfig = {\n apiVersion: string\n select?: Record<string, string>\n languages: Language[] | LanguageCallback\n defaultLanguages?: string[]\n type: string | FieldDefinition\n}\n\nexport type ArrayFieldOptions = Pick<\n ArrayFactoryConfig,\n 'apiVersion' | 'select' | 'languages'\n>\n\nexport default (config: ArrayFactoryConfig): FieldDefinition<'array'> => {\n const {apiVersion, select, languages, type} = config\n const typeName = typeof type === `string` ? type : type.name\n const arrayName = createFieldName(typeName)\n const objectName = createFieldName(typeName, true)\n\n return defineField({\n name: arrayName,\n title: 'Internationalized array',\n type: 'array',\n components: {\n input: InternationalizedArray,\n },\n options: {\n // @ts-expect-error - these options are required for validation rules – not the custom input component\n apiVersion,\n select,\n languages,\n },\n of: [\n defineField({\n ...(typeof type === 'string' ? {} : type),\n name: objectName,\n type: objectName,\n }),\n ],\n // @ts-expect-error - fix typings\n validation: (rule: Rule) =>\n rule.custom<Value[]>(async (value, context) => {\n if (!value || value.length === 0) {\n return true\n }\n\n // Early return for simple cases to avoid expensive operations\n if (value.length === 1 && !value[0]?._key) {\n return true\n }\n\n const selectedValue = getSelectedValue(select, context.document)\n const client = context.getClient({apiVersion})\n\n let contextLanguages: Language[] = []\n const languagesFieldOption = getLanguagesFieldOption(context?.type)\n\n if (Array.isArray(languagesFieldOption)) {\n contextLanguages = languagesFieldOption\n } else if (Array.isArray(peek(selectedValue))) {\n contextLanguages = peek(selectedValue) || []\n } else if (typeof languagesFieldOption === 'function') {\n // Try to get from function cache first (if it's the same function as the component)\n const cachedLanguages = getFunctionCache(\n languagesFieldOption,\n selectedValue\n )\n\n if (Array.isArray(cachedLanguages)) {\n contextLanguages = cachedLanguages\n } else {\n // Try suspend cache as fallback\n const suspendCachedLanguages = peek(selectedValue)\n if (Array.isArray(suspendCachedLanguages)) {\n contextLanguages = suspendCachedLanguages\n } else {\n // Only make the async call if we don't have cached data\n contextLanguages = await languagesFieldOption(\n client,\n selectedValue\n )\n // Cache the result for future validation calls\n setFunctionCache(\n languagesFieldOption,\n selectedValue,\n contextLanguages\n )\n }\n }\n }\n\n if (value && value.length > contextLanguages.length) {\n return `Cannot be more than ${\n contextLanguages.length === 1\n ? `1 item`\n : `${contextLanguages.length} items`\n }`\n }\n\n // Create a Set for faster language ID lookups\n const languageIds = new Set(contextLanguages.map((lang) => lang.id))\n\n // Check for invalid language keys\n const nonLanguageKeys = value.filter(\n (item) => item?._key && !languageIds.has(item._key)\n )\n if (nonLanguageKeys.length) {\n return {\n message: `Array item keys must be valid languages registered to the field type`,\n paths: nonLanguageKeys.map((item) => [{_key: item._key}]),\n }\n }\n\n // Check for duplicate language keys (more efficient)\n const seenKeys = new Set<string>()\n const duplicateValues: Value[] = []\n\n for (const item of value) {\n if (item?._key) {\n if (seenKeys.has(item._key)) {\n duplicateValues.push(item)\n } else {\n seenKeys.add(item._key)\n }\n }\n }\n\n if (duplicateValues.length) {\n return {\n message: 'There can only be one field per language',\n paths: duplicateValues.map((item) => [{_key: item._key}]),\n }\n }\n\n return true\n }),\n })\n}\n","import type {CardTone} from '@sanity/ui'\nimport type {FormNodeValidation} from 'sanity'\n\nexport function getToneFromValidation(\n validations: FormNodeValidation[]\n): CardTone | undefined {\n if (!validations?.length) {\n return undefined\n }\n\n const validationLevels = validations.map((v) => v.level)\n\n if (validationLevels.includes('error')) {\n return `critical`\n } else if (validationLevels.includes('warning')) {\n return `caution`\n }\n\n return undefined\n}\n","import {RemoveCircleIcon} from '@sanity/icons'\nimport {\n Button,\n Card,\n Flex,\n Label,\n Menu,\n MenuButton,\n MenuItem,\n Spinner,\n Stack,\n Text,\n Tooltip,\n} from '@sanity/ui'\nimport type React from 'react'\nimport {ReactNode, useCallback, useMemo} from 'react'\nimport {type ObjectItemProps, useFormValue} from 'sanity'\nimport {set, unset} from 'sanity'\n\nimport {getLanguageDisplay} from '../utils/getLanguageDisplay'\nimport {getToneFromValidation} from './getToneFromValidation'\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\nexport type InternationalizedValue = {\n _type: string\n _key: string\n value: string\n}\n\nexport default function InternationalizedInput(\n props: ObjectItemProps<InternationalizedValue>\n): ReactNode {\n const parentValue = useFormValue(\n props.path.slice(0, -1)\n ) as InternationalizedValue[]\n\n // Extract the original onChange to avoid dependency issues\n const originalOnChange = props.inputProps.onChange\n\n // Create a wrapped onChange handler to intercept patches for paste operations\n const wrappedOnChange = useCallback(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (patches: any) => {\n // Ensure patches is an array before proceeding with paste logic\n // For single patch operations (like unset), pass through directly\n if (!Array.isArray(patches)) {\n return originalOnChange(patches)\n }\n\n // Check if this is a paste operation into an empty or uninitialized Portable Text field\n const valueField = props.value?.value\n const isEmptyOrUndefined =\n valueField === undefined ||\n valueField === null ||\n (Array.isArray(valueField) && valueField.length === 0)\n\n if (isEmptyOrUndefined) {\n // Check for insert patches that are trying to operate on a non-existent structure\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const hasProblematicInsert = patches.some((patch: any) => {\n // Ensure patch exists and has required properties\n if (!patch || typeof patch !== 'object') {\n return false\n }\n\n // Look for insert patches targeting the value field or direct array index\n if (\n patch.type === 'insert' &&\n patch.path &&\n Array.isArray(patch.path) &&\n patch.path.length > 0\n ) {\n // The path might be ['value', index] or just [index] depending on context\n const isTargetingValue =\n patch.path[0] === 'value' || typeof patch.path[0] === 'number'\n return isTargetingValue\n }\n return false\n })\n\n if (hasProblematicInsert) {\n // First, ensure the value field exists as an empty array if it doesn't\n const initPatch =\n valueField === undefined\n ? {type: 'setIfMissing', path: ['value'], value: []}\n : null\n\n // Transform the patches to ensure they work with the nested structure\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const fixedPatches = patches.map((patch: any) => {\n // Ensure patch exists and has required properties\n if (!patch || typeof patch !== 'object') {\n return patch\n }\n\n if (\n patch.type === 'insert' &&\n patch.path &&\n Array.isArray(patch.path)\n ) {\n // Ensure the path is correct for the nested structure\n const fixedPath =\n patch.path[0] === 'value'\n ? patch.path\n : ['value', ...patch.path]\n const fixedPatch = {...patch, path: fixedPath}\n return fixedPatch\n }\n return patch\n })\n\n // If we need to initialize the field, include that patch first\n const allPatches = initPatch\n ? [initPatch, ...fixedPatches]\n : fixedPatches\n\n return originalOnChange(allPatches)\n }\n }\n\n // For all other cases, pass through unchanged\n return originalOnChange(patches)\n },\n [props.value, originalOnChange]\n )\n\n const inlineProps = {\n ...props.inputProps,\n // This is the magic that makes inline editing work?\n members: props.inputProps.members.filter(\n (m) => m.kind === 'field' && m.name === 'value'\n ),\n // This just overrides the type\n // Remove this as it shouldn't be necessary?\n value: props.value as InternationalizedValue,\n // Use our wrapped onChange handler\n onChange: wrappedOnChange,\n }\n\n const {validation, value, onChange, readOnly} = inlineProps\n\n // The parent array contains the languages from the plugin config\n const {languages, languageDisplay, defaultLanguages} =\n useInternationalizedArrayContext()\n\n const languageKeysInUse = useMemo(\n () => parentValue?.map((v) => v._key) ?? [],\n [parentValue]\n )\n const keyIsValid = languages?.length\n ? languages.find((l) => l.id === value._key)\n : false\n\n // Changes the key of this item, ideally to a valid language\n const handleKeyChange = useCallback(\n (event: React.MouseEvent<HTMLButtonElement, MouseEvent>): void => {\n const languageId = event?.currentTarget?.value\n\n if (\n !value ||\n !languages?.length ||\n !languages.find((l) => l.id === languageId)\n ) {\n return\n }\n\n onChange([set(languageId, ['_key'])])\n },\n [onChange, value, languages]\n )\n\n // Removes this item from the array\n const handleUnset = useCallback((): void => {\n onChange(unset())\n }, [onChange])\n\n if (!languages) {\n return <Spinner />\n }\n\n const language = languages.find((l) => l.id === value._key)\n const languageTitle: string =\n keyIsValid && language\n ? getLanguageDisplay(languageDisplay, language.title, language.id)\n : ''\n\n const isDefault = defaultLanguages.includes(value._key)\n\n const removeButton = (\n <Button\n mode=\"bleed\"\n icon={RemoveCircleIcon}\n tone=\"critical\"\n disabled={readOnly || isDefault}\n onClick={handleUnset}\n />\n )\n\n return (\n <Card paddingTop={2} tone={getToneFromValidation(validation)}>\n <Stack space={2}>\n <Card tone=\"inherit\">\n {keyIsValid ? (\n <Label muted size={1}>\n {languageTitle}\n </Label>\n ) : (\n <MenuButton\n button={<Button fontSize={1} text={`Change \"${value._key}\"`} />}\n id={`${value._key}-change-key`}\n menu={\n <Menu>\n {languages.map((lang) => (\n <MenuItem\n disabled={languageKeysInUse.includes(lang.id)}\n fontSize={1}\n key={lang.id}\n text={lang.id.toLocaleUpperCase()}\n value={lang.id}\n // @ts-expect-error - fix typings\n onClick={handleKeyChange}\n />\n ))}\n </Menu>\n }\n popover={{portal: true}}\n />\n )}\n </Card>\n <Flex align=\"center\" gap={2}>\n <Card flex={1} tone=\"inherit\">\n {props.inputProps.renderInput(inlineProps)}\n </Card>\n\n <Card tone=\"inherit\">\n {isDefault ? (\n <Tooltip\n content={\n <Text muted size={1}>\n Can&apos;t remove default language\n </Text>\n }\n fallbackPlacements={['right', 'left']}\n placement=\"top\"\n portal\n >\n <span>{removeButton}</span>\n </Tooltip>\n ) : (\n removeButton\n )}\n </Card>\n </Flex>\n </Stack>\n </Card>\n )\n}\n","import {defineField, FieldDefinition} from 'sanity'\n\nimport {createFieldName} from '../components/createFieldName'\nimport InternationalizedInput from '../components/InternationalizedInput'\n\ntype ObjectFactoryConfig = {\n type: string | FieldDefinition\n}\n\nexport default (config: ObjectFactoryConfig): FieldDefinition<'object'> => {\n const {type} = config\n const typeName = typeof type === `string` ? type : type.name\n const objectName = createFieldName(typeName, true)\n\n return defineField({\n name: objectName,\n title: `Internationalized array ${type}`,\n type: 'object',\n components: {\n // @ts-expect-error - fix typings\n item: InternationalizedInput,\n },\n fields: [\n defineField({\n ...(typeof type === 'string' ? {type} : type),\n name: 'value',\n }),\n ],\n preview: {\n select: {\n title: 'value',\n subtitle: '_key',\n },\n },\n })\n}\n","import {\n isDocumentSchemaType,\n type ObjectField,\n type Path,\n type SchemaType,\n} from 'sanity'\n\ntype ObjectFieldWithPath = ObjectField<SchemaType> & {path: Path}\n\n/**\n * Flattens a document's schema type into a flat array of fields and includes their path\n */\nexport function flattenSchemaType(\n schemaType: SchemaType\n): ObjectFieldWithPath[] {\n if (!isDocumentSchemaType(schemaType)) {\n console.error(`Schema type is not a document`)\n return []\n }\n\n return extractInnerFields(schemaType.fields, [], 3)\n}\n\nfunction extractInnerFields(\n fields: ObjectField<SchemaType>[],\n path: Path,\n maxDepth: number\n): ObjectFieldWithPath[] {\n if (path.length >= maxDepth) {\n return []\n }\n\n return fields.reduce<ObjectFieldWithPath[]>((acc, field) => {\n const thisFieldWithPath = {path: [...path, field.name], ...field}\n\n if (field.type.jsonType === 'object') {\n const innerFields = extractInnerFields(\n field.type.fields,\n [...path, field.name],\n maxDepth\n )\n\n return [...acc, thisFieldWithPath, ...innerFields]\n } else if (\n field.type.jsonType === 'array' &&\n field.type.of.length &&\n field.type.of.some((item) => 'fields' in item)\n ) {\n const innerFields = field.type.of.flatMap((innerField) =>\n extractInnerFields(\n // @ts-expect-error - Fix TS assertion for array fields\n innerField.fields,\n [...path, field.name],\n maxDepth\n )\n )\n\n return [...acc, thisFieldWithPath, ...innerFields]\n }\n\n return [...acc, thisFieldWithPath]\n }, [])\n}\n","import {definePlugin, isObjectInputProps} from 'sanity'\n\nimport {InternationalizedArrayProvider} from './components/InternationalizedArrayContext'\nimport InternationalizedField from './components/InternationalizedField'\nimport Preload from './components/Preload'\nimport {CONFIG_DEFAULT} from './constants'\nimport {internationalizedArrayFieldAction} from './fieldActions'\nimport array from './schema/array'\nimport object from './schema/object'\nimport {PluginConfig} from './types'\nimport {flattenSchemaType} from './utils/flattenSchemaType'\n\nexport const internationalizedArray = definePlugin<PluginConfig>((config) => {\n const pluginConfig = {...CONFIG_DEFAULT, ...config}\n const {\n apiVersion = '2025-10-15',\n select,\n languages,\n fieldTypes,\n defaultLanguages,\n buttonLocations,\n } = pluginConfig\n\n return {\n name: 'sanity-plugin-internationalized-array',\n // Preload languages for use throughout the Studio\n studio: Array.isArray(languages)\n ? undefined\n : {\n components: {\n layout: (props) => (\n <>\n <Preload apiVersion={apiVersion} languages={languages} />\n {props.renderDefault(props)}\n </>\n ),\n },\n },\n // Optional: render \"add language\" buttons as field actions\n document: {\n unstable_fieldActions: buttonLocations.includes('unstable__fieldAction')\n ? (prev) => [...prev, internationalizedArrayFieldAction]\n : undefined,\n },\n // Wrap document editor with a language provider\n form: {\n components: {\n field: (props) => <InternationalizedField {...props} />,\n\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 const hasInternationalizedArray = flatFieldTypeNames.some((name) =>\n name.startsWith('internationalizedArray')\n )\n\n if (!hasInternationalizedArray) {\n return props.renderDefault(props)\n }\n\n return (\n <InternationalizedArrayProvider\n {...props}\n internationalizedArray={pluginConfig}\n />\n )\n },\n },\n },\n // Register custom schema types for the outer array and the inner object\n schema: {\n types: [\n ...fieldTypes.map((type) =>\n array({type, apiVersion, select, languages, defaultLanguages})\n ),\n ...fieldTypes.map((type) => object({type})),\n ],\n },\n }\n})\n"],"names":["AddButtons","internationalizedArray","suspend"],"mappings":";;;;;;;;;;;AAMO,MAAM,YAAY,yCAEZ,UAAU,MAMjB,oCAAoB,IAAA,GAGpB,mBAAmB,oBAAI,QAAA,GAOhB,iBAAiB,CAC5B,IACA,QACG,QAAQ,QAAQ,MAAM,GAAA,GAAM,GAAG,GAGvB,QAAQ,MAAM,QAAQ,MAAM,CAAC,SAAS,SAAS,CAAC,GAGhD,OAAO,CAAC,kBACnB,QAAQ,KAAK,CAAC,SAAS,WAAW,aAAa,CAAC,GAGrC,iBAAiB,CAC5B,eACA,gBACG;AACH,QAAM,oBAAoB,KAAK,UAAU,aAAa;AACtD,SAAO,cACH,CAAC,SAAS,WAAW,mBAAmB,WAAW,IACnD,CAAC,SAAS,WAAW,iBAAiB;AAC5C,GAYa,iBAAiB,CAAC,OAAiC;AAE9D,QAAM,YAAY,iBAAiB,IAAI,EAAE;AACzC,MAAI;AACF,WAAO;AAIT,QAAM,QAAQ,GAAG,SAAA;AACjB,MAAI,OAAO;AAEX,QAAM,YAAY,KAAK,IAAI,MAAM,QAAQ,GAAG;AAC5C,WAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAClC,UAAM,OAAO,MAAM,WAAW,CAAC;AAE/B,YAAQ,QAAQ,KAAK,OAAO,MAE5B,QAAQ;AAAA,EACV;AACA,QAAM,MAAM,aAAa,KAAK,IAAI,IAAI,CAAC;AACvC,SAAA,iBAAiB,IAAI,IAAI,GAAG,GACrB;AACT,GAGa,yBAAyB,CACpC,IACA,eACA,gBACW;AACX,QAAM,cAAc,eAAe,EAAE,GAC/B,oBAAoB,KAAK,UAAU,aAAa;AACtD,SAAO,cACH,GAAG,WAAW,IAAI,iBAAiB,IAAI,WAAW,KAClD,GAAG,WAAW,IAAI,iBAAiB;AACzC,GAmBa,mBAAmB,CAC9B,IACA,eACA,gBAC2B;AAC3B,QAAM,MAAM,uBAAuB,IAAI,eAAe,WAAW;AACjE,SAAO,cAAc,IAAI,GAAG;AAC9B,GAEa,mBAAmB,CAC9B,IACA,eACA,WACA,gBACS;AACT,QAAM,MAAM,uBAAuB,IAAI,eAAe,WAAW;AACjE,gBAAc,IAAI,KAAK,SAAS;AAClC,GC9Ha,cAAc;AAAA,EACzB,UAAU;AAAA,EACV,WAAW;AAAA,EACX,cAAc;AAChB,GAEa,iBAAyC;AAAA,EACpD,WAAW,CAAA;AAAA,EACX,QAAQ,CAAA;AAAA,EACR,kBAAkB,CAAA;AAAA,EAClB,YAAY,CAAA;AAAA,EACZ,YAAY;AAAA,EACZ,iBAAiB,CAAC,OAAO;AAAA,EACzB,cAAc;AAAA,EACd,iBAAiB;AACnB,GCPa,0BAA0B,CACrC,OACA,WAAgC,OACL;AAC3B,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,UAAM,gBAAgB,CAAC,GAAG,QAAQ,GAG5B,0BAA0B,MAAM,OAAO,CAAC,SAAS;AACrD,UAAI,MAAM,QAAQ,IAAI,EAAG,QAAO;AAEhC,UAAI,OAAO,QAAS,UAAU;AAC5B,cAAM,OAAO,MAAM;AACnB,eACE,MAAM,WAAW,wBAAwB,KAAK,MAAM,SAAS,OAAO;AAAA,MAExE;AACA,aAAO;AAAA,IACT,CAAC;AAED,WAAI,wBAAwB,SAAS,IAC5B,wBAAwB,IAAI,CAAC,4BAC3B;AAAA,MACL,GAAG;AAAA,MACH,MAAM;AAAA,MACN,YAAY,cAAc,KAAK,GAAG;AAAA,IAAA,EAErC,IAGC,MAAM,SAAS,IACV,MACJ;AAAA,MAAI,CAAC,MAAM,UACV,wBAAwB,MAAM,CAAC,GAAG,eAAe,KAAK,CAAC;AAAA,IAAA,EAExD,KAAA,IAGE,CAAA;AAAA,EACT;AACA,MAAI,OAAO,SAAU,YAAY,OAAO;AACtC,UAAM,4BAA4B;AAKlC,WAJiB,OAAO,KAAK,KAAK,EAAE;AAAA,MAClC,CAAC,QAAQ,CAAC,IAAI,MAAM,yBAAyB;AAAA,IAAA,EAI5C,IAAI,CAAC,SAAS;AACb,YAAM,gBAAgB,MAAM,IAAI,GAC1B,OAAO,CAAC,GAAG,UAAU,IAAI;AAC/B,aAAO,wBAAwB,eAAe,IAAI;AAAA,IACpD,CAAC,EACA,KAAA;AAAA,EACL;AACA,SAAO,CAAA;AACT;AC/DO,SAAS,mBACd,iBACA,OACA,MACQ;AACR,SAAI,oBAAoB,aAAmB,KAAK,YAAA,IAC5C,oBAAoB,cAAoB,QACxC,oBAAoB,iBACf,GAAG,KAAK,KAAK,KAAK,YAAA,CAAa,MACjC;AACT;ACKA,SAASA,aAAW,OAAwB;AAC1C,QAAM,EAAC,WAAW,UAAU,OAAO,QAAA,IAAW,OACxC,EAAC,gBAAA,IAAmB,iCAAA;AAE1B,SAAO,UAAU,SAAS,IACxB;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,SAAS,KAAK,IAAI,UAAU,QAAQ,YAAY,eAAe,CAAC;AAAA,MAChE,KAAK;AAAA,MAEJ,UAAA,UAAU,IAAI,CAAC,aAAa;AAC3B,cAAM,gBAAwB;AAAA,UAC5B;AAAA,UACA,SAAS;AAAA,UACT,SAAS;AAAA,QAAA;AAEX,eACE;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,MAAK;AAAA,YACL,MAAK;AAAA,YACL,UAAU;AAAA,YACV,UACE,YACA,CAAA,CAAQ,OAAO,KAAK,CAAC,SAAS,KAAK,SAAS,SAAS,EAAE;AAAA,YAEzD,MAAM;AAAA,YAEN,MACE,UAAU,SAAS,YAAY,eAAe,KAC9C,oBAAoB,aAChB,SACA;AAAA,YAEN,OAAO,SAAS;AAAA,YAChB;AAAA,UAAA;AAAA,UAjBK,SAAS;AAAA,QAAA;AAAA,MAoBpB,CAAC;AAAA,IAAA;AAAA,EAAA,IAED;AACN;AAEA,IAAA,aAAe,KAAKA,YAAU;ACnC9B,SAAwB,mBACtB,OACoB;AACpB,QAAM,EAAC,kBAAA,IAAqB,iCAAA,GACtB,QAAQ,iBAAiB,MAAM,KAAK,IAAI,MAAM,QAAQ,QAEtD,QAAQ,SAAA,GACR,EAAC,SAAA,IAAY,gBAAA,GACb,SAAS,UAAA,GAET,yBAAyB,wBAAwB,OAAO,EAAE,GAG1D,yBAAyB;AAAA,IAC7B,CAAC,aAA8B;AAC7B,UAAI,CAAC,SAAU;AAIf,YAAM,QAAQ,SAAS,MAAM,mCAAmC;AAChE,UAAI,CAAC,MAAO;AAEZ,YAAM,eAAe,MAAM,CAAC,EAAE,OAAO,CAAC,EAAE,YAAA,IAAgB,MAAM,CAAC,EAAE,MAAM,CAAC,GAGlE,kBAAkB;AAAA,QACtB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAEF,UAAI,gBAAgB,SAAS,YAAY;AACvC,eAAO,CAAA;AAIT,UAAI;AACF,cAAM,aAAa,OAAO,IAAI,QAAQ;AACtC,YAAI,YAAY;AAGd,gBAAM,aAAc,YAAoB,QAAQ;AAAA;AAAA,YAE9C,CAAC,MAAW,EAAE,SAAS;AAAA,UAAA;AAEzB,cAAI,YAAY;AACd,kBAAM,YAAY,WAAW;AAE7B,gBACE,WAAW,aAAa,WACxB,WAAW,SAAS,WACpB,WAAW,SAAS,WACpB,WAAW,OAAO,UAClB,gBAAgB,SAAS,WAAW,IAAI;AAExC,qBAAO,CAAA;AAAA,UAEX;AAAA,QACF;AAAA,MACF,SAAS,OAAO;AAEd,gBAAQ;AAAA,UACN;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,MAEJ;AAAA,IAGF;AAAA,IACA,CAAC,MAAM;AAAA,EAAA,GAGH,4BAA4B;AAAA,IAChC,OAAO,UAA2D;AAChE,YAAM,aAAa,MAAM,cAAc;AACvC,UAAI,CAAC,YAAY;AACf,cAAM,KAAK;AAAA,UACT,QAAQ;AAAA,UACR,OAAO;AAAA,QAAA,CACR;AACD;AAAA,MACF;AACA,YAAM,oBAAoB,uBAAuB;AAAA,QAC/C,CAAC,gBAAgB,aAAa,SAAS;AAAA,MAAA,GAEnC,mBAAmB,uBAAuB,OAE9C,CAAC,sBAAsB,gBAErB,kBAAkB;AAAA,QAChB,CAAC,uBACC,mBAAmB,eAAe,YAAY;AAAA,MAAA,EAChD,SAAS,KAIoB,qBAAqB;AAAA,QACpD,CAAC,wBAAwB,oBAAoB,SAAS,YAAY;AAAA,MAAA,EAGvC,SAAS,IAC7B,uBAEF,CAAC,GAAG,sBAAsB,WAAW,GAC3C,EAAE;AACL,UAAI,iBAAiB,WAAW,GAAG;AACjC,cAAM,KAAK;AAAA,UACT,QAAQ;AAAA,UACR,OAAO;AAAA,QAAA,CACR;AACD;AAAA,MACF;AAGA,YAAM,UAAuD,CAAA;AAE7D,iBAAW,eAAe,kBAAkB;AAC1C,cAAM,OAAO,YAAY,MAGnB,eAAe,uBAAuB,YAAY,KAAK,GAEvD,YAAY,aAAa,CAAA,GAAI,IAAI,GACjC,cAAc;AAAA,UAClB;AAAA,YACE;AAAA,cACE,MAAM;AAAA,cACN,OAAO,YAAY;AAAA,cACnB,OAAO;AAAA;AAAA,YAAA;AAAA,UACT;AAAA,UAEF;AAAA,UACA,CAAC,GAAG,MAAM,EAAE;AAAA,QAAA;AAEd,gBAAQ,KAAK,SAAS,GACtB,QAAQ,KAAK,WAAW;AAAA,MAC1B;AAEA,eAAS,WAAW,KAAK,QAAQ,KAAA,CAAM,CAAC;AAAA,IAC1C;AAAA,IACA,CAAC,wBAAwB,wBAAwB,UAAU,KAAK;AAAA,EAAA;AAElE,SACE,qBAAC,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,IAAA,oBAAC,KAAA,EACC,8BAAC,MAAA,EAAK,MAAM,GAAG,QAAO,YAAW,yDAEjC,EAAA,CACF;AAAA,IACA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW;AAAA,QACX,UAAU;AAAA,QACV,OAAO;AAAA,QACP,SAAS;AAAA,MAAA;AAAA,IAAA;AAAA,EACX,GACF;AAEJ;ACpLO,MAAM,mBAAmB,CAC9B,QACA,aAK4B;AAC5B,MAAI,CAAC,UAAU,CAAC;AACd,WAAO,CAAA;AAGT,QAAM,YAAoC,UAAU,CAAA,GAC9C,gBAAyC,CAAA;AAC/C,aAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,SAAS,GAAG;AACnD,QAAI,QAAQ,IAAI,UAAU,IAAI;AAC1B,UAAM,QAAQ,KAAK,MAErB,QAAQ,MAAM;AAAA,MAAO,CAAC,SACpB,OAAO,QAAS,WACZ,MAAM,UAAU,eAAe,UAAU,OACzC;AAAA,IAAA,IAGR,cAAc,GAAG,IAAI;AAAA,EACvB;AAEA,SAAO;AACT,GCPa,gCACX,cAAkD;AAAA,EAChD,GAAG;AAAA,EACH,WAAW,CAAA;AAAA,EACX,mBAAmB,CAAA;AACrB,CAAC;AAEI,SAAS,mCAAuE;AACrF,SAAO,WAAW,6BAA6B;AACjD;AAMO,SAAS,+BACd,OACoB;AACpB,QAAM,EAAC,wBAAAC,4BAA0B,OAE3B,SAAS,UAAU,EAAC,YAAYA,wBAAuB,WAAA,CAAW,GAClE,YAAY,aAAA,GACZ,EAAC,cAAa,mBACd,mBAAmB,iBAAiB,WAAW,KAAK,GACpD,gBAAgB;AAAA,IACpB,MAAM,iBAAiBA,wBAAuB,QAAQ,gBAAgB;AAAA,IACtE,CAACA,wBAAuB,QAAQ,gBAAgB;AAAA,EAAA,GAI5C,cAAc,QAAQ,MAAM;AAEhC,QAAI,WAAW;AACb,aAAO,UAAU;AAGnB,UAAM,eAAe;AAAA,MACnB,MAAM,WAAW;AAAA,MACjB,OAAO,WAAW;AAAA;AAAA,IAAA;AAGpB,WAAO,KAAK,UAAU,YAAY;AAAA,EACpC,GAAG,CAAC,SAAS,CAAC,GAGR,WAAW;AAAA,IACf,MAAM,eAAe,eAAe,WAAW;AAAA,IAC/C,CAAC,eAAe,WAAW;AAAA,EAAA,GAIvB,YAAY,MAAM,QAAQA,wBAAuB,SAAS,IAC5DA,wBAAuB,YACvBC;AAAAA;AAAAA,IAEE,YAAY;AACV,UAAI,OAAOD,wBAAuB,aAAc,YAAY;AAC1D,cAAM,SAAS,MAAMA,wBAAuB;AAAA,UAC1C;AAAA,UACA;AAAA,QAAA;AAGF,eAAA;AAAA,UACEA,wBAAuB;AAAA,UACvB;AAAA,UACA;AAAA,UACA;AAAA,QAAA,GAEK;AAAA,MACT;AACA,aAAOA,wBAAuB;AAAA,IAChC;AAAA,IACA;AAAA,IACA,EAAC,MAAA;AAAA,EAAK,GAIN,EAAC,qBAAqB,SAAS,sBAAA,IACnC,kCAEI,oBAAoB,QAAQ,MAAM;AACtC,UAAM,eAAe,mBAAmB,iBAAiB,QAAQ;AAKjE,WAHE,OAAO,gBAAiB,YACxB,sBAAsB,cAAc,SAAS,YAAY,IAGvD,UAAU;AAAA,MAAO,CAAC,aAChB,oBAAoB,SAAS,SAAS,EAAE;AAAA,IAAA,IAE1C;AAAA,EACN,GAAG,CAAC,kBAAkB,uBAAuB,WAAW,mBAAmB,CAAC,GAEtE,sBACJA,wBAAuB,gBAAgB,SAAS,UAAU,GACtD,UAAU;AAAA,IACd,OAAO,EAAC,GAAGA,yBAAwB,WAAW,kBAAA;AAAA,IAC9C,CAAC,mBAAmBA,yBAAwB,SAAS;AAAA,EAAA;AAGvD,SACE,oBAAC,8BAA8B,UAA9B,EAAuC,OAAO,SAC5C,UAAA,sBACC,qBAAC,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,IAAA,oBAAC,oBAAA,EAAmB,OAAO,MAAM,MAAA,CAAO;AAAA,IACvC,MAAM,cAAc,KAAK;AAAA,EAAA,EAAA,CAC5B,IAEA,MAAM,cAAc,KAAK,EAAA,CAE7B;AAEJ;ACjIA,SAAwB,uBAAuB,OAA8B;AAC3E,QAAM,EAAC,UAAA,IAAa,oCAGd,cAAc,QAAQ,MAAM;AAChC,UAAM,cAAc,MAAM,KAAK,MAAM,GAAG,EAAE,EAAE,CAAC,GACvC,aACJ,OAAO,eAAgB,YAAY,UAAU,cACzC,YAAY,OACZ,QACA,qBAAqB,aACvB,UAAU,KAAK,CAAC,MAAM,EAAE,OAAO,UAAU,IACzC,IACE,kBACJ,MAAM,OAAO,YAAA,MAAkB,WAAW;AAE5C,WAAO;AAAA,MACL,GAAG;AAAA,MACH,OAAO,kBAAkB,KAAK,MAAM;AAAA,IAAA;AAAA,EAExC,GAAG,CAAC,OAAO,SAAS,CAAC;AAErB,SAAK,YAAY,WAAW,KAAK,WAAW,wBAAwB,IAKhE,YAAY,WAAW,SAAS,eAAe,YAAY,QACtD,YAAY,cAAc;AAAA,IAC/B,GAAG;AAAA,IACH,OAAO;AAAA,IACP,OAAO;AAAA;AAAA,EAAA,CACR,IAKD,YAAY,WAAW,SAAS,YAChC,YAAY,WAAW,SAAS,YAChC,YAAY,WAAW,SAAS,SAEzB,YAAY,WAKd,YAAY,cAAc;AAAA,IAC/B,GAAG;AAAA,IACH,OAAO;AAAA;AAAA,EAAA,CACR,IA1BQ,YAAY,cAAc,WAAW;AA2BhD;AClDA,IAAA,UAAe,KAAK,SAClB,OACA;AACA,QAAM,SAAS,UAAU,EAAC,YAAY,MAAM,WAAA,CAAW,GAIjD,WAAW,eAAe,EAAE;AAElC,SAAK,MAAM,QAAQ,KAAK,CAAA,CAAE,CAAC,KAEzB,eAAe,YAAY;AACzB,QAAI,MAAM,QAAQ,MAAM,SAAS;AAC/B,aAAO,MAAM;AAEf,UAAM,SAAS,MAAM,MAAM,UAAU,QAAQ,CAAA,CAAE;AAG/C,WAAA,iBAAiB,MAAM,WAAW,CAAA,GAAI,MAAM,GACrC;AAAA,EACT,GAAG,QAAQ,GAGN;AACT,CAAC;AC5BM,SAAS,4BACd,WACA,OACS;AACT,QAAM,sBAAsB,UAAU,IAAI,CAAC,MAAM,EAAE,EAAE,GAC/C,oBAAoB,QAAQ,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,CAAA;AAE7D,SACE,kBAAkB,WAAW,oBAAoB,UACjD,kBAAkB,MAAM,CAAC,MAAM,oBAAoB,SAAS,CAAC,CAAC;AAElE;ACXO,SAAS,kBACd,OACA,WACQ;AACR,SAAI,OAAO,SACF,eACL,UAAU,SAAS,MAAM,WAAW,IAAI,aAAa,WACvD,KAGK,UAAU,WAAW,IACxB,OAAO,UAAU,CAAC,EAAE,KAAK,WACzB;AACN;ACbO,SAAS,0BAA0B,YAAgC;AACxE,SAAO,GAAG,WAAW,IAAI;AAC3B;ACgBO,SAAS,yBAAyB,QAAsC;AAC7E,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,CAAA;AAAA,EAAC,IACN,QAEE,WAAW,EAAC,OAAO,0BAA0B,UAAU,KAoBvD,WAhBA,MAAM,QAAQ,eAAe,KAAK,gBAAgB,SAAS,IACtD,gBAAgB,IAAI,CAAC,QAAQ;AAAA,IAClC,GAAG;AAAA,IACH,MAAM;AAAA,EAAA,EACN,IAGG,kBACJ;AAAA,IAAO,CAAC,aACP,OAAO,SAAS,CAAC,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,IAAI;AAAA,EAAA,EAE9D,IAAI,CAAC,cAAc;AAAA,IAClB,GAAG;AAAA,IACH,MAAM,SAAS;AAAA,EAAA,EACf,GAKA,iBAAiB,OAAO,SAAS,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAA;AA6B7D,SA3BmB,SAAS,IAAI,CAAC,SAAS;AAExC,UAAM,gBAAgB,UAAU,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE,EAAE,GAG7D,qBAAqB,UAAU,MAAM,gBAAgB,CAAC,GAGtD,oBAAoB,eAAe;AAAA,MAAU,CAAC;AAAA;AAAA,QAElD,mBAAmB,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI;AAAA;AAAA,IAAA;AAIhD,WAAI,oBAAoB,IACtB,eAAe,KAAK,IAAI,IAExB,eAAe,OAAO,mBAAmB,GAAG,IAAI,GAG3C,oBAAoB;AAAA;AAAA,MAEvB,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC,GAAG,MAAM,iBAAiB,CAAC;AAAA;AAAA;AAAA,MAEpD,OAAO,CAAC,IAAI,GAAG,UAAU,CAAC,GAAG,MAAM,iBAAiB,CAAC;AAAA;AAAA,EAC3D,CAAC;AAGH;ACjEA,MAAM,8BAM2B,CAC/B,kBACA,EAAC,WAAW,wBAEZ,UAAU,IAAI,CAAC,aAAa;AAC1B,QAAM,QAAQ,aAAa,iBAAiB,IAAI,GAC1C,WACJ,SAAS,MAAM,QAAQ,KAAK,IACxB,EAAQ,OAAO,KAAK,CAAC,SAAS,KAAK,SAAS,SAAS,EAAE,IACvD,IACA,SAAS,CAAC,kBAAkB,KAAK,CAAC,MAAM,EAAE,OAAO,SAAS,EAAE,GAE5D,EAAC,SAAA,IAAY,mBAEb,WAAW,YAAY,MAAM;AACjC,UAAM,EAAC,YAAY,KAAA,IAAQ,kBAErB,kBAAkB,CAAC,SAAS,EAAE,GAC9B,UAAU,yBAAyB;AAAA,MACvC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACD;AAED,aAAS,WAAW,KAAK,CAAC,aAAa,CAAA,GAAI,IAAI,GAAG,GAAG,OAAO,CAAC,CAAC;AAAA,EAChE,GAAG,CAAC,SAAS,IAAI,OAAO,QAAQ,CAAC;AAEjC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN;AAAA,IACA,OAAO,SAAS;AAAA,IAChB;AAAA,IACA;AAAA,EAAA;AAEJ,CAAC,GAEG,oCAMyB,CAC7B,kBACA,EAAC,WAAW,wBACT;AACH,QAAM,QAAQ,aAAa,iBAAiB,IAAI,GAC1C,WAAW,SAAS,MAAM,WAAW,kBAAkB,QACvD,SAAS,4BAA4B,mBAAmB,KAAK,GAE7D,EAAC,SAAA,IAAY,gBAAA,GAEb,WAAW,YAAY,MAAM;AACjC,UAAM,EAAC,YAAY,KAAA,IAAQ,kBAGrB,UAAU,yBAAyB;AAAA,MACvC,iBAFgC,CAAA;AAAA,MAGhC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACD;AAED,aAAS,WAAW,KAAK,CAAC,aAAa,CAAA,GAAI,IAAI,GAAG,GAAG,OAAO,CAAC,CAAC;AAAA,EAChE,GAAG,CAAC,kBAAkB,mBAAmB,WAAW,UAAU,KAAK,CAAC;AAEpE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN;AAAA,IACA,OAAO,kBAAkB,OAAO,iBAAiB;AAAA,IACjD;AAAA,IACA;AAAA,EAAA;AAEJ,GAEa,oCAAoC,0BAA0B;AAAA,EACzE,MAAM;AAAA,EACN,UAAU,kBAAkB;AAC1B,UAAM,gCACJ,kBAAkB,YAAY,MAAM,KAAK;AAAA,MACvC;AAAA,IAAA,GAEE,EAAC,WAAW,sBAAqB,iCAAA,GAEjC,wBAAwB;AAAA,MAC5B;AAAA,MACA,EAAC,WAAW,kBAAA;AAAA,IAAiB;AAG/B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO;AAAA,MACP,gBAAgB;AAAA,MAChB,UAAU,gCACN;AAAA,QACE,GAAG;AAAA,QACH,kCAAkC,kBAAkB;AAAA,UAClD;AAAA,UACA;AAAA,QAAA,CACD;AAAA,MAAA,IAEH,CAAA;AAAA,MACJ,QAAQ,CAAC;AAAA,IAAA;AAAA,EAEb;AACF,CAAC;ACzIM,SAAS,UAAU,QAAwB;AAChD,SAAO,OAAO,QAAQ,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,aAAa;AAC9D;AAEO,SAAS,UAAU,QAAwB;AAChD,SAAO,OACJ,MAAM,GAAG,EACT,IAAI,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,YAAA,IAAgB,KAAK,MAAM,CAAC,CAAC,EAC1D,KAAK,GAAG;AACb;AAEO,SAAS,WAAW,QAAwB;AACjD,SAAO,UAAU,UAAU,MAAM,CAAC;AACpC;AAEO,SAAS,gBAAgB,MAAc,WAAW,IAAe;AACtE,SAAO,WACH,CAAC,0BAA0B,WAAW,IAAI,GAAG,OAAO,EAAE,KAAK,EAAE,IAC7D,CAAC,0BAA0B,WAAW,IAAI,CAAC,EAAE,KAAK,EAAE;AAC1D;AChBA,MAAM,gBAAgB;AAAA,EACpB,WAAW;AAAA,IACT,EAAC,IAAI,MAAM,OAAO,UAAA;AAAA,IAClB,EAAC,IAAI,MAAM,OAAO,QAAA;AAAA,EAAO;AAE7B;AAEA,SAAwB,WAA+B;AACrD,SACE,oBAAC,MAAA,EAAK,MAAK,WAAU,QAAM,IAAC,QAAQ,GAAG,SAAS,GAC9C,UAAA,qBAAC,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,IAAA,qBAAC,MAAA,EAAK,UAAA;AAAA,MAAA;AAAA,MACiD;AAAA,MACrD,oBAAC,UAAK,UAAA,yBAAA,CAAsB;AAAA,MAAO;AAAA,MAA+B;AAAA,MAClE,oBAAC,UAAK,UAAA,KAAA,CAAE;AAAA,MAAO;AAAA,MAAK,oBAAC,UAAK,UAAA,QAAA,CAAK;AAAA,MAAO;AAAA,IAAA,GACxC;AAAA,IACA,oBAAC,QAAK,SAAS,GAAG,QAAM,IAAC,QAAQ,GAC/B,UAAA,oBAAC,MAAA,EAAK,MAAM,GAAG,UAAS,cACrB,UAAA,KAAK,UAAU,eAAe,MAAM,CAAC,GACxC,EAAA,CACF;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;ACEA,SAAwB,uBACtB,OACoB;AACpB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,EAAA,IACR,OAEE,WACJ,OAAO,WAAW,YAAa,YAAY,WAAW,WAAW,IAC7D,QAAQ,SAAA,GAER;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IACE,iCAAA,GAGE,EAAC,qBAAqB,SAAS,sBAAA,IACnC,+BAAA,GACI,eAAe,aAAa,CAAC,OAAO,CAAC,GACrC,wBACJ,OAAO,gBAAiB,YACxB,sBAAsB,cAAc,SAAS,YAAY,GAErD,kBAAkB;AAAA,IACtB,MACE,wBACI,QAAQ,OAAO,CAAC,WAAW;AAGzB,UAAI,OAAO,SAAS;AAClB,eAAO;AAIT,YAAM,cAAc,OAAO,KAAK,QAAQ,CAAC;AAGzC,aAAI,YAAY,SAAS,UAChB,KAGF,sBAAsB;AAAA,QAC3B,OAAO,KAAK;AAAA,QACZ;AAAA,QACA;AAAA,MAAA;AAAA,IAEJ,CAAC,IACD;AAAA,IACN,CAAC,uBAAuB,SAAS,uBAAuB,mBAAmB;AAAA,EAAA,GAGvE,oBAAoB;AAAA,IACxB,OACE,UACG;AACH,UAAI,CAAC,mBAAmB;AACtB;AAGF,YAAM,kBAA4B,MAAM,QAAQ,KAAK,IACjD,QACC,CAAC,OAAO,eAAe,KAAK,EAAE,OAAO,OAAO,GAE3C,UAAU,yBAAyB;AAAA,QACvC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA,CACD;AAED,eAAS,CAAC,aAAa,CAAA,CAAE,GAAG,GAAG,OAAO,CAAC;AAAA,IACzC;AAAA,IACA,CAAC,mBAAmB,WAAW,UAAU,YAAY,KAAK;AAAA,EAAA,GAGtD,EAAC,WAAA,IAAc,mBAEf,iBAAiB,QAAQ,IAAI,CAAC,EAAC,IAAA,MAAS,GAAG,GAC3C,2BAA2B,iBAC9B,OAAO,CAAC,aAAa,UAAU,KAAK,CAAC,MAAM,EAAE,OAAO,QAAQ,CAAC,EAC7D,MAAM,CAAC,aAAa,eAAe,SAAS,QAAQ,CAAC;AAExD,YAAU,MAAM;AACd,QAAI,CAAC,cAAc,CAAC,0BAA0B;AAC5C,YAAM,iBAAiB,iBACpB,OAAO,CAAC,aAAa,CAAC,eAAe,SAAS,QAAQ,CAAC,EACvD,OAAO,CAAC,aAAa,UAAU,KAAK,CAAC,MAAM,EAAE,OAAO,QAAQ,CAAC,GAE1D,UAAU,WAAW,MAAM;AAC1B,4BAAkB,kBAAkB,cAAc;AAAA,MACzD,CAAC;AACD,aAAO,MAAM,aAAa,OAAO;AAAA,IACnC;AAAA,EAEF,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,CACD;AAGD,QAAM,qBAAqB,YAAY,MAAM;AAC3C,QAAI,CAAC,OAAO,UAAU,CAAC,WAAW;AAChC;AAKF,UAAM,eAAe,MAClB,OAAO,CAAC,KAAK,MAAM;AAClB,YAAM,WAAW,UAAU,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;AAE5D,aAAI,WAAW,OACb,IAAI,QAAQ,IAAI,IAGX;AAAA,IACT,GAAG,CAAA,CAAa,EACf,OAAO,OAAO;AAEb,WAAO,WAAW,aAAa,UACjC,MAAM,KAAK;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,IAAA,CACT,GAGH,SAAS,IAAI,YAAY,CAAC;AAAA,EAC5B,GAAG,CAAC,OAAO,WAAW,UAAU,KAAK,CAAC,GAEhC,sBAAsB,QAAQ,MAC9B,CAAC,OAAO,UAAU,CAAC,WAAW,SACzB,KAGF,OAAO,MAAM,CAAC,MAAM,UAAU,KAAK,CAAC,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,GAClE,CAAC,OAAO,SAAS,CAAC,GAGf,iBAAiB;AAAA,IACrB,MACE,aAAa,UAAU,SAAS,IAC5B,UAAU,OAAO,CAAC,MAAM,OAAO,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,IAC3D,CAAA;AAAA,IACN,CAAC,WAAW,KAAK;AAAA,EAAA,GAGb,sBAAsB,QAAQ,MAC9B,CAAC,OAAO,UAAU,CAAC,eAAe,SAC7B,KAGF,MACJ;AAAA,IAAI,CAAC,GAAG,WACP,WAAW,eAAe,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,IAAI,OAAO;AAAA,EAAA,EAEtE,OAAO,OAAO,GAChB,CAAC,OAAO,cAAc,CAAC,GAEpB,oBAAoB;AAAA,IACxB,MACE,CAAC,WAAW,UACX,WAAW,UAAU,UAAU,MAAM,CAAC,SAAS,KAAK,MAAM,KAAK,KAAK;AAAA,IACvE,CAAC,SAAS;AAAA,EAAA;AAIZ,YAAU,MAAM;AACV,wBAAoB,SAAS,KAAK,uBACpC,mBAAA;AAAA,EAEJ,GAAG,CAAC,qBAAqB,qBAAqB,kBAAkB,CAAC;AAGjE,QAAM,yBAAyB;AAAA,IAC7B,MAAM,4BAA4B,mBAAmB,KAAK;AAAA,IAC1D,CAAC,mBAAmB,KAAK;AAAA,EAAA;AAG3B,MAAI,CAAC;AACH,+BAAQ,UAAA,EAAS;AAGnB,QAAM;AAAA;AAAA,IAEJ,gBAAgB,SAAS,OAAO;AAAA,IAEhC,mBAAmB,SAAS;AAAA,IAE5B,CAAC;AAAA,KACG,kBAAkB,SAAS,SAAS;AAE1C,SACE,qBAAC,OAAA,EAAM,OAAO,GACX,UAAA;AAAA,IAAA,kDAEI,UAAA,gBAAgB,IAAI,CAAC,WAChB,OAAO,SAAS,SAEhB;AAAA,MAAC;AAAA,MAAA;AAAA,QACE,GAAG;AAAA,QACJ,KAAK,OAAO;AAAA,QACZ;AAAA,MAAA;AAAA,IAAA,wBAKE,iBAAA,EAAiC,OAAA,GAAZ,OAAO,GAAqB,CAC1D,GACH,IACE;AAAA,IAGH,CAAC,wBAAwB,CAAC,sCACxB,MAAA,EAAK,QAAM,IAAC,MAAK,eAAc,SAAS,GAAG,QAAQ,GAClD,UAAA,oBAAC,MAAA,EAAK,MAAM,GAAG,UAAA,+DAEf,GACF,IACE;AAAA,IAEH,uBACC,qBAAC,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,MAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAW;AAAA,UACX;AAAA,UACA;AAAA,UACA,SAAS;AAAA,QAAA;AAAA,MAAA;AAAA,MAEV,eACC;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,MAAK;AAAA,UACL,UAAU,YAAY;AAAA,UACtB,MAAM;AAAA,UACN,MAAM,kBAAkB,OAAO,iBAAiB;AAAA,UAChD,SAAS;AAAA,QAAA;AAAA,MAAA,IAET;AAAA,IAAA,EAAA,CACN,IACE;AAAA,EAAA,GACN;AAEJ;ACzRO,SAAS,wBACd,YAC4C;AAC5C,SAAK,aAGoB,WAAW,SAA+B,aAI5D,wBAAwB,WAAW,IAAI,IAN5C;AAOJ;ACQA,IAAA,QAAe,CAAC,WAAyD;AACvE,QAAM,EAAC,YAAY,QAAQ,WAAW,SAAQ,QACxC,WAAW,OAAO,QAAS,WAAW,OAAO,KAAK,MAClD,YAAY,gBAAgB,QAAQ,GACpC,aAAa,gBAAgB,UAAU,EAAI;AAEjD,SAAO,YAAY;AAAA,IACjB,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,YAAY;AAAA,MACV,OAAO;AAAA,IAAA;AAAA,IAET,SAAS;AAAA;AAAA,MAEP;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,IAEF,IAAI;AAAA,MACF,YAAY;AAAA,QACV,GAAI,OAAO,QAAS,WAAW,CAAA,IAAK;AAAA,QACpC,MAAM;AAAA,QACN,MAAM;AAAA,MAAA,CACP;AAAA,IAAA;AAAA;AAAA,IAGH,YAAY,CAAC,SACX,KAAK,OAAgB,OAAO,OAAO,YAAY;AAM7C,UALI,CAAC,SAAS,MAAM,WAAW,KAK3B,MAAM,WAAW,KAAK,CAAC,MAAM,CAAC,GAAG;AACnC,eAAO;AAGT,YAAM,gBAAgB,iBAAiB,QAAQ,QAAQ,QAAQ,GACzD,SAAS,QAAQ,UAAU,EAAC,WAAA,CAAW;AAE7C,UAAI,mBAA+B,CAAA;AACnC,YAAM,uBAAuB,wBAAwB,SAAS,IAAI;AAElE,UAAI,MAAM,QAAQ,oBAAoB;AACpC,2BAAmB;AAAA,eACV,MAAM,QAAQ,KAAK,aAAa,CAAC;AAC1C,2BAAmB,KAAK,aAAa,KAAK,CAAA;AAAA,eACjC,OAAO,wBAAyB,YAAY;AAErD,cAAM,kBAAkB;AAAA,UACtB;AAAA,UACA;AAAA,QAAA;AAGF,YAAI,MAAM,QAAQ,eAAe;AAC/B,6BAAmB;AAAA,aACd;AAEL,gBAAM,yBAAyB,KAAK,aAAa;AAC7C,gBAAM,QAAQ,sBAAsB,IACtC,mBAAmB,0BAGnB,mBAAmB,MAAM;AAAA,YACvB;AAAA,YACA;AAAA,UAAA,GAGF;AAAA,YACE;AAAA,YACA;AAAA,YACA;AAAA,UAAA;AAAA,QAGN;AAAA,MACF;AAEA,UAAI,SAAS,MAAM,SAAS,iBAAiB;AAC3C,eAAO,uBACL,iBAAiB,WAAW,IACxB,WACA,GAAG,iBAAiB,MAAM,QAChC;AAIF,YAAM,cAAc,IAAI,IAAI,iBAAiB,IAAI,CAAC,SAAS,KAAK,EAAE,CAAC,GAG7D,kBAAkB,MAAM;AAAA,QAC5B,CAAC,SAAS,MAAM,QAAQ,CAAC,YAAY,IAAI,KAAK,IAAI;AAAA,MAAA;AAEpD,UAAI,gBAAgB;AAClB,eAAO;AAAA,UACL,SAAS;AAAA,UACT,OAAO,gBAAgB,IAAI,CAAC,SAAS,CAAC,EAAC,MAAM,KAAK,MAAK,CAAC;AAAA,QAAA;AAK5D,YAAM,WAAW,oBAAI,IAAA,GACf,kBAA2B,CAAA;AAEjC,iBAAW,QAAQ;AACb,cAAM,SACJ,SAAS,IAAI,KAAK,IAAI,IACxB,gBAAgB,KAAK,IAAI,IAEzB,SAAS,IAAI,KAAK,IAAI;AAK5B,aAAI,gBAAgB,SACX;AAAA,QACL,SAAS;AAAA,QACT,OAAO,gBAAgB,IAAI,CAAC,SAAS,CAAC,EAAC,MAAM,KAAK,MAAK,CAAC;AAAA,MAAA,IAIrD;AAAA,IACT,CAAC;AAAA,EAAA,CACJ;AACH;AChJO,SAAS,sBACd,aACsB;AACtB,MAAI,CAAC,aAAa;AAChB;AAGF,QAAM,mBAAmB,YAAY,IAAI,CAAC,MAAM,EAAE,KAAK;AAEvD,MAAI,iBAAiB,SAAS,OAAO;AACnC,WAAO;AACF,MAAI,iBAAiB,SAAS,SAAS;AAC5C,WAAO;AAIX;ACUA,SAAwB,uBACtB,OACW;AACX,QAAM,cAAc;AAAA,IAClB,MAAM,KAAK,MAAM,GAAG,EAAE;AAAA,EAAA,GAIlB,mBAAmB,MAAM,WAAW,UAGpC,kBAAkB;AAAA;AAAA,IAEtB,CAAC,YAAiB;AAGhB,UAAI,CAAC,MAAM,QAAQ,OAAO;AACxB,eAAO,iBAAiB,OAAO;AAIjC,YAAM,aAAa,MAAM,OAAO;AAMhC,WAHE,cAAe,QACd,MAAM,QAAQ,UAAU,KAAK,WAAW,WAAW,MAKvB,QAAQ,KAAK,CAAC,UAErC,CAAC,SAAS,OAAO,SAAU,WACtB,KAKP,MAAM,SAAS,YACf,MAAM,QACN,MAAM,QAAQ,MAAM,IAAI,KACxB,MAAM,KAAK,SAAS,IAIlB,MAAM,KAAK,CAAC,MAAM,WAAW,OAAO,MAAM,KAAK,CAAC,KAAM,WAGnD,EACR,GAEyB;AAExB,cAAM,YACJ,eAAe,SACX,EAAC,MAAM,gBAAgB,MAAM,CAAC,OAAO,GAAG,OAAO,CAAA,MAC/C,MAIA,eAAe,QAAQ,IAAI,CAAC,UAAe;AAE/C,cAAI,CAAC,SAAS,OAAO,SAAU;AAC7B,mBAAO;AAGT,cACE,MAAM,SAAS,YACf,MAAM,QACN,MAAM,QAAQ,MAAM,IAAI,GACxB;AAEA,kBAAM,YACJ,MAAM,KAAK,CAAC,MAAM,UACd,MAAM,OACN,CAAC,SAAS,GAAG,MAAM,IAAI;AAE7B,mBADmB,EAAC,GAAG,OAAO,MAAM,UAAA;AAAA,UAEtC;AACA,iBAAO;AAAA,QACT,CAAC,GAGK,aAAa,YACf,CAAC,WAAW,GAAG,YAAY,IAC3B;AAEJ,eAAO,iBAAiB,UAAU;AAAA,MACpC;AAIF,aAAO,iBAAiB,OAAO;AAAA,IACjC;AAAA,IACA,CAAC,MAAM,OAAO,gBAAgB;AAAA,EAAA,GAG1B,cAAc;AAAA,IAClB,GAAG,MAAM;AAAA;AAAA,IAET,SAAS,MAAM,WAAW,QAAQ;AAAA,MAChC,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,SAAS;AAAA,IAAA;AAAA;AAAA;AAAA,IAI1C,OAAO,MAAM;AAAA;AAAA,IAEb,UAAU;AAAA,EAAA,GAGN,EAAC,YAAY,OAAO,UAAU,SAAA,IAAY,aAG1C,EAAC,WAAW,iBAAiB,iBAAA,IACjC,iCAAA,GAEI,oBAAoB;AAAA,IACxB,MAAM,aAAa,IAAI,CAAC,MAAM,EAAE,IAAI,KAAK,CAAA;AAAA,IACzC,CAAC,WAAW;AAAA,EAAA,GAER,aAAa,WAAW,SAC1B,UAAU,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,IAAI,IACzC,IAGE,kBAAkB;AAAA,IACtB,CAAC,UAAiE;AAChE,YAAM,aAAa,OAAO,eAAe;AAGvC,OAAC,SACD,CAAC,WAAW,UACZ,CAAC,UAAU,KAAK,CAAC,MAAM,EAAE,OAAO,UAAU,KAK5C,SAAS,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;AAAA,IACtC;AAAA,IACA,CAAC,UAAU,OAAO,SAAS;AAAA,EAAA,GAIvB,cAAc,YAAY,MAAY;AAC1C,aAAS,OAAO;AAAA,EAClB,GAAG,CAAC,QAAQ,CAAC;AAEb,MAAI,CAAC;AACH,+BAAQ,SAAA,EAAQ;AAGlB,QAAM,WAAW,UAAU,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,IAAI,GACpD,gBACJ,cAAc,WACV,mBAAmB,iBAAiB,SAAS,OAAO,SAAS,EAAE,IAC/D,IAEA,YAAY,iBAAiB,SAAS,MAAM,IAAI,GAEhD,eACJ;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,MAAM;AAAA,MACN,MAAK;AAAA,MACL,UAAU,YAAY;AAAA,MACtB,SAAS;AAAA,IAAA;AAAA,EAAA;AAIb,SACE,oBAAC,MAAA,EAAK,YAAY,GAAG,MAAM,sBAAsB,UAAU,GACzD,UAAA,qBAAC,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,IAAA,oBAAC,MAAA,EAAK,MAAK,WACR,UAAA,aACC,oBAAC,OAAA,EAAM,OAAK,IAAC,MAAM,GAChB,UAAA,cAAA,CACH,IAEA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,4BAAS,QAAA,EAAO,UAAU,GAAG,MAAM,WAAW,MAAM,IAAI,IAAA,CAAK;AAAA,QAC7D,IAAI,GAAG,MAAM,IAAI;AAAA,QACjB,MACE,oBAAC,MAAA,EACE,UAAA,UAAU,IAAI,CAAC,SACd;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,UAAU,kBAAkB,SAAS,KAAK,EAAE;AAAA,YAC5C,UAAU;AAAA,YAEV,MAAM,KAAK,GAAG,kBAAA;AAAA,YACd,OAAO,KAAK;AAAA,YAEZ,SAAS;AAAA,UAAA;AAAA,UAJJ,KAAK;AAAA,QAAA,CAMb,GACH;AAAA,QAEF,SAAS,EAAC,QAAQ,GAAA;AAAA,MAAI;AAAA,IAAA,GAG5B;AAAA,IACA,qBAAC,MAAA,EAAK,OAAM,UAAS,KAAK,GACxB,UAAA;AAAA,MAAA,oBAAC,MAAA,EAAK,MAAM,GAAG,MAAK,WACjB,UAAA,MAAM,WAAW,YAAY,WAAW,EAAA,CAC3C;AAAA,MAEA,oBAAC,MAAA,EAAK,MAAK,WACR,UAAA,YACC;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,SACE,oBAAC,MAAA,EAAK,OAAK,IAAC,MAAM,GAAG,UAAA,iCAErB;AAAA,UAEF,oBAAoB,CAAC,SAAS,MAAM;AAAA,UACpC,WAAU;AAAA,UACV,QAAM;AAAA,UAEN,UAAA,oBAAC,UAAM,UAAA,aAAA,CAAa;AAAA,QAAA;AAAA,MAAA,IAGtB,aAAA,CAEJ;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;ACvPA,IAAA,SAAe,CAAC,WAA2D;AACzE,QAAM,EAAC,KAAA,IAAQ,QACT,WAAW,OAAO,QAAS,WAAW,OAAO,KAAK,MAClD,aAAa,gBAAgB,UAAU,EAAI;AAEjD,SAAO,YAAY;AAAA,IACjB,MAAM;AAAA,IACN,OAAO,2BAA2B,IAAI;AAAA,IACtC,MAAM;AAAA,IACN,YAAY;AAAA;AAAA,MAEV,MAAM;AAAA,IAAA;AAAA,IAER,QAAQ;AAAA,MACN,YAAY;AAAA,QACV,GAAI,OAAO,QAAS,WAAW,EAAC,SAAQ;AAAA,QACxC,MAAM;AAAA,MAAA,CACP;AAAA,IAAA;AAAA,IAEH,SAAS;AAAA,MACP,QAAQ;AAAA,QACN,OAAO;AAAA,QACP,UAAU;AAAA,MAAA;AAAA,IACZ;AAAA,EACF,CACD;AACH;ACvBO,SAAS,kBACd,YACuB;AACvB,SAAK,qBAAqB,UAAU,IAK7B,mBAAmB,WAAW,QAAQ,IAAI,CAAC,KAJhD,QAAQ,MAAM,+BAA+B,GACtC,CAAA;AAIX;AAEA,SAAS,mBACP,QACA,MACA,UACuB;AACvB,SAAI,KAAK,UAAU,WACV,CAAA,IAGF,OAAO,OAA8B,CAAC,KAAK,UAAU;AAC1D,UAAM,oBAAoB,EAAC,MAAM,CAAC,GAAG,MAAM,MAAM,IAAI,GAAG,GAAG,MAAA;AAE3D,QAAI,MAAM,KAAK,aAAa,UAAU;AACpC,YAAM,cAAc;AAAA,QAClB,MAAM,KAAK;AAAA,QACX,CAAC,GAAG,MAAM,MAAM,IAAI;AAAA,QACpB;AAAA,MAAA;AAGF,aAAO,CAAC,GAAG,KAAK,mBAAmB,GAAG,WAAW;AAAA,IACnD,WACE,MAAM,KAAK,aAAa,WACxB,MAAM,KAAK,GAAG,UACd,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,YAAY,IAAI,GAC7C;AACA,YAAM,cAAc,MAAM,KAAK,GAAG;AAAA,QAAQ,CAAC,eACzC;AAAA;AAAA,UAEE,WAAW;AAAA,UACX,CAAC,GAAG,MAAM,MAAM,IAAI;AAAA,UACpB;AAAA,QAAA;AAAA,MACF;AAGF,aAAO,CAAC,GAAG,KAAK,mBAAmB,GAAG,WAAW;AAAA,IACnD;AAEA,WAAO,CAAC,GAAG,KAAK,iBAAiB;AAAA,EACnC,GAAG,CAAA,CAAE;AACP;AClDO,MAAM,yBAAyB,aAA2B,CAAC,WAAW;AAC3E,QAAM,eAAe,EAAC,GAAG,gBAAgB,GAAG,UACtC;AAAA,IACJ,aAAa;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IAEA;AAAA,EAAA,IACE;AAEJ,SAAO;AAAA,IACL,MAAM;AAAA;AAAA,IAEN,QAAQ,MAAM,QAAQ,SAAS,IAC3B,SACA;AAAA,MACE,YAAY;AAAA,QACV,QAAQ,CAAC,UACP,qBAAA,UAAA,EACE,UAAA;AAAA,UAAA,oBAAC,SAAA,EAAQ,YAAwB,UAAA,CAAsB;AAAA,UACtD,MAAM,cAAc,KAAK;AAAA,QAAA,EAAA,CAC5B;AAAA,MAAA;AAAA,IAEJ;AAAA;AAAA,IAGN,UAAU;AAAA,MACR,uBAAuB,gBAAgB,SAAS,uBAAuB,IACnE,CAAC,SAAS,CAAC,GAAG,MAAM,iCAAiC,IACrD;AAAA,IAAA;AAAA;AAAA,IAGN,MAAM;AAAA,MACJ,YAAY;AAAA,QACV,OAAO,CAAC,UAAU,oBAAC,wBAAA,EAAwB,GAAG,OAAO;AAAA,QAErD,OAAO,CAAC,UAGF,EAFgB,MAAM,OAAO,UAAU,mBAAmB,KAAK,MAa/D,CAPuB,kBAAkB,MAAM,UAAU,EAAE;AAAA,UAC7D,CAAC,UAAU,MAAM,KAAK;AAAA,QAAA,EAE6B;AAAA,UAAK,CAAC,SACzD,KAAK,WAAW,wBAAwB;AAAA,QAAA,IAIjC,MAAM,cAAc,KAAK,IAIhC;AAAA,UAAC;AAAA,UAAA;AAAA,YACE,GAAG;AAAA,YACJ,wBAAwB;AAAA,UAAA;AAAA,QAAA;AAAA,MAC1B;AAAA,IAGN;AAAA;AAAA,IAGF,QAAQ;AAAA,MACN,OAAO;AAAA,QACL,GAAG,WAAW;AAAA,UAAI,CAAC,SACjB,MAAM,EAAC,MAAM,YAAY,QAAQ,UAA2B,CAAC;AAAA,QAAA;AAAA,QAE/D,GAAG,WAAW,IAAI,CAAC,SAAS,OAAO,EAAC,MAAK,CAAC;AAAA,MAAA;AAAA,IAC5C;AAAA,EACF;AAEJ,CAAC;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sanity-plugin-internationalized-array",
3
- "version": "3.2.1",
3
+ "version": "3.2.2",
4
4
  "description": "Store localized fields in an array to save on attributes",
5
5
  "keywords": [
6
6
  "sanity",
@@ -49,7 +49,7 @@
49
49
  "@sanity/icons": "^3.5.3",
50
50
  "@sanity/incompatible-plugin": "^1.0.5",
51
51
  "@sanity/language-filter": "^4.0.3",
52
- "@sanity/ui": "^2.10.11",
52
+ "@sanity/ui": "^3.1.11",
53
53
  "fast-deep-equal": "^3.1.3",
54
54
  "lodash": "^4.17.21",
55
55
  "suspend-react": "0.1.3"
@@ -85,7 +85,7 @@
85
85
  },
86
86
  "peerDependencies": {
87
87
  "react": "^18.3 || ^19",
88
- "sanity": "^3.52.4 || ^4.0.0-0",
88
+ "sanity": "^3.52.4 || ^4.0.0-0 || ^5",
89
89
  "styled-components": "^6.1"
90
90
  },
91
91
  "engines": {