gt-sanity 2.0.21 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/index.cjs +1220 -763
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +113 -1
  4. package/dist/index.d.ts +113 -1
  5. package/dist/index.js +1211 -754
  6. package/dist/index.js.map +1 -1
  7. package/package.json +2 -2
  8. package/src/adapter/core.ts +27 -2
  9. package/src/adapter/types.ts +9 -0
  10. package/src/components/TranslationsProvider.tsx +92 -6
  11. package/src/components/page/TranslationsTable.tsx +5 -3
  12. package/src/components/shared/SingleDocumentView.tsx +5 -3
  13. package/src/components/tab/TranslationView.tsx +24 -14
  14. package/src/configuration/baseDocumentLevelConfig/documentLevelPatch.ts +1 -1
  15. package/src/configuration/baseFieldLevelConfig.ts +1 -1
  16. package/src/configuration/internationalizedArrayConfig/internationalizedArrayPatch.ts +59 -0
  17. package/src/index.ts +114 -58
  18. package/src/schema/InternationalizedArrayInput.tsx +278 -0
  19. package/src/schema/__tests__/createInternationalizedArrayTypes.test.ts +169 -0
  20. package/src/schema/createInternationalizedArrayTypes.ts +209 -0
  21. package/src/schema/types.ts +84 -0
  22. package/src/serialization/__tests__/BaseDocumentDeserializer/baseDeserialization.test.ts +3 -3
  23. package/src/serialization/__tests__/BaseDocumentMerger/baseMerge.test.ts +1 -1
  24. package/src/serialization/__tests__/BaseDocumentMerger/documentLevelMerge.test.ts +1 -1
  25. package/src/serialization/__tests__/BaseDocumentMerger/fieldLevelMerge.test.ts +1 -1
  26. package/src/serialization/__tests__/BaseDocumentSerializer/baseSerialization.test.ts +2 -2
  27. package/src/serialization/__tests__/BaseDocumentSerializer/documentInlineMarks.test.ts +4 -2
  28. package/src/serialization/__tests__/global.setup.ts +6 -0
  29. package/src/serialization/__tests__/helpers.ts +2 -1
  30. package/src/serialization/internationalizedArray/__tests__/internationalizedArray.test.ts +265 -0
  31. package/src/serialization/internationalizedArray/__tests__/serializeRoundTrip.test.ts +83 -0
  32. package/src/serialization/internationalizedArray/collapse.ts +52 -0
  33. package/src/serialization/internationalizedArray/detect.ts +81 -0
  34. package/src/serialization/internationalizedArray/merge.ts +149 -0
  35. package/src/serialization/types.ts +5 -1
  36. package/src/translation/__tests__/strategy.test.ts +47 -0
  37. package/src/translation/importDocument.ts +9 -5
  38. package/src/translation/strategy.ts +92 -0
  39. package/src/translation/uploadFiles.ts +1 -1
  40. package/src/types.ts +1 -1
  41. package/src/utils/__tests__/batchProcessor.test.ts +61 -2
  42. package/src/utils/batchProcessor.ts +11 -6
  43. package/src/utils/serialize.ts +24 -7
  44. package/src/serialization/index.ts +0 -16
package/dist/index.d.cts CHANGED
@@ -1,12 +1,16 @@
1
+ import type { ArrayOfObjectsInputProps } from "sanity";
2
+ import type { ComponentType } from "react";
1
3
  import type { DeserializerRule } from "@portabletext/block-tools";
2
4
  import { DocumentActionComponent } from "sanity";
3
5
  import { documentInternationalization } from "@sanity/document-internationalization";
4
6
  import { PluginConfig as DocumentInternationalizationConfig } from "@sanity/document-internationalization";
5
7
  import { DocumentInternationalizationMenu } from "@sanity/document-internationalization";
8
+ import type { FieldProps } from "sanity";
6
9
  import { GT } from "generaltranslation";
7
10
  import { Language } from "@sanity/document-internationalization";
8
11
  import { Metadata } from "@sanity/document-internationalization";
