sanity-plugin-internationalized-array 4.0.2 → 4.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","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/types.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":["import 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// Cache for React.use promises\nconst promiseCache = new Map<string, Promise<Language[]>>()\n\n// Helper to create a cache key string from an array\nfunction stringifyCacheKey(key: unknown[]): string {\n return JSON.stringify(key)\n}\n\n// Preloading: store promises in cache for React.use\nexport const preload = (fn: () => Promise<Language[]>) => {\n const key = stringifyCacheKey([version, namespace])\n if (!promiseCache.has(key)) {\n promiseCache.set(key, fn())\n }\n}\n\n// Enhanced preload function that can use custom cache keys\nexport const preloadWithKey = (fn: () => Promise<Language[]>, key: (string | number)[]) => {\n const keyStr = stringifyCacheKey(key)\n if (!promiseCache.has(keyStr)) {\n promiseCache.set(keyStr, fn())\n }\n}\n\n// Cache busting: clear all promise caches\nexport const clear = () => {\n promiseCache.clear()\n}\n\n// Peeking into entries outside of suspense\nexport const peek = (selectedValue: Record<string, unknown>) => {\n const key = stringifyCacheKey([version, namespace, selectedValue])\n const promise = promiseCache.get(key)\n if (promise) {\n // Check if promise is resolved\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const status = (promise as any)._status\n if (status === 'fulfilled') {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n return (promise as any)._value as Language[] | undefined\n }\n }\n return undefined\n}\n\n// Helper function to create a stable cache key that matches the component's key structure\nexport const createCacheKey = (selectedValue: Record<string, unknown>, workspaceId?: string) => {\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 = (selectedValue: Record<string, unknown>, workspaceId?: string) => {\n const key = stringifyCacheKey(createCacheKey(selectedValue, workspaceId))\n const promise = promiseCache.get(key)\n if (promise) {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const status = (promise as any)._status\n if (status === 'fulfilled') {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n return (promise as any)._value as Language[] | undefined\n }\n }\n return undefined\n}\n\n// Create or get cached promise for React.use\nexport const createOrGetPromise = (\n fn: () => Promise<Language[]>,\n key: (string | number | Record<string, unknown>)[],\n): Promise<Language[]> => {\n const keyStr = stringifyCacheKey(key)\n if (promiseCache.has(keyStr)) {\n return promiseCache.get(keyStr)!\n }\n const promise = fn()\n promiseCache.set(keyStr, promise)\n return promise\n}\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 hash = (hash << 5) - hash + char\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 = (key: string, languages: Language[]): 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 promiseCache.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 = (fn1: LanguageCallback, fn2: LanguageCallback): boolean => {\n return fn1 === fn2 || getFunctionKey(fn1) === getFunctionKey(fn2)\n}\n","import type {PluginConfig} from './types'\n\n/**\n * The field name used to identify the language of an internationalized array item.\n *\n * In v4.x this was '_key', in v5+ this will be 'language'.\n * Having this as a constant makes the codebase easier to maintain.\n */\nexport const LANGUAGE_FIELD_NAME = '_key' as const\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 type {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\n/**\n * Recursively traverses a Sanity document (or any nested value) and collects\n * all internationalized array items found within it.\n *\n * An item is considered an internationalized array value when its `_type`\n * starts with `\"internationalizedArray\"` and ends with `\"Value\"`.\n *\n * The function walks through objects and arrays, skipping keys that start\n * with `_` (internal Sanity fields like `_id`, `_type`, `_rev`). Each\n * returned item includes the original properties plus `path` (array of\n * segments) and `pathString` (dot-joined) indicating where it was found.\n */\nexport const getDocumentsToTranslate = (\n // oxlint-disable-next-line typescript-eslint/no-redundant-type-constituents\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 // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const type = item?._type as string | undefined\n return type?.startsWith('internationalizedArray') && type?.endsWith('Value')\n }\n return false\n })\n\n if (internationalizedValues.length > 0) {\n return internationalizedValues.map((internationalizedValue) => {\n return Object.assign({}, internationalizedValue, {\n path: arrayRootPath,\n pathString: arrayRootPath.join('.'),\n })\n })\n }\n\n if (value.length > 0) {\n return value.flatMap((item, index) =>\n getDocumentsToTranslate(item, [...arrayRootPath, index]),\n )\n }\n\n return []\n }\n if (typeof value === 'object' && value) {\n const startsWithUnderscoreRegex = /^_/\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const itemKeys = Object.keys(value).filter(\n (key) => !key.match(startsWithUnderscoreRegex),\n ) as (keyof typeof value)[]\n\n return itemKeys.flatMap((item) => {\n const selectedValue = value[item] as unknown\n const path = [...rootPath, item]\n return getDocumentsToTranslate(selectedValue, path)\n })\n }\n return []\n}\n","import type {LanguageDisplay} from '../types'\n\n/**\n * Formats a language label for display in buttons and field headers\n * based on the configured `languageDisplay` mode:\n *\n * - `'codeOnly'` -> uppercase code, e.g. `\"EN\"`\n * - `'titleOnly'` -> title as-is, e.g. `\"English\"`\n * - `'titleAndCode'` -> title with uppercase code, e.g. `\"English (EN)\"`\n *\n * Falls back to `title` for any unrecognized display mode.\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') return `${title} (${code.toUpperCase()})`\n return title\n}\n","import {AddIcon} from '@sanity/icons'\nimport {Button, Grid} from '@sanity/ui'\n\nimport type {Language, InternationalizedArrayItem} from '../types'\n\nimport {LANGUAGE_FIELD_NAME, MAX_COLUMNS} from '../constants'\nimport {getLanguageDisplay} from '../utils/getLanguageDisplay'\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\ntype AddButtonsProps = {\n languages: Language[]\n readOnly: boolean\n value: InternationalizedArrayItem[] | undefined\n handleClick: (languageId: string) => void\n}\n\n/**\n * Renders a grid of \"add language\" buttons — one per configured language.\n *\n * Returns `null` when the `languages` array is empty.\n *\n * Each button is disabled when:\n * - `readOnly` is `true`, or\n * - the language already exists in the current `value` array\n * (matched via `LANGUAGE_FIELD_NAME`).\n *\n * The button label is formatted according to the `languageDisplay` setting\n * from the plugin context (e.g. code-only, title-only, or both).\n * An `AddIcon` is shown unless there are more languages than fit in one row\n * and the display mode is `'codeOnly'`.\n */\nfunction AddButtons(props: AddButtonsProps) {\n const {languages, readOnly, value, handleClick} = props\n const {languageDisplay} = useInternationalizedArrayContext()\n\n return languages.length > 0 ? (\n <Grid columns={Math.min(languages.length, MAX_COLUMNS[languageDisplay])} gap={2}>\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 data-testid={`add-${language.id}`}\n disabled={\n readOnly || Boolean(value?.find((item) => item[LANGUAGE_FIELD_NAME] === 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] && languageDisplay === 'codeOnly'\n ? undefined\n : AddIcon\n }\n value={language.id}\n onClick={() => handleClick(language.id)}\n />\n )\n })}\n </Grid>\n ) : null\n}\n\nexport default AddButtons\n","import {Box, Stack, Text, useToast} from '@sanity/ui'\nimport {type ReactElement, useCallback} from 'react'\nimport {\n type FormInsertPatch,\n type FormSetIfMissingPatch,\n insert,\n isSanityDocument,\n PatchEvent,\n setIfMissing,\n useSchema,\n} from 'sanity'\nimport {useDocumentPane} from 'sanity/structure'\n\nimport type {DocumentsToTranslate} from '../utils/getDocumentsToTranslate'\n\nimport {LANGUAGE_FIELD_NAME} from '../constants'\nimport {getDocumentsToTranslate} from '../utils/getDocumentsToTranslate'\nimport AddButtons from './AddButtons'\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\ntype DocumentAddButtonsProps = {\n value: Record<string, unknown> | undefined\n}\n/**\n * Document-level \"add translation\" panel that appears outside individual\n * internationalized array fields (when `buttonLocations` includes `'document'`).\n *\n * Renders a heading and a row of per-language buttons. When a language button\n * is clicked the component:\n *\n * 1. Scans the current document for all internationalized array fields\n * using `getDocumentsToTranslate`.\n * 2. Filters out fields that already contain a translation for the selected\n * language, and deduplicates by field path.\n * 3. Shows an error toast if no eligible fields remain.\n * 4. Creates `setIfMissing` + `insert` patches to add the new language\n * entry to each eligible field, dispatching them via `onChange`.\n *\n * For Portable Text and other array-based value fields, the initial value\n * is set to an empty array (`[]`) rather than `undefined`.\n */\nexport default function DocumentAddButtons(props: DocumentAddButtonsProps): 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 || !match[1]) 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 = new Set(['body', 'htmlContent', 'blockContent', 'portableText'])\n if (arrayBasedTypes.has(baseTypeName)) {\n return []\n }\n\n // Try to look up the schema type to determine if it's an array\n const schemaType = schema.get(typeName)\n if (schemaType && 'fields' in schemaType) {\n // Check if this is an object type with a 'value' field\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const fields = schemaType.fields as Array<{\n name: string\n type?: {jsonType?: string; name?: string; type?: string; of?: unknown}\n }>\n const valueField = fields.find((f) => f.name === 'value')\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 (fieldType?.name && arrayBasedTypes.has(fieldType.name))\n ) {\n return []\n }\n }\n }\n\n return undefined\n },\n [schema],\n )\n\n const handleDocumentButtonClick = useCallback(\n async (languageId: string) => {\n const alreadyTranslated = documentsToTranslation.filter(\n (translation) => translation?.[LANGUAGE_FIELD_NAME] === languageId,\n )\n const removeDuplicates = documentsToTranslation.reduce<DocumentsToTranslate[]>(\n (filteredTranslations, translation) => {\n if (\n alreadyTranslated.filter(\n (alreadyTranslation) => 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 filteredTranslations.push(translation)\n return filteredTranslations\n },\n [],\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 [LANGUAGE_FIELD_NAME]: 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 handleClick={handleDocumentButtonClick}\n />\n </Stack>\n )\n}\n","import {get} from 'lodash-es'\n\n/**\n * Extracts a subset of values from a Sanity document based on a `select`\n * mapping (as configured in the plugin's `select` option).\n *\n * Each key in `select` becomes a key in the returned object, with its value\n * resolved from the document using the corresponding dot-path (via lodash `get`).\n *\n * Array values are filtered to remove incomplete references (objects with\n * `_type: 'reference'` but no `_ref`), since those represent empty reference\n * fields that should be ignored.\n *\n * Returns an empty object when either `select` or `document` is undefined.\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' ? item?._type === 'reference' && '_ref' in item : true,\n )\n }\n selectedValue[key] = value\n }\n\n return selectedValue\n}\n","import type React from 'react'\n\nimport {useLanguageFilterStudioContext} from '@sanity/language-filter'\nimport {Stack} from '@sanity/ui'\nimport {createContext, use, useContext, useDeferredValue, useMemo} from 'react'\nimport {type ObjectInputProps, useClient, useWorkspace} from 'sanity'\nimport {useDocumentPane} from 'sanity/structure'\n\nimport type {Language, PluginConfig} from '../types'\n\nimport {createCacheKey, createOrGetPromise, setFunctionCache} from '../cache'\nimport {CONFIG_DEFAULT} from '../constants'\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\nexport type InternationalizedArrayContextProps = Required<PluginConfig> & {\n languages: Language[]\n filteredLanguages: Language[]\n}\n\nexport const InternationalizedArrayContext = 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 languagesPromise = useMemo(() => {\n if (Array.isArray(internationalizedArray.languages)) {\n return null // Return null for synchronous arrays\n }\n\n // Create or get cached promise for React.use\n return createOrGetPromise(async () => {\n if (typeof internationalizedArray.languages === 'function') {\n const result = await internationalizedArray.languages(client, selectedValue)\n // Populate function cache for use outside React context\n setFunctionCache(internationalizedArray.languages, selectedValue, result, workspaceId)\n return result\n }\n return internationalizedArray.languages\n }, cacheKey)\n }, [internationalizedArray, client, selectedValue, workspaceId, cacheKey])\n\n // Use React.use to handle the promise with Suspense, or return array directly\n const languages = languagesPromise\n ? use(languagesPromise)\n : // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n (internationalizedArray.languages as Language[])\n\n // Filter out some languages if language filter is enabled\n const {selectedLanguageIds, options: languageFilterOptions} = useLanguageFilterStudioContext()\n\n const filteredLanguages = useMemo(() => {\n const documentType = deferredDocument ? deferredDocument['_type'] : undefined\n const languageFilterEnabled =\n typeof documentType === 'string' && languageFilterOptions.documentTypes.includes(documentType)\n\n return languageFilterEnabled\n ? languages.filter((language) => selectedLanguageIds.includes(language.id))\n : languages\n }, [deferredDocument, languageFilterOptions, languages, selectedLanguageIds])\n\n const showDocumentButtons = 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'\n\nimport {useMemo} from 'react'\nimport {type FieldProps, useFormValue} from 'sanity'\n\nimport {LANGUAGE_FIELD_NAME} from '../constants'\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\n/**\n * Extracts the language identifier from a parent internationalized array item.\n *\n * Returns the `LANGUAGE_FIELD_NAME` value when the parent is an object whose\n * `_type` starts with `\"internationalizedArray\"` and has a string-valued\n * language field. Returns `undefined` otherwise (including on error).\n */\nconst getLanguageId = (fieldParent: unknown): string | undefined => {\n try {\n const languageId =\n typeof fieldParent === 'object' &&\n fieldParent !== null &&\n // Checks if it's an internationalized array item\n '_type' in fieldParent &&\n typeof fieldParent._type === 'string' &&\n fieldParent._type.startsWith('internationalizedArray') &&\n // Checks if the language field name is in the field and if it's a string\n LANGUAGE_FIELD_NAME in fieldParent &&\n typeof fieldParent[LANGUAGE_FIELD_NAME] === 'string'\n ? fieldParent[LANGUAGE_FIELD_NAME]\n : undefined\n return languageId\n } catch (error) {\n console.error('Error getting language id', error)\n return undefined\n }\n}\n\n/**\n * Custom field renderer for fields inside internationalized array items.\n *\n * - Hides the \"Value\" title label when the parent item has a valid language\n * (one that exists in the configured languages list).\n * - Routes rendering based on the field's schema type name:\n * - Non-internationalized types -> `renderDefault` (with title adjustment)\n * - `reference` with a value -> `renderDefault` at level 0\n * - `string` / `number` / `text` -> returns `children` directly for\n * inline editing\n * - Complex internationalized types (e.g. markdown) -> `renderDefault`\n * at level 0\n */\nexport default function InternationalizedField(props: FieldProps): ReactNode {\n const {languages} = useInternationalizedArrayContext()\n // Get the array item (parent of the field) to look up the language from it\n const fieldParent = useFormValue(props.path.slice(0, -1))\n\n const languageId = getLanguageId(fieldParent)\n const customProps = useMemo(() => {\n const hasValidLanguageId = languageId ? languages.some((l) => l.id === languageId) : false\n // hide titles for 'value' fields within valid language entries\n const shouldHideTitle = props.title?.toLowerCase() === 'value' && hasValidLanguageId\n\n return {\n ...props,\n title: shouldHideTitle ? '' : props.title,\n }\n }, [props, languages, languageId])\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 {useClient} from 'sanity'\n\nimport type {PluginConfig} from '../types'\n\nimport {createCacheKey, peek, preloadWithKey, setFunctionCache} from '../cache'\n\nexport default function Preload(props: Required<Pick<PluginConfig, 'apiVersion' | 'languages'>>) {\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 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 type {Language, InternationalizedArrayItem} from '../types'\n\nimport {LANGUAGE_FIELD_NAME} from '../constants'\n\n/**\n * Checks whether every language in the provided list has a corresponding entry\n * in the value array. It extracts language IDs from value items using\n * `LANGUAGE_FIELD_NAME` and compares them against the expected language IDs.\n *\n * Returns `true` only when the value array length matches the number of unique\n * languages and every value language ID is found in the languages list\n * (order does not matter). The length check ensures duplicates in value are\n * correctly rejected.\n */\nexport function checkAllLanguagesArePresent(\n languages: Language[],\n value: InternationalizedArrayItem[] | undefined,\n): boolean {\n const filteredLanguageIds = new Set(languages.map((l) => l.id))\n const languagesInUseIds = value ? value.map((v) => v[LANGUAGE_FIELD_NAME]) : []\n\n if (languagesInUseIds.length !== filteredLanguageIds.size) return false\n if (new Set(languagesInUseIds).size !== languagesInUseIds.length) return false\n return languagesInUseIds.every((key) => filteredLanguageIds.has(key))\n}\n","import type {Language, InternationalizedArrayItem} from '../types'\n\n/**\n * Generates the label text for the \"add all / add missing languages\" button.\n *\n * - When there is no existing value: returns `\"Add {title} Field\"` for a\n * single language, or `\"Add all languages\"` for multiple.\n * - When some values already exist: returns `\"Add missing language\"` (singular)\n * or `\"Add missing languages\"` (plural) depending on how many are left.\n */\nexport function createAddAllTitle(\n value: InternationalizedArrayItem[] | undefined,\n languages: Language[],\n): string {\n if (value?.length) {\n return `Add missing ${languages.length - value.length === 1 ? `language` : `languages`}`\n }\n\n return languages.length === 1 && languages[0]\n ? `Add ${languages[0].title} Field`\n : `Add all languages`\n}\n","import type {FieldDefinition, Rule, RuleTypeConstraint, SanityClient} from 'sanity'\n\nexport type Language = {\n id: Intl.UnicodeBCP47LocaleIdentifier\n title: string\n}\n\nexport type AllowedType = 'string' | 'number' | 'boolean' | 'text' | 'reference'\n\nexport type ArrayConfig = {\n name: string\n type: AllowedType\n languages: Language[]\n title?: string\n group?: string\n hidden?: boolean | (() => boolean)\n readOnly?: boolean | (() => boolean)\n validation?: Rule | Rule[]\n field?: {[key: string]: unknown; options: {[key: string]: unknown}}\n}\n\n/**\n * @deprecated Use InternationalizedArrayItem instead\n */\nexport type Value = {\n _key: string\n value?: unknown\n}\n\nexport function isInternationalizedArrayItemType(\n type: string,\n): type is InternationalizedArrayItem['_type'] {\n return type.startsWith('internationalizedArray') && type.endsWith('Value')\n}\n\nexport type InternationalizedArrayItem<T = unknown> = {\n _key: string\n value?: T\n /**\n * string that starts with \"internationalizedArray\" and ends with \"Value\"\n */\n _type: `internationalizedArray${string}Value`\n}\n\nexport type LanguageCallback = (\n client: SanityClient,\n selectedValue: Record<string, unknown>,\n) => Promise<Language[]>\n\nexport type LanguageDisplay = 'titleOnly' | 'codeOnly' | 'titleAndCode'\n\nexport type PluginConfig = {\n /**\n * https://www.sanity.io/docs/api-versioning\n * @defaultValue '2025-10-15'\n */\n apiVersion?: string\n /**\n * Specify fields that should be available in the language callback:\n * ```tsx\n * {\n * select: {\n * markets: 'markets'\n * },\n * languages: (client, {markets}) =>\n * query.fetch(groq`*[_type == \"language\" && market in $markets]{id,title}`, {markets})\n * }\n * ```\n */\n select?: Record<string, string>\n /**\n * You can give it an array of language definitions:\n * ```tsx\n * {\n * languages: [\n * {id: 'en', title: 'English'},\n * {id: 'fr', title: 'French'}\n * ]\n * }\n * ```\n * You can load them async by passing a function that returns a promise:\n * ```tsx\n * {\n * languages: async () => {\n * const response = await fetch('https://example.com/languages')\n * return response.json()\n * }\n * }\n * ```\n * You can query your dataset for languages::\n * ```tsx\n * {\n * languages: (client) =>\n * query.fetch(groq`*[_type == \"language\"]{id,title}`)\n * }\n * ```\n */\n languages: Language[] | LanguageCallback\n /**\n * You can specify a list of language IDs that should be pre-filled when creating a new document\n * ```tsx\n * {\n * defaultLanguages: ['en']\n * }\n * ```\n */\n defaultLanguages?: string[]\n /**\n * Can be a string matching core field types, as well as custom ones:\n * ```tsx\n * {\n * fieldTypes: [\n * \"date\", \"datetime\", \"file\", \"image\", \"number\", \"string\", \"text\", \"url\"\n * ]\n * }\n * ```\n * You can also define a type directly:\n * ```tsx\n * {\n * fieldTypes: [\n * defineField({\n * name: 'featuredProduct',\n * type: 'reference',\n * to: [{type: 'product'}]\n * hidden: (({document}) => !document?.title)\n * })\n * ]\n * }\n * ```\n */\n // oxlint-disable-next-line typescript-eslint/no-redundant-type-constituents\n fieldTypes: (string | RuleTypeConstraint | FieldDefinition)[]\n /**\n * Locations where the \"+ EN\" add language buttons are visible\n * @defaultValue ['field']\n * */\n buttonLocations?: ('field' | 'unstable__fieldAction' | 'document')[]\n /**\n * Show or hide the \"Add missing languages\" button\n * @defaultValue true\n * */\n buttonAddAll?: boolean\n /**\n * How to display the languages on buttons and fields\n * @defaultValue 'code'\n * */\n languageDisplay?: LanguageDisplay\n}\n","import {type FormInsertPatch, insert, type Path} from 'sanity'\n\nimport {LANGUAGE_FIELD_NAME} from '../constants'\nimport {\n type Language,\n type InternationalizedArrayItem,\n isInternationalizedArrayItemType,\n} from '../types'\n\ntype AddConfig = {\n // New keys to add to the field\n addLanguageKeys: string[]\n // Schema of the current field\n schemaTypeName: string\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?: InternationalizedArrayItem[]\n // Path to this item\n path?: Path\n}\n\n/**\n * Creates an array of Sanity `FormInsertPatch` objects that add new language\n * entries to an internationalized array field.\n *\n * If `addLanguageKeys` is provided, patches are created for those specific\n * language IDs. Otherwise, patches are created for all filtered languages\n * that are not already present in the current `value` array, for example when adding all missing languages.\n *\n * Each new item is assigned the correct `_type` (derived from the schema)\n * and the language identifier via `LANGUAGE_FIELD_NAME`.\n *\n * Insertions are ordered to maintain the same sequence as the master\n * `languages` list: each new item is inserted before the next existing\n * language in the value array, or appended at the end if no subsequent\n * language exists.\n */\nexport function createAddLanguagePatches(config: AddConfig): FormInsertPatch[] {\n const {addLanguageKeys, schemaTypeName, languages, filteredLanguages, value, path = []} = config\n\n const type = `${schemaTypeName}Value`\n if (!isInternationalizedArrayItemType(type)) {\n throw new Error(`Invalid internationalized array type: ${type}`)\n }\n const itemBase = {_type: type}\n\n // Create new items\n const getNewItems = () => {\n if (Array.isArray(addLanguageKeys) && addLanguageKeys.length > 0) {\n return addLanguageKeys\n .filter((id) => {\n if (value?.length) {\n // Check if the language is already in the value and filter it out if it exists to avoid duplicates\n return !value.find((v) => v[LANGUAGE_FIELD_NAME] === id)\n }\n return true\n })\n .map((id) => Object.assign({}, itemBase, {[LANGUAGE_FIELD_NAME]: id}))\n }\n\n return filteredLanguages\n .filter((language) => {\n return value?.length ? !value.find((v) => v[LANGUAGE_FIELD_NAME] === language.id) : true\n })\n .map((language) => Object.assign({}, itemBase, {[LANGUAGE_FIELD_NAME]: language.id}))\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 itemLanguage = item[LANGUAGE_FIELD_NAME]\n const languageIndex = languages.findIndex((l) => itemLanguage === 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 remainingLanguages.find((r) => r.id === l[LANGUAGE_FIELD_NAME]),\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 type {Language, InternationalizedArrayItem} from '../types'\n\nimport {useInternationalizedArrayContext} from '../components/InternationalizedArrayContext'\nimport {LANGUAGE_FIELD_NAME} from '../constants'\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[] = (fieldActionProps, {languages, filteredLanguages}) =>\n languages.map((language) => {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const value = useFormValue(fieldActionProps.path) as InternationalizedArrayItem[]\n const disabled =\n value && Array.isArray(value)\n ? Boolean(value?.find((item) => item[LANGUAGE_FIELD_NAME] === 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 schemaTypeName: schemaType.name,\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 = (fieldActionProps, {languages, filteredLanguages}) => {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const value = useFormValue(fieldActionProps.path) as InternationalizedArrayItem[]\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 schemaTypeName: schemaType.name,\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('internationalizedArray')\n const {languages, filteredLanguages} = useInternationalizedArrayContext()\n\n const translateFieldActions = createTranslateFieldActions(fieldActionProps, {\n languages,\n 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","import {camelCase, upperFirst} from 'lodash-es'\n\n/**\n * Converts a string to PascalCase (e.g. `\"my-field\"` -> `\"MyField\"`).\n */\nexport function pascalCase(string: string): string {\n return upperFirst(camelCase(string))\n}\n\n/**\n * Generates the schema type name for an internationalized array field.\n *\n * - Without the value suffix: `\"internationalizedArray{PascalName}\"`\n * (used for the outer array type)\n * - With the value suffix: `\"internationalizedArray{PascalName}Value\"`\n * (used for the inner object type that wraps each language entry)\n *\n * For example, `createFieldName('block-content', true)` returns\n * `\"internationalizedArrayBlockContentValue\"`.\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 type React from 'react'\n\nimport {Card, Code, Stack, Text} from '@sanity/ui'\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 <code>internationalizedArray</code>{' '}\n helper function, each with an <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 type React from 'react'\n\nimport {AddIcon} from '@sanity/icons'\nimport {useLanguageFilterStudioContext} from '@sanity/language-filter'\nimport {Button, Card, Stack, Text, useToast} from '@sanity/ui'\nimport {useCallback, useEffect, useMemo} from 'react'\nimport {\n type ArrayOfObjectsInputProps,\n ArrayOfObjectsItem,\n MemberItemError,\n set,\n setIfMissing,\n useFormValue,\n} from 'sanity'\nimport {useDocumentPane} from 'sanity/structure'\n\nimport type {InternationalizedArrayItem} from '../types'\n\nimport {LANGUAGE_FIELD_NAME} from '../constants'\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<InternationalizedArrayItem>\n\n/**\n * Main array input component for internationalized array fields.\n *\n * Replaces the default Sanity array input and manages the full lifecycle of\n * language entries:\n *\n * - **Language filter integration**: When `@sanity/language-filter` is active\n * for the current document type, array members are filtered to only show\n * languages matching the user's selection.\n * - **Adding languages**: Exposes per-language buttons and an \"Add all / Add\n * missing languages\" button (controlled by `buttonAddAll` and\n * `buttonLocations` config). Dispatches `setIfMissing` + `insert` patches.\n * - **Default languages**: Automatically adds entries for languages listed in\n * `defaultLanguages` when a document is first created or when those entries\n * are missing.\n * - **Ordering**: Detects when value items are out of order relative to the\n * master `languages` list and automatically re-sorts them.\n * - **Validation**: Shows a `<Feedback>` component if the languages\n * configuration is invalid (e.g. missing `id` or `title`).\n * - **Empty state**: Displays a \"no translations\" message when the field has\n * no entries and the add buttons are not visible.\n */\nexport default function InternationalizedArray(\n props: ArrayOfObjectsInputProps,\n): React.ReactElement {\n const {members, value: _value, schemaType, onChange, readOnly: documentReadOnly} = props\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion\n const value = _value as InternationalizedArrayItem[]\n const readOnly = typeof schemaType.readOnly === 'boolean' ? schemaType.readOnly : false\n const toast = useToast()\n\n const {languages, filteredLanguages, defaultLanguages, buttonAddAll, buttonLocations} =\n useInternationalizedArrayContext()\n\n // Support updating the UI if languageFilter is installed\n const {selectedLanguageIds, options: languageFilterOptions} = useLanguageFilterStudioContext()\n const documentType = useFormValue(['_type'])\n const languageFilterEnabled =\n typeof documentType === 'string' && 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 || 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 (addLanguageKeys: string[] | string) => {\n if (!filteredLanguages?.length) {\n return\n }\n\n const patches = createAddLanguagePatches({\n addLanguageKeys: Array.isArray(addLanguageKeys) ? addLanguageKeys : [addLanguageKeys],\n schemaTypeName: schemaType.name,\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 = useMemo(() => {\n if (!value?.length) return []\n return value.map((v) => v[LANGUAGE_FIELD_NAME] ?? v._key).filter(Boolean)\n }, [value])\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?.[LANGUAGE_FIELD_NAME])\n\n if (newIndex > -1) {\n acc[newIndex] = v\n }\n\n return acc\n }, [] as InternationalizedArrayItem[])\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?.[LANGUAGE_FIELD_NAME]))\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[LANGUAGE_FIELD_NAME] === 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[LANGUAGE_FIELD_NAME]) ? null : v,\n )\n .filter(Boolean)\n }, [value, languagesInUse])\n\n const languagesAreValid = useMemo(\n () =>\n !languages?.length || (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 && !documentReadOnly) {\n handleRestoreOrder()\n }\n }, [languagesOutOfOrder, allKeysAreLanguages, handleRestoreOrder, documentReadOnly])\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 <ArrayOfObjectsItem {...props} key={member.key} member={member} />\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}>This internationalized field currently has no translations.</Text>\n </Card>\n ) : null}\n\n {addButtonsAreVisible ? (\n <Stack space={2}>\n <AddButtons\n languages={filteredLanguages}\n value={value}\n readOnly={readOnly}\n handleClick={handleAddLanguage}\n />\n {buttonAddAll ? (\n <Button\n tone=\"primary\"\n mode=\"ghost\"\n data-testid=\"add-all-languages\"\n disabled={readOnly || allLanguagesArePresent}\n icon={AddIcon}\n text={createAddAllTitle(value, filteredLanguages)}\n onClick={() => handleAddLanguage(filteredLanguages.map((language) => language.id))}\n />\n ) : null}\n </Stack>\n ) : null}\n </Stack>\n )\n}\n","import type {SchemaType} from 'sanity'\n\nimport type {ArrayFieldOptions} from '../schema/array'\n\nexport function getLanguagesFieldOption(\n schemaType: SchemaType | undefined,\n): ArrayFieldOptions['languages'] | undefined {\n if (!schemaType) {\n return undefined\n }\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const languagesOption = (schemaType.options as ArrayFieldOptions)?.languages\n if (languagesOption) {\n return languagesOption\n }\n return getLanguagesFieldOption(schemaType.type)\n}\n","import {defineField, type FieldDefinition, type Rule} from 'sanity'\n\nimport type {Language, LanguageCallback, InternationalizedArrayItem} from '../types'\n\nimport {getFunctionCache, peek, setFunctionCache} from '../cache'\nimport {createFieldName} from '../components/createFieldName'\nimport {getSelectedValue} from '../components/getSelectedValue'\nimport InternationalizedArray from '../components/InternationalizedArray'\nimport {LANGUAGE_FIELD_NAME} from '../constants'\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<ArrayFactoryConfig, 'apiVersion' | 'select' | 'languages'>\n\nexport default (config: ArrayFactoryConfig) => {\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<InternationalizedArrayItem[]>(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]?.[LANGUAGE_FIELD_NAME]) {\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(languagesFieldOption, selectedValue)\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(client, selectedValue)\n // Cache the result for future validation calls\n setFunctionCache(languagesFieldOption, selectedValue, contextLanguages)\n }\n }\n }\n\n if (value && value.length > contextLanguages.length) {\n return `Cannot be more than ${\n contextLanguages.length === 1 ? `1 item` : `${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?.[LANGUAGE_FIELD_NAME] && !languageIds.has(item[LANGUAGE_FIELD_NAME]),\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 seenLanguages = new Set<string>()\n const duplicateValues: InternationalizedArrayItem[] = []\n\n for (const item of value) {\n if (item?.[LANGUAGE_FIELD_NAME]) {\n if (seenLanguages.has(item[LANGUAGE_FIELD_NAME])) {\n duplicateValues.push(item)\n } else {\n seenLanguages.add(item[LANGUAGE_FIELD_NAME])\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\n/**\n * Maps an array of Sanity form validation entries to a `@sanity/ui` `CardTone`\n * for visual feedback on internationalized array items.\n *\n * - Returns `'critical'` if any validation has `level: 'error'`\n * - Returns `'caution'` if any validation has `level: 'warning'` (and no errors)\n * - Returns `undefined` otherwise (no tone applied)\n *\n * Error level always takes precedence over warning.\n */\nexport function getToneFromValidation(validations: FormNodeValidation[]): CardTone | undefined {\n if (!validations?.length) {\n return undefined\n }\n\n const validationLevels = new Set(validations.map((v) => v.level))\n\n if (validationLevels.has('error')) {\n return `critical`\n } else if (validationLevels.has('warning')) {\n return `caution`\n }\n\n return undefined\n}\n","import type React from 'react'\n\nimport {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 ReactNode, useMemo} from 'react'\nimport {type ObjectItemProps, useFormValue} from 'sanity'\nimport {set, unset} from 'sanity'\n\nimport {LANGUAGE_FIELD_NAME} from '../constants'\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\n/**\n * Renders a single row of an internationalized array: a language label (or\n * \"Change\" menu for invalid keys), the value input, and a remove button.\n *\n * Key behaviours:\n * - Wraps `onChange` to intercept paste operations into empty Portable Text\n * fields, ensuring `setIfMissing` and correct path prefixing.\n * - Detects items needing migration (missing `LANGUAGE_FIELD_NAME`) and hides\n * the language label in that state.\n * - Shows a `MenuButton` with available languages when the current key is\n * not a valid language.\n * - Disables the remove button for languages listed in `defaultLanguages`.\n * - Shows a `Spinner` when languages have not been loaded yet.\n * - Applies a `CardTone` based on validation state via `getToneFromValidation`.\n */\nexport default function InternationalizedInput(\n props: ObjectItemProps<InternationalizedValue>,\n): ReactNode {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const parentValue = useFormValue(props.path.slice(0, -1)) 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 = (patches: unknown) => {\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 // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n return originalOnChange(patches as Parameters<typeof originalOnChange>[0])\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 const hasProblematicInsert = patches.some((patch: {type?: string; path?: unknown[]}) => {\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 = 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 ? {type: 'setIfMissing', path: ['value'], value: []} : null\n\n // Transform the patches to ensure they work with the nested structure\n const fixedPatches = patches.map(\n (patch: {type?: string; path?: unknown[]; [key: string]: unknown}) => {\n // Ensure patch exists and has required properties\n if (!patch || typeof patch !== 'object') {\n return patch\n }\n\n if (patch.type === 'insert' && patch.path && Array.isArray(patch.path)) {\n // Ensure the path is correct for the nested structure\n const fixedPath = patch.path[0] === 'value' ? patch.path : ['value', ...patch.path]\n const fixedPatch = {...patch, path: fixedPath}\n return fixedPatch\n }\n return patch\n },\n )\n\n // If we need to initialize the field, include that patch first\n const allPatches = initPatch ? [initPatch, ...fixedPatches] : fixedPatches\n\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n return originalOnChange(allPatches as Parameters<typeof originalOnChange>[0])\n }\n }\n\n // For all other cases, pass through unchanged\n return originalOnChange(patches as Parameters<typeof originalOnChange>[0])\n }\n\n const inlineProps = {\n ...props.inputProps,\n // This is the magic that makes inline editing work?\n members: props.inputProps.members.filter((m) => m.kind === 'field' && m.name === 'value'),\n // This just overrides the type\n // Remove this as it shouldn't be necessary?\n // oxlint-disable-next-line typescript-eslint/no-unnecessary-type-assertion\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} = useInternationalizedArrayContext()\n\n const languageKeysInUse = useMemo(\n () => parentValue?.map((v) => v[LANGUAGE_FIELD_NAME]) ?? [],\n [parentValue],\n )\n const keyIsValid = languages?.length\n ? languages.find((l) => l.id === value[LANGUAGE_FIELD_NAME])\n : false\n\n // Changes the key of this item, ideally to a valid language\n const handleKeyChange = (event: React.MouseEvent<HTMLButtonElement>): void => {\n const languageId = event?.currentTarget?.value\n\n if (!value || !languages?.length || !languages.find((l) => l.id === languageId)) {\n return\n }\n\n onChange([set(languageId, [LANGUAGE_FIELD_NAME])])\n }\n\n // Removes this item from the array\n const handleUnset = (): void => {\n onChange(unset())\n }\n\n if (!languages) {\n return <Spinner />\n }\n\n const language = languages.find((l) => l.id === value[LANGUAGE_FIELD_NAME])\n const languageTitle: string =\n keyIsValid && language ? getLanguageDisplay(languageDisplay, language.title, language.id) : ''\n\n const isDefault = defaultLanguages.includes(value[LANGUAGE_FIELD_NAME])\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[LANGUAGE_FIELD_NAME]}\"`} />}\n id={`${value[LANGUAGE_FIELD_NAME]}-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'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, type FieldDefinition} from 'sanity'\n\nimport {createFieldName} from '../components/createFieldName'\nimport InternationalizedInput from '../components/InternationalizedInput'\nimport {LANGUAGE_FIELD_NAME} from '../constants'\n\ntype ObjectFactoryConfig = {\n type: string | FieldDefinition\n}\n\nexport default (config: ObjectFactoryConfig) => {\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 ${typeName}`,\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: LANGUAGE_FIELD_NAME,\n },\n },\n })\n}\n","import {isDocumentSchemaType, type ObjectField, type Path, type SchemaType} from 'sanity'\n\ntype ObjectFieldWithPath = ObjectField & {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(schemaType: SchemaType): 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[],\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(field.type.fields, [...path, field.name], maxDepth)\n\n acc.push(thisFieldWithPath, ...innerFields)\n return acc\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 acc.push(thisFieldWithPath, ...innerFields)\n return acc\n }\n\n acc.push(thisFieldWithPath)\n return acc\n }, [])\n}\n","import {definePlugin, isObjectInputProps} from 'sanity'\n\nimport type {PluginConfig} from './types'\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 {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 <InternationalizedArrayProvider {...props} internationalizedArray={pluginConfig} />\n },\n },\n },\n // Register custom schema types for the outer array and the inner object\n schema: {\n types: [\n ...fieldTypes.map((type) => array({type, apiVersion, select, languages, defaultLanguages})),\n ...fieldTypes.map((type) => object({type})),\n ],\n },\n }\n})\n"],"names":["namespace","functionCache","Map","functionKeyCache","WeakMap","promiseCache","stringifyCacheKey","key","JSON","stringify","preloadWithKey","fn","keyStr","has","set","clear","peek","selectedValue","version","promise","get","_status","_value","createCacheKey","workspaceId","selectedValueHash","createOrGetPromise","getFunctionKey","cachedKey","fnStr","toString","hash","maxLength","Math","min","length","i","char","charCodeAt","abs","createFunctionCacheKey","functionKey","getFunctionCache","setFunctionCache","languages","LANGUAGE_FIELD_NAME","MAX_COLUMNS","codeOnly","titleOnly","titleAndCode","CONFIG_DEFAULT","select","defaultLanguages","fieldTypes","apiVersion","buttonLocations","buttonAddAll","languageDisplay","getDocumentsToTranslate","value","rootPath","Array","isArray","arrayRootPath","internationalizedValues","filter","item","type","_type","startsWith","endsWith","map","internationalizedValue","Object","assign","path","pathString","join","flatMap","index","startsWithUnderscoreRegex","keys","match","getLanguageDisplay","title","code","toUpperCase","AddButtons","props","$","_c","readOnly","handleClick","useInternationalizedArrayContext","t0","language","languageTitle","id","Boolean","find","undefined","AddIcon","DocumentAddButtons","filteredLanguages","isSanityDocument","toast","useToast","onChange","useDocumentPane","schema","useSchema","documentsToTranslation","t1","typeName","baseTypeName","charAt","toLowerCase","slice","arrayBasedTypes","Set","schemaType","valueField","fields","_temp","fieldType","jsonType","name","of","getInitialValueForType","t2","languageId","alreadyTranslated","translation","removeDuplicates","reduce","filteredTranslations","translation_0","alreadyTranslation","filteredTranslation","push","status","patches","toTranslate","initialValue","ifMissing","setIfMissing","insertValue","insert","PatchEvent","from","flat","handleDocumentButtonClick","t3","Symbol","for","t4","f","getSelectedValue","document","selection","entries","InternationalizedArrayContext","createContext","useContext","InternationalizedArrayProvider","internationalizedArray","client","useClient","workspace","useWorkspace","formState","deferredDocument","useDeferredValue","bb0","t5","cacheKey","bb1","result","t6","languagesPromise","use","selectedLanguageIds","options","languageFilterOptions","useLanguageFilterStudioContext","documentType","documentTypes","includes","languageFilterEnabled","t7","showDocumentButtons","t8","context","t9","renderDefault","t10","getLanguageId","fieldParent","error","console","InternationalizedField","useFormValue","hasValidLanguageId","some","l","customProps","level","children","Preload","checkAllLanguagesArePresent","filteredLanguageIds","languagesInUseIds","v","size","every","createAddAllTitle","isInternationalizedArrayItemType","createAddLanguagePatches","config","addLanguageKeys","schemaTypeName","Error","itemBase","newItems","languagesInUse","itemLanguage","languageIndex","findIndex","remainingLanguages","nextLanguageIndex","r","splice","createTranslateFieldActions","fieldActionProps","disabled","hidden","onAction","useCallback","icon","AddMissingTranslationsFieldAction","internationalizedArrayFieldAction","defineDocumentFieldAction","useAction","isInternationalizedArrayField","translateFieldActions","TranslateIcon","renderAsButton","pascalCase","string","upperFirst","camelCase","createFieldName","addValue","schemaExample","Feedback","InternationalizedArray","members","documentReadOnly","member","kind","valueMember","filterField","filteredMembers","handleAddLanguage","isDeleting","addedLanguages","language_0","hasAddedDefaultLanguages","languagesToAdd","language_1","language_2","l_0","timeout","setTimeout","clearTimeout","useEffect","updatedValue","acc","v_0","newIndex","l_1","handleRestoreOrder","v_1","l_2","allKeysAreLanguages","l_3","v_2","t11","bb2","t12","t13","v_3","vIndex","l_4","languagesOutOfOrder","languagesAreValid","_temp2","t14","allLanguagesArePresent","t15","addButtonsAreVisible","fieldHasMembers","t16","member_0","t17","t18","_temp3","t19","language_3","_key","getLanguagesFieldOption","arrayName","objectName","defineField","components","input","validation","rule","custom","getClient","contextLanguages","languagesFieldOption","cachedLanguages","suspendCachedLanguages","languageIds","lang","nonLanguageKeys","message","paths","seenLanguages","duplicateValues","add","getToneFromValidation","validations","validationLevels","InternationalizedInput","parentValue","originalOnChange","inputProps","initPatch","fixedPatches","allPatches","wrappedOnChange","inlineProps","_temp4","languageKeysInUse","keyIsValid","handleKeyChange","event","currentTarget","handleUnset","unset","isDefault","removeButton","RemoveCircleIcon","toLocaleUpperCase","portal","T0","Card","renderInput","m","patch_0","patch","fixedPath","preview","subtitle","flattenSchemaType","isDocumentSchemaType","extractInnerFields","maxDepth","field","thisFieldWithPath","innerFields","innerField","definePlugin","pluginConfig","studio","layout","unstable_fieldActions","prev","form","isObjectInputProps","types","array","object"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","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/types.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":["import 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// Cache for React.use promises\nconst promiseCache = new Map<string, Promise<Language[]>>()\n\n// Helper to create a cache key string from an array\nfunction stringifyCacheKey(key: unknown[]): string {\n return JSON.stringify(key)\n}\n\n// Preloading: store promises in cache for React.use\nexport const preload = (fn: () => Promise<Language[]>) => {\n const key = stringifyCacheKey([version, namespace])\n if (!promiseCache.has(key)) {\n promiseCache.set(key, fn())\n }\n}\n\n// Enhanced preload function that can use custom cache keys\nexport const preloadWithKey = (fn: () => Promise<Language[]>, key: (string | number)[]) => {\n const keyStr = stringifyCacheKey(key)\n if (!promiseCache.has(keyStr)) {\n promiseCache.set(keyStr, fn())\n }\n}\n\n// Cache busting: clear all promise caches\nexport const clear = () => {\n promiseCache.clear()\n}\n\n// Peeking into entries outside of suspense\nexport const peek = (selectedValue: Record<string, unknown>) => {\n const key = stringifyCacheKey([version, namespace, selectedValue])\n const promise = promiseCache.get(key)\n if (promise) {\n // Check if promise is resolved\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const status = (promise as any)._status\n if (status === 'fulfilled') {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n return (promise as any)._value as Language[] | undefined\n }\n }\n return undefined\n}\n\n// Helper function to create a stable cache key that matches the component's key structure\nexport const createCacheKey = (selectedValue: Record<string, unknown>, workspaceId?: string) => {\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 = (selectedValue: Record<string, unknown>, workspaceId?: string) => {\n const key = stringifyCacheKey(createCacheKey(selectedValue, workspaceId))\n const promise = promiseCache.get(key)\n if (promise) {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const status = (promise as any)._status\n if (status === 'fulfilled') {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n return (promise as any)._value as Language[] | undefined\n }\n }\n return undefined\n}\n\n// Create or get cached promise for React.use\nexport const createOrGetPromise = (\n fn: () => Promise<Language[]>,\n key: (string | number | Record<string, unknown>)[],\n): Promise<Language[]> => {\n const keyStr = stringifyCacheKey(key)\n if (promiseCache.has(keyStr)) {\n return promiseCache.get(keyStr)!\n }\n const promise = fn()\n promiseCache.set(keyStr, promise)\n return promise\n}\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 hash = (hash << 5) - hash + char\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 = (key: string, languages: Language[]): 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 promiseCache.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 = (fn1: LanguageCallback, fn2: LanguageCallback): boolean => {\n return fn1 === fn2 || getFunctionKey(fn1) === getFunctionKey(fn2)\n}\n","import type {PluginConfig} from './types'\n\n/**\n * The field name used to identify the language of an internationalized array item.\n *\n * In v4.x this was '_key', in v5+ this will be 'language'.\n * Having this as a constant makes the codebase easier to maintain.\n */\nexport const LANGUAGE_FIELD_NAME = '_key' as const\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 type {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\n/**\n * Recursively traverses a Sanity document (or any nested value) and collects\n * all internationalized array items found within it.\n *\n * An item is considered an internationalized array value when its `_type`\n * starts with `\"internationalizedArray\"` and ends with `\"Value\"`.\n *\n * The function walks through objects and arrays, skipping keys that start\n * with `_` (internal Sanity fields like `_id`, `_type`, `_rev`). Each\n * returned item includes the original properties plus `path` (array of\n * segments) and `pathString` (dot-joined) indicating where it was found.\n */\nexport const getDocumentsToTranslate = (\n // oxlint-disable-next-line typescript-eslint/no-redundant-type-constituents\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 // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const type = item?._type as string | undefined\n return type?.startsWith('internationalizedArray') && type?.endsWith('Value')\n }\n return false\n })\n\n if (internationalizedValues.length > 0) {\n return internationalizedValues.map((internationalizedValue) => {\n return Object.assign({}, internationalizedValue, {\n path: arrayRootPath,\n pathString: arrayRootPath.join('.'),\n })\n })\n }\n\n if (value.length > 0) {\n return value.flatMap((item, index) =>\n getDocumentsToTranslate(item, [...arrayRootPath, index]),\n )\n }\n\n return []\n }\n if (typeof value === 'object' && value) {\n const startsWithUnderscoreRegex = /^_/\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const itemKeys = Object.keys(value).filter(\n (key) => !key.match(startsWithUnderscoreRegex),\n ) as (keyof typeof value)[]\n\n return itemKeys.flatMap((item) => {\n const selectedValue = value[item] as unknown\n const path = [...rootPath, item]\n return getDocumentsToTranslate(selectedValue, path)\n })\n }\n return []\n}\n","import type {LanguageDisplay} from '../types'\n\n/**\n * Formats a language label for display in buttons and field headers\n * based on the configured `languageDisplay` mode:\n *\n * - `'codeOnly'` -> uppercase code, e.g. `\"EN\"`\n * - `'titleOnly'` -> title as-is, e.g. `\"English\"`\n * - `'titleAndCode'` -> title with uppercase code, e.g. `\"English (EN)\"`\n *\n * Falls back to `title` for any unrecognized display mode.\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') return `${title} (${code.toUpperCase()})`\n return title\n}\n","import {AddIcon} from '@sanity/icons'\nimport {Button, Grid} from '@sanity/ui'\n\nimport type {Language, InternationalizedArrayItem} from '../types'\n\nimport {LANGUAGE_FIELD_NAME, MAX_COLUMNS} from '../constants'\nimport {getLanguageDisplay} from '../utils/getLanguageDisplay'\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\ntype AddButtonsProps = {\n languages: Language[]\n readOnly: boolean\n value: InternationalizedArrayItem[] | undefined\n handleClick: (languageId: string) => void\n}\n\n/**\n * Renders a grid of \"add language\" buttons — one per configured language.\n *\n * Returns `null` when the `languages` array is empty.\n *\n * Each button is disabled when:\n * - `readOnly` is `true`, or\n * - the language already exists in the current `value` array\n * (matched via `LANGUAGE_FIELD_NAME`).\n *\n * The button label is formatted according to the `languageDisplay` setting\n * from the plugin context (e.g. code-only, title-only, or both).\n * An `AddIcon` is shown unless there are more languages than fit in one row\n * and the display mode is `'codeOnly'`.\n */\nfunction AddButtons(props: AddButtonsProps) {\n const {languages, readOnly, value, handleClick} = props\n const {languageDisplay} = useInternationalizedArrayContext()\n\n return languages.length > 0 ? (\n <Grid columns={Math.min(languages.length, MAX_COLUMNS[languageDisplay])} gap={2}>\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 data-testid={`add-${language.id}`}\n disabled={\n readOnly || Boolean(value?.find((item) => item[LANGUAGE_FIELD_NAME] === 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] && languageDisplay === 'codeOnly'\n ? undefined\n : AddIcon\n }\n value={language.id}\n onClick={() => handleClick(language.id)}\n />\n )\n })}\n </Grid>\n ) : null\n}\n\nexport default AddButtons\n","import {Box, Stack, Text, useToast} from '@sanity/ui'\nimport {type ReactElement, useCallback} from 'react'\nimport {\n type FormInsertPatch,\n type FormSetIfMissingPatch,\n insert,\n isSanityDocument,\n PatchEvent,\n setIfMissing,\n useSchema,\n} from 'sanity'\nimport {useDocumentPane} from 'sanity/structure'\n\nimport type {DocumentsToTranslate} from '../utils/getDocumentsToTranslate'\n\nimport {LANGUAGE_FIELD_NAME} from '../constants'\nimport {getDocumentsToTranslate} from '../utils/getDocumentsToTranslate'\nimport AddButtons from './AddButtons'\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\ntype DocumentAddButtonsProps = {\n value: Record<string, unknown> | undefined\n}\n/**\n * Document-level \"add translation\" panel that appears outside individual\n * internationalized array fields (when `buttonLocations` includes `'document'`).\n *\n * Renders a heading and a row of per-language buttons. When a language button\n * is clicked the component:\n *\n * 1. Scans the current document for all internationalized array fields\n * using `getDocumentsToTranslate`.\n * 2. Filters out fields that already contain a translation for the selected\n * language, and deduplicates by field path.\n * 3. Shows an error toast if no eligible fields remain.\n * 4. Creates `setIfMissing` + `insert` patches to add the new language\n * entry to each eligible field, dispatching them via `onChange`.\n *\n * For Portable Text and other array-based value fields, the initial value\n * is set to an empty array (`[]`) rather than `undefined`.\n */\nexport default function DocumentAddButtons(props: DocumentAddButtonsProps): 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 || !match[1]) 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 = new Set(['body', 'htmlContent', 'blockContent', 'portableText'])\n if (arrayBasedTypes.has(baseTypeName)) {\n return []\n }\n\n // Try to look up the schema type to determine if it's an array\n const schemaType = schema.get(typeName)\n if (schemaType && 'fields' in schemaType) {\n // Check if this is an object type with a 'value' field\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const fields = schemaType.fields as Array<{\n name: string\n type?: {jsonType?: string; name?: string; type?: string; of?: unknown}\n }>\n const valueField = fields.find((f) => f.name === 'value')\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 (fieldType?.name && arrayBasedTypes.has(fieldType.name))\n ) {\n return []\n }\n }\n }\n\n return undefined\n },\n [schema],\n )\n\n const handleDocumentButtonClick = useCallback(\n async (languageId: string) => {\n const alreadyTranslated = documentsToTranslation.filter(\n (translation) => translation?.[LANGUAGE_FIELD_NAME] === languageId,\n )\n const removeDuplicates = documentsToTranslation.reduce<DocumentsToTranslate[]>(\n (filteredTranslations, translation) => {\n if (\n alreadyTranslated.filter(\n (alreadyTranslation) => 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 filteredTranslations.push(translation)\n return filteredTranslations\n },\n [],\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 [LANGUAGE_FIELD_NAME]: 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 handleClick={handleDocumentButtonClick}\n />\n </Stack>\n )\n}\n","import {get} from 'lodash-es'\n\n/**\n * Extracts a subset of values from a Sanity document based on a `select`\n * mapping (as configured in the plugin's `select` option).\n *\n * Each key in `select` becomes a key in the returned object, with its value\n * resolved from the document using the corresponding dot-path (via lodash `get`).\n *\n * Array values are filtered to remove incomplete references (objects with\n * `_type: 'reference'` but no `_ref`), since those represent empty reference\n * fields that should be ignored.\n *\n * Returns an empty object when either `select` or `document` is undefined.\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' ? item?._type === 'reference' && '_ref' in item : true,\n )\n }\n selectedValue[key] = value\n }\n\n return selectedValue\n}\n","import type React from 'react'\n\nimport {useLanguageFilterStudioContext} from '@sanity/language-filter'\nimport {Stack} from '@sanity/ui'\nimport {createContext, use, useContext, useDeferredValue, useMemo} from 'react'\nimport {type ObjectInputProps, useClient, useWorkspace} from 'sanity'\nimport {useDocumentPane} from 'sanity/structure'\n\nimport type {Language, PluginConfig} from '../types'\n\nimport {createCacheKey, createOrGetPromise, setFunctionCache} from '../cache'\nimport {CONFIG_DEFAULT} from '../constants'\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\nexport type InternationalizedArrayContextProps = Required<PluginConfig> & {\n languages: Language[]\n filteredLanguages: Language[]\n}\n\nexport const InternationalizedArrayContext = 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 languagesPromise = useMemo(() => {\n if (Array.isArray(internationalizedArray.languages)) {\n return null // Return null for synchronous arrays\n }\n\n // Create or get cached promise for React.use\n return createOrGetPromise(async () => {\n if (typeof internationalizedArray.languages === 'function') {\n const result = await internationalizedArray.languages(client, selectedValue)\n // Populate function cache for use outside React context\n setFunctionCache(internationalizedArray.languages, selectedValue, result, workspaceId)\n return result\n }\n return internationalizedArray.languages\n }, cacheKey)\n }, [internationalizedArray, client, selectedValue, workspaceId, cacheKey])\n\n // Use React.use to handle the promise with Suspense, or return array directly\n const languages = languagesPromise\n ? use(languagesPromise)\n : // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n (internationalizedArray.languages as Language[])\n\n // Filter out some languages if language filter is enabled\n const {selectedLanguageIds, options: languageFilterOptions} = useLanguageFilterStudioContext()\n\n const filteredLanguages = useMemo(() => {\n const documentType = deferredDocument ? deferredDocument['_type'] : undefined\n const languageFilterEnabled =\n typeof documentType === 'string' && languageFilterOptions.documentTypes.includes(documentType)\n\n return languageFilterEnabled\n ? languages.filter((language) => selectedLanguageIds.includes(language.id))\n : languages\n }, [deferredDocument, languageFilterOptions, languages, selectedLanguageIds])\n\n const showDocumentButtons = 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'\n\nimport {useMemo} from 'react'\nimport {type FieldProps, useFormValue} from 'sanity'\n\nimport {LANGUAGE_FIELD_NAME} from '../constants'\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\n/**\n * Extracts the language identifier from a parent internationalized array item.\n *\n * Returns the `LANGUAGE_FIELD_NAME` value when the parent is an object whose\n * `_type` starts with `\"internationalizedArray\"` and has a string-valued\n * language field. Returns `undefined` otherwise (including on error).\n */\nconst getLanguageId = (fieldParent: unknown): string | undefined => {\n try {\n const languageId =\n typeof fieldParent === 'object' &&\n fieldParent !== null &&\n // Checks if it's an internationalized array item\n '_type' in fieldParent &&\n typeof fieldParent._type === 'string' &&\n fieldParent._type.startsWith('internationalizedArray') &&\n // Checks if the language field name is in the field and if it's a string\n LANGUAGE_FIELD_NAME in fieldParent &&\n typeof fieldParent[LANGUAGE_FIELD_NAME] === 'string'\n ? fieldParent[LANGUAGE_FIELD_NAME]\n : undefined\n return languageId\n } catch (error) {\n console.error('Error getting language id', error)\n return undefined\n }\n}\n\n/**\n * Custom field renderer for fields inside internationalized array items.\n *\n * - Hides the \"Value\" title label when the parent item has a valid language\n * (one that exists in the configured languages list).\n * - Routes rendering based on the field's schema type name:\n * - Non-internationalized types -> `renderDefault` (with title adjustment)\n * - `reference` with a value -> `renderDefault` at level 0\n * - `string` / `number` / `text` -> returns `children` directly for\n * inline editing\n * - Complex internationalized types (e.g. markdown) -> `renderDefault`\n * at level 0\n */\nexport default function InternationalizedField(props: FieldProps): ReactNode {\n const {languages} = useInternationalizedArrayContext()\n // Get the array item (parent of the field) to look up the language from it\n const fieldParent = useFormValue(props.path.slice(0, -1))\n\n const languageId = getLanguageId(fieldParent)\n const customProps = useMemo(() => {\n const hasValidLanguageId = languageId ? languages.some((l) => l.id === languageId) : false\n // hide titles for 'value' fields within valid language entries\n const shouldHideTitle = props.title?.toLowerCase() === 'value' && hasValidLanguageId\n\n return {\n ...props,\n title: shouldHideTitle ? '' : props.title,\n }\n }, [props, languages, languageId])\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 {useClient} from 'sanity'\n\nimport type {PluginConfig} from '../types'\n\nimport {createCacheKey, peek, preloadWithKey, setFunctionCache} from '../cache'\n\nexport default function Preload(props: Required<Pick<PluginConfig, 'apiVersion' | 'languages'>>) {\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 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 type {Language, InternationalizedArrayItem} from '../types'\n\nimport {LANGUAGE_FIELD_NAME} from '../constants'\n\n/**\n * Checks whether every language in the provided list has a corresponding entry\n * in the value array. It extracts language IDs from value items using\n * `LANGUAGE_FIELD_NAME` and compares them against the expected language IDs.\n *\n * Returns `true` only when the value array length matches the number of unique\n * languages and every value language ID is found in the languages list\n * (order does not matter). The length check ensures duplicates in value are\n * correctly rejected.\n */\nexport function checkAllLanguagesArePresent(\n languages: Language[],\n value: InternationalizedArrayItem[] | undefined,\n): boolean {\n const filteredLanguageIds = new Set(languages.map((l) => l.id))\n const languagesInUseIds = value ? value.map((v) => v[LANGUAGE_FIELD_NAME]) : []\n\n if (languagesInUseIds.length !== filteredLanguageIds.size) return false\n if (new Set(languagesInUseIds).size !== languagesInUseIds.length) return false\n return languagesInUseIds.every((key) => filteredLanguageIds.has(key))\n}\n","import type {Language, InternationalizedArrayItem} from '../types'\n\n/**\n * Generates the label text for the \"add all / add missing languages\" button.\n *\n * - When there is no existing value: returns `\"Add {title} Field\"` for a\n * single language, or `\"Add all languages\"` for multiple.\n * - When some values already exist: returns `\"Add missing language\"` (singular)\n * or `\"Add missing languages\"` (plural) depending on how many are left.\n */\nexport function createAddAllTitle(\n value: InternationalizedArrayItem[] | undefined,\n languages: Language[],\n): string {\n if (value?.length) {\n return `Add missing ${languages.length - value.length === 1 ? `language` : `languages`}`\n }\n\n return languages.length === 1 && languages[0]\n ? `Add ${languages[0].title} Field`\n : `Add all languages`\n}\n","import type {FieldDefinition, Rule, RuleTypeConstraint, SanityClient} from 'sanity'\n\nexport type Language = {\n id: Intl.UnicodeBCP47LocaleIdentifier\n title: string\n}\n\nexport type AllowedType = 'string' | 'number' | 'boolean' | 'text' | 'reference'\n\nexport type ArrayConfig = {\n name: string\n type: AllowedType\n languages: Language[]\n title?: string\n group?: string\n hidden?: boolean | (() => boolean)\n readOnly?: boolean | (() => boolean)\n validation?: Rule | Rule[]\n field?: {[key: string]: unknown; options: {[key: string]: unknown}}\n}\n\n/**\n * @deprecated Use InternationalizedArrayItem instead\n */\nexport type Value = {\n _key: string\n value?: unknown\n}\n\nexport function isInternationalizedArrayItemType(\n type: string,\n): type is InternationalizedArrayItem['_type'] {\n return type.startsWith('internationalizedArray') && type.endsWith('Value')\n}\n\nexport type InternationalizedArrayItem<T = unknown> = {\n _key: string\n value?: T\n /**\n * string that starts with \"internationalizedArray\" and ends with \"Value\"\n */\n _type: `internationalizedArray${string}Value`\n}\n\nexport type LanguageCallback = (\n client: SanityClient,\n selectedValue: Record<string, unknown>,\n) => Promise<Language[]>\n\nexport type LanguageDisplay = 'titleOnly' | 'codeOnly' | 'titleAndCode'\n\nexport type PluginConfig = {\n /**\n * https://www.sanity.io/docs/api-versioning\n * @defaultValue '2025-10-15'\n */\n apiVersion?: string\n /**\n * Specify fields that should be available in the language callback:\n * ```tsx\n * {\n * select: {\n * markets: 'markets'\n * },\n * languages: (client, {markets}) =>\n * query.fetch(groq`*[_type == \"language\" && market in $markets]{id,title}`, {markets})\n * }\n * ```\n */\n select?: Record<string, string>\n /**\n * You can give it an array of language definitions:\n * ```tsx\n * {\n * languages: [\n * {id: 'en', title: 'English'},\n * {id: 'fr', title: 'French'}\n * ]\n * }\n * ```\n * You can load them async by passing a function that returns a promise:\n * ```tsx\n * {\n * languages: async () => {\n * const response = await fetch('https://example.com/languages')\n * return response.json()\n * }\n * }\n * ```\n * You can query your dataset for languages::\n * ```tsx\n * {\n * languages: (client) =>\n * query.fetch(groq`*[_type == \"language\"]{id,title}`)\n * }\n * ```\n */\n languages: Language[] | LanguageCallback\n /**\n * You can specify a list of language IDs that should be pre-filled when creating a new document\n * ```tsx\n * {\n * defaultLanguages: ['en']\n * }\n * ```\n */\n defaultLanguages?: string[]\n /**\n * Can be a string matching core field types, as well as custom ones:\n * ```tsx\n * {\n * fieldTypes: [\n * \"date\", \"datetime\", \"file\", \"image\", \"number\", \"string\", \"text\", \"url\"\n * ]\n * }\n * ```\n * You can also define a type directly:\n * ```tsx\n * {\n * fieldTypes: [\n * defineField({\n * name: 'featuredProduct',\n * type: 'reference',\n * to: [{type: 'product'}]\n * hidden: (({document}) => !document?.title)\n * })\n * ]\n * }\n * ```\n */\n // oxlint-disable-next-line typescript-eslint/no-redundant-type-constituents\n fieldTypes: (string | RuleTypeConstraint | FieldDefinition)[]\n /**\n * Locations where the \"+ EN\" add language buttons are visible\n * @defaultValue ['field']\n * */\n buttonLocations?: ('field' | 'unstable__fieldAction' | 'document')[]\n /**\n * Show or hide the \"Add missing languages\" button\n * @defaultValue true\n * */\n buttonAddAll?: boolean\n /**\n * How to display the languages on buttons and fields\n * @defaultValue 'code'\n * */\n languageDisplay?: LanguageDisplay\n}\n","import {type FormInsertPatch, insert, type Path} from 'sanity'\n\nimport {LANGUAGE_FIELD_NAME} from '../constants'\nimport {\n type Language,\n type InternationalizedArrayItem,\n isInternationalizedArrayItemType,\n} from '../types'\n\ntype AddConfig = {\n // New keys to add to the field\n addLanguageKeys: string[]\n // Schema of the current field\n schemaTypeName: string\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?: InternationalizedArrayItem[]\n // Path to this item\n path?: Path\n}\n\n/**\n * Creates an array of Sanity `FormInsertPatch` objects that add new language\n * entries to an internationalized array field.\n *\n * If `addLanguageKeys` is provided, patches are created for those specific\n * language IDs. Otherwise, patches are created for all filtered languages\n * that are not already present in the current `value` array, for example when adding all missing languages.\n *\n * Each new item is assigned the correct `_type` (derived from the schema)\n * and the language identifier via `LANGUAGE_FIELD_NAME`.\n *\n * Insertions are ordered to maintain the same sequence as the master\n * `languages` list: each new item is inserted before the next existing\n * language in the value array, or appended at the end if no subsequent\n * language exists.\n */\nexport function createAddLanguagePatches(config: AddConfig): FormInsertPatch[] {\n const {addLanguageKeys, schemaTypeName, languages, filteredLanguages, value, path = []} = config\n\n const type = `${schemaTypeName}Value`\n if (!isInternationalizedArrayItemType(type)) {\n throw new Error(`Invalid internationalized array type: ${type}`)\n }\n const itemBase = {_type: type}\n\n // Create new items\n const getNewItems = () => {\n if (Array.isArray(addLanguageKeys) && addLanguageKeys.length > 0) {\n return addLanguageKeys\n .filter((id) => {\n if (value?.length) {\n // Check if the language is already in the value and filter it out if it exists to avoid duplicates\n return !value.find((v) => v[LANGUAGE_FIELD_NAME] === id)\n }\n return true\n })\n .map((id) => Object.assign({}, itemBase, {[LANGUAGE_FIELD_NAME]: id}))\n }\n\n return filteredLanguages\n .filter((language) => {\n return value?.length ? !value.find((v) => v[LANGUAGE_FIELD_NAME] === language.id) : true\n })\n .map((language) => Object.assign({}, itemBase, {[LANGUAGE_FIELD_NAME]: language.id}))\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 itemLanguage = item[LANGUAGE_FIELD_NAME]\n const languageIndex = languages.findIndex((l) => itemLanguage === 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 remainingLanguages.find((r) => r.id === l[LANGUAGE_FIELD_NAME]),\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 type {Language, InternationalizedArrayItem} from '../types'\n\nimport {useInternationalizedArrayContext} from '../components/InternationalizedArrayContext'\nimport {LANGUAGE_FIELD_NAME} from '../constants'\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[] = (fieldActionProps, {languages, filteredLanguages}) =>\n languages.map((language) => {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const value = useFormValue(fieldActionProps.path) as InternationalizedArrayItem[]\n const disabled =\n value && Array.isArray(value)\n ? Boolean(value?.find((item) => item[LANGUAGE_FIELD_NAME] === 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 schemaTypeName: schemaType.name,\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 = (fieldActionProps, {languages, filteredLanguages}) => {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const value = useFormValue(fieldActionProps.path) as InternationalizedArrayItem[]\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 schemaTypeName: schemaType.name,\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('internationalizedArray')\n const {languages, filteredLanguages} = useInternationalizedArrayContext()\n\n const translateFieldActions = createTranslateFieldActions(fieldActionProps, {\n languages,\n 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","import {camelCase, upperFirst} from 'lodash-es'\n\n/**\n * Converts a string to PascalCase (e.g. `\"my-field\"` -> `\"MyField\"`).\n */\nexport function pascalCase(string: string): string {\n return upperFirst(camelCase(string))\n}\n\n/**\n * Generates the schema type name for an internationalized array field.\n *\n * - Without the value suffix: `\"internationalizedArray{PascalName}\"`\n * (used for the outer array type)\n * - With the value suffix: `\"internationalizedArray{PascalName}Value\"`\n * (used for the inner object type that wraps each language entry)\n *\n * For example, `createFieldName('block-content', true)` returns\n * `\"internationalizedArrayBlockContentValue\"`.\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 type React from 'react'\n\nimport {Card, Code, Stack, Text} from '@sanity/ui'\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 <code>internationalizedArray</code>{' '}\n helper function, each with an <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 type React from 'react'\n\nimport {AddIcon} from '@sanity/icons'\nimport {useLanguageFilterStudioContext} from '@sanity/language-filter'\nimport {Button, Card, Stack, Text, useToast} from '@sanity/ui'\nimport {useCallback, useEffect, useMemo} from 'react'\nimport {\n type ArrayOfObjectsInputProps,\n ArrayOfObjectsItem,\n MemberItemError,\n set,\n setIfMissing,\n useFormValue,\n} from 'sanity'\nimport {useDocumentPane} from 'sanity/structure'\n\nimport type {InternationalizedArrayItem} from '../types'\n\nimport {LANGUAGE_FIELD_NAME} from '../constants'\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\n/**\n * Main array input component for internationalized array fields.\n *\n * Replaces the default Sanity array input and manages the full lifecycle of\n * language entries:\n *\n * - **Language filter integration**: When `@sanity/language-filter` is active\n * for the current document type, array members are filtered to only show\n * languages matching the user's selection.\n * - **Adding languages**: Exposes per-language buttons and an \"Add all / Add\n * missing languages\" button (controlled by `buttonAddAll` and\n * `buttonLocations` config). Dispatches `setIfMissing` + `insert` patches.\n * - **Default languages**: Automatically adds entries for languages listed in\n * `defaultLanguages` when a document is first created or when those entries\n * are missing.\n * - **Ordering**: Detects when value items are out of order relative to the\n * master `languages` list and automatically re-sorts them.\n * - **Validation**: Shows a `<Feedback>` component if the languages\n * configuration is invalid (e.g. missing `id` or `title`).\n * - **Empty state**: Displays a \"no translations\" message when the field has\n * no entries and the add buttons are not visible.\n */\nexport default function InternationalizedArray(\n props: ArrayOfObjectsInputProps,\n): React.ReactElement {\n const {members, value: _value, schemaType, onChange, readOnly: documentReadOnly} = props\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion\n const value = _value as InternationalizedArrayItem[]\n const readOnly = typeof schemaType.readOnly === 'boolean' ? schemaType.readOnly : false\n const toast = useToast()\n\n const {languages, filteredLanguages, defaultLanguages, buttonAddAll, buttonLocations} =\n useInternationalizedArrayContext()\n\n // Support updating the UI if languageFilter is installed\n const {selectedLanguageIds, options: languageFilterOptions} = useLanguageFilterStudioContext()\n const documentType = useFormValue(['_type'])\n const languageFilterEnabled =\n typeof documentType === 'string' && 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 || 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 (addLanguageKeys: string[] | string) => {\n if (!filteredLanguages?.length) {\n return\n }\n\n const patches = createAddLanguagePatches({\n addLanguageKeys: Array.isArray(addLanguageKeys) ? addLanguageKeys : [addLanguageKeys],\n schemaTypeName: schemaType.name,\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 = useMemo(() => {\n if (!value?.length) return []\n return value.map((v) => v[LANGUAGE_FIELD_NAME] ?? v._key).filter(Boolean)\n }, [value])\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?.[LANGUAGE_FIELD_NAME])\n\n if (newIndex > -1) {\n acc[newIndex] = v\n }\n\n return acc\n }, [] as InternationalizedArrayItem[])\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?.[LANGUAGE_FIELD_NAME]))\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[LANGUAGE_FIELD_NAME] === 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[LANGUAGE_FIELD_NAME]) ? null : v,\n )\n .filter(Boolean)\n }, [value, languagesInUse])\n\n const languagesAreValid = useMemo(\n () =>\n !languages?.length || (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 && !documentReadOnly) {\n handleRestoreOrder()\n }\n }, [languagesOutOfOrder, allKeysAreLanguages, handleRestoreOrder, documentReadOnly])\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 <ArrayOfObjectsItem {...props} key={member.key} member={member} />\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}>This internationalized field currently has no translations.</Text>\n </Card>\n ) : null}\n\n {addButtonsAreVisible ? (\n <Stack space={2}>\n <AddButtons\n languages={filteredLanguages}\n value={value}\n readOnly={readOnly}\n handleClick={handleAddLanguage}\n />\n {buttonAddAll ? (\n <Button\n tone=\"primary\"\n mode=\"ghost\"\n data-testid=\"add-all-languages\"\n disabled={readOnly || allLanguagesArePresent}\n icon={AddIcon}\n text={createAddAllTitle(value, filteredLanguages)}\n onClick={() => handleAddLanguage(filteredLanguages.map((language) => language.id))}\n />\n ) : null}\n </Stack>\n ) : null}\n </Stack>\n )\n}\n","import type {SchemaType} from 'sanity'\n\nimport type {ArrayFieldOptions} from '../schema/array'\n\nexport function getLanguagesFieldOption(\n schemaType: SchemaType | undefined,\n): ArrayFieldOptions['languages'] | undefined {\n if (!schemaType) {\n return undefined\n }\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const languagesOption = (schemaType.options as ArrayFieldOptions)?.languages\n if (languagesOption) {\n return languagesOption\n }\n return getLanguagesFieldOption(schemaType.type)\n}\n","import {defineField, type FieldDefinition, type Rule} from 'sanity'\n\nimport type {Language, LanguageCallback, InternationalizedArrayItem} from '../types'\n\nimport {getFunctionCache, peek, setFunctionCache} from '../cache'\nimport {createFieldName} from '../components/createFieldName'\nimport {getSelectedValue} from '../components/getSelectedValue'\nimport InternationalizedArray from '../components/InternationalizedArray'\nimport {LANGUAGE_FIELD_NAME} from '../constants'\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<ArrayFactoryConfig, 'apiVersion' | 'select' | 'languages'>\n\nexport default (config: ArrayFactoryConfig) => {\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<InternationalizedArrayItem[]>(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]?.[LANGUAGE_FIELD_NAME]) {\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(languagesFieldOption, selectedValue)\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(client, selectedValue)\n // Cache the result for future validation calls\n setFunctionCache(languagesFieldOption, selectedValue, contextLanguages)\n }\n }\n }\n\n if (value && value.length > contextLanguages.length) {\n return `Cannot be more than ${\n contextLanguages.length === 1 ? `1 item` : `${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?.[LANGUAGE_FIELD_NAME] && !languageIds.has(item[LANGUAGE_FIELD_NAME]),\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 seenLanguages = new Set<string>()\n const duplicateValues: InternationalizedArrayItem[] = []\n\n for (const item of value) {\n if (item?.[LANGUAGE_FIELD_NAME]) {\n if (seenLanguages.has(item[LANGUAGE_FIELD_NAME])) {\n duplicateValues.push(item)\n } else {\n seenLanguages.add(item[LANGUAGE_FIELD_NAME])\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\n/**\n * Maps an array of Sanity form validation entries to a `@sanity/ui` `CardTone`\n * for visual feedback on internationalized array items.\n *\n * - Returns `'critical'` if any validation has `level: 'error'`\n * - Returns `'caution'` if any validation has `level: 'warning'` (and no errors)\n * - Returns `undefined` otherwise (no tone applied)\n *\n * Error level always takes precedence over warning.\n */\nexport function getToneFromValidation(validations: FormNodeValidation[]): CardTone | undefined {\n if (!validations?.length) {\n return undefined\n }\n\n const validationLevels = new Set(validations.map((v) => v.level))\n\n if (validationLevels.has('error')) {\n return `critical`\n } else if (validationLevels.has('warning')) {\n return `caution`\n }\n\n return undefined\n}\n","import type React from 'react'\n\nimport {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 ReactNode, useMemo} from 'react'\nimport {type ObjectItemProps, useFormValue} from 'sanity'\nimport {set, unset} from 'sanity'\n\nimport type {InternationalizedArrayItem} from '../types'\n\nimport {LANGUAGE_FIELD_NAME} from '../constants'\nimport {getLanguageDisplay} from '../utils/getLanguageDisplay'\nimport {getToneFromValidation} from './getToneFromValidation'\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\n/**\n * Renders a single row of an internationalized array: a language label (or\n * \"Change\" menu for invalid keys), the value input, and a remove button.\n *\n * Key behaviours:\n * - Wraps `onChange` to intercept paste operations into empty Portable Text\n * fields, ensuring `setIfMissing` and correct path prefixing.\n * - Detects items needing migration (missing `LANGUAGE_FIELD_NAME`) and hides\n * the language label in that state.\n * - Shows a `MenuButton` with available languages when the current key is\n * not a valid language.\n * - Disables the remove button for languages listed in `defaultLanguages`.\n * - Shows a `Spinner` when languages have not been loaded yet.\n * - Applies a `CardTone` based on validation state via `getToneFromValidation`.\n */\nexport default function InternationalizedInput(\n props: ObjectItemProps<InternationalizedArrayItem>,\n): ReactNode {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const parentValue = useFormValue(props.path.slice(0, -1)) as InternationalizedArrayItem[]\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 = (patches: unknown) => {\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 // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n return originalOnChange(patches as Parameters<typeof originalOnChange>[0])\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 const hasProblematicInsert = patches.some((patch: {type?: string; path?: unknown[]}) => {\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 = 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 ? {type: 'setIfMissing', path: ['value'], value: []} : null\n\n // Transform the patches to ensure they work with the nested structure\n const fixedPatches = patches.map(\n (patch: {type?: string; path?: unknown[]; [key: string]: unknown}) => {\n // Ensure patch exists and has required properties\n if (!patch || typeof patch !== 'object') {\n return patch\n }\n\n if (patch.type === 'insert' && patch.path && Array.isArray(patch.path)) {\n // Ensure the path is correct for the nested structure\n const fixedPath = patch.path[0] === 'value' ? patch.path : ['value', ...patch.path]\n const fixedPatch = {...patch, path: fixedPath}\n return fixedPatch\n }\n return patch\n },\n )\n\n // If we need to initialize the field, include that patch first\n const allPatches = initPatch ? [initPatch, ...fixedPatches] : fixedPatches\n\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n return originalOnChange(allPatches as Parameters<typeof originalOnChange>[0])\n }\n }\n\n // For all other cases, pass through unchanged\n return originalOnChange(patches as Parameters<typeof originalOnChange>[0])\n }\n\n const inlineProps = {\n ...props.inputProps,\n // This is the magic that makes inline editing work?\n members: props.inputProps.members.filter((m) => m.kind === 'field' && m.name === 'value'),\n // This just overrides the type\n // Remove this as it shouldn't be necessary?\n // oxlint-disable-next-line typescript-eslint/no-unnecessary-type-assertion\n value: props.value as InternationalizedArrayItem,\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} = useInternationalizedArrayContext()\n\n const languageKeysInUse = useMemo(\n () => parentValue?.map((v) => v[LANGUAGE_FIELD_NAME]) ?? [],\n [parentValue],\n )\n const keyIsValid = languages?.length\n ? languages.find((l) => l.id === value[LANGUAGE_FIELD_NAME])\n : false\n\n // Changes the key of this item, ideally to a valid language\n const handleKeyChange = (event: React.MouseEvent<HTMLButtonElement>): void => {\n const languageId = event?.currentTarget?.value\n\n if (!value || !languages?.length || !languages.find((l) => l.id === languageId)) {\n return\n }\n\n onChange([set(languageId, [LANGUAGE_FIELD_NAME])])\n }\n\n // Removes this item from the array\n const handleUnset = (): void => {\n onChange(unset())\n }\n\n if (!languages) {\n return <Spinner />\n }\n\n const language = languages.find((l) => l.id === value[LANGUAGE_FIELD_NAME])\n const languageTitle: string =\n keyIsValid && language ? getLanguageDisplay(languageDisplay, language.title, language.id) : ''\n\n const isDefault = defaultLanguages.includes(value[LANGUAGE_FIELD_NAME])\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[LANGUAGE_FIELD_NAME]}\"`} />}\n id={`${value[LANGUAGE_FIELD_NAME]}-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'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, type FieldDefinition} from 'sanity'\n\nimport {createFieldName} from '../components/createFieldName'\nimport InternationalizedInput from '../components/InternationalizedInput'\nimport {LANGUAGE_FIELD_NAME} from '../constants'\n\ntype ObjectFactoryConfig = {\n type: string | FieldDefinition\n}\n\nexport default (config: ObjectFactoryConfig) => {\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 ${typeName}`,\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: LANGUAGE_FIELD_NAME,\n },\n },\n })\n}\n","import {isDocumentSchemaType, type ObjectField, type Path, type SchemaType} from 'sanity'\n\ntype ObjectFieldWithPath = ObjectField & {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(schemaType: SchemaType): 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[],\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(field.type.fields, [...path, field.name], maxDepth)\n\n acc.push(thisFieldWithPath, ...innerFields)\n return acc\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 acc.push(thisFieldWithPath, ...innerFields)\n return acc\n }\n\n acc.push(thisFieldWithPath)\n return acc\n }, [])\n}\n","import {definePlugin, isObjectInputProps} from 'sanity'\n\nimport type {PluginConfig} from './types'\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 {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 <InternationalizedArrayProvider {...props} internationalizedArray={pluginConfig} />\n },\n },\n },\n // Register custom schema types for the outer array and the inner object\n schema: {\n types: [\n ...fieldTypes.map((type) => array({type, apiVersion, select, languages, defaultLanguages})),\n ...fieldTypes.map((type) => object({type})),\n ],\n },\n }\n})\n"],"names":["namespace","functionCache","Map","functionKeyCache","WeakMap","promiseCache","stringifyCacheKey","key","JSON","stringify","preloadWithKey","fn","keyStr","has","set","clear","peek","selectedValue","version","promise","get","_status","_value","createCacheKey","workspaceId","selectedValueHash","createOrGetPromise","getFunctionKey","cachedKey","fnStr","toString","hash","maxLength","Math","min","length","i","char","charCodeAt","abs","createFunctionCacheKey","functionKey","getFunctionCache","setFunctionCache","languages","LANGUAGE_FIELD_NAME","MAX_COLUMNS","codeOnly","titleOnly","titleAndCode","CONFIG_DEFAULT","select","defaultLanguages","fieldTypes","apiVersion","buttonLocations","buttonAddAll","languageDisplay","getDocumentsToTranslate","value","rootPath","Array","isArray","arrayRootPath","internationalizedValues","filter","item","type","_type","startsWith","endsWith","map","internationalizedValue","Object","assign","path","pathString","join","flatMap","index","startsWithUnderscoreRegex","keys","match","getLanguageDisplay","title","code","toUpperCase","AddButtons","props","$","_c","readOnly","handleClick","useInternationalizedArrayContext","t0","language","languageTitle","id","Boolean","find","undefined","AddIcon","DocumentAddButtons","filteredLanguages","isSanityDocument","toast","useToast","onChange","useDocumentPane","schema","useSchema","documentsToTranslation","t1","typeName","baseTypeName","charAt","toLowerCase","slice","arrayBasedTypes","Set","schemaType","valueField","fields","_temp","fieldType","jsonType","name","of","getInitialValueForType","t2","languageId","alreadyTranslated","translation","removeDuplicates","reduce","filteredTranslations","translation_0","alreadyTranslation","filteredTranslation","push","status","patches","toTranslate","initialValue","ifMissing","setIfMissing","insertValue","insert","PatchEvent","from","flat","handleDocumentButtonClick","t3","Symbol","for","t4","f","getSelectedValue","document","selection","entries","InternationalizedArrayContext","createContext","useContext","InternationalizedArrayProvider","internationalizedArray","client","useClient","workspace","useWorkspace","formState","deferredDocument","useDeferredValue","bb0","t5","cacheKey","bb1","result","t6","languagesPromise","use","selectedLanguageIds","options","languageFilterOptions","useLanguageFilterStudioContext","documentType","documentTypes","includes","languageFilterEnabled","t7","showDocumentButtons","t8","context","t9","renderDefault","t10","getLanguageId","fieldParent","error","console","InternationalizedField","useFormValue","hasValidLanguageId","some","l","customProps","level","children","Preload","checkAllLanguagesArePresent","filteredLanguageIds","languagesInUseIds","v","size","every","createAddAllTitle","isInternationalizedArrayItemType","createAddLanguagePatches","config","addLanguageKeys","schemaTypeName","Error","itemBase","newItems","languagesInUse","itemLanguage","languageIndex","findIndex","remainingLanguages","nextLanguageIndex","r","splice","createTranslateFieldActions","fieldActionProps","disabled","hidden","onAction","useCallback","icon","AddMissingTranslationsFieldAction","internationalizedArrayFieldAction","defineDocumentFieldAction","useAction","isInternationalizedArrayField","translateFieldActions","TranslateIcon","renderAsButton","pascalCase","string","upperFirst","camelCase","createFieldName","addValue","schemaExample","Feedback","InternationalizedArray","members","documentReadOnly","member","kind","valueMember","filterField","filteredMembers","handleAddLanguage","isDeleting","addedLanguages","language_0","hasAddedDefaultLanguages","languagesToAdd","language_1","language_2","l_0","timeout","setTimeout","clearTimeout","useEffect","updatedValue","acc","v_0","newIndex","l_1","handleRestoreOrder","v_1","l_2","allKeysAreLanguages","l_3","v_2","t11","bb2","t12","t13","v_3","vIndex","l_4","languagesOutOfOrder","languagesAreValid","_temp2","t14","allLanguagesArePresent","t15","addButtonsAreVisible","fieldHasMembers","t16","member_0","t17","t18","_temp3","t19","language_3","_key","getLanguagesFieldOption","arrayName","objectName","defineField","components","input","validation","rule","custom","getClient","contextLanguages","languagesFieldOption","cachedLanguages","suspendCachedLanguages","languageIds","lang","nonLanguageKeys","message","paths","seenLanguages","duplicateValues","add","getToneFromValidation","validations","validationLevels","InternationalizedInput","parentValue","originalOnChange","inputProps","initPatch","fixedPatches","allPatches","wrappedOnChange","inlineProps","_temp4","languageKeysInUse","keyIsValid","handleKeyChange","event","currentTarget","handleUnset","unset","isDefault","removeButton","RemoveCircleIcon","toLocaleUpperCase","portal","T0","Card","renderInput","m","patch_0","patch","fixedPath","preview","subtitle","flattenSchemaType","isDocumentSchemaType","extractInnerFields","maxDepth","field","thisFieldWithPath","innerFields","innerField","definePlugin","pluginConfig","studio","layout","unstable_fieldActions","prev","form","isObjectInputProps","types","array","object"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sanity-plugin-internationalized-array",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.3",
|
|
4
4
|
"description": "Store localized fields in an array to save on attributes",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sanity",
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
"react": "^19.2.4",
|
|
46
46
|
"react-dom": "^19.2.4",
|
|
47
47
|
"sanity": "^5.8.1",
|
|
48
|
-
"@repo/
|
|
49
|
-
"@repo/
|
|
48
|
+
"@repo/package.config": "0.0.0",
|
|
49
|
+
"@repo/tsconfig": "0.0.0"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
52
|
"react": "^19.2",
|