@easyling/sanity-connector 1.4.0 → 2.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/README.md +560 -90
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -0
- package/package.json +38 -54
- package/LICENSE +0 -21
- package/dist/.tsbuildinfo +0 -1
- package/dist-types/actions/bulkTranslate.d.ts +0 -6
- package/dist-types/actions/manageDNTFields.d.ts +0 -11
- package/dist-types/actions/translateDocument.d.ts +0 -6
- package/dist-types/components/RadioWithDefault.d.ts +0 -16
- package/dist-types/components/auth/AuthNavbar.d.ts +0 -17
- package/dist-types/components/auth/AuthStatus.d.ts +0 -26
- package/dist-types/components/auth/AuthStatusWrapper.d.ts +0 -14
- package/dist-types/components/auth/MigrationPrompt.d.ts +0 -19
- package/dist-types/components/auth/MigrationPromptWrapper.d.ts +0 -13
- package/dist-types/components/auth/OAuthCallback.d.ts +0 -19
- package/dist-types/components/auth/index.d.ts +0 -14
- package/dist-types/components/config/LocaleConfigTool.d.ts +0 -16
- package/dist-types/components/config/LocaleConfigToolWrapper.d.ts +0 -12
- package/dist-types/components/config/OAuthConfig.d.ts +0 -25
- package/dist-types/components/config/OAuthConfigWrapper.d.ts +0 -12
- package/dist-types/components/config/PasswordInput.d.ts +0 -13
- package/dist-types/components/config/index.d.ts +0 -8
- package/dist-types/components/config/localeConfigToolDefinition.d.ts +0 -12
- package/dist-types/components/config/oauthConfigToolDefinition.d.ts +0 -12
- package/dist-types/components/dialogs/ConfirmationDialog.d.ts +0 -20
- package/dist-types/components/dialogs/ErrorDialog.d.ts +0 -20
- package/dist-types/components/dialogs/LocaleSelectionDialog.d.ts +0 -62
- package/dist-types/components/dialogs/SuccessDialog.d.ts +0 -18
- package/dist-types/components/dialogs/index.d.ts +0 -11
- package/dist-types/components/dnt/DNTFieldBadge.d.ts +0 -15
- package/dist-types/components/dnt/DNTFieldComponent.d.ts +0 -16
- package/dist-types/components/dnt/DNTFieldInput.d.ts +0 -13
- package/dist-types/components/dnt/DebugDNTBadge.d.ts +0 -19
- package/dist-types/components/dnt/index.d.ts +0 -7
- package/dist-types/config/index.d.ts +0 -5
- package/dist-types/config/pluginConfig.d.ts +0 -162
- package/dist-types/index.d.ts +0 -11
- package/dist-types/plugin.d.ts +0 -12
- package/dist-types/services/authStateManager.d.ts +0 -93
- package/dist-types/services/collisionDetectionService.d.ts +0 -85
- package/dist-types/services/contentExtractor.d.ts +0 -161
- package/dist-types/services/dialogService.d.ts +0 -95
- package/dist-types/services/dntServiceManager.d.ts +0 -43
- package/dist-types/services/dntStorageAdapter.d.ts +0 -72
- package/dist-types/services/documentCreationService.d.ts +0 -262
- package/dist-types/services/localeService.d.ts +0 -159
- package/dist-types/services/localeStorageAdapter.d.ts +0 -41
- package/dist-types/services/oauthConfigStorage.d.ts +0 -45
- package/dist-types/services/oauthService.d.ts +0 -47
- package/dist-types/services/oauthServiceManager.d.ts +0 -195
- package/dist-types/services/tokenStorage.d.ts +0 -53
- package/dist-types/services/translationService.d.ts +0 -385
- package/dist-types/services/unifiedConfigStorage.d.ts +0 -158
- package/dist-types/test-utils.d.ts +0 -8
- package/dist-types/types/dialog.d.ts +0 -118
- package/dist-types/types/dnt.d.ts +0 -83
- package/dist-types/types/index.d.ts +0 -11
- package/dist-types/types/locale.d.ts +0 -115
- package/dist-types/types/oauth.d.ts +0 -89
- package/dist-types/types/pluginConfig.d.ts +0 -64
- package/dist-types/types/translation.d.ts +0 -121
- package/dist-types/utils/dntDefaults.d.ts +0 -101
- package/dist-types/utils/htmlFormatter.d.ts +0 -65
- package/dist-types/utils/index.d.ts +0 -16
- package/dist-types/utils/logger.d.ts +0 -104
- package/dist-types/utils/oauthErrorFeedback.d.ts +0 -75
- package/dist-types/utils/oauthLogger.d.ts +0 -175
- package/dist-types/utils/validator.d.ts +0 -66
package/README.md
CHANGED
|
@@ -1,154 +1,624 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @easyling/sanity-connector
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Sanity Studio v3 plugin for document translation with Easyling. Provides UI-based translation functionality with support for single document translation, bulk operations, and granular control over translatable content.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **Single Document Translation**: Translate individual documents directly from the document form
|
|
8
|
-
- **Bulk Translation**: Batch process multiple documents via a dedicated tool
|
|
9
|
-
- **Smart Content Extraction**: Converts Sanity Portable Text to HTML for translation and back again
|
|
10
|
-
- **Translation Collision Handling**: Intelligent detection and resolution when re-translating to the same locale
|
|
11
|
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
- **
|
|
17
|
-
- **
|
|
18
|
-
- **Progress Tracking**: Real-time feedback for long-running bulk operations.
|
|
7
|
+
- **Single Document Translation**: Translate individual documents directly from the document form
|
|
8
|
+
- **Bulk Translation Tool**: Batch process multiple documents via a dedicated tool
|
|
9
|
+
- **Smart Content Extraction**: Converts Sanity Portable Text to HTML for translation and back again
|
|
10
|
+
- **Translation Collision Handling**: Intelligent detection and resolution when re-translating to the same locale
|
|
11
|
+
- **Do Not Translate (DNT) Control**: Granular field-level control over what gets translated
|
|
12
|
+
- Inline badges for toggling translation status
|
|
13
|
+
- Dedicated field management action
|
|
14
|
+
- Smart defaults based on field types and names
|
|
15
|
+
- **OAuth Integration**: Secure authentication with translation services
|
|
16
|
+
- **Real-time Progress Tracking**: Visual feedback for long-running operations
|
|
17
|
+
- **Debug Mode**: Detailed field information for troubleshooting
|
|
19
18
|
|
|
20
19
|
## Installation
|
|
21
20
|
|
|
22
|
-
Install the plugin in your Sanity Studio project:
|
|
23
|
-
|
|
24
21
|
```bash
|
|
25
|
-
npm install sanity-
|
|
22
|
+
npm install @easyling/sanity-connector
|
|
26
23
|
```
|
|
27
24
|
|
|
28
|
-
|
|
25
|
+
### Peer Dependencies
|
|
26
|
+
|
|
27
|
+
The plugin requires the following peer dependencies:
|
|
28
|
+
|
|
29
|
+
- `sanity` ^3.0.0
|
|
30
|
+
- `react` ^18.0.0
|
|
31
|
+
- `react-dom` ^18.0.0
|
|
32
|
+
|
|
33
|
+
These are typically already installed in your Sanity Studio project.
|
|
34
|
+
|
|
35
|
+
## Setup
|
|
36
|
+
|
|
37
|
+
### Basic Configuration
|
|
38
|
+
|
|
39
|
+
Add the plugin to your `sanity.config.ts` or `sanity.config.js`:
|
|
29
40
|
|
|
30
41
|
```typescript
|
|
31
42
|
import { defineConfig } from 'sanity'
|
|
32
|
-
import translationPlugin from 'sanity-
|
|
43
|
+
import translationPlugin from '@easyling/sanity-connector'
|
|
33
44
|
|
|
34
45
|
export default defineConfig({
|
|
35
|
-
// ...
|
|
46
|
+
// ... other config
|
|
36
47
|
plugins: [
|
|
37
|
-
// ... other plugins
|
|
38
48
|
translationPlugin()
|
|
39
49
|
]
|
|
40
50
|
})
|
|
41
51
|
```
|
|
42
52
|
|
|
43
|
-
|
|
53
|
+
That's it! The plugin will automatically:
|
|
54
|
+
- Register document actions (Translate, Manage DNT Fields)
|
|
55
|
+
- Add the Bulk Translate tool to your Studio
|
|
56
|
+
- Create configuration document types
|
|
57
|
+
- Initialize services on Studio load
|
|
58
|
+
|
|
59
|
+
### Initial Configuration
|
|
60
|
+
|
|
61
|
+
After installing the plugin, you'll need to configure:
|
|
62
|
+
|
|
63
|
+
1. **OAuth Credentials** (required for translation)
|
|
64
|
+
2. **Target Locales** (languages to translate to)
|
|
65
|
+
3. **Translation API Endpoint** (optional, defaults to Easyling)
|
|
66
|
+
|
|
67
|
+
Configuration is stored in your Sanity dataset as an `EL_PluginConfiguration` document. You can configure through:
|
|
68
|
+
|
|
69
|
+
- The Studio UI (recommended)
|
|
70
|
+
- Direct document editing
|
|
71
|
+
- The UnifiedConfigStorage API
|
|
72
|
+
|
|
73
|
+
## Configuration Options
|
|
74
|
+
|
|
75
|
+
### OAuth Configuration
|
|
76
|
+
|
|
77
|
+
Configure authentication with your translation service:
|
|
78
|
+
|
|
79
|
+
1. Navigate to your Studio
|
|
80
|
+
2. Create or edit the `EL_PluginConfiguration` document
|
|
81
|
+
3. Fill in the OAuth section:
|
|
82
|
+
- **Project ID**: Your translation project identifier
|
|
83
|
+
- **Access Token**: Long-lived access token (hidden for security)
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
// Example: Programmatic configuration
|
|
87
|
+
import { UnifiedConfigStorage } from '@easyling/sanity-connector'
|
|
88
|
+
import { createClient } from 'sanity'
|
|
89
|
+
|
|
90
|
+
const client = createClient({
|
|
91
|
+
projectId: 'your-project-id',
|
|
92
|
+
dataset: 'production',
|
|
93
|
+
apiVersion: '2024-01-01',
|
|
94
|
+
token: 'your-token'
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
const configStorage = new UnifiedConfigStorage(client)
|
|
98
|
+
|
|
99
|
+
await configStorage.update({
|
|
100
|
+
projectId: 'your-easyling-project-id',
|
|
101
|
+
accessToken: 'your-access-token'
|
|
102
|
+
})
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Locale Configuration
|
|
106
|
+
|
|
107
|
+
Define which languages you want to translate to:
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
await configStorage.update({
|
|
111
|
+
locales: [
|
|
112
|
+
{
|
|
113
|
+
code: 'en',
|
|
114
|
+
title: 'English',
|
|
115
|
+
enabled: true,
|
|
116
|
+
isDefault: true
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
code: 'ja',
|
|
120
|
+
title: 'Japanese',
|
|
121
|
+
enabled: true,
|
|
122
|
+
isDefault: false
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
code: 'de',
|
|
126
|
+
title: 'German',
|
|
127
|
+
enabled: true,
|
|
128
|
+
isDefault: false
|
|
129
|
+
}
|
|
130
|
+
]
|
|
131
|
+
})
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Locale Fields:**
|
|
135
|
+
- `code`: Language code (e.g., 'en', 'ja-JP')
|
|
136
|
+
- `title`: Display name for the language
|
|
137
|
+
- `enabled`: Whether this locale is active for translation
|
|
138
|
+
- `isDefault`: Whether this is the source language (only one should be true)
|
|
139
|
+
|
|
140
|
+
### Translation API Configuration
|
|
141
|
+
|
|
142
|
+
Customize the translation service endpoint and format:
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
await configStorage.update({
|
|
146
|
+
translationApiEndpoint: 'https://api.easyling.com/translate',
|
|
147
|
+
requestContentType: 'application/x-protobuf', // or 'application/json'
|
|
148
|
+
responseAcceptHeader: 'application/x-protobuf' // or 'application/json'
|
|
149
|
+
})
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Default values:**
|
|
153
|
+
- Endpoint: Easyling translation API
|
|
154
|
+
- Content Type: `application/x-protobuf`
|
|
155
|
+
- Accept Header: `application/x-protobuf`
|
|
156
|
+
|
|
157
|
+
### Document Creation Options
|
|
158
|
+
|
|
159
|
+
Control how translated documents are created:
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
await configStorage.update({
|
|
163
|
+
defaultDocumentCreationMode: 'draft', // or 'published'
|
|
164
|
+
collisionResolutionMode: 'skip', // or 'replace', 'merge'
|
|
165
|
+
existingDocumentHandling: 'keep' // or 'archive', 'delete'
|
|
166
|
+
})
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Creation Modes:**
|
|
170
|
+
- `draft`: Create translated documents as drafts (recommended)
|
|
171
|
+
- `published`: Create translated documents as published
|
|
44
172
|
|
|
45
|
-
|
|
173
|
+
**Collision Resolution:**
|
|
174
|
+
- `skip`: Don't create if translation already exists
|
|
175
|
+
- `replace`: Overwrite existing translation
|
|
176
|
+
- `merge`: Merge with existing translation (preserves untranslated fields)
|
|
46
177
|
|
|
47
|
-
|
|
178
|
+
**Existing Document Handling:**
|
|
179
|
+
- `keep`: Keep existing document as-is
|
|
180
|
+
- `archive`: Move existing document to drafts
|
|
181
|
+
- `delete`: Delete existing document
|
|
48
182
|
|
|
49
|
-
|
|
50
|
-
- Uses secure token-based authentication.
|
|
51
|
-
- Configurable via the **OAuth Configuration** tool within Sanity Studio.
|
|
52
|
-
- Supports project-specific access control.
|
|
183
|
+
### DNT (Do Not Translate) Configuration
|
|
53
184
|
|
|
54
|
-
|
|
55
|
-
- Default behavior out of the box.
|
|
56
|
-
- Points to `http://app.easyling.com` by default.
|
|
57
|
-
- Useful for local development and testing without setting up full auth.
|
|
185
|
+
Configure which fields should not be translated by default:
|
|
58
186
|
|
|
59
|
-
|
|
187
|
+
```typescript
|
|
188
|
+
await configStorage.setDNTField('article', 'author.name', true)
|
|
189
|
+
await configStorage.setDNTField('article', 'publishDate', true)
|
|
190
|
+
```
|
|
60
191
|
|
|
61
|
-
|
|
192
|
+
The plugin automatically applies smart defaults for common non-translatable fields:
|
|
193
|
+
- Author names
|
|
194
|
+
- Dates and timestamps
|
|
195
|
+
- IDs and references
|
|
196
|
+
- Technical metadata
|
|
62
197
|
|
|
63
|
-
|
|
198
|
+
You can override these defaults on a per-field basis using the inline DNT badges or the Manage DNT Fields action.
|
|
64
199
|
|
|
65
|
-
###
|
|
200
|
+
### Debug Mode
|
|
66
201
|
|
|
67
|
-
|
|
202
|
+
Enable debug mode to see detailed field information:
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
await configStorage.update({
|
|
206
|
+
debugMode: true
|
|
207
|
+
})
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
When enabled, all fields will show debug badges with:
|
|
211
|
+
- Field path
|
|
212
|
+
- Field type
|
|
213
|
+
- DNT status (default and stored)
|
|
214
|
+
- Group/fieldset information
|
|
68
215
|
|
|
69
216
|
## Usage
|
|
70
217
|
|
|
71
218
|
### Single Document Translation
|
|
72
219
|
|
|
73
|
-
1.
|
|
74
|
-
2.
|
|
75
|
-
3.
|
|
76
|
-
4.
|
|
77
|
-
5.
|
|
220
|
+
1. Open any document in your Studio
|
|
221
|
+
2. Click the **Translate** button in the document toolbar
|
|
222
|
+
3. Select target languages
|
|
223
|
+
4. Configure translation options (creation mode, collision handling)
|
|
224
|
+
5. Click **Translate**
|
|
225
|
+
|
|
226
|
+
The plugin will:
|
|
227
|
+
- Extract translatable content from the document
|
|
228
|
+
- Send translation request to the configured API
|
|
229
|
+
- Create new documents for each target language
|
|
230
|
+
- Show progress and results
|
|
78
231
|
|
|
79
232
|
### Bulk Translation
|
|
80
233
|
|
|
81
|
-
1.
|
|
82
|
-
2.
|
|
83
|
-
3.
|
|
84
|
-
4.
|
|
85
|
-
5.
|
|
234
|
+
1. Open the **Bulk Translate** tool from the Studio tools menu
|
|
235
|
+
2. Select document type to translate
|
|
236
|
+
3. Choose documents (or select all)
|
|
237
|
+
4. Select target languages
|
|
238
|
+
5. Configure translation options
|
|
239
|
+
6. Click **Start Translation**
|
|
240
|
+
|
|
241
|
+
The tool provides:
|
|
242
|
+
- Real-time progress tracking
|
|
243
|
+
- Success/failure counts
|
|
244
|
+
- Detailed results for each document
|
|
245
|
+
- Rollback capability if needed
|
|
86
246
|
|
|
87
|
-
### Managing
|
|
247
|
+
### Managing DNT Fields
|
|
88
248
|
|
|
89
|
-
|
|
249
|
+
#### Inline Badges
|
|
90
250
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
-
|
|
94
|
-
-
|
|
95
|
-
Click the badge to toggle the status.
|
|
251
|
+
For translatable fields (string, text, array), you'll see a DNT badge:
|
|
252
|
+
- **Green badge**: Field will be translated
|
|
253
|
+
- **Red badge**: Field will NOT be translated
|
|
254
|
+
- Click the badge to toggle the DNT status
|
|
96
255
|
|
|
97
|
-
|
|
98
|
-
For a high-level view:
|
|
99
|
-
1. Click the document menu (three dots) in the top right.
|
|
100
|
-
2. Select **Manage Translation Fields**.
|
|
101
|
-
3. View and toggle the translation status for all fields in the document.
|
|
256
|
+
#### Manage DNT Fields Action
|
|
102
257
|
|
|
103
|
-
|
|
258
|
+
1. Open any document
|
|
259
|
+
2. Click **Manage DNT Fields** in the document toolbar
|
|
260
|
+
3. View all fields with their DNT status
|
|
261
|
+
4. Toggle individual fields or apply bulk changes
|
|
262
|
+
5. Save changes
|
|
104
263
|
|
|
105
|
-
|
|
264
|
+
The action shows:
|
|
265
|
+
- Field path and type
|
|
266
|
+
- Current DNT status
|
|
267
|
+
- Smart default recommendations
|
|
268
|
+
- Ability to reset to defaults
|
|
106
269
|
|
|
107
|
-
|
|
108
|
-
A collision is detected when a translated document already exists for the same source document and target locale. The plugin identifies existing translations by:
|
|
109
|
-
1. **Parent Reference**: Documents linked via `parentDocument._ref` to the source document.
|
|
110
|
-
2. **Slug + Locale**: Documents with matching slug and locale (as a fallback).
|
|
270
|
+
## Migration from Previous Version
|
|
111
271
|
|
|
112
|
-
|
|
272
|
+
If you're upgrading from the single-package version (pre-monorepo), follow these steps:
|
|
113
273
|
|
|
114
|
-
|
|
274
|
+
### 1. Update Package Name
|
|
115
275
|
|
|
116
|
-
|
|
117
|
-
- **Create new translated document**: Creates a new document with a unique ID. You can also specify what happens to the existing document:
|
|
118
|
-
- **Set existing document to draft**: Converts the existing published translation to a draft.
|
|
119
|
-
- **Delete existing document**: Permanently removes the existing translation.
|
|
276
|
+
The plugin package name remains the same, but the internal structure has changed:
|
|
120
277
|
|
|
121
|
-
|
|
278
|
+
```bash
|
|
279
|
+
# Uninstall old version
|
|
280
|
+
npm uninstall @easyling/sanity-connector
|
|
122
281
|
|
|
123
|
-
|
|
282
|
+
# Install new version
|
|
283
|
+
npm install @easyling/sanity-connector
|
|
284
|
+
```
|
|
124
285
|
|
|
125
|
-
|
|
126
|
-
2. Find the **Translation** settings group.
|
|
127
|
-
3. Set the **Default Collision Resolution Mode** (Replace or Create).
|
|
128
|
-
4. If using Create mode, set the **Existing Document Handling** preference (Draft or Delete).
|
|
286
|
+
### 2. Update Imports
|
|
129
287
|
|
|
130
|
-
|
|
288
|
+
Most imports remain the same, but some have moved to the shared library:
|
|
289
|
+
|
|
290
|
+
**Before:**
|
|
291
|
+
```typescript
|
|
292
|
+
import { UnifiedConfigStorage } from '@easyling/sanity-connector'
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
**After:**
|
|
296
|
+
```typescript
|
|
297
|
+
// Still works - re-exported from plugin
|
|
298
|
+
import { UnifiedConfigStorage } from '@easyling/sanity-connector'
|
|
299
|
+
|
|
300
|
+
// Or import directly from shared library
|
|
301
|
+
import { UnifiedConfigStorage } from '@easyling/sanity-connector-shared'
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### 3. Configuration Migration
|
|
305
|
+
|
|
306
|
+
The plugin automatically migrates legacy configuration documents:
|
|
307
|
+
|
|
308
|
+
- **Legacy OAuth Config** (`EL_oauth-config`) → Merged into `EL_PluginConfiguration`
|
|
309
|
+
- **Legacy Locale Config** (`EL_locale-config`) → Merged into `EL_PluginConfiguration`
|
|
310
|
+
|
|
311
|
+
Migration happens automatically on first load. Legacy documents are hidden from the UI but preserved for rollback if needed.
|
|
312
|
+
|
|
313
|
+
### 4. Verify Configuration
|
|
314
|
+
|
|
315
|
+
After migration, verify your configuration:
|
|
316
|
+
|
|
317
|
+
1. Open the `EL_PluginConfiguration` document in your Studio
|
|
318
|
+
2. Check that OAuth credentials are present
|
|
319
|
+
3. Verify locale settings
|
|
320
|
+
4. Test a translation to ensure everything works
|
|
321
|
+
|
|
322
|
+
### 5. Update Custom Code (if applicable)
|
|
323
|
+
|
|
324
|
+
If you have custom code using the plugin's APIs:
|
|
325
|
+
|
|
326
|
+
**Service Imports:**
|
|
327
|
+
```typescript
|
|
328
|
+
// Before
|
|
329
|
+
import { ContentExtractor } from '@easyling/sanity-connector/services'
|
|
330
|
+
|
|
331
|
+
// After - import from shared library
|
|
332
|
+
import { ContentExtractor } from '@easyling/sanity-connector-shared'
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
**Type Imports:**
|
|
336
|
+
```typescript
|
|
337
|
+
// Before
|
|
338
|
+
import type { TranslationRequest } from '@easyling/sanity-connector/types'
|
|
339
|
+
|
|
340
|
+
// After - still works, or use shared library
|
|
341
|
+
import type { TranslationRequest } from '@easyling/sanity-connector'
|
|
342
|
+
// or
|
|
343
|
+
import type { TranslationRequest } from '@easyling/sanity-connector-shared'
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### Breaking Changes
|
|
347
|
+
|
|
348
|
+
The monorepo restructuring introduces minimal breaking changes:
|
|
349
|
+
|
|
350
|
+
1. **Internal file structure**: If you were importing from internal paths (not recommended), update to use public exports
|
|
351
|
+
2. **Service initialization**: Some services now require explicit client initialization
|
|
352
|
+
3. **Configuration storage**: Legacy config documents are deprecated (but still supported)
|
|
353
|
+
|
|
354
|
+
### Rollback
|
|
355
|
+
|
|
356
|
+
If you need to rollback to the previous version:
|
|
357
|
+
|
|
358
|
+
```bash
|
|
359
|
+
npm install @easyling/sanity-connector@1.3.0
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
Your configuration will remain intact as the document structure hasn't changed.
|
|
363
|
+
|
|
364
|
+
## Advanced Usage
|
|
365
|
+
|
|
366
|
+
### Custom Translation Workflow
|
|
367
|
+
|
|
368
|
+
You can build custom translation workflows using the exported services:
|
|
369
|
+
|
|
370
|
+
```typescript
|
|
371
|
+
import {
|
|
372
|
+
ContentExtractor,
|
|
373
|
+
TranslationService,
|
|
374
|
+
DocumentCreationService,
|
|
375
|
+
UnifiedConfigStorage
|
|
376
|
+
} from '@easyling/sanity-connector-shared'
|
|
377
|
+
import { useClient } from 'sanity'
|
|
378
|
+
|
|
379
|
+
function MyCustomTranslationComponent() {
|
|
380
|
+
const client = useClient()
|
|
381
|
+
|
|
382
|
+
const handleCustomTranslation = async (document) => {
|
|
383
|
+
// Initialize services
|
|
384
|
+
const configStorage = new UnifiedConfigStorage(client)
|
|
385
|
+
const extractor = new ContentExtractor(client)
|
|
386
|
+
const translationService = new TranslationService(client)
|
|
387
|
+
const docCreationService = new DocumentCreationService(client)
|
|
388
|
+
|
|
389
|
+
// Load configuration
|
|
390
|
+
const config = await configStorage.load()
|
|
391
|
+
translationService.setEndpoint(config.translationApiEndpoint)
|
|
392
|
+
translationService.setAuthToken(config.accessToken, config.projectId)
|
|
393
|
+
|
|
394
|
+
// Extract content
|
|
395
|
+
const structured = await extractor.extractStructuredContent(
|
|
396
|
+
document,
|
|
397
|
+
configStorage
|
|
398
|
+
)
|
|
399
|
+
|
|
400
|
+
// Translate
|
|
401
|
+
const response = await translationService.translateDocument(
|
|
402
|
+
structured,
|
|
403
|
+
document._type,
|
|
404
|
+
'en',
|
|
405
|
+
undefined,
|
|
406
|
+
['ja', 'de']
|
|
407
|
+
)
|
|
408
|
+
|
|
409
|
+
// Create translated documents
|
|
410
|
+
for (const translatedDoc of response.translatedDocuments) {
|
|
411
|
+
await docCreationService.createDocumentFromTranslation(
|
|
412
|
+
document,
|
|
413
|
+
{ ...response, translatedDocuments: [translatedDoc] },
|
|
414
|
+
{
|
|
415
|
+
targetLanguage: translatedDoc.locale,
|
|
416
|
+
creationMode: 'draft'
|
|
417
|
+
}
|
|
418
|
+
)
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
return <button onClick={() => handleCustomTranslation(doc)}>Translate</button>
|
|
423
|
+
}
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### Custom DNT Logic
|
|
427
|
+
|
|
428
|
+
Implement custom DNT logic for your schema:
|
|
429
|
+
|
|
430
|
+
```typescript
|
|
431
|
+
import { DNTServiceManager } from '@easyling/sanity-connector'
|
|
432
|
+
import { useClient } from 'sanity'
|
|
433
|
+
|
|
434
|
+
function MyComponent() {
|
|
435
|
+
const client = useClient()
|
|
436
|
+
const dntService = DNTServiceManager.getInstance(client)
|
|
437
|
+
|
|
438
|
+
const checkDNTStatus = async (documentType, fieldPath) => {
|
|
439
|
+
const isDNT = await dntService.getDNTFieldStatus(documentType, fieldPath)
|
|
440
|
+
console.log(`Field ${fieldPath} is ${isDNT ? 'NOT' : ''} translatable`)
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
const setDNTStatus = async (documentType, fieldPath, isDNT) => {
|
|
444
|
+
await dntService.setDNTField(documentType, fieldPath, isDNT)
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
return <div>Custom DNT UI</div>
|
|
448
|
+
}
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
### Accessing Configuration
|
|
452
|
+
|
|
453
|
+
Access plugin configuration in your custom components:
|
|
454
|
+
|
|
455
|
+
```typescript
|
|
456
|
+
import { UnifiedConfigStorage } from '@easyling/sanity-connector'
|
|
457
|
+
import { useClient } from 'sanity'
|
|
458
|
+
import { useEffect, useState } from 'react'
|
|
459
|
+
|
|
460
|
+
function MyConfigComponent() {
|
|
461
|
+
const client = useClient()
|
|
462
|
+
const [config, setConfig] = useState(null)
|
|
463
|
+
|
|
464
|
+
useEffect(() => {
|
|
465
|
+
const loadConfig = async () => {
|
|
466
|
+
const configStorage = new UnifiedConfigStorage(client)
|
|
467
|
+
const cfg = await configStorage.load()
|
|
468
|
+
setConfig(cfg)
|
|
469
|
+
}
|
|
470
|
+
loadConfig()
|
|
471
|
+
}, [client])
|
|
472
|
+
|
|
473
|
+
return (
|
|
474
|
+
<div>
|
|
475
|
+
<h2>Current Configuration</h2>
|
|
476
|
+
<pre>{JSON.stringify(config, null, 2)}</pre>
|
|
477
|
+
</div>
|
|
478
|
+
)
|
|
479
|
+
}
|
|
480
|
+
```
|
|
131
481
|
|
|
132
482
|
## Troubleshooting
|
|
133
483
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
484
|
+
### Translation Fails with Authentication Error
|
|
485
|
+
|
|
486
|
+
**Problem**: Translation requests fail with 401 or 403 errors
|
|
487
|
+
|
|
488
|
+
**Solution**:
|
|
489
|
+
1. Verify OAuth credentials in `EL_PluginConfiguration`
|
|
490
|
+
2. Check that Project ID and Access Token are correct
|
|
491
|
+
3. Ensure access token hasn't expired
|
|
492
|
+
4. Contact your translation service provider for new credentials
|
|
493
|
+
|
|
494
|
+
### DNT Badges Not Showing
|
|
495
|
+
|
|
496
|
+
**Problem**: DNT badges don't appear on fields
|
|
497
|
+
|
|
498
|
+
**Solution**:
|
|
499
|
+
1. Check that the field type is translatable (string, text, array)
|
|
500
|
+
2. Verify the field isn't blacklisted (locale, _id, _type, etc.)
|
|
501
|
+
3. Enable debug mode to see all fields
|
|
502
|
+
4. Check browser console for errors
|
|
503
|
+
|
|
504
|
+
### Translated Documents Not Created
|
|
138
505
|
|
|
139
|
-
**Translation
|
|
140
|
-
- The action only appears on documents that have translatable fields defined in their schema.
|
|
506
|
+
**Problem**: Translation succeeds but no documents are created
|
|
141
507
|
|
|
142
|
-
**
|
|
143
|
-
|
|
144
|
-
|
|
508
|
+
**Solution**:
|
|
509
|
+
1. Check collision resolution mode - may be set to 'skip'
|
|
510
|
+
2. Verify you have write permissions in the dataset
|
|
511
|
+
3. Check browser console for document creation errors
|
|
512
|
+
4. Ensure target locale codes match your schema
|
|
513
|
+
|
|
514
|
+
### Bulk Translation Stalls
|
|
515
|
+
|
|
516
|
+
**Problem**: Bulk translation stops or hangs
|
|
517
|
+
|
|
518
|
+
**Solution**:
|
|
519
|
+
1. Check network connection
|
|
520
|
+
2. Verify translation API is responding
|
|
521
|
+
3. Try translating a single document to isolate the issue
|
|
522
|
+
4. Check browser console for errors
|
|
523
|
+
5. Reduce batch size if translating many documents
|
|
524
|
+
|
|
525
|
+
### Configuration Not Persisting
|
|
526
|
+
|
|
527
|
+
**Problem**: Configuration changes don't save
|
|
528
|
+
|
|
529
|
+
**Solution**:
|
|
530
|
+
1. Verify you have write permissions in the dataset
|
|
531
|
+
2. Check that `EL_PluginConfiguration` document exists
|
|
532
|
+
3. Look for validation errors in the Studio
|
|
533
|
+
4. Check browser console for save errors
|
|
534
|
+
|
|
535
|
+
### Migration Issues
|
|
536
|
+
|
|
537
|
+
**Problem**: Legacy configuration not migrated
|
|
538
|
+
|
|
539
|
+
**Solution**:
|
|
540
|
+
1. Check that legacy documents exist (`EL_oauth-config`, `EL_locale-config`)
|
|
541
|
+
2. Manually create `EL_PluginConfiguration` document
|
|
542
|
+
3. Copy values from legacy documents
|
|
543
|
+
4. Contact support if automatic migration fails
|
|
544
|
+
|
|
545
|
+
## API Reference
|
|
546
|
+
|
|
547
|
+
### Exported Components
|
|
548
|
+
|
|
549
|
+
- `DNTFieldBadge`: Standalone DNT badge component
|
|
550
|
+
- `withDNTBadge`: HOC for adding DNT badge to custom fields
|
|
551
|
+
- `DNTFieldInput`: Complete field input with DNT badge
|
|
552
|
+
|
|
553
|
+
### Exported Services
|
|
554
|
+
|
|
555
|
+
- `UnifiedConfigStorage`: Configuration management
|
|
556
|
+
- `DNTServiceManager`: DNT field management
|
|
557
|
+
- `DNTStorageAdapter`: DNT storage interface
|
|
558
|
+
- `LegacyDNTStorageAdapter`: Legacy DNT storage support
|
|
559
|
+
|
|
560
|
+
### Exported Types
|
|
561
|
+
|
|
562
|
+
```typescript
|
|
563
|
+
import type {
|
|
564
|
+
LocaleDefinition,
|
|
565
|
+
LocaleConfig,
|
|
566
|
+
TranslationRequestPayload,
|
|
567
|
+
TranslationResponse,
|
|
568
|
+
TranslatableField,
|
|
569
|
+
DNTFieldPreference,
|
|
570
|
+
DNTPreferences,
|
|
571
|
+
DNTTypeConfig,
|
|
572
|
+
DNTStorage,
|
|
573
|
+
UnifiedPluginConfig
|
|
574
|
+
} from '@easyling/sanity-connector'
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
See the [shared library documentation](../shared/README.md) for complete API reference.
|
|
578
|
+
|
|
579
|
+
## Development
|
|
580
|
+
|
|
581
|
+
### Building
|
|
582
|
+
|
|
583
|
+
```bash
|
|
584
|
+
npm run build # Production build
|
|
585
|
+
npm run dev # Development build with watch
|
|
586
|
+
npm run clean # Remove build artifacts
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
### Testing
|
|
590
|
+
|
|
591
|
+
```bash
|
|
592
|
+
npm test # Run all tests
|
|
593
|
+
npm run test:watch # Run tests in watch mode
|
|
594
|
+
npm run test:coverage # Generate coverage report
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
### Code Quality
|
|
598
|
+
|
|
599
|
+
```bash
|
|
600
|
+
npm run lint # Check for linting issues
|
|
601
|
+
npm run lint:fix # Auto-fix linting issues
|
|
602
|
+
npm run typecheck # Type check without emitting
|
|
603
|
+
```
|
|
145
604
|
|
|
146
605
|
## Support
|
|
147
606
|
|
|
148
|
-
|
|
607
|
+
For questions, issues, or feature requests:
|
|
149
608
|
|
|
150
|
-
**
|
|
609
|
+
- **Email**: support@easyling.com
|
|
610
|
+
- **Issues**: [GitHub Issues](https://github.com/easyling/el-sanity-connector/issues)
|
|
611
|
+
- **Documentation**: [Main README](../README.md) | [Shared Library](../shared/README.md)
|
|
151
612
|
|
|
152
613
|
## License
|
|
153
614
|
|
|
154
|
-
MIT
|
|
615
|
+
MIT
|
|
616
|
+
|
|
617
|
+
## Related Packages
|
|
618
|
+
|
|
619
|
+
- [@easyling/sanity-connector-shared](../shared/README.md) - Core translation logic
|
|
620
|
+
- [@easyling/sanity-function-auto-translate](../function/README.md) - Automatic translation on publish
|
|
621
|
+
|
|
622
|
+
## Changelog
|
|
623
|
+
|
|
624
|
+
See [CHANGELOG.md](CHANGELOG.md) for version history and migration notes.
|