9
12
  import { ObjectField } from "sanity";
13
+ import type { ObjectItemProps } from "sanity";
10
14
  import { Plugin as Plugin_2 } from "sanity";
11
15
  import { PortableTextHtmlComponents } from "@portabletext/to-html";
12
16
  import { PortableTextTypeComponent } from "@portabletext/to-html";
@@ -14,6 +18,7 @@ import { default as React_2 } from "react";
14
18
  import { SanityClient } from "sanity";
15
19
  import { SanityDocument } from "sanity";
16
20
  import { Schema } from "sanity";
21
+ import { SchemaTypeDefinition } from "sanity";
17
22
  import { TranslationReference } from "@sanity/document-internationalization";
18
23
  import { TypedObject } from "sanity";
19
24
  import { useDeleteTranslationAction } from "@sanity/document-internationalization";
@@ -84,6 +89,32 @@ export declare const BaseDocumentSerializer: (schemas: Schema) => {
84
89
  ) => string;
85
90
  };
86
91
 
92
+ /**
93
+ * Generate `internationalizedArray*` schema types from gtPlugin locale config.
94
+ *
95
+ * Each generated type is an array of `{ _key, _type, language, value }` objects
96
+ * matching `sanity-plugin-internationalized-array`, giving zero-migration
97
+ * interop with existing internationalized-array data.
98
+ *
99
+ * When `typePrefix` is customized and `includeCompatibilityTypes` is true, the
100
+ * standard `internationalizedArray*` names are also generated so existing
101
+ * content keeps resolving.
102
+ */
103
+ export declare function createInternationalizedArrayTypes(
104
+ options: CreateInternationalizedArrayTypesOptions,
105
+ ): SchemaTypeDefinition[];
106
+
107
+ declare type CreateInternationalizedArrayTypesOptions = {
108
+ sourceLocale: string;
109
+ locales: string[];
110
+ fieldTypes: FieldLevelFieldType[];
111
+ languageTitles?: Record<string, string>;
112
+ getLanguageTitle?: (locale: string) => string;
113
+ typePrefix?: string;
114
+ includeCompatibilityTypes?: boolean;
115
+ components?: FieldLevelUIComponents;
116
+ };
117
+
87
118
  declare type CustomDeserializer = (
88
119
  element: HTMLElement,
89
120
  ) => Record<string, unknown> | unknown[];
@@ -129,6 +160,54 @@ export declare type ExportForTranslation = (
129
160
  context: TranslationFunctionContext,
130
161
  ) => Promise<GTSerializedDocument>;
131
162
 
