sanity-plugin-internationalized-array 4.0.0 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
- import { isSanityDocument, useSchema, setIfMissing, insert, PatchEvent, useClient, useWorkspace, defineDocumentFieldAction, useFormValue, ArrayOfObjectsItem, MemberItemError, set, defineField, unset, isDocumentSchemaType, definePlugin, isObjectInputProps } from "sanity";
2
+ import { isSanityDocument, useSchema, setIfMissing, insert, PatchEvent, useClient, useWorkspace, useFormValue, defineDocumentFieldAction, ArrayOfObjectsItem, MemberItemError, set, defineField, unset, isDocumentSchemaType, definePlugin, isObjectInputProps } from "sanity";
3
3
  import { c } from "react/compiler-runtime";
4
4
  import { useLanguageFilterStudioContext } from "@sanity/language-filter";
5
5
  import { Grid, Button, useToast, Stack, Box, Text, Card, Code, Spinner, Label, MenuButton, Menu, MenuItem, Flex, Tooltip } from "@sanity/ui";
@@ -51,7 +51,7 @@ const preloadWithKey = (fn, key) => {
51
51
  }, setFunctionCache = (fn, selectedValue, languages, workspaceId) => {
52
52
  const key = createFunctionCacheKey(fn, selectedValue, workspaceId);
53
53
  functionCache.set(key, languages);
54
- }, MAX_COLUMNS = {
54
+ }, LANGUAGE_FIELD_NAME = "_key", MAX_COLUMNS = {
55
55
  codeOnly: 5,
56
56
  titleOnly: 4,
57
57
  titleAndCode: 3
@@ -96,15 +96,15 @@ function AddButtons(props) {
96
96
  languages,
97
97
  readOnly,
98
98
  value,
99
- onClick
99
+ handleClick
100
100
  } = props, {
101
101
  languageDisplay
102
102
  } = useInternationalizedArrayContext();
103
103
  let t0;
104
- return $[0] !== languageDisplay || $[1] !== languages || $[2] !== onClick || $[3] !== readOnly || $[4] !== value ? (t0 = languages.length > 0 ? /* @__PURE__ */ jsx(Grid, { columns: Math.min(languages.length, MAX_COLUMNS[languageDisplay]), gap: 2, children: languages.map((language) => {
104
+ return $[0] !== handleClick || $[1] !== languageDisplay || $[2] !== languages || $[3] !== readOnly || $[4] !== value ? (t0 = languages.length > 0 ? /* @__PURE__ */ jsx(Grid, { columns: Math.min(languages.length, MAX_COLUMNS[languageDisplay]), gap: 2, children: languages.map((language) => {
105
105
  const languageTitle = getLanguageDisplay(languageDisplay, language.title, language.id);
106
- return /* @__PURE__ */ jsx(Button, { tone: "primary", mode: "ghost", fontSize: 1, disabled: readOnly || !!value?.find((item) => item._key === language.id), text: languageTitle, icon: languages.length > MAX_COLUMNS[languageDisplay] && languageDisplay === "codeOnly" ? void 0 : AddIcon, value: language.id, onClick }, language.id);
107
- }) }) : null, $[0] = languageDisplay, $[1] = languages, $[2] = onClick, $[3] = readOnly, $[4] = value, $[5] = t0) : t0 = $[5], t0;
106
+ return /* @__PURE__ */ jsx(Button, { tone: "primary", mode: "ghost", fontSize: 1, "data-testid": `add-${language.id}`, disabled: readOnly || !!value?.find((item) => item[LANGUAGE_FIELD_NAME] === language.id), text: languageTitle, icon: languages.length > MAX_COLUMNS[languageDisplay] && languageDisplay === "codeOnly" ? void 0 : AddIcon, value: language.id, onClick: () => handleClick(language.id) }, language.id);
107
+ }) }) : null, $[0] = handleClick, $[1] = languageDisplay, $[2] = languages, $[3] = readOnly, $[4] = value, $[5] = t0) : t0 = $[5], t0;
108
108
  }
