gt-sanity 0.0.5 → 1.0.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.
- package/LICENSE.md +1 -8
- package/README.md +5 -5
- package/dist/index.d.mts +122 -95
- package/dist/index.d.ts +122 -95
- package/dist/index.js +9089 -1119
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +9099 -1100
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -4
- package/src/adapter/core.ts +111 -9
- package/src/adapter/createTask.ts +1 -1
- package/src/adapter/getLocales.ts +2 -2
- package/src/adapter/types.ts +9 -0
- package/src/components/TranslationsProvider.tsx +942 -0
- package/src/components/page/BatchProgress.tsx +27 -0
- package/src/components/page/ImportAllDialog.tsx +51 -0
- package/src/components/page/ImportMissingDialog.tsx +55 -0
- package/src/components/page/TranslateAllDialog.tsx +55 -0
- package/src/components/page/TranslationsTable.tsx +81 -0
- package/src/components/page/TranslationsTool.tsx +338 -0
- package/src/components/shared/BaseTranslationWrapper.tsx +82 -0
- package/src/components/{LanguageStatus.tsx → shared/LanguageStatus.tsx} +2 -0
- package/src/components/shared/LocaleCheckbox.tsx +47 -0
- package/src/components/{ProgressBar.tsx → shared/ProgressBar.tsx} +2 -0
- package/src/components/shared/SingleDocumentView.tsx +108 -0
- package/src/components/tab/TranslationView.tsx +379 -0
- package/src/components/tab/TranslationsTab.tsx +25 -0
- package/src/configuration/baseDocumentLevelConfig/documentLevelPatch.ts +21 -11
- package/src/configuration/baseDocumentLevelConfig/helpers/createI18nDocAndPatchMetadata.ts +57 -23
- package/src/configuration/baseDocumentLevelConfig/helpers/createTranslationMetadata.ts +2 -0
- package/src/configuration/baseDocumentLevelConfig/helpers/getOrCreateTranslationMetadata.ts +2 -0
- package/src/configuration/baseDocumentLevelConfig/helpers/getTranslationMetadata.ts +2 -0
- package/src/configuration/baseDocumentLevelConfig/helpers/patchI18nDoc.ts +31 -8
- package/src/configuration/baseDocumentLevelConfig/index.ts +18 -101
- package/src/configuration/baseFieldLevelConfig.ts +19 -51
- package/src/configuration/utils/checkSerializationVersion.ts +2 -0
- package/src/configuration/utils/findDocumentAtRevision.ts +2 -0
- package/src/configuration/utils/findLatestDraft.ts +2 -0
- package/src/hooks/useClient.ts +3 -1
- package/src/hooks/useSecrets.ts +2 -0
- package/src/index.ts +91 -67
- package/src/sanity-api/findDocuments.ts +44 -0
- package/src/sanity-api/publishDocuments.ts +49 -0
- package/src/sanity-api/resolveRefs.ts +146 -0
- package/src/serialization/BaseDocumentMerger.ts +138 -0
- package/src/serialization/BaseSerializationConfig.ts +220 -0
- package/src/serialization/__tests__/BaseDocumentDeserializer/__snapshots__/documentLevelDeserialization.test.ts.snap +189 -0
- package/src/serialization/__tests__/BaseDocumentDeserializer/__snapshots__/fieldLevelDeserialization.test.ts.snap +107 -0
- package/src/serialization/__tests__/BaseDocumentDeserializer/baseDeserialization.test.ts +397 -0
- package/src/serialization/__tests__/BaseDocumentDeserializer/documentLevelDeserialization.test.ts +107 -0
- package/src/serialization/__tests__/BaseDocumentDeserializer/fieldLevelDeserialization.test.ts +107 -0
- package/src/serialization/__tests__/BaseDocumentMerger/__snapshots__/documentLevelMerge.test.ts.snap +193 -0
- package/src/serialization/__tests__/BaseDocumentMerger/__snapshots__/fieldLevelMerge.test.ts.snap +97 -0
- package/src/serialization/__tests__/BaseDocumentMerger/baseMerge.test.ts +36 -0
- package/src/serialization/__tests__/BaseDocumentMerger/documentLevelMerge.test.ts +96 -0
- package/src/serialization/__tests__/BaseDocumentMerger/fieldLevelMerge.test.ts +142 -0
- package/src/serialization/__tests__/BaseDocumentMerger/utils.ts +52 -0
- package/src/serialization/__tests__/BaseDocumentSerializer/__snapshots__/documentInlineMarks.test.ts.snap +39 -0
- package/src/serialization/__tests__/BaseDocumentSerializer/__snapshots__/documentLevelSerialization.test.ts.snap +8 -0
- package/src/serialization/__tests__/BaseDocumentSerializer/__snapshots__/fieldLevelSerialization.test.ts.snap +8 -0
- package/src/serialization/__tests__/BaseDocumentSerializer/baseSerialization.test.ts +345 -0
- package/src/serialization/__tests__/BaseDocumentSerializer/documentInlineMarks.test.ts +53 -0
- package/src/serialization/__tests__/BaseDocumentSerializer/documentLevelSerialization.test.ts +120 -0
- package/src/serialization/__tests__/BaseDocumentSerializer/fieldLevelSerialization.test.ts +153 -0
- package/src/serialization/__tests__/BaseDocumentSerializer/utils.ts +27 -0
- package/src/serialization/__tests__/README +2 -0
- package/src/serialization/__tests__/__fixtures__/annotationAndInlineBlocks.json +140 -0
- package/src/serialization/__tests__/__fixtures__/customStyles.json +62 -0
- package/src/serialization/__tests__/__fixtures__/documentInlineMarks.json +70 -0
- package/src/serialization/__tests__/__fixtures__/documentLevelArticle.json +185 -0
- package/src/serialization/__tests__/__fixtures__/fieldLevelArticle.json +107 -0
- package/src/serialization/__tests__/__fixtures__/inlineDocumentLevelArticle.json +134 -0
- package/src/serialization/__tests__/__fixtures__/inlineSchema.ts +270 -0
- package/src/serialization/__tests__/__fixtures__/messy-html.html +26 -0
- package/src/serialization/__tests__/__fixtures__/nestedLanguageFields.json +54 -0
- package/src/serialization/__tests__/__fixtures__/schema.ts +310 -0
- package/src/serialization/__tests__/global.setup.ts +40 -0
- package/src/serialization/__tests__/helpers.ts +132 -0
- package/src/serialization/data.ts +82 -0
- package/src/serialization/deserialize/BaseDocumentDeserializer.ts +171 -0
- package/src/serialization/deserialize/helpers.ts +42 -0
- package/src/serialization/helpers.ts +18 -0
- package/src/serialization/index.ts +11 -0
- package/src/serialization/serialize/fieldFilters.ts +124 -0
- package/src/serialization/serialize/index.ts +284 -0
- package/src/serialization/types.ts +41 -0
- package/src/translation/checkTranslationStatus.ts +42 -0
- package/src/translation/createJobs.ts +16 -0
- package/src/translation/downloadTranslations.ts +68 -0
- package/src/translation/importDocument.ts +23 -0
- package/src/translation/initProject.ts +61 -0
- package/src/translation/uploadFiles.ts +32 -0
- package/src/types.ts +7 -20
- package/src/utils/applyDocuments.ts +72 -0
- package/src/utils/batchProcessor.ts +111 -0
- package/src/utils/importUtils.ts +95 -0
- package/src/utils/serialize.ts +52 -0
- package/src/utils/shared.ts +1 -0
- package/src/adapter/index.ts +0 -13
- package/src/components/NewTask.tsx +0 -249
- package/src/components/TaskView.tsx +0 -255
- package/src/components/TranslationContext.tsx +0 -19
- package/src/components/TranslationView.tsx +0 -82
- package/src/components/TranslationsTab.tsx +0 -177
- package/src/configuration/baseDocumentLevelConfig/helpers/index.ts +0 -5
- package/src/configuration/baseDocumentLevelConfig/legacyDocumentLevelPatch.ts +0 -69
- package/src/configuration/index.ts +0 -18
- package/src/configuration/utils/index.ts +0 -3
|
@@ -1,12 +1,18 @@
|
|
|
1
|
+
// adapted from https://github.com/sanity-io/sanity-translations-tab. See LICENSE.md for more details.
|
|
2
|
+
|
|
1
3
|
import { SanityClient, SanityDocumentLike } from 'sanity';
|
|
4
|
+
import { pluginConfig } from '../../../adapter/core';
|
|
5
|
+
import { applyDocuments } from '../../../utils/applyDocuments';
|
|
2
6
|
|
|
3
|
-
export
|
|
7
|
+
export async function createI18nDocAndPatchMetadata(
|
|
8
|
+
sourceDocument: SanityDocumentLike,
|
|
4
9
|
translatedDoc: SanityDocumentLike,
|
|
5
10
|
localeId: string,
|
|
6
11
|
client: SanityClient,
|
|
7
12
|
translationMetadata: SanityDocumentLike,
|
|
13
|
+
sourceDocumentId: string,
|
|
8
14
|
languageField: string = 'language'
|
|
9
|
-
): void
|
|
15
|
+
): Promise<void> {
|
|
10
16
|
translatedDoc[languageField] = localeId;
|
|
11
17
|
const translations = translationMetadata.translations as Record<
|
|
12
18
|
string,
|
|
@@ -22,26 +28,54 @@ export const createI18nDocAndPatchMetadata = (
|
|
|
22
28
|
|
|
23
29
|
//remove system fields
|
|
24
30
|
const { _updatedAt, _createdAt, ...rest } = translatedDoc;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
31
|
+
|
|
32
|
+
const appliedDocument = applyDocuments(
|
|
33
|
+
sourceDocumentId,
|
|
34
|
+
sourceDocument,
|
|
35
|
+
rest,
|
|
36
|
+
pluginConfig.getIgnoreFields()
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
// Check if this is a singleton document and apply singleton mapping
|
|
40
|
+
const singletons = pluginConfig.getSingletons();
|
|
41
|
+
const isSingleton = singletons.includes(sourceDocumentId);
|
|
42
|
+
|
|
43
|
+
let createDocumentPromise;
|
|
44
|
+
if (isSingleton) {
|
|
45
|
+
const singletonMapping = pluginConfig.getSingletonMapping();
|
|
46
|
+
const translatedDocId = singletonMapping(sourceDocumentId, localeId);
|
|
47
|
+
createDocumentPromise = client.create({
|
|
48
|
+
...appliedDocument,
|
|
49
|
+
_type: rest._type,
|
|
50
|
+
_id: `drafts.${translatedDocId}`,
|
|
51
|
+
});
|
|
52
|
+
} else {
|
|
53
|
+
createDocumentPromise = client.create({
|
|
54
|
+
...appliedDocument,
|
|
55
|
+
_type: rest._type,
|
|
56
|
+
_id: 'drafts.',
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const doc = await createDocumentPromise;
|
|
61
|
+
const _ref = doc._id.replace('drafts.', '');
|
|
62
|
+
const result = await client
|
|
63
|
+
.transaction()
|
|
64
|
+
.patch(translationMetadata._id, (p) =>
|
|
65
|
+
p.insert(operation, location, [
|
|
66
|
+
{
|
|
67
|
+
_key: localeId,
|
|
68
|
+
_type: 'internationalizedArrayReferenceValue',
|
|
69
|
+
value: {
|
|
70
|
+
_type: 'reference',
|
|
71
|
+
_ref,
|
|
72
|
+
_weak: true,
|
|
73
|
+
_strengthenOnPublish: {
|
|
74
|
+
type: doc._type,
|
|
41
75
|
},
|
|
42
76
|
},
|
|
43
|
-
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
77
|
+
},
|
|
78
|
+
])
|
|
79
|
+
)
|
|
80
|
+
.commit();
|
|
81
|
+
}
|
|
@@ -1,25 +1,48 @@
|
|
|
1
|
+
// adapted from https://github.com/sanity-io/sanity-translations-tab. See LICENSE.md for more details.
|
|
2
|
+
|
|
1
3
|
import { SanityClient, SanityDocumentLike } from 'sanity';
|
|
4
|
+
import { applyDocuments } from '../../../utils/applyDocuments';
|
|
5
|
+
import { pluginConfig } from '../../../adapter/core';
|
|
6
|
+
|
|
7
|
+
const SYSTEM_FIELDS = ['_id', '_rev', '_updatedAt', 'language'];
|
|
2
8
|
|
|
3
|
-
|
|
9
|
+
const isSystemField = (field: string) => SYSTEM_FIELDS.includes(field);
|
|
10
|
+
|
|
11
|
+
export async function patchI18nDoc(
|
|
12
|
+
sourceDocumentId: string,
|
|
4
13
|
i18nDocId: string,
|
|
14
|
+
sourceDocument: SanityDocumentLike,
|
|
5
15
|
mergedDocument: SanityDocumentLike,
|
|
6
16
|
translatedFields: Record<string, any>,
|
|
7
17
|
client: SanityClient
|
|
8
|
-
): void
|
|
18
|
+
): Promise<void> {
|
|
9
19
|
const cleanedMerge: Record<string, any> = {};
|
|
10
20
|
Object.entries(mergedDocument).forEach(([key, value]) => {
|
|
11
21
|
if (
|
|
12
22
|
//only patch those fields that had translated strings
|
|
13
23
|
key in translatedFields &&
|
|
14
24
|
//don't overwrite any existing system values on the i18n doc
|
|
15
|
-
!
|
|
25
|
+
!isSystemField(key)
|
|
16
26
|
) {
|
|
17
27
|
cleanedMerge[key] = value;
|
|
18
28
|
}
|
|
19
29
|
});
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
30
|
+
const cleanedSourceDocument: Record<string, any> = {};
|
|
31
|
+
Object.entries(sourceDocument).forEach(([key, value]) => {
|
|
32
|
+
if (
|
|
33
|
+
// extract only the fields that are not system fields
|
|
34
|
+
!isSystemField(key)
|
|
35
|
+
) {
|
|
36
|
+
cleanedSourceDocument[key] = value;
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
const appliedDocument = applyDocuments(
|
|
40
|
+
sourceDocumentId,
|
|
41
|
+
cleanedSourceDocument,
|
|
42
|
+
cleanedMerge,
|
|
43
|
+
pluginConfig.getIgnoreFields()
|
|
44
|
+
);
|
|
45
|
+
const newDocument = await client
|
|
46
|
+
.patch(i18nDocId, { set: appliedDocument })
|
|
24
47
|
.commit();
|
|
25
|
-
}
|
|
48
|
+
}
|
|
@@ -1,53 +1,26 @@
|
|
|
1
|
+
// adapted from https://github.com/sanity-io/sanity-translations-tab. See LICENSE.md for more details.
|
|
2
|
+
|
|
1
3
|
import {
|
|
2
4
|
ExportForTranslation,
|
|
3
5
|
GTSerializedDocument,
|
|
4
6
|
ImportTranslation,
|
|
5
7
|
} from '../../types';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
BaseDocumentDeserializer,
|
|
12
|
-
BaseDocumentSerializer,
|
|
13
|
-
defaultStopTypes,
|
|
14
|
-
customSerializers,
|
|
15
|
-
customBlockDeserializers,
|
|
16
|
-
} from 'sanity-naive-html-serializer';
|
|
17
|
-
import { gtConfig } from '../../adapter/core';
|
|
8
|
+
import { findLatestDraft } from '../utils/findLatestDraft';
|
|
9
|
+
import { pluginConfig } from '../../adapter/core';
|
|
10
|
+
import { importDocument } from '../../translation/importDocument';
|
|
11
|
+
import { serializeDocument } from '../../utils/serialize';
|
|
18
12
|
|
|
19
13
|
export const baseDocumentLevelConfig = {
|
|
20
14
|
exportForTranslation: async (
|
|
21
|
-
|
|
15
|
+
docInfo: Parameters<ExportForTranslation>[0],
|
|
16
|
+
context: Parameters<ExportForTranslation>[1]
|
|
22
17
|
): Promise<GTSerializedDocument> => {
|
|
23
|
-
const [
|
|
24
|
-
docInfo,
|
|
25
|
-
context,
|
|
26
|
-
serializationOptions = {},
|
|
27
|
-
languageField = 'language',
|
|
28
|
-
] = params;
|
|
29
18
|
const { client, schema } = context;
|
|
30
|
-
const
|
|
31
|
-
...(serializationOptions.additionalStopTypes ?? []),
|
|
32
|
-
...defaultStopTypes,
|
|
33
|
-
];
|
|
34
|
-
const serializers = {
|
|
35
|
-
...customSerializers,
|
|
36
|
-
types: {
|
|
37
|
-
...customSerializers.types,
|
|
38
|
-
...(serializationOptions.additionalSerializers ?? {}),
|
|
39
|
-
},
|
|
40
|
-
};
|
|
19
|
+
const languageField = pluginConfig.getLanguageField();
|
|
41
20
|
const doc = await findLatestDraft(docInfo.documentId, client);
|
|
42
21
|
delete doc[languageField];
|
|
43
|
-
const baseLanguage =
|
|
44
|
-
const serialized =
|
|
45
|
-
doc,
|
|
46
|
-
'document',
|
|
47
|
-
baseLanguage,
|
|
48
|
-
stopTypes,
|
|
49
|
-
serializers
|
|
50
|
-
);
|
|
22
|
+
const baseLanguage = pluginConfig.getSourceLocale();
|
|
23
|
+
const serialized = serializeDocument(doc, schema, baseLanguage);
|
|
51
24
|
return {
|
|
52
25
|
content: serialized.content,
|
|
53
26
|
documentId: docInfo.documentId,
|
|
@@ -55,75 +28,19 @@ export const baseDocumentLevelConfig = {
|
|
|
55
28
|
};
|
|
56
29
|
},
|
|
57
30
|
importTranslation: (
|
|
58
|
-
|
|
31
|
+
docInfo: Parameters<ImportTranslation>[0],
|
|
32
|
+
localeId: Parameters<ImportTranslation>[1],
|
|
33
|
+
document: Parameters<ImportTranslation>[2],
|
|
34
|
+
context: Parameters<ImportTranslation>[3],
|
|
35
|
+
mergeWithTargetLocale: boolean = false
|
|
59
36
|
): Promise<void> => {
|
|
60
|
-
|
|
37
|
+
return importDocument(
|
|
61
38
|
docInfo,
|
|
62
39
|
localeId,
|
|
63
40
|
document,
|
|
64
41
|
context,
|
|
65
|
-
serializationOptions = {},
|
|
66
|
-
languageField = 'language',
|
|
67
|
-
mergeWithTargetLocale = false,
|
|
68
|
-
] = params;
|
|
69
|
-
const { client } = context;
|
|
70
|
-
const deserializers = {
|
|
71
|
-
types: {
|
|
72
|
-
...(serializationOptions.additionalDeserializers ?? {}),
|
|
73
|
-
},
|
|
74
|
-
};
|
|
75
|
-
const blockDeserializers = [
|
|
76
|
-
...(serializationOptions.additionalBlockDeserializers ?? []),
|
|
77
|
-
...customBlockDeserializers,
|
|
78
|
-
];
|
|
79
|
-
|
|
80
|
-
const deserialized = BaseDocumentDeserializer.deserializeDocument(
|
|
81
|
-
document,
|
|
82
|
-
deserializers,
|
|
83
|
-
blockDeserializers
|
|
84
|
-
) as SanityDocument;
|
|
85
|
-
return documentLevelPatch(
|
|
86
|
-
docInfo, // versionId is not used here, since we just use the _rev id in the deserialized HTML itself
|
|
87
|
-
deserialized,
|
|
88
|
-
localeId,
|
|
89
|
-
client,
|
|
90
|
-
languageField,
|
|
91
42
|
mergeWithTargetLocale
|
|
92
43
|
);
|
|
93
44
|
},
|
|
94
|
-
secretsNamespace: '
|
|
45
|
+
secretsNamespace: 'generaltranslation',
|
|
95
46
|
};
|
|
96
|
-
|
|
97
|
-
export const legacyDocumentLevelConfig = {
|
|
98
|
-
...baseDocumentLevelConfig,
|
|
99
|
-
importTranslation: (
|
|
100
|
-
...params: Parameters<ImportTranslation>
|
|
101
|
-
): Promise<void> => {
|
|
102
|
-
const [docInfo, localeId, document, context, serializationOptions = {}] =
|
|
103
|
-
params;
|
|
104
|
-
const { client } = context;
|
|
105
|
-
const deserializers = {
|
|
106
|
-
types: {
|
|
107
|
-
...(serializationOptions.additionalDeserializers ?? {}),
|
|
108
|
-
},
|
|
109
|
-
};
|
|
110
|
-
const blockDeserializers = [
|
|
111
|
-
...(serializationOptions.additionalBlockDeserializers ?? []),
|
|
112
|
-
...customBlockDeserializers,
|
|
113
|
-
];
|
|
114
|
-
|
|
115
|
-
const deserialized = BaseDocumentDeserializer.deserializeDocument(
|
|
116
|
-
document,
|
|
117
|
-
deserializers,
|
|
118
|
-
blockDeserializers
|
|
119
|
-
) as SanityDocument;
|
|
120
|
-
return legacyDocumentLevelPatch(
|
|
121
|
-
docInfo, // versionId is not used here, since we just use the _rev id in the deserialized HTML itself
|
|
122
|
-
deserialized,
|
|
123
|
-
localeId,
|
|
124
|
-
client
|
|
125
|
-
);
|
|
126
|
-
},
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
export { documentLevelPatch, legacyDocumentLevelPatch };
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// adapted from https://github.com/sanity-io/sanity-translations-tab. See LICENSE.md for more details.
|
|
2
|
+
|
|
1
3
|
import { SanityClient, SanityDocument } from 'sanity';
|
|
2
4
|
import {
|
|
3
5
|
BaseDocumentSerializer,
|
|
@@ -6,7 +8,7 @@ import {
|
|
|
6
8
|
defaultStopTypes,
|
|
7
9
|
customSerializers,
|
|
8
10
|
customBlockDeserializers,
|
|
9
|
-
} from '
|
|
11
|
+
} from '../serialization/';
|
|
10
12
|
|
|
11
13
|
import type {
|
|
12
14
|
ExportForTranslation,
|
|
@@ -14,8 +16,10 @@ import type {
|
|
|
14
16
|
GTSerializedDocument,
|
|
15
17
|
ImportTranslation,
|
|
16
18
|
} from '../types';
|
|
17
|
-
import { findLatestDraft
|
|
18
|
-
import {
|
|
19
|
+
import { findLatestDraft } from './utils/findLatestDraft';
|
|
20
|
+
import { findDocumentAtRevision } from './utils/findDocumentAtRevision';
|
|
21
|
+
import { pluginConfig } from '../adapter/core';
|
|
22
|
+
import { deserializeDocument, serializeDocument } from '../utils/serialize';
|
|
19
23
|
|
|
20
24
|
export const fieldLevelPatch = async (
|
|
21
25
|
docInfo: GTFile,
|
|
@@ -25,7 +29,7 @@ export const fieldLevelPatch = async (
|
|
|
25
29
|
mergeWithTargetLocale: boolean = false
|
|
26
30
|
): Promise<void> => {
|
|
27
31
|
let baseDoc: SanityDocument;
|
|
28
|
-
const baseLanguage =
|
|
32
|
+
const baseLanguage = pluginConfig.getSourceLocale();
|
|
29
33
|
if (docInfo.documentId && docInfo.versionId) {
|
|
30
34
|
baseDoc = await findDocumentAtRevision(
|
|
31
35
|
docInfo.documentId,
|
|
@@ -48,30 +52,13 @@ export const fieldLevelPatch = async (
|
|
|
48
52
|
|
|
49
53
|
export const baseFieldLevelConfig = {
|
|
50
54
|
exportForTranslation: async (
|
|
51
|
-
|
|
55
|
+
docInfo: Parameters<ExportForTranslation>[0],
|
|
56
|
+
context: Parameters<ExportForTranslation>[1]
|
|
52
57
|
): Promise<GTSerializedDocument> => {
|
|
53
|
-
const
|
|
54
|
-
const baseLanguage = gtConfig.getSourceLocale();
|
|
58
|
+
const baseLanguage = pluginConfig.getSourceLocale();
|
|
55
59
|
const { client, schema } = context;
|
|
56
|
-
const stopTypes = [
|
|
57
|
-
...(serializationOptions.additionalStopTypes ?? []),
|
|
58
|
-
...defaultStopTypes,
|
|
59
|
-
];
|
|
60
|
-
const serializers = {
|
|
61
|
-
...customSerializers,
|
|
62
|
-
types: {
|
|
63
|
-
...customSerializers.types,
|
|
64
|
-
...(serializationOptions.additionalSerializers ?? {}),
|
|
65
|
-
},
|
|
66
|
-
};
|
|
67
60
|
const doc = await findLatestDraft(docInfo.documentId, client);
|
|
68
|
-
const serialized =
|
|
69
|
-
doc,
|
|
70
|
-
'field',
|
|
71
|
-
baseLanguage,
|
|
72
|
-
stopTypes,
|
|
73
|
-
serializers
|
|
74
|
-
);
|
|
61
|
+
const serialized = serializeDocument(doc, schema, baseLanguage);
|
|
75
62
|
return {
|
|
76
63
|
content: serialized.content,
|
|
77
64
|
documentId: docInfo.documentId,
|
|
@@ -79,33 +66,14 @@ export const baseFieldLevelConfig = {
|
|
|
79
66
|
};
|
|
80
67
|
},
|
|
81
68
|
importTranslation: (
|
|
82
|
-
|
|
69
|
+
docInfo: Parameters<ImportTranslation>[0],
|
|
70
|
+
localeId: Parameters<ImportTranslation>[1],
|
|
71
|
+
document: Parameters<ImportTranslation>[2],
|
|
72
|
+
context: Parameters<ImportTranslation>[3],
|
|
73
|
+
mergeWithTargetLocale: boolean = false
|
|
83
74
|
): Promise<void> => {
|
|
84
|
-
const [
|
|
85
|
-
docInfo,
|
|
86
|
-
localeId,
|
|
87
|
-
document,
|
|
88
|
-
context,
|
|
89
|
-
serializationOptions = {},
|
|
90
|
-
,
|
|
91
|
-
mergeWithTargetLocale,
|
|
92
|
-
] = params;
|
|
93
75
|
const { client } = context;
|
|
94
|
-
const
|
|
95
|
-
types: {
|
|
96
|
-
...(serializationOptions.additionalDeserializers ?? {}),
|
|
97
|
-
},
|
|
98
|
-
};
|
|
99
|
-
const blockDeserializers = [
|
|
100
|
-
...(serializationOptions.additionalBlockDeserializers ?? []),
|
|
101
|
-
...customBlockDeserializers,
|
|
102
|
-
];
|
|
103
|
-
|
|
104
|
-
const deserialized = BaseDocumentDeserializer.deserializeDocument(
|
|
105
|
-
document,
|
|
106
|
-
deserializers,
|
|
107
|
-
blockDeserializers
|
|
108
|
-
) as SanityDocument;
|
|
76
|
+
const deserialized = deserializeDocument(document);
|
|
109
77
|
return fieldLevelPatch(
|
|
110
78
|
docInfo,
|
|
111
79
|
deserialized,
|
|
@@ -114,5 +82,5 @@ export const baseFieldLevelConfig = {
|
|
|
114
82
|
mergeWithTargetLocale
|
|
115
83
|
);
|
|
116
84
|
},
|
|
117
|
-
secretsNamespace: '
|
|
85
|
+
secretsNamespace: 'generaltranslation',
|
|
118
86
|
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// adapted from https://github.com/sanity-io/sanity-translations-tab. See LICENSE.md for more details.
|
|
2
|
+
|
|
1
3
|
export const checkSerializationVersion = (HTMLdoc: string): string | null => {
|
|
2
4
|
const parser = new DOMParser();
|
|
3
5
|
const node = parser.parseFromString(HTMLdoc, 'text/html');
|
package/src/hooks/useClient.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
// adapted from https://github.com/sanity-io/sanity-translations-tab. See LICENSE.md for more details.
|
|
2
|
+
|
|
1
3
|
import { SanityClient, useClient as useSanityClient } from 'sanity';
|
|
2
4
|
|
|
3
5
|
export const useClient = (): SanityClient => {
|
|
4
|
-
return useSanityClient({ apiVersion: '
|
|
6
|
+
return useSanityClient({ apiVersion: '2025-09-15' });
|
|
5
7
|
};
|
package/src/hooks/useSecrets.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import TranslationsTab from './components/TranslationsTab';
|
|
1
|
+
import TranslationsTab from './components/tab/TranslationsTab';
|
|
2
2
|
import {
|
|
3
3
|
Secrets,
|
|
4
4
|
Adapter,
|
|
@@ -6,17 +6,8 @@ import {
|
|
|
6
6
|
ImportTranslation,
|
|
7
7
|
TranslationFunctionContext,
|
|
8
8
|
TranslationsTabConfigOptions,
|
|
9
|
-
GTFile,
|
|
10
9
|
} from './types';
|
|
11
|
-
import {
|
|
12
|
-
baseDocumentLevelConfig,
|
|
13
|
-
legacyDocumentLevelConfig as baseLegacyDocumentLevelConfig,
|
|
14
|
-
legacyDocumentLevelPatch,
|
|
15
|
-
baseFieldLevelConfig,
|
|
16
|
-
findLatestDraft,
|
|
17
|
-
documentLevelPatch,
|
|
18
|
-
fieldLevelPatch,
|
|
19
|
-
} from './configuration';
|
|
10
|
+
import { findLatestDraft } from './configuration/utils/findLatestDraft';
|
|
20
11
|
import {
|
|
21
12
|
BaseDocumentSerializer,
|
|
22
13
|
BaseDocumentDeserializer,
|
|
@@ -24,7 +15,7 @@ import {
|
|
|
24
15
|
defaultStopTypes,
|
|
25
16
|
customSerializers,
|
|
26
17
|
SerializedDocument,
|
|
27
|
-
} from '
|
|
18
|
+
} from './serialization';
|
|
28
19
|
|
|
29
20
|
export type {
|
|
30
21
|
Secrets,
|
|
@@ -39,63 +30,50 @@ export {
|
|
|
39
30
|
TranslationsTab,
|
|
40
31
|
//helpers for end developers who may need to customize serialization
|
|
41
32
|
findLatestDraft,
|
|
42
|
-
legacyDocumentLevelPatch,
|
|
43
|
-
documentLevelPatch,
|
|
44
|
-
fieldLevelPatch,
|
|
45
33
|
BaseDocumentSerializer,
|
|
46
34
|
BaseDocumentDeserializer,
|
|
47
35
|
BaseDocumentMerger,
|
|
48
36
|
defaultStopTypes,
|
|
49
37
|
customSerializers,
|
|
38
|
+
attachGTData,
|
|
39
|
+
detachGTData,
|
|
50
40
|
};
|
|
51
41
|
|
|
52
|
-
import { GTAdapter } from './adapter';
|
|
53
42
|
import { definePlugin } from 'sanity';
|
|
54
|
-
import {
|
|
55
|
-
import {
|
|
43
|
+
import { route } from 'sanity/router';
|
|
44
|
+
import { gt, pluginConfig } from './adapter/core';
|
|
56
45
|
import { libraryDefaultLocale } from 'generaltranslation/internal';
|
|
46
|
+
import type { IgnoreFields, TranslateDocumentFilter } from './adapter/types';
|
|
47
|
+
import TranslationsTool from './components/page/TranslationsTool';
|
|
48
|
+
import { SECRETS_NAMESPACE } from './utils/shared';
|
|
49
|
+
import type { PortableTextHtmlComponents } from '@portabletext/to-html';
|
|
50
|
+
import { attachGTData, detachGTData } from './serialization/data';
|
|
57
51
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
adapter: GTAdapter,
|
|
76
|
-
secretsNamespace: 'generaltranslation',
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
export const legacyDocumentLevelConfig: ConfigOptions = {
|
|
80
|
-
...baseLegacyDocumentLevelConfig,
|
|
81
|
-
adapter: GTAdapter,
|
|
82
|
-
secretsNamespace: 'generaltranslation',
|
|
52
|
+
export type GTPluginConfig = Omit<
|
|
53
|
+
Parameters<typeof gt.setConfig>[0],
|
|
54
|
+
'locales'
|
|
55
|
+
> & {
|
|
56
|
+
locales: string[];
|
|
57
|
+
singletons?: string[];
|
|
58
|
+
// Optional mapping function to map source document ids to translated singleton document ids
|
|
59
|
+
// By default, the translated singleton document is is `${sourceDocumentId}-${locale}`
|
|
60
|
+
singletonMapping?: (sourceDocumentId: string, locale: string) => string;
|
|
61
|
+
ignoreFields?: IgnoreFields[];
|
|
62
|
+
languageField?: string;
|
|
63
|
+
translateDocuments?: TranslateDocumentFilter[];
|
|
64
|
+
secretsNamespace?: string;
|
|
65
|
+
additionalStopTypes?: string[];
|
|
66
|
+
additionalSerializers?: Partial<PortableTextHtmlComponents>;
|
|
67
|
+
additionalDeserializers?: Record<string, any>;
|
|
68
|
+
additionalBlockDeserializers?: any[];
|
|
83
69
|
};
|
|
84
70
|
|
|
85
|
-
export const defaultFieldLevelConfig: ConfigOptions = {
|
|
86
|
-
...baseFieldLevelConfig,
|
|
87
|
-
adapter: GTAdapter,
|
|
88
|
-
secretsNamespace: 'generaltranslation',
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
export { GTAdapter };
|
|
92
|
-
|
|
93
71
|
/**
|
|
94
72
|
* Usage in `sanity.config.ts` (or .js)
|
|
95
73
|
*
|
|
96
74
|
* ```ts
|
|
97
75
|
* import {defineConfig} from 'sanity'
|
|
98
|
-
* import {gtPlugin} from '
|
|
76
|
+
* import {gtPlugin} from 'gt-sanity'
|
|
99
77
|
*
|
|
100
78
|
* export default defineConfig({
|
|
101
79
|
* // ...
|
|
@@ -103,18 +81,64 @@ export { GTAdapter };
|
|
|
103
81
|
* })
|
|
104
82
|
* ```
|
|
105
83
|
*/
|
|
106
|
-
export const gtPlugin = definePlugin<
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
84
|
+
export const gtPlugin = definePlugin<GTPluginConfig>(
|
|
85
|
+
({
|
|
86
|
+
languageField = 'language',
|
|
87
|
+
sourceLocale = libraryDefaultLocale,
|
|
88
|
+
locales,
|
|
89
|
+
customMapping,
|
|
90
|
+
apiKey,
|
|
91
|
+
projectId,
|
|
92
|
+
singletons,
|
|
93
|
+
singletonMapping,
|
|
94
|
+
ignoreFields,
|
|
95
|
+
translateDocuments,
|
|
96
|
+
secretsNamespace = SECRETS_NAMESPACE,
|
|
97
|
+
additionalStopTypes = [],
|
|
98
|
+
additionalSerializers = {},
|
|
99
|
+
additionalDeserializers = {},
|
|
100
|
+
additionalBlockDeserializers = [],
|
|
101
|
+
}) => {
|
|
102
|
+
// Validate the translateDocuments
|
|
103
|
+
translateDocuments = translateDocuments?.filter((filter) => {
|
|
104
|
+
if (filter.documentId || filter.type) {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
return false;
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
pluginConfig.init(
|
|
111
|
+
secretsNamespace,
|
|
112
|
+
languageField,
|
|
113
|
+
sourceLocale,
|
|
114
|
+
locales,
|
|
115
|
+
singletons || [],
|
|
116
|
+
// singletons is a string array of singleton document ids
|
|
117
|
+
singletonMapping ||
|
|
118
|
+
((sourceDocumentId, locale) => `${sourceDocumentId}-${locale}`),
|
|
119
|
+
ignoreFields || [],
|
|
120
|
+
translateDocuments || [],
|
|
121
|
+
additionalStopTypes,
|
|
122
|
+
additionalSerializers,
|
|
123
|
+
additionalDeserializers,
|
|
124
|
+
additionalBlockDeserializers
|
|
125
|
+
);
|
|
126
|
+
gt.setConfig({
|
|
127
|
+
sourceLocale: sourceLocale,
|
|
128
|
+
customMapping: customMapping,
|
|
129
|
+
apiKey: apiKey,
|
|
130
|
+
projectId: projectId,
|
|
131
|
+
});
|
|
132
|
+
return {
|
|
133
|
+
name: 'gt-sanity',
|
|
134
|
+
tools: [
|
|
135
|
+
{
|
|
136
|
+
name: 'translations',
|
|
137
|
+
title: 'Translations',
|
|
138
|
+
component: TranslationsTool,
|
|
139
|
+
router: route.create('/*'),
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
);
|