163
+ /**
164
+ * A localizable field type. Built-in shortcuts (`string`, `text`, `block`) map
165
+ * to generated `value` field definitions; an object form supplies a custom
166
+ * `value` field definition verbatim.
167
+ */
168
+ export declare type FieldLevelFieldType =
169
+ | "string"
170
+ | "text"
171
+ | "block"
172
+ | {
173
+ /** Suffix used in the generated type name, e.g. `seo` → `internationalizedArraySeo`. */
174
+ name: string;
175
+ /** Sanity type of the generated `value` field (e.g. an object type name). */
176
+ type: string;
177
+ title?: string;
178
+ of?: unknown[];
179
+ fields?: unknown[];
180
+ options?: Record<string, unknown>;
181
+ };
182
+
183
+ export declare type FieldLevelTranslationMode =
184
+ | "document"
185
+ | "internationalizedArray"
186
+ | "mixed";
187
+
188
+ /**
189
+ * Studio component overrides for generated `internationalizedArray*` types.
190
+ *
191
+ * Each slot defaults to GT's inline UI (per-locale labeled inputs with
192
+ * remove buttons and add-locale buttons). Pass a component to replace a
193
+ * slot, or `false` to detach GT's component and fall back to Sanity's
194
+ * default rendering. Translation is unaffected either way — it operates on
195
+ * the stored `{_key, language, value}` data, not on the components.
196
+ */
197
+ export declare type FieldLevelUIComponents = {
198
+ /** Input for the generated array types. Default: GT's inline input. */
199
+ input?: ComponentType<ArrayOfObjectsInputProps> | false;
200
+ /** Item for the generated `*Value` objects. Default: GT's inline item. */
201
+ item?: ComponentType<ObjectItemProps> | false;
202
+ /**
203
+ * Field wrapper for the generated array types. Defaults to a wrapper that
204
+ * resets the field level (removes nested-object indentation) — but only
205
+ * while GT's default input is in use; with a custom or disabled `input`,
206
+ * this defaults to Sanity's standard field rendering.
207
+ */
208
+ field?: ComponentType<FieldProps> | false;
209
+ };
210
+
132
211
  declare type FieldMatcher = {
133
212
  documentId?: string | null;
134
213
  fields?: {
@@ -144,6 +223,35 @@ export declare const findLatestDraft: (
144
223
 
145
224
  declare const gt: GT;
146
225
 
226
+ /**
227
+ * Field-level localization options, mirroring the useful parts of
228
+ * `sanity-plugin-internationalized-array` while keeping `sourceLocale` /
229
+ * `locales` from `gtPlugin()` as the only source of locale identity.
230
+ */
231
+ export declare type GTFieldLevelLocalizationConfig = {
232
+ /** Generate `internationalizedArray*` schema types + input components. Default `false`. */
233
+ enabled?: boolean;
234
+ /** Which field types to generate. Default `['string', 'text']`. */
235
+ fieldTypes?: FieldLevelFieldType[];
236
+ /** Per-locale display labels shown in the Studio input. */
237
+ languageTitles?: Record<string, string>;
238
+ /** Compute a display label for a locale (overrides `languageTitles`). */
239
+ getLanguageTitle?: (locale: string) => string;
240
+ /** Prefix for generated type names. Default `'internationalizedArray'`. */
241
+ typePrefix?: string;
242
+ /**
243
+ * When `typePrefix` is customized, also generate `internationalizedArray*`
244
+ * aliases for interop with existing data. Default `true`.
245
+ */
246
+ includeCompatibilityTypes?: boolean;
247
+ /**
248
+ * Override or detach the Studio components attached to generated types.
249
+ * Use this to keep your own UI (or Sanity's default) while GT generates
250
+ * the schema types and handles translation.
251
+ */
252
+ components?: FieldLevelUIComponents;
253
+ };
254
+
147
255
  declare type GTFile = {
148
256
  documentId: string;
149
257
  versionId?: string;
@@ -183,6 +291,10 @@ export declare type GTPluginConfig = Omit<
183
291
  additionalDeserializers?: CustomDeserializers;
184
292
  additionalBlockDeserializers?: unknown[];
185
293
  showDocumentInternationalization?: boolean;
294
+ internationalizedArray?: GTFieldLevelLocalizationConfig;
295
+ fieldLevelLocalization?: GTFieldLevelLocalizationConfig;
296
+ translationLevel?: FieldLevelTranslationMode;
297
+ fieldLevelDocuments?: TranslateDocumentFilter[] | string[];
186
298
  };
187
299
 
188
300
  declare type GTSerializedDocument = Omit<SerializedDocument, "name"> & GTFile;
@@ -255,7 +367,7 @@ export declare interface TranslationFunctionContext {
255
367
  schema: Schema;
256
368
  }
257
369
 
258
- declare type TranslationLevel = "document" | "field";
370
+ declare type TranslationLevel = "document" | "field" | "internationalizedArray";
259
371
 
260
372
  declare type TranslationLocale = {
261
373
  localeId: string;
package/dist/index.d.ts CHANGED
@@ -1,12 +1,16 @@
1
+ import type { ArrayOfObjectsInputProps } from "sanity";
2
+ import type { ComponentType } from "react";
1
3
  import type { DeserializerRule } from "@portabletext/block-tools";
2
4
  import { DocumentActionComponent } from "sanity";
3
5
  import { documentInternationalization } from "@sanity/document-internationalization";
4
6
  import { PluginConfig as DocumentInternationalizationConfig } from "@sanity/document-internationalization";
5
7
  import { DocumentInternationalizationMenu } from "@sanity/document-internationalization";
8
+ import type { FieldProps } from "sanity";
6
9
  import { GT } from "generaltranslation";
7
10
  import { Language } from "@sanity/document-internationalization";
8
11
  import { Metadata } from "@sanity/document-internationalization";
9
12
  import { ObjectField } from "sanity";
13
+ import type { ObjectItemProps } from "sanity";
10
14
  import { Plugin as Plugin_2 } from "sanity";
11
15
  import { PortableTextHtmlComponents } from "@portabletext/to-html";
12
16
  import { PortableTextTypeComponent } from "@portabletext/to-html";
@@ -14,6 +18,7 @@ import { default as React_2 } from "react";
14
18
  import { SanityClient } from "sanity";
15
19
  import { SanityDocument } from "sanity";
16
20
  import { Schema } from "sanity";
21
+ import { SchemaTypeDefinition } from "sanity";
17
22
  import { TranslationReference } from "@sanity/document-internationalization";
18
23
  import { TypedObject } from "sanity";
19
24
  import { useDeleteTranslationAction } from "@sanity/document-internationalization";
@@ -84,6 +89,32 @@ export declare const BaseDocumentSerializer: (schemas: Schema) => {
84
89
  ) => string;
85
90
  };
86
91
 
92
+ /**
93
+ * Generate `internationalizedArray*` schema types from gtPlugin locale config.
94
+ *
95
+ * Each generated type is an array of `{ _key, _type, language, value }` objects
96
+ * matching `sanity-plugin-internationalized-array`, giving zero-migration
97
+ * interop with existing internationalized-array data.
98
+ *
99
+ * When `typePrefix` is customized and `includeCompatibilityTypes` is true, the
100
+ * standard `internationalizedArray*` names are also generated so existing
101
+ * content keeps resolving.
102
+ */
103
+ export declare function createInternationalizedArrayTypes(
104
+ options: CreateInternationalizedArrayTypesOptions,
105
+ ): SchemaTypeDefinition[];
106
+
107
+ declare type CreateInternationalizedArrayTypesOptions = {
108
+ sourceLocale: string;
109
+ locales: string[];
110
+ fieldTypes: FieldLevelFieldType[];
111
+ languageTitles?: Record<string, string>;
112
+ getLanguageTitle?: (locale: string) => string;
113
+ typePrefix?: string;
114
+ includeCompatibilityTypes?: boolean;
115
+ components?: FieldLevelUIComponents;
116
+ };
117
+
87
118
  declare type CustomDeserializer = (
88
119
  element: HTMLElement,
89
120
  ) => Record<string, unknown> | unknown[];
@@ -129,6 +160,54 @@ export declare type ExportForTranslation = (
129
160
  context: TranslationFunctionContext,
130
161
  ) => Promise<GTSerializedDocument>;
131
162
 
163
+ /**
164
+ * A localizable field type. Built-in shortcuts (`string`, `text`, `block`) map
165
+ * to generated `value` field definitions; an object form supplies a custom
166
+ * `value` field definition verbatim.
167
+ */
168
+ export declare type FieldLevelFieldType =
169
+ | "string"
170
+ | "text"
171
+ | "block"
172
+ | {
173
+ /** Suffix used in the generated type name, e.g. `seo` → `internationalizedArraySeo`. */
174
+ name: string;
175
+ /** Sanity type of the generated `value` field (e.g. an object type name). */
176
+ type: string;
177
+ title?: string;
178
+ of?: unknown[];
179
+ fields?: unknown[];
180
+ options?: Record<string, unknown>;
181
+ };
182
+
183
+ export declare type FieldLevelTranslationMode =
184
+ | "document"
185
+ | "internationalizedArray"
186
+ | "mixed";
187
+
188
+ /**
189
+ * Studio component overrides for generated `internationalizedArray*` types.
190
+ *
191
+ * Each slot defaults to GT's inline UI (per-locale labeled inputs with
192
+ * remove buttons and add-locale buttons). Pass a component to replace a
193
+ * slot, or `false` to detach GT's component and fall back to Sanity's
194
+ * default rendering. Translation is unaffected either way — it operates on
195
+ * the stored `{_key, language, value}` data, not on the components.
196
+ */
197
+ export declare type FieldLevelUIComponents = {
198
+ /** Input for the generated array types. Default: GT's inline input. */
199
+ input?: ComponentType<ArrayOfObjectsInputProps> | false;
200
+ /** Item for the generated `*Value` objects. Default: GT's inline item. */
201
+ item?: ComponentType<ObjectItemProps> | false;
202
+ /**
203
+ * Field wrapper for the generated array types. Defaults to a wrapper that
204
+ * resets the field level (removes nested-object indentation) — but only
205
+ * while GT's default input is in use; with a custom or disabled `input`,
206
+ * this defaults to Sanity's standard field rendering.
207
+ */
208
+ field?: ComponentType<FieldProps> | false;
209
+ };
210
+
132
211
  declare type FieldMatcher = {
133
212
  documentId?: string | null;
134
213
  fields?: {
@@ -144,6 +223,35 @@ export declare const findLatestDraft: (
144
223
 
145
224
  declare const gt: GT;
146
225
 
226
+ /**
227
+ * Field-level localization options, mirroring the useful parts of
228
+ * `sanity-plugin-internationalized-array` while keeping `sourceLocale` /
229
+ * `locales` from `gtPlugin()` as the only source of locale identity.
230
+ */
231
+ export declare type GTFieldLevelLocalizationConfig = {
232
+ /** Generate `internationalizedArray*` schema types + input components. Default `false`. */
233
+ enabled?: boolean;
234
+ /** Which field types to generate. Default `['string', 'text']`. */
235
+ fieldTypes?: FieldLevelFieldType[];
236
+ /** Per-locale display labels shown in the Studio input. */
237
+ languageTitles?: Record<string, string>;
238
+ /** Compute a display label for a locale (overrides `languageTitles`). */
239
+ getLanguageTitle?: (locale: string) => string;
240
+ /** Prefix for generated type names. Default `'internationalizedArray'`. */
241
+ typePrefix?: string;
242
+ /**
243
+ * When `typePrefix` is customized, also generate `internationalizedArray*`
244
+ * aliases for interop with existing data. Default `true`.
245
+ */
246
+ includeCompatibilityTypes?: boolean;
247
+ /**
248
+ * Override or detach the Studio components attached to generated types.
249
+ * Use this to keep your own UI (or Sanity's default) while GT generates
250
+ * the schema types and handles translation.
251
+ */
252
+ components?: FieldLevelUIComponents;
253
+ };
254
+
147
255
  declare type GTFile = {
148
256
  documentId: string;
149
257
  versionId?: string;
@@ -183,6 +291,10 @@ export declare type GTPluginConfig = Omit<
183
291
  additionalDeserializers?: CustomDeserializers;
184
292
  additionalBlockDeserializers?: unknown[];
185
293
  showDocumentInternationalization?: boolean;
294
+ internationalizedArray?: GTFieldLevelLocalizationConfig;
295
+ fieldLevelLocalization?: GTFieldLevelLocalizationConfig;
296
+ translationLevel?: FieldLevelTranslationMode;
297
+ fieldLevelDocuments?: TranslateDocumentFilter[] | string[];
186
298
  };
187
299
 
188
300
  declare type GTSerializedDocument = Omit<SerializedDocument, "name"> & GTFile;
@@ -255,7 +367,7 @@ export declare interface TranslationFunctionContext {
255
367
  schema: Schema;
256
368
  }
257
369
 
258
- declare type TranslationLevel = "document" | "field";
370
+ declare type TranslationLevel = "document" | "field" | "internationalizedArray";
259
371
 
260
372
  declare type TranslationLocale = {
261
373
  localeId: string;