109
109
  function DocumentAddButtons(props) {
110
110
  const $ = c(13), {
@@ -137,16 +137,8 @@ function DocumentAddButtons(props) {
137
137
  }, $[2] = schema, $[3] = t1) : t1 = $[3];
138
138
  const getInitialValueForType = t1;
139
139
  let t2;
140
- $[4] !== documentsToTranslation || $[5] !== getInitialValueForType || $[6] !== onChange || $[7] !== toast ? (t2 = async (event) => {
141
- const languageId = event.currentTarget.value;
142
- if (!languageId) {
143
- toast.push({
144
- status: "error",
145
- title: "No language selected"
146
- });
147
- return;
148
- }
149
- const alreadyTranslated = documentsToTranslation.filter((translation) => translation?._key === languageId), removeDuplicates = documentsToTranslation.reduce((filteredTranslations, translation_0) => (alreadyTranslated.filter((alreadyTranslation) => alreadyTranslation.pathString === translation_0.pathString).length > 0 || filteredTranslations.filter((filteredTranslation) => filteredTranslation.path === translation_0.path).length > 0 || filteredTranslations.push(translation_0), filteredTranslations), []);
140
+ $[4] !== documentsToTranslation || $[5] !== getInitialValueForType || $[6] !== onChange || $[7] !== toast ? (t2 = async (languageId) => {
141
+ const alreadyTranslated = documentsToTranslation.filter((translation) => translation?.[LANGUAGE_FIELD_NAME] === languageId), removeDuplicates = documentsToTranslation.reduce((filteredTranslations, translation_0) => (alreadyTranslated.filter((alreadyTranslation) => alreadyTranslation.pathString === translation_0.pathString).length > 0 || filteredTranslations.filter((filteredTranslation) => filteredTranslation.path === translation_0.path).length > 0 || filteredTranslations.push(translation_0), filteredTranslations), []);
150
142
  if (removeDuplicates.length === 0) {
151
143
  toast.push({
152
144
  status: "error",
@@ -157,7 +149,7 @@ function DocumentAddButtons(props) {
157
149
  const patches = [];
158
150
  for (const toTranslate of removeDuplicates) {
159
151
  const path = toTranslate.path, initialValue = getInitialValueForType(toTranslate._type), ifMissing = setIfMissing([], path), insertValue = insert([{
160
- _key: languageId,
152
+ [LANGUAGE_FIELD_NAME]: languageId,
161
153
  _type: toTranslate._type,
162
154
  value: initialValue
163
155
  }], "after", [...path, -1]);
@@ -171,7 +163,7 @@ function DocumentAddButtons(props) {
171
163
  let t4;
172
164
  return $[10] !== filteredLanguages || $[11] !== handleDocumentButtonClick ? (t4 = /* @__PURE__ */ jsxs(Stack, { space: 3, children: [
173
165
  t3,
174
- /* @__PURE__ */ jsx(AddButtons, { languages: filteredLanguages, readOnly: !1, value: void 0, onClick: handleDocumentButtonClick })
166
+ /* @__PURE__ */ jsx(AddButtons, { languages: filteredLanguages, readOnly: !1, value: void 0, handleClick: handleDocumentButtonClick })
175
167
  ] }), $[10] = filteredLanguages, $[11] = handleDocumentButtonClick, $[12] = t4) : t4 = $[12], t4;
176
168
  }
177
169
  function _temp$2(f) {
@@ -270,35 +262,48 @@ function InternationalizedArrayProvider(props) {
270
262
  let t10;
271
263
  return $[35] !== context || $[36] !== t9 ? (t10 = /* @__PURE__ */ jsx(InternationalizedArrayContext.Provider, { value: context, children: t9 }), $[35] = context, $[36] = t9, $[37] = t10) : t10 = $[37], t10;
272
264
  }
265
+ const getLanguageId = (fieldParent) => {
266
+ try {
267
+ return typeof fieldParent == "object" && fieldParent !== null && // Checks if it's an internationalized array item
268
+ "_type" in fieldParent && typeof fieldParent._type == "string" && fieldParent._type.startsWith("internationalizedArray") && // Checks if the language field name is in the field and if it's a string
269
+ LANGUAGE_FIELD_NAME in fieldParent && typeof fieldParent[LANGUAGE_FIELD_NAME] == "string" ? fieldParent[LANGUAGE_FIELD_NAME] : void 0;
270
+ } catch (error) {
271
+ console.error("Error getting language id", error);
272
+ return;
273
+ }
274
+ };
273
275
  function InternationalizedField(props) {
274
- const $ = c(9), {
276
+ const $ = c(11), {
275
277
  languages
276
- } = useInternationalizedArrayContext(), pathSegment = props.path.slice(0, -1)[1], languageId = typeof pathSegment == "object" && "_key" in pathSegment ? pathSegment._key : void 0, hasValidLanguageId = languageId ? languages.some((l) => l.id === languageId) : !1, t0 = props.title?.toLowerCase() === "value" && hasValidLanguageId ? "" : props.title;
277
- let t1;
278
- $[0] !== props || $[1] !== t0 ? (t1 = {
278
+ } = useInternationalizedArrayContext();
279
+ let t0;
280
+ $[0] !== props.path ? (t0 = props.path.slice(0, -1), $[0] = props.path, $[1] = t0) : t0 = $[1];
281
+ const fieldParent = useFormValue(t0), languageId = getLanguageId(fieldParent), hasValidLanguageId = languageId ? languages.some((l) => l.id === languageId) : !1, t1 = props.title?.toLowerCase() === "value" && hasValidLanguageId ? "" : props.title;
282
+ let t2;
283
+ $[2] !== props || $[3] !== t1 ? (t2 = {
279
284
  ...props,
280
- title: t0
281
- }, $[0] = props, $[1] = t0, $[2] = t1) : t1 = $[2];
282
- const customProps = t1;
285
+ title: t1
286
+ }, $[2] = props, $[3] = t1, $[4] = t2) : t2 = $[4];
287
+ const customProps = t2;
283
288
  if (!customProps.schemaType.name.startsWith("internationalizedArray")) {
284
- let t22;
285
- return $[3] !== customProps ? (t22 = customProps.renderDefault(customProps), $[3] = customProps, $[4] = t22) : t22 = $[4], t22;
289
+ let t32;
290
+ return $[5] !== customProps ? (t32 = customProps.renderDefault(customProps), $[5] = customProps, $[6] = t32) : t32 = $[6], t32;
286
291
  }
287
292
  if (customProps.schemaType.name === "reference" && customProps.value) {
288
- let t22;
289
- return $[5] !== customProps ? (t22 = customProps.renderDefault({
293
+ let t32;
294
+ return $[7] !== customProps ? (t32 = customProps.renderDefault({
290
295
  ...customProps,
291
296
  title: "",
292
297
  level: 0
293
- }), $[5] = customProps, $[6] = t22) : t22 = $[6], t22;
298
+ }), $[7] = customProps, $[8] = t32) : t32 = $[8], t32;
294
299
  }
295
300
  if (customProps.schemaType.name === "string" || customProps.schemaType.name === "number" || customProps.schemaType.name === "text")
296
301
  return customProps.children;
297
- let t2;
298
- return $[7] !== customProps ? (t2 = customProps.renderDefault({
302
+ let t3;
303
+ return $[9] !== customProps ? (t3 = customProps.renderDefault({
299
304
  ...customProps,
300
305
  level: 0
301
- }), $[7] = customProps, $[8] = t2) : t2 = $[8], t2;
306
+ }), $[9] = customProps, $[10] = t3) : t3 = $[10], t3;
302
307
  }
303
308
  function Preload(props) {
304
309
  const $ = c(2);
@@ -315,32 +320,29 @@ function Preload(props) {
315
320
  }, cacheKey), null;
316
321
  }
317
322
  function checkAllLanguagesArePresent(languages, value) {
318
- const filteredLanguageIds = languages.map((l) => l.id), languagesInUseIds = value ? value.map((v) => v._key) : [];
319
- return languagesInUseIds.length === filteredLanguageIds.length && languagesInUseIds.every((l) => filteredLanguageIds.includes(l));
323
+ const filteredLanguageIds = new Set(languages.map((l) => l.id)), languagesInUseIds = value ? value.map((v) => v[LANGUAGE_FIELD_NAME]) : [];
324
+ return languagesInUseIds.length !== filteredLanguageIds.size || new Set(languagesInUseIds).size !== languagesInUseIds.length ? !1 : languagesInUseIds.every((key) => filteredLanguageIds.has(key));
320
325
  }
321
326
  function createAddAllTitle(value, languages) {
322
327
  return value?.length ? `Add missing ${languages.length - value.length === 1 ? "language" : "languages"}` : languages.length === 1 && languages[0] ? `Add ${languages[0].title} Field` : "Add all languages";
323
328
  }
324
- function createValueSchemaTypeName(schemaType) {
325
- return `${schemaType.name}Value`;
326
- }
327
329
  function createAddLanguagePatches(config) {
328
330
  const {
329
331
  addLanguageKeys,
330
- schemaType,
332
+ schemaTypeName,
331
333
  languages,
332
334
  filteredLanguages,
333
335
  value,
334
336
  path = []
335
337
  } = config, itemBase = {
336
- _type: createValueSchemaTypeName(schemaType)
338
+ _type: `${schemaTypeName}Value`
337
339
  }, newItems = Array.isArray(addLanguageKeys) && addLanguageKeys.length > 0 ? addLanguageKeys.map((id) => Object.assign({}, itemBase, {
338
- _key: id
339
- })) : filteredLanguages.filter((language) => value?.length ? !value.find((v) => v._key === language.id) : !0).map((language) => Object.assign({}, itemBase, {
340
- _key: language.id
340
+ [LANGUAGE_FIELD_NAME]: id
341
+ })) : filteredLanguages.filter((language) => value?.length ? !value.find((v) => v[LANGUAGE_FIELD_NAME] === language.id) : !0).map((language) => Object.assign({}, itemBase, {
342
+ [LANGUAGE_FIELD_NAME]: language.id
341
343
  })), languagesInUse = value?.length ? value.map((v) => v) : [];
342
344
  return newItems.map((item) => {
343
- const languageIndex = languages.findIndex((l) => item._key === l.id), remainingLanguages = languages.slice(languageIndex + 1), nextLanguageIndex = languagesInUse.findIndex((l) => remainingLanguages.find((r) => r.id === l._key));
345
+ const itemLanguage = item[LANGUAGE_FIELD_NAME], languageIndex = languages.findIndex((l) => itemLanguage === l.id), remainingLanguages = languages.slice(languageIndex + 1), nextLanguageIndex = languagesInUse.findIndex((l) => remainingLanguages.find((r) => r.id === l[LANGUAGE_FIELD_NAME]));
344
346
  return nextLanguageIndex < 0 ? languagesInUse.push(item) : languagesInUse.splice(nextLanguageIndex, 0, item), nextLanguageIndex < 0 ? (
345
347
  // No next language (-1), add to end of array
346
348
  insert([item], "after", [...path, nextLanguageIndex])
@@ -354,7 +356,7 @@ const createTranslateFieldActions = (fieldActionProps, {
354
356
  languages,
355
357
  filteredLanguages
356
358
  }) => languages.map((language) => {
357
- const value = useFormValue(fieldActionProps.path), disabled = value && Array.isArray(value) ? !!value?.find((item) => item._key === language.id) : !1, hidden = !filteredLanguages.some((f) => f.id === language.id), {
359
+ const value = useFormValue(fieldActionProps.path), disabled = value && Array.isArray(value) ? !!value?.find((item) => item[LANGUAGE_FIELD_NAME] === language.id) : !1, hidden = !filteredLanguages.some((f) => f.id === language.id), {
358
360
  onChange
359
361
  } = useDocumentPane(), onAction = useCallback(() => {
360
362
  const {
@@ -362,7 +364,7 @@ const createTranslateFieldActions = (fieldActionProps, {
362
364
  path
363
365
  } = fieldActionProps, addLanguageKeys = [language.id], patches = createAddLanguagePatches({
364
366
  addLanguageKeys,
365
- schemaType,
367
+ schemaTypeName: schemaType.name,
366
368
  languages,
367
369
  filteredLanguages,
368
370
  value,
@@ -390,7 +392,7 @@ const createTranslateFieldActions = (fieldActionProps, {
390
392
  path
391
393
  } = fieldActionProps, patches = createAddLanguagePatches({
392
394
  addLanguageKeys: [],
393
- schemaType,
395
+ schemaTypeName: schemaType.name,
394
396
  languages,
395
397
  filteredLanguages,
396
398
  value,
@@ -468,7 +470,7 @@ function Feedback() {
468
470
  ] }) }), $[3] = t3) : t3 = $[3], t3;
469
471
  }
470
472
  function InternationalizedArray(props) {
471
- const $ = c(85), {
473
+ const $ = c(89), {
472
474
  members,
473
475
  value,
474
476
  schemaType,
@@ -499,121 +501,133 @@ function InternationalizedArray(props) {
499
501
  }) : members, $[4] = languageFilterEnabled, $[5] = languageFilterOptions, $[6] = members, $[7] = selectedLanguageIds, $[8] = t2) : t2 = $[8];
500
502
  const filteredMembers = t2;
501
503
  let t3;
502
- $[9] !== filteredLanguages || $[10] !== languages || $[11] !== onChange || $[12] !== schemaType || $[13] !== value ? (t3 = async (param) => {
504
+ $[9] !== filteredLanguages || $[10] !== languages || $[11] !== onChange || $[12] !== schemaType.name || $[13] !== value ? (t3 = (addLanguageKeys) => {
503
505
  if (!filteredLanguages?.length)
504
506
  return;
505
- const addLanguageKeys = Array.isArray(param) ? param : [param?.currentTarget?.value].filter(Boolean), patches = createAddLanguagePatches({
506
- addLanguageKeys,
507
- schemaType,
507
+ const patches = createAddLanguagePatches({
508
+ addLanguageKeys: Array.isArray(addLanguageKeys) ? addLanguageKeys : [addLanguageKeys],
509
+ schemaTypeName: schemaType.name,
508
510
  languages,
509
511
  filteredLanguages,
510
512
  value
511
513
  });
512
514
  onChange([setIfMissing([]), ...patches]);
513
- }, $[9] = filteredLanguages, $[10] = languages, $[11] = onChange, $[12] = schemaType, $[13] = value, $[14] = t3) : t3 = $[14];
515
+ }, $[9] = filteredLanguages, $[10] = languages, $[11] = onChange, $[12] = schemaType.name, $[13] = value, $[14] = t3) : t3 = $[14];
514
516
  const handleAddLanguage = t3, {
515
517
  isDeleting
516
518
  } = useDocumentPane();
517
- let addedLanguages, t4;
518
- if ($[15] !== defaultLanguages || $[16] !== languages || $[17] !== members) {
519
- addedLanguages = members.map(_temp$1);
519
+ let t4;
520
+ bb0: {
521
+ if (!value?.length) {
522
+ let t53;
523
+ $[15] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t53 = [], $[15] = t53) : t53 = $[15], t4 = t53;
524
+ break bb0;
525
+ }
520
526
  let t52;
521
- $[20] !== languages ? (t52 = (language) => languages.find((l) => l.id === language), $[20] = languages, $[21] = t52) : t52 = $[21], t4 = defaultLanguages.filter(t52).every((language_0) => addedLanguages.includes(language_0)), $[15] = defaultLanguages, $[16] = languages, $[17] = members, $[18] = addedLanguages, $[19] = t4;
527
+ $[16] !== value ? (t52 = value.map(_temp$1).filter(Boolean), $[16] = value, $[17] = t52) : t52 = $[17], t4 = t52;
528
+ }
529
+ const addedLanguages = t4;
530
+ let t5;
531
+ if ($[18] !== addedLanguages || $[19] !== defaultLanguages || $[20] !== languages) {
532
+ let t62;
533
+ $[22] !== languages ? (t62 = (language) => languages.find((l) => l.id === language), $[22] = languages, $[23] = t62) : t62 = $[23];
534
+ let t72;
535
+ $[24] !== addedLanguages ? (t72 = (language_0) => addedLanguages.includes(language_0), $[24] = addedLanguages, $[25] = t72) : t72 = $[25], t5 = defaultLanguages.filter(t62).every(t72), $[18] = addedLanguages, $[19] = defaultLanguages, $[20] = languages, $[21] = t5;
522
536
  } else
523
- addedLanguages = $[18], t4 = $[19];
524
- const hasAddedDefaultLanguages = t4;
525
- let t5, t6;
526
- $[22] !== addedLanguages || $[23] !== defaultLanguages || $[24] !== documentReadOnly || $[25] !== handleAddLanguage || $[26] !== hasAddedDefaultLanguages || $[27] !== isDeleting || $[28] !== languages ? (t5 = () => {
537
+ t5 = $[21];
538
+ const hasAddedDefaultLanguages = t5;
539
+ let t6, t7;
540
+ $[26] !== addedLanguages || $[27] !== defaultLanguages || $[28] !== documentReadOnly || $[29] !== handleAddLanguage || $[30] !== hasAddedDefaultLanguages || $[31] !== isDeleting || $[32] !== languages ? (t6 = () => {
527
541
  if (!isDeleting && !hasAddedDefaultLanguages) {
528
542
  const languagesToAdd = defaultLanguages.filter((language_1) => !addedLanguages.includes(language_1)).filter((language_2) => languages.find((l_0) => l_0.id === language_2)), timeout = setTimeout(() => {
529
543
  documentReadOnly || handleAddLanguage(languagesToAdd);
530
544
  });
531
545
  return () => clearTimeout(timeout);
532
546
  }
533
- }, t6 = [isDeleting, hasAddedDefaultLanguages, handleAddLanguage, defaultLanguages, addedLanguages, languages, documentReadOnly], $[22] = addedLanguages, $[23] = defaultLanguages, $[24] = documentReadOnly, $[25] = handleAddLanguage, $[26] = hasAddedDefaultLanguages, $[27] = isDeleting, $[28] = languages, $[29] = t5, $[30] = t6) : (t5 = $[29], t6 = $[30]), useEffect(t5, t6);
534
- let t7;
535
- $[31] !== languages || $[32] !== onChange || $[33] !== toast || $[34] !== value ? (t7 = () => {
547
+ }, t7 = [isDeleting, hasAddedDefaultLanguages, handleAddLanguage, defaultLanguages, addedLanguages, languages, documentReadOnly], $[26] = addedLanguages, $[27] = defaultLanguages, $[28] = documentReadOnly, $[29] = handleAddLanguage, $[30] = hasAddedDefaultLanguages, $[31] = isDeleting, $[32] = languages, $[33] = t6, $[34] = t7) : (t6 = $[33], t7 = $[34]), useEffect(t6, t7);
548
+ let t8;
549
+ $[35] !== languages || $[36] !== onChange || $[37] !== toast || $[38] !== value ? (t8 = () => {
536
550
  if (!value?.length || !languages?.length)
537
551
  return;
538
- const updatedValue = value.reduce((acc, v) => {
539
- const newIndex = languages.findIndex((l_1) => l_1.id === v?._key);
540
- return newIndex > -1 && (acc[newIndex] = v), acc;
552
+ const updatedValue = value.reduce((acc, v_0) => {
553
+ const newIndex = languages.findIndex((l_1) => l_1.id === v_0?.[LANGUAGE_FIELD_NAME]);
554
+ return newIndex > -1 && (acc[newIndex] = v_0), acc;
541
555
  }, []).filter(Boolean);
542
556
  value?.length !== updatedValue.length && toast.push({
543
557
  title: "There was an error reordering languages",
544
558
  status: "warning"
545
559
  }), onChange(set(updatedValue));
546
- }, $[31] = languages, $[32] = onChange, $[33] = toast, $[34] = value, $[35] = t7) : t7 = $[35];
547
- const handleRestoreOrder = t7;
548
- let t8;
549
- bb0: {
560
+ }, $[35] = languages, $[36] = onChange, $[37] = toast, $[38] = value, $[39] = t8) : t8 = $[39];
561
+ const handleRestoreOrder = t8;
562
+ let t9;
563
+ bb1: {
550
564
  if (!value?.length || !languages?.length) {
551
- t8 = !0;
552
- break bb0;
565
+ t9 = !0;
566
+ break bb1;
553
567
  }
554
- let t92;
555
- $[36] !== languages || $[37] !== value ? (t92 = value?.every((v_0) => languages.find((l_2) => l_2?.id === v_0?._key)), $[36] = languages, $[37] = value, $[38] = t92) : t92 = $[38], t8 = t92;
568
+ let t102;
569
+ $[40] !== languages || $[41] !== value ? (t102 = value?.every((v_1) => languages.find((l_2) => l_2?.id === v_1?.[LANGUAGE_FIELD_NAME])), $[40] = languages, $[41] = value, $[42] = t102) : t102 = $[42], t9 = t102;
556
570
  }
557
- const allKeysAreLanguages = t8;
558
- let t9;
559
- $[39] !== languages || $[40] !== value ? (t9 = languages && languages.length > 1 ? languages.filter((l_3) => value?.find((v_1) => v_1._key === l_3.id)) : [], $[39] = languages, $[40] = value, $[41] = t9) : t9 = $[41];
560
- const languagesInUse = t9;
571
+ const allKeysAreLanguages = t9;
561
572
  let t10;
562
- bb1: {
573
+ $[43] !== languages || $[44] !== value ? (t10 = languages && languages.length > 1 ? languages.filter((l_3) => value?.find((v_2) => v_2[LANGUAGE_FIELD_NAME] === l_3.id)) : [], $[43] = languages, $[44] = value, $[45] = t10) : t10 = $[45];
574
+ const languagesInUse = t10;
575
+ let t11;
576
+ bb2: {
563
577
  if (!value?.length || !languagesInUse.length) {
564
- let t113;
565
- $[42] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t113 = [], $[42] = t113) : t113 = $[42], t10 = t113;
566
- break bb1;
578
+ let t123;
579
+ $[46] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t123 = [], $[46] = t123) : t123 = $[46], t11 = t123;
580
+ break bb2;
567
581
  }
568
- let t112;
569
- if ($[43] !== languagesInUse || $[44] !== value) {
570
- let t122;
571
- $[46] !== languagesInUse ? (t122 = (v_2, vIndex) => vIndex === languagesInUse.findIndex((l_4) => l_4.id === v_2._key) ? null : v_2, $[46] = languagesInUse, $[47] = t122) : t122 = $[47], t112 = value.map(t122).filter(Boolean), $[43] = languagesInUse, $[44] = value, $[45] = t112;
582
+ let t122;
583
+ if ($[47] !== languagesInUse || $[48] !== value) {
584
+ let t132;
585
+ $[50] !== languagesInUse ? (t132 = (v_3, vIndex) => vIndex === languagesInUse.findIndex((l_4) => l_4.id === v_3[LANGUAGE_FIELD_NAME]) ? null : v_3, $[50] = languagesInUse, $[51] = t132) : t132 = $[51], t122 = value.map(t132).filter(Boolean), $[47] = languagesInUse, $[48] = value, $[49] = t122;
572
586
  } else
573
- t112 = $[45];
574
- t10 = t112;
587
+ t122 = $[49];
588
+ t11 = t122;
575
589
  }
576
- const languagesOutOfOrder = t10, languagesAreValid = !languages?.length || languages?.length && languages.every(_temp2$1);
577
- let t11;
578
- $[48] !== allKeysAreLanguages || $[49] !== documentReadOnly || $[50] !== handleRestoreOrder || $[51] !== languagesOutOfOrder.length ? (t11 = () => {
579
- languagesOutOfOrder.length > 0 && allKeysAreLanguages && !documentReadOnly && handleRestoreOrder();
580
- }, $[48] = allKeysAreLanguages, $[49] = documentReadOnly, $[50] = handleRestoreOrder, $[51] = languagesOutOfOrder.length, $[52] = t11) : t11 = $[52];
590
+ const languagesOutOfOrder = t11, languagesAreValid = !languages?.length || languages?.length && languages.every(_temp2$1);
581
591
  let t12;
582
- $[53] !== allKeysAreLanguages || $[54] !== documentReadOnly || $[55] !== handleRestoreOrder || $[56] !== languagesOutOfOrder ? (t12 = [languagesOutOfOrder, allKeysAreLanguages, handleRestoreOrder, documentReadOnly], $[53] = allKeysAreLanguages, $[54] = documentReadOnly, $[55] = handleRestoreOrder, $[56] = languagesOutOfOrder, $[57] = t12) : t12 = $[57], useEffect(t11, t12);
592
+ $[52] !== allKeysAreLanguages || $[53] !== documentReadOnly || $[54] !== handleRestoreOrder || $[55] !== languagesOutOfOrder.length ? (t12 = () => {
593
+ languagesOutOfOrder.length > 0 && allKeysAreLanguages && !documentReadOnly && handleRestoreOrder();
594
+ }, $[52] = allKeysAreLanguages, $[53] = documentReadOnly, $[54] = handleRestoreOrder, $[55] = languagesOutOfOrder.length, $[56] = t12) : t12 = $[56];
583
595
  let t13;
584
- $[58] !== filteredLanguages || $[59] !== value ? (t13 = checkAllLanguagesArePresent(filteredLanguages, value), $[58] = filteredLanguages, $[59] = value, $[60] = t13) : t13 = $[60];
585
- const allLanguagesArePresent = t13;
596
+ $[57] !== allKeysAreLanguages || $[58] !== documentReadOnly || $[59] !== handleRestoreOrder || $[60] !== languagesOutOfOrder ? (t13 = [languagesOutOfOrder, allKeysAreLanguages, handleRestoreOrder, documentReadOnly], $[57] = allKeysAreLanguages, $[58] = documentReadOnly, $[59] = handleRestoreOrder, $[60] = languagesOutOfOrder, $[61] = t13) : t13 = $[61], useEffect(t12, t13);
597
+ let t14;
598
+ $[62] !== filteredLanguages || $[63] !== value ? (t14 = checkAllLanguagesArePresent(filteredLanguages, value), $[62] = filteredLanguages, $[63] = value, $[64] = t14) : t14 = $[64];
599
+ const allLanguagesArePresent = t14;
586
600
  if (!languagesAreValid) {
587
- let t142;
588
- return $[61] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t142 = /* @__PURE__ */ jsx(Feedback, {}), $[61] = t142) : t142 = $[61], t142;
601
+ let t152;
602
+ return $[65] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t152 = /* @__PURE__ */ jsx(Feedback, {}), $[65] = t152) : t152 = $[65], t152;
589
603
  }
590
- let t14;
591
- $[62] !== allLanguagesArePresent || $[63] !== buttonLocations || $[64] !== filteredLanguages?.length ? (t14 = buttonLocations.includes("field") && filteredLanguages?.length > 0 && !allLanguagesArePresent, $[62] = allLanguagesArePresent, $[63] = buttonLocations, $[64] = filteredLanguages?.length, $[65] = t14) : t14 = $[65];
592
- const addButtonsAreVisible = t14, fieldHasMembers = members?.length > 0;
593
604
  let t15;
594
- $[66] !== fieldHasMembers || $[67] !== filteredMembers || $[68] !== props ? (t15 = fieldHasMembers ? /* @__PURE__ */ jsx(Fragment, { children: filteredMembers.map((member_0) => member_0.kind === "item" ? /* @__PURE__ */ createElement(ArrayOfObjectsItem, { ...props, key: member_0.key, member: member_0 }) : /* @__PURE__ */ jsx(MemberItemError, { member: member_0 }, member_0.key)) }) : null, $[66] = fieldHasMembers, $[67] = filteredMembers, $[68] = props, $[69] = t15) : t15 = $[69];
605
+ $[66] !== allLanguagesArePresent || $[67] !== buttonLocations || $[68] !== filteredLanguages?.length ? (t15 = buttonLocations.includes("field") && filteredLanguages?.length > 0 && !allLanguagesArePresent, $[66] = allLanguagesArePresent, $[67] = buttonLocations, $[68] = filteredLanguages?.length, $[69] = t15) : t15 = $[69];
606
+ const addButtonsAreVisible = t15, fieldHasMembers = members?.length > 0;
595
607
  let t16;
596
- $[70] !== addButtonsAreVisible || $[71] !== fieldHasMembers ? (t16 = !addButtonsAreVisible && !fieldHasMembers ? /* @__PURE__ */ jsx(Card, { border: !0, tone: "transparent", padding: 3, radius: 2, children: /* @__PURE__ */ jsx(Text, { size: 1, children: "This internationalized field currently has no translations." }) }) : null, $[70] = addButtonsAreVisible, $[71] = fieldHasMembers, $[72] = t16) : t16 = $[72];
608
+ $[70] !== fieldHasMembers || $[71] !== filteredMembers || $[72] !== props ? (t16 = fieldHasMembers ? /* @__PURE__ */ jsx(Fragment, { children: filteredMembers.map((member_0) => member_0.kind === "item" ? /* @__PURE__ */ createElement(ArrayOfObjectsItem, { ...props, key: member_0.key, member: member_0 }) : /* @__PURE__ */ jsx(MemberItemError, { member: member_0 }, member_0.key)) }) : null, $[70] = fieldHasMembers, $[71] = filteredMembers, $[72] = props, $[73] = t16) : t16 = $[73];
597
609
  let t17;
598
- $[73] !== addButtonsAreVisible || $[74] !== allLanguagesArePresent || $[75] !== buttonAddAll || $[76] !== filteredLanguages || $[77] !== handleAddLanguage || $[78] !== readOnly || $[79] !== value ? (t17 = addButtonsAreVisible ? /* @__PURE__ */ jsxs(Stack, { space: 2, children: [
599
- /* @__PURE__ */ jsx(AddButtons, { languages: filteredLanguages, value, readOnly, onClick: handleAddLanguage }),
600
- buttonAddAll ? /* @__PURE__ */ jsx(Button, { tone: "primary", mode: "ghost", disabled: readOnly || allLanguagesArePresent, icon: AddIcon, text: createAddAllTitle(value, filteredLanguages), onClick: handleAddLanguage }) : null
601
- ] }) : null, $[73] = addButtonsAreVisible, $[74] = allLanguagesArePresent, $[75] = buttonAddAll, $[76] = filteredLanguages, $[77] = handleAddLanguage, $[78] = readOnly, $[79] = value, $[80] = t17) : t17 = $[80];
610
+ $[74] !== addButtonsAreVisible || $[75] !== fieldHasMembers ? (t17 = !addButtonsAreVisible && !fieldHasMembers ? /* @__PURE__ */ jsx(Card, { border: !0, tone: "transparent", padding: 3, radius: 2, children: /* @__PURE__ */ jsx(Text, { size: 1, children: "This internationalized field currently has no translations." }) }) : null, $[74] = addButtonsAreVisible, $[75] = fieldHasMembers, $[76] = t17) : t17 = $[76];
602
611
  let t18;
603
- return $[81] !== t15 || $[82] !== t16 || $[83] !== t17 ? (t18 = /* @__PURE__ */ jsxs(Stack, { space: 2, children: [
604
- t15,
612
+ $[77] !== addButtonsAreVisible || $[78] !== allLanguagesArePresent || $[79] !== buttonAddAll || $[80] !== filteredLanguages || $[81] !== handleAddLanguage || $[82] !== readOnly || $[83] !== value ? (t18 = addButtonsAreVisible ? /* @__PURE__ */ jsxs(Stack, { space: 2, children: [
613
+ /* @__PURE__ */ jsx(AddButtons, { languages: filteredLanguages, value, readOnly, handleClick: handleAddLanguage }),
614
+ buttonAddAll ? /* @__PURE__ */ jsx(Button, { tone: "primary", mode: "ghost", "data-testid": "add-all-languages", disabled: readOnly || allLanguagesArePresent, icon: AddIcon, text: createAddAllTitle(value, filteredLanguages), onClick: () => handleAddLanguage(filteredLanguages.map(_temp3$1)) }) : null
615
+ ] }) : null, $[77] = addButtonsAreVisible, $[78] = allLanguagesArePresent, $[79] = buttonAddAll, $[80] = filteredLanguages, $[81] = handleAddLanguage, $[82] = readOnly, $[83] = value, $[84] = t18) : t18 = $[84];
616
+ let t19;
617
+ return $[85] !== t16 || $[86] !== t17 || $[87] !== t18 ? (t19 = /* @__PURE__ */ jsxs(Stack, { space: 2, children: [
605
618
  t16,
606
- t17
607
- ] }), $[81] = t15, $[82] = t16, $[83] = t17, $[84] = t18) : t18 = $[84], t18;
619
+ t17,
620
+ t18
621
+ ] }), $[85] = t16, $[86] = t17, $[87] = t18, $[88] = t19) : t19 = $[88], t19;
622
+ }
623
+ function _temp3$1(language_3) {
624
+ return language_3.id;
608
625
  }
609
626
  function _temp2$1(item) {
610
627
  return item.id && item.title;
611
628
  }
612
- function _temp$1(t0) {
613
- const {
614
- key
615
- } = t0;
616
- return key;
629
+ function _temp$1(v) {
630
+ return v[LANGUAGE_FIELD_NAME] ?? v._key;
617
631
  }
618
632
  function getLanguagesFieldOption(schemaType) {
619
633
  return schemaType ? schemaType.options?.languages || getLanguagesFieldOption(schemaType.type) : void 0;
@@ -645,7 +659,7 @@ var array = (config) => {
645
659
  })],
646
660
  // @ts-expect-error - fix typings
647
661
  validation: (rule) => rule.custom(async (value, context) => {
648
- if (!value || value.length === 0 || value.length === 1 && !value[0]?._key)
662
+ if (!value || value.length === 0 || value.length === 1 && !value[0]?.[LANGUAGE_FIELD_NAME])
649
663
  return !0;
650
664
  const selectedValue = getSelectedValue(select, context.document), client = context.getClient({
651
665
  apiVersion
@@ -667,7 +681,7 @@ var array = (config) => {
667
681
  }
668
682
  if (value && value.length > contextLanguages.length)
669
683
  return `Cannot be more than ${contextLanguages.length === 1 ? "1 item" : `${contextLanguages.length} items`}`;
670
- const languageIds = new Set(contextLanguages.map((lang) => lang.id)), nonLanguageKeys = value.filter((item) => item?._key && !languageIds.has(item._key));
684
+ const languageIds = new Set(contextLanguages.map((lang) => lang.id)), nonLanguageKeys = value.filter((item) => item?.[LANGUAGE_FIELD_NAME] && !languageIds.has(item[LANGUAGE_FIELD_NAME]));
671
685
  if (nonLanguageKeys.length)
672
686
  return {
673
687
  message: "Array item keys must be valid languages registered to the field type",
@@ -675,9 +689,9 @@ var array = (config) => {
675
689
  _key: item._key
676
690
  }])
677
691
  };
678
- const seenKeys = /* @__PURE__ */ new Set(), duplicateValues = [];
692
+ const seenLanguages = /* @__PURE__ */ new Set(), duplicateValues = [];
679
693
  for (const item of value)
680
- item?._key && (seenKeys.has(item._key) ? duplicateValues.push(item) : seenKeys.add(item._key));
694
+ item?.[LANGUAGE_FIELD_NAME] && (seenLanguages.has(item[LANGUAGE_FIELD_NAME]) ? duplicateValues.push(item) : seenLanguages.add(item[LANGUAGE_FIELD_NAME]));
681
695
  return duplicateValues.length ? {
682
696
  message: "There can only be one field per language",
683
697
  paths: duplicateValues.map((item) => [{
@@ -733,9 +747,9 @@ function InternationalizedInput(props) {
733
747
  } = useInternationalizedArrayContext();
734
748
  let t2;
735
749
  $[5] !== parentValue ? (t2 = parentValue?.map(_temp4) ?? [], $[5] = parentValue, $[6] = t2) : t2 = $[6];
736
- const languageKeysInUse = t2, keyIsValid = languages?.length ? languages.find((l) => l.id === value._key) : !1, handleKeyChange = (event) => {
750
+ const languageKeysInUse = t2, keyIsValid = languages?.length ? languages.find((l) => l.id === value[LANGUAGE_FIELD_NAME]) : !1, handleKeyChange = (event) => {
737
751
  const languageId = event?.currentTarget?.value;
738
- !value || !languages?.length || !languages.find((l_0) => l_0.id === languageId) || onChange([set(languageId, ["_key"])]);
752
+ !value || !languages?.length || !languages.find((l_0) => l_0.id === languageId) || onChange([set(languageId, [LANGUAGE_FIELD_NAME])]);
739
753
  }, handleUnset = () => {
740
754
  onChange(unset());
741
755
  };
@@ -743,7 +757,7 @@ function InternationalizedInput(props) {
743
757
  let t32;
744
758
  return $[7] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t32 = /* @__PURE__ */ jsx(Spinner, {}), $[7] = t32) : t32 = $[7], t32;
745
759
  }
746
- const language = languages.find((l_1) => l_1.id === value._key), languageTitle = keyIsValid && language ? getLanguageDisplay(languageDisplay, language.title, language.id) : "", isDefault = defaultLanguages.includes(value._key), removeButton = /* @__PURE__ */ jsx(Button, { mode: "bleed", icon: RemoveCircleIcon, tone: "critical", disabled: readOnly || isDefault, onClick: handleUnset }), t3 = getToneFromValidation(validation), t4 = keyIsValid ? /* @__PURE__ */ jsx(Label, { muted: !0, size: 1, children: languageTitle }) : /* @__PURE__ */ jsx(MenuButton, { button: /* @__PURE__ */ jsx(Button, { fontSize: 1, text: `Change "${value._key}"` }), id: `${value._key}-change-key`, menu: /* @__PURE__ */ jsx(Menu, { children: languages.map((lang) => /* @__PURE__ */ jsx(MenuItem, { disabled: languageKeysInUse.includes(lang.id), fontSize: 1, text: lang.id.toLocaleUpperCase(), value: lang.id, onClick: handleKeyChange }, lang.id)) }), popover: {
760
+ const language = languages.find((l_1) => l_1.id === value[LANGUAGE_FIELD_NAME]), languageTitle = keyIsValid && language ? getLanguageDisplay(languageDisplay, language.title, language.id) : "", isDefault = defaultLanguages.includes(value[LANGUAGE_FIELD_NAME]), removeButton = /* @__PURE__ */ jsx(Button, { mode: "bleed", icon: RemoveCircleIcon, tone: "critical", disabled: readOnly || isDefault, onClick: handleUnset }), t3 = getToneFromValidation(validation), t4 = keyIsValid ? /* @__PURE__ */ jsx(Label, { muted: !0, size: 1, children: languageTitle }) : /* @__PURE__ */ jsx(MenuButton, { button: /* @__PURE__ */ jsx(Button, { fontSize: 1, text: `Change "${value[LANGUAGE_FIELD_NAME]}"` }), id: `${value[LANGUAGE_FIELD_NAME]}-change-key`, menu: /* @__PURE__ */ jsx(Menu, { children: languages.map((lang) => /* @__PURE__ */ jsx(MenuItem, { disabled: languageKeysInUse.includes(lang.id), fontSize: 1, text: lang.id.toLocaleUpperCase(), value: lang.id, onClick: handleKeyChange }, lang.id)) }), popover: {
747
761
  portal: !0
748
762
  } });
749
763
  let t5;
@@ -759,7 +773,7 @@ function InternationalizedInput(props) {
759
773
  ] }) });
760
774
  }
761
775
  function _temp4(v) {
762
- return v._key;
776
+ return v[LANGUAGE_FIELD_NAME];
763
777
  }
764
778
  function _temp3(m) {
765
779
  return m.kind === "field" && m.name === "value";
@@ -800,7 +814,7 @@ var object = (config) => {
800
814
  preview: {
801
815
  select: {
802
816
  title: "value",
803
- subtitle: "_key"
817
+ subtitle: LANGUAGE_FIELD_NAME
804
818
  }
805
819
  }
806
820
  });
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/utils/createValueSchemaTypeName.ts","../src/utils/createAddLanguagePatches.ts","../src/fieldActions/index.ts","../src/components/createFieldName.ts","../src/components/Feedback.tsx","../src/components/InternationalizedArray.tsx","../src/utils/getLanguagesFieldOption.ts","../src/schema/array.ts","../src/components/getToneFromValidation.ts","../src/components/InternationalizedInput.tsx","../src/schema/object.ts","../src/utils/flattenSchemaType.ts","../src/plugin.tsx"],"sourcesContent":["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\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\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\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 type React from 'react'\n\nimport {AddIcon} from '@sanity/icons'\nimport {Button, Grid} from '@sanity/ui'\n\nimport type {Language, Value} from '../types'\n\nimport {MAX_COLUMNS} from '../constants'\nimport {getLanguageDisplay} from '../utils/getLanguageDisplay'\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\ntype AddButtonsProps = {\n languages: Language[]\n readOnly: boolean\n value: Value[] | undefined\n onClick: (event: React.MouseEvent<HTMLButtonElement>) => void\n}\n\nfunction AddButtons(props: AddButtonsProps) {\n const {languages, readOnly, value, onClick} = props\n const {languageDisplay} = useInternationalizedArrayContext()\n\n return languages.length > 0 ? (\n <Grid 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 disabled={readOnly || Boolean(value?.find((item) => item._key === language.id))}\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={onClick}\n />\n )\n })}\n </Grid>\n ) : null\n}\n\nexport default AddButtons\n","import {Box, Stack, Text, useToast} from '@sanity/ui'\nimport {type ReactElement, type MouseEvent, 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 {getDocumentsToTranslate} from '../utils/getDocumentsToTranslate'\nimport AddButtons from './AddButtons'\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\ntype DocumentAddButtonsProps = {\n value: Record<string, unknown> | 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 (event: MouseEvent<HTMLButtonElement>) => {\n const languageId = event.currentTarget.value\n if (!languageId) {\n toast.push({\n status: 'error',\n title: 'No language selected',\n })\n return\n }\n const alreadyTranslated = documentsToTranslation.filter(\n (translation) => translation?._key === languageId,\n )\n const removeDuplicates = documentsToTranslation.reduce<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 _key: languageId,\n _type: toTranslate._type,\n value: initialValue, // Use the determined initial value instead of undefined\n },\n ],\n 'after',\n [...path, -1],\n )\n patches.push(ifMissing)\n patches.push(insertValue)\n }\n\n onChange(PatchEvent.from(patches.flat()))\n },\n [documentsToTranslation, getInitialValueForType, onChange, toast],\n )\n return (\n <Stack space={3}>\n <Box>\n <Text size={1} weight=\"semibold\">\n Add translation to internationalized fields\n </Text>\n </Box>\n <AddButtons\n languages={filteredLanguages}\n readOnly={false}\n value={undefined}\n onClick={handleDocumentButtonClick}\n />\n </Stack>\n )\n}\n","import {get} from 'lodash-es'\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\ntype 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} from 'sanity'\n\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\nexport default function InternationalizedField(props: FieldProps): ReactNode {\n const {languages} = useInternationalizedArrayContext()\n\n // hide titles for 'value' fields within valid language entries\n const customProps = useMemo(() => {\n const pathSegment = props.path.slice(0, -1)[1]\n const languageId =\n typeof pathSegment === 'object' && '_key' in pathSegment ? pathSegment._key : undefined\n const hasValidLanguageId = languageId ? languages.some((l) => l.id === languageId) : false\n const shouldHideTitle = props.title?.toLowerCase() === 'value' && hasValidLanguageId\n\n return {\n ...props,\n title: shouldHideTitle ? '' : props.title,\n }\n }, [props, languages])\n\n if (!customProps.schemaType.name.startsWith('internationalizedArray')) {\n return customProps.renderDefault(customProps)\n }\n\n // Show reference field selector if there's a value\n if (customProps.schemaType.name === 'reference' && customProps.value) {\n return customProps.renderDefault({\n ...customProps,\n title: '',\n level: 0, // Reset the level to avoid nested styling\n })\n }\n\n // For basic field types, we can use children to keep the simple input\n if (\n customProps.schemaType.name === 'string' ||\n customProps.schemaType.name === 'number' ||\n customProps.schemaType.name === 'text'\n ) {\n return customProps.children\n }\n\n // For complex fields (like markdown), we need to use renderDefault\n // to get all the field's functionality\n return customProps.renderDefault({\n ...customProps,\n level: 0, // Reset the level to avoid nested styling\n })\n}\n","import {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, Value} from '../types'\n\nexport function checkAllLanguagesArePresent(\n languages: Language[],\n value: Value[] | undefined,\n): boolean {\n const filteredLanguageIds = languages.map((l) => l.id)\n const languagesInUseIds = value ? value.map((v) => v._key) : []\n\n return (\n languagesInUseIds.length === filteredLanguageIds.length &&\n languagesInUseIds.every((l) => filteredLanguageIds.includes(l))\n )\n}\n","import type {Language, Value} from '../types'\n\nexport function createAddAllTitle(value: Value[] | undefined, languages: Language[]): 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 {SchemaType} from 'sanity'\n\nexport function createValueSchemaTypeName(schemaType: SchemaType): string {\n return `${schemaType.name}Value`\n}\n","import {type FormInsertPatch, insert, type Path, type SchemaType} from 'sanity'\n\nimport type {Language, Value} from '../types'\n\nimport {createValueSchemaTypeName} from './createValueSchemaTypeName'\n\ntype AddConfig = {\n // New keys to add to the field\n addLanguageKeys: string[]\n // Schema of the current field\n schemaType: SchemaType\n // All languages registered in the plugin\n languages: Language[]\n // Languages that are currently visible\n filteredLanguages: Language[]\n // Current value of the internationalizedArray field\n value?: Value[]\n // Path to this item\n path?: Path\n}\n\nexport function createAddLanguagePatches(config: AddConfig): FormInsertPatch[] {\n const {addLanguageKeys, schemaType, languages, filteredLanguages, value, path = []} = config\n\n const itemBase = {_type: createValueSchemaTypeName(schemaType)}\n\n // Create new items\n const getNewItems = () => {\n if (Array.isArray(addLanguageKeys) && addLanguageKeys.length > 0) {\n return addLanguageKeys.map((id) => Object.assign({}, itemBase, {_key: id}))\n }\n\n return filteredLanguages\n .filter((language) => (value?.length ? !value.find((v) => v._key === language.id) : true))\n .map((language) => Object.assign({}, itemBase, {_key: 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 languageIndex = languages.findIndex((l) => item._key === l.id)\n\n // What languages are there beyond that index?\n const remainingLanguages = languages.slice(languageIndex + 1)\n\n // So what is the index in the current value array of the next language in the language array?\n const nextLanguageIndex = languagesInUse.findIndex((l) =>\n remainingLanguages.find((r) => r.id === l._key),\n )\n\n // Keep local state up to date incase multiple insertions are being made\n if (nextLanguageIndex < 0) {\n languagesInUse.push(item)\n } else {\n languagesInUse.splice(nextLanguageIndex, 0, item)\n }\n\n return nextLanguageIndex < 0\n ? // No next language (-1), add to end of array\n insert([item], 'after', [...path, nextLanguageIndex])\n : // Next language found, insert before that\n insert([item], 'before', [...path, nextLanguageIndex])\n })\n\n return insertions\n}\n","import {AddIcon, TranslateIcon} from '@sanity/icons'\nimport {useCallback} from 'react'\nimport {\n defineDocumentFieldAction,\n type DocumentFieldActionItem,\n type DocumentFieldActionProps,\n PatchEvent,\n setIfMissing,\n useFormValue,\n} from 'sanity'\nimport {useDocumentPane} from 'sanity/structure'\n\nimport type {Language, Value} from '../types'\n\nimport {useInternationalizedArrayContext} from '../components/InternationalizedArrayContext'\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 Value[]\n const disabled =\n value && Array.isArray(value)\n ? Boolean(value?.find((item) => item._key === language.id))\n : false\n const hidden = !filteredLanguages.some((f) => f.id === language.id)\n\n const {onChange} = useDocumentPane()\n\n const onAction = useCallback(() => {\n const {schemaType, path} = fieldActionProps\n\n const addLanguageKeys = [language.id]\n const patches = createAddLanguagePatches({\n addLanguageKeys,\n schemaType,\n languages,\n filteredLanguages,\n value,\n path,\n })\n\n onChange(PatchEvent.from([setIfMissing([], path), ...patches]))\n }, [language.id, value, onChange])\n\n return {\n type: 'action',\n icon: AddIcon,\n onAction,\n title: language.title,\n hidden,\n disabled,\n }\n })\n\nconst AddMissingTranslationsFieldAction: (\n fieldActionProps: DocumentFieldActionProps,\n context: {\n languages: Language[]\n filteredLanguages: Language[]\n },\n) => DocumentFieldActionItem = (fieldActionProps, {languages, filteredLanguages}) => {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n const value = useFormValue(fieldActionProps.path) as Value[]\n const disabled = value && value.length === filteredLanguages.length\n const hidden = checkAllLanguagesArePresent(filteredLanguages, value)\n\n const {onChange} = useDocumentPane()\n\n const onAction = useCallback(() => {\n const {schemaType, path} = fieldActionProps\n\n const addLanguageKeys: string[] = []\n const patches = createAddLanguagePatches({\n addLanguageKeys,\n schemaType,\n languages,\n filteredLanguages,\n value,\n path,\n })\n\n onChange(PatchEvent.from([setIfMissing([], path), ...patches]))\n }, [fieldActionProps, filteredLanguages, languages, onChange, value])\n\n return {\n type: 'action',\n icon: AddIcon,\n onAction,\n title: createAddAllTitle(value, filteredLanguages),\n disabled,\n hidden,\n }\n}\n\nexport const internationalizedArrayFieldAction = defineDocumentFieldAction({\n name: 'internationalizedArray',\n useAction(fieldActionProps) {\n const isInternationalizedArrayField =\n fieldActionProps?.schemaType?.type?.name.startsWith('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\nexport function pascalCase(string: string): string {\n return upperFirst(camelCase(string))\n}\n\nexport function createFieldName(name: string, addValue = false): string {\n return addValue\n ? [`internationalizedArray`, pascalCase(name), `Value`].join(``)\n : [`internationalizedArray`, pascalCase(name)].join(``)\n}\n","import 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 {Value} from '../types'\n\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<Value>\n\nexport default function InternationalizedArray(\n props: InternationalizedArrayProps,\n): React.ReactElement {\n const {members, value, schemaType, onChange, readOnly: documentReadOnly} = props\n\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 async (param?: React.MouseEvent<HTMLButtonElement> | string[]) => {\n if (!filteredLanguages?.length) {\n return\n }\n\n const addLanguageKeys: string[] = Array.isArray(param)\n ? param\n : // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\n ([param?.currentTarget?.value].filter(Boolean) as string[])\n\n const patches = createAddLanguagePatches({\n addLanguageKeys,\n schemaType,\n languages,\n filteredLanguages,\n value,\n })\n\n onChange([setIfMissing([]), ...patches])\n },\n [filteredLanguages, languages, onChange, schemaType, value],\n )\n\n const {isDeleting} = useDocumentPane()\n\n const addedLanguages = members.map(({key}) => key)\n const hasAddedDefaultLanguages = defaultLanguages\n .filter((language) => languages.find((l) => l.id === language))\n .every((language) => addedLanguages.includes(language))\n\n useEffect(() => {\n if (!isDeleting && !hasAddedDefaultLanguages) {\n const languagesToAdd = defaultLanguages\n .filter((language) => !addedLanguages.includes(language))\n .filter((language) => languages.find((l) => l.id === language))\n // Account for strict mode by scheduling the update\n const timeout = setTimeout(() => {\n if (!documentReadOnly) void handleAddLanguage(languagesToAdd)\n })\n return () => clearTimeout(timeout)\n }\n return undefined\n }, [\n isDeleting,\n hasAddedDefaultLanguages,\n handleAddLanguage,\n defaultLanguages,\n addedLanguages,\n languages,\n documentReadOnly,\n ])\n\n // NOTE: This is reordering and re-setting the whole array, it could be surgical\n const handleRestoreOrder = useCallback(() => {\n if (!value?.length || !languages?.length) {\n return\n }\n\n // Create a new value array in the correct order\n // This would also strip out values that don't have a language as the key\n const updatedValue = value\n .reduce((acc, v) => {\n const newIndex = languages.findIndex((l) => l.id === v?._key)\n\n if (newIndex > -1) {\n acc[newIndex] = v\n }\n\n return acc\n }, [] as Value[])\n .filter(Boolean)\n\n if (value?.length !== updatedValue.length) {\n toast.push({\n title: 'There was an error reordering languages',\n status: 'warning',\n })\n }\n\n onChange(set(updatedValue))\n }, [toast, languages, onChange, value])\n\n const allKeysAreLanguages = useMemo(() => {\n if (!value?.length || !languages?.length) {\n return true\n }\n\n return value?.every((v) => languages.find((l) => l?.id === v?._key))\n }, [value, languages])\n\n // Check languages are in the correct order\n const languagesInUse = useMemo(\n () =>\n languages && languages.length > 1\n ? languages.filter((l) => value?.find((v) => v._key === l.id))\n : [],\n [languages, value],\n )\n\n const languagesOutOfOrder = useMemo(() => {\n if (!value?.length || !languagesInUse.length) {\n return []\n }\n\n return value\n .map((v, vIndex) => (vIndex === languagesInUse.findIndex((l) => l.id === v._key) ? null : v))\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 onClick={handleAddLanguage}\n />\n {buttonAddAll ? (\n <Button\n tone=\"primary\"\n mode=\"ghost\"\n disabled={readOnly || allLanguagesArePresent}\n icon={AddIcon}\n text={createAddAllTitle(value, filteredLanguages)}\n onClick={handleAddLanguage}\n />\n ) : null}\n </Stack>\n ) : null}\n </Stack>\n )\n}\n","import 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, Value} 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 {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): FieldDefinition<'array'> => {\n const {apiVersion, select, languages, type} = config\n const typeName = typeof type === `string` ? type : type.name\n const arrayName = createFieldName(typeName)\n const objectName = createFieldName(typeName, true)\n\n return defineField({\n name: arrayName,\n title: 'Internationalized array',\n type: 'array',\n components: {\n input: InternationalizedArray,\n },\n options: {\n // @ts-expect-error - these options are required for validation rules – not the custom input component\n apiVersion,\n select,\n languages,\n },\n of: [\n defineField({\n ...(typeof type === 'string' ? {} : type),\n name: objectName,\n type: objectName,\n }),\n ],\n // @ts-expect-error - fix typings\n validation: (rule: Rule) =>\n rule.custom<Value[]>(async (value, context) => {\n if (!value || value.length === 0) {\n return true\n }\n\n // Early return for simple cases to avoid expensive operations\n if (value.length === 1 && !value[0]?._key) {\n return true\n }\n\n const selectedValue = getSelectedValue(select, context.document)\n const client = context.getClient({apiVersion})\n\n let contextLanguages: Language[] = []\n const languagesFieldOption = getLanguagesFieldOption(context?.type)\n\n if (Array.isArray(languagesFieldOption)) {\n contextLanguages = languagesFieldOption\n } else if (Array.isArray(peek(selectedValue))) {\n contextLanguages = peek(selectedValue) || []\n } else if (typeof languagesFieldOption === 'function') {\n // Try to get from function cache first (if it's the same function as the component)\n const cachedLanguages = getFunctionCache(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((item) => item?._key && !languageIds.has(item._key))\n if (nonLanguageKeys.length) {\n return {\n message: `Array item keys must be valid languages registered to the field type`,\n paths: nonLanguageKeys.map((item) => [{_key: item._key}]),\n }\n }\n\n // Check for duplicate language keys (more efficient)\n const seenKeys = new Set<string>()\n const duplicateValues: Value[] = []\n\n for (const item of value) {\n if (item?._key) {\n if (seenKeys.has(item._key)) {\n duplicateValues.push(item)\n } else {\n seenKeys.add(item._key)\n }\n }\n }\n\n if (duplicateValues.length) {\n return {\n message: 'There can only be one field per language',\n paths: duplicateValues.map((item) => [{_key: item._key}]),\n }\n }\n\n return true\n }),\n })\n}\n","import type {CardTone} from '@sanity/ui'\nimport type {FormNodeValidation} from 'sanity'\n\nexport function getToneFromValidation(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 {getLanguageDisplay} from '../utils/getLanguageDisplay'\nimport {getToneFromValidation} from './getToneFromValidation'\nimport {useInternationalizedArrayContext} from './InternationalizedArrayContext'\n\nexport type InternationalizedValue = {\n _type: string\n _key: string\n value: string\n}\n\nexport default function InternationalizedInput(\n props: ObjectItemProps<InternationalizedValue>,\n): ReactNode {\n // 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 // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion\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(() => parentValue?.map((v) => v._key) ?? [], [parentValue])\n const keyIsValid = languages?.length ? languages.find((l) => l.id === value._key) : 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, ['_key'])])\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._key)\n const languageTitle: string =\n keyIsValid && language ? getLanguageDisplay(languageDisplay, language.title, language.id) : ''\n\n const isDefault = defaultLanguages.includes(value._key)\n\n const removeButton = (\n <Button\n mode=\"bleed\"\n icon={RemoveCircleIcon}\n tone=\"critical\"\n disabled={readOnly || isDefault}\n onClick={handleUnset}\n />\n )\n\n return (\n <Card paddingTop={2} tone={getToneFromValidation(validation)}>\n <Stack space={2}>\n <Card tone=\"inherit\">\n {keyIsValid ? (\n <Label muted size={1}>\n {languageTitle}\n </Label>\n ) : (\n <MenuButton\n button={<Button fontSize={1} text={`Change \"${value._key}\"`} />}\n id={`${value._key}-change-key`}\n menu={\n <Menu>\n {languages.map((lang) => (\n <MenuItem\n disabled={languageKeysInUse.includes(lang.id)}\n fontSize={1}\n key={lang.id}\n text={lang.id.toLocaleUpperCase()}\n value={lang.id}\n // @ts-expect-error - fix typings\n onClick={handleKeyChange}\n />\n ))}\n </Menu>\n }\n popover={{portal: true}}\n />\n )}\n </Card>\n <Flex align=\"center\" gap={2}>\n <Card flex={1} tone=\"inherit\">\n {props.inputProps.renderInput(inlineProps)}\n </Card>\n\n <Card tone=\"inherit\">\n {isDefault ? (\n <Tooltip\n content={\n <Text muted size={1}>\n Can&apos;t remove default language\n </Text>\n }\n fallbackPlacements={['right', 'left']}\n placement=\"top\"\n portal\n >\n <span>{removeButton}</span>\n </Tooltip>\n ) : (\n removeButton\n )}\n </Card>\n </Flex>\n </Stack>\n </Card>\n )\n}\n","import {defineField, type FieldDefinition} from 'sanity'\n\nimport {createFieldName} from '../components/createFieldName'\nimport InternationalizedInput from '../components/InternationalizedInput'\n\ntype ObjectFactoryConfig = {\n type: string | FieldDefinition\n}\n\nexport default (config: ObjectFactoryConfig): FieldDefinition<'object'> => {\n const {type} = config\n const typeName = typeof type === `string` ? type : type.name\n const objectName = createFieldName(typeName, true)\n\n return defineField({\n name: objectName,\n title: `Internationalized array ${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: '_key',\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","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","onClick","useInternationalizedArrayContext","t0","language","languageTitle","id","Boolean","find","_key","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","event","languageId","currentTarget","push","status","alreadyTranslated","translation","removeDuplicates","reduce","filteredTranslations","translation_0","alreadyTranslation","filteredTranslation","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","InternationalizedField","pathSegment","hasValidLanguageId","some","l","customProps","level","children","Preload","checkAllLanguagesArePresent","filteredLanguageIds","languagesInUseIds","v","every","createAddAllTitle","createValueSchemaTypeName","createAddLanguagePatches","config","addLanguageKeys","itemBase","newItems","languagesInUse","languageIndex","findIndex","remainingLanguages","nextLanguageIndex","r","splice","createTranslateFieldActions","fieldActionProps","useFormValue","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","param","handleAddLanguage","isDeleting","addedLanguages","language_0","hasAddedDefaultLanguages","languagesToAdd","language_1","language_2","l_0","timeout","setTimeout","clearTimeout","useEffect","updatedValue","acc","newIndex","l_1","handleRestoreOrder","v_0","l_2","allKeysAreLanguages","l_3","v_1","t11","t12","v_2","vIndex","l_4","languagesOutOfOrder","languagesAreValid","_temp2","t13","allLanguagesArePresent","t14","addButtonsAreVisible","fieldHasMembers","t15","member_0","t16","t17","t18","getLanguagesFieldOption","arrayName","objectName","defineField","components","input","validation","rule","custom","getClient","contextLanguages","languagesFieldOption","cachedLanguages","suspendCachedLanguages","languageIds","lang","nonLanguageKeys","message","paths","seenKeys","duplicateValues","add","getToneFromValidation","validations","validationLevels","InternationalizedInput","parentValue","originalOnChange","inputProps","initPatch","fixedPatches","allPatches","wrappedOnChange","inlineProps","_temp3","_temp4","languageKeysInUse","keyIsValid","handleKeyChange","handleUnset","unset","isDefault","removeButton","RemoveCircleIcon","toLocaleUpperCase","portal","T0","Card","renderInput","m","patch_0","patch","fixedPath","preview","subtitle","flattenSchemaType","isDocumentSchemaType","extractInnerFields","console","error","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/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, Value} 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: Value[] | 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, Value} 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: Value[] | 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, Value} 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(value: Value[] | undefined, languages: Language[]): 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 FormInsertPatch, insert, type Path} from 'sanity'\n\nimport type {Language, Value} from '../types'\n\nimport {LANGUAGE_FIELD_NAME} from '../constants'\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?: Value[]\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.\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 itemBase = {_type: `${schemaTypeName}Value`}\n\n // Create new items\n const getNewItems = () => {\n if (Array.isArray(addLanguageKeys) && addLanguageKeys.length > 0) {\n return addLanguageKeys.map((id) => Object.assign({}, itemBase, {[LANGUAGE_FIELD_NAME]: id}))\n }\n\n return filteredLanguages\n .filter((language) =>\n 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, Value} 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 Value[]\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 Value[]\n const disabled = value && value.length === filteredLanguages.length\n const hidden = checkAllLanguagesArePresent(filteredLanguages, value)\n\n const {onChange} = useDocumentPane()\n\n const onAction = useCallback(() => {\n const {schemaType, path} = fieldActionProps\n\n const addLanguageKeys: string[] = []\n const patches = createAddLanguagePatches({\n addLanguageKeys,\n 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 {Value} 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<Value>\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: InternationalizedArrayProps,\n): React.ReactElement {\n const {members, value, schemaType, onChange, readOnly: documentReadOnly} = props\n\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 Value[])\n .filter(Boolean)\n\n if (value?.length !== updatedValue.length) {\n toast.push({\n title: 'There was an error reordering languages',\n status: 'warning',\n })\n }\n\n onChange(set(updatedValue))\n }, [toast, languages, onChange, value])\n\n const allKeysAreLanguages = useMemo(() => {\n if (!value?.length || !languages?.length) {\n return true\n }\n\n return value?.every((v) => languages.find((l) => l?.id === v?.[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, Value} 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<Value[]>(async (value, context) => {\n if (!value || value.length === 0) {\n return true\n }\n\n // Early return for simple cases to avoid expensive operations\n if (value.length === 1 && !value[0]?.[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: Value[] = []\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&apos;t remove default language\n </Text>\n }\n fallbackPlacements={['right', 'left']}\n placement=\"top\"\n portal\n >\n <span>{removeButton}</span>\n </Tooltip>\n ) : (\n removeButton\n )}\n </Card>\n </Flex>\n </Stack>\n </Card>\n )\n}\n","import {defineField, 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","createAddLanguagePatches","config","addLanguageKeys","schemaTypeName","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.0",
3
+ "version": "4.0.1",
4
4
  "description": "Store localized fields in an array to save on attributes",
5
5
  "keywords": [
6
6
  "sanity",
@@ -34,16 +34,17 @@
34
34
  "lodash-es": "^4.17.23"
35
35
  },
36
36
  "devDependencies": {
37
- "@sanity/pkg-utils": "^10.4.3",
37
+ "@sanity/pkg-utils": "^10.4.4",
38
+ "@testing-library/jest-dom": "^6.9.1",
39
+ "@testing-library/react": "^16.3.2",
38
40
  "@types/lodash-es": "^4.17.12",
39
- "@types/react": "^19.2.10",
41
+ "@types/react": "^19.2.13",
40
42
  "@types/react-dom": "^19.2.3",
41
43
  "babel-plugin-react-compiler": "^1.0.0",
42
- "eslint": "^9.39.2",
44
+ "jsdom": "^28.0.0",
43
45
  "react": "^19.2.4",
44
46
  "react-dom": "^19.2.4",
45
- "sanity": "^5.7.0",
46
- "@repo/eslint-config": "0.0.0",
47
+ "sanity": "^5.8.1",
47
48
  "@repo/package.config": "0.0.0",
48
49
  "@repo/tsconfig": "0.0.0"
49
50
  },
@@ -56,7 +57,6 @@
56
57
  "node": ">=20.19 <22 || >=22.12"
57
58
  },
58
59
  "scripts": {
59
- "build": "pkg build --strict --check --clean",
60
- "lint": "eslint ."
60
+ "build": "pkg build --strict --check --clean"
61
61
  }
62
62
  }