@easyling/sanity-connector 0.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/LICENSE +21 -0
- package/README.md +482 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/actions/bulkTranslate.d.ts +7 -0
- package/dist/actions/bulkTranslate.d.ts.map +1 -0
- package/dist/actions/bulkTranslate.js +543 -0
- package/dist/actions/bulkTranslate.js.map +1 -0
- package/dist/actions/manageDNTFields.d.ts +12 -0
- package/dist/actions/manageDNTFields.d.ts.map +1 -0
- package/dist/actions/manageDNTFields.js +100 -0
- package/dist/actions/manageDNTFields.js.map +1 -0
- package/dist/actions/translateDocument.d.ts +7 -0
- package/dist/actions/translateDocument.d.ts.map +1 -0
- package/dist/actions/translateDocument.js +256 -0
- package/dist/actions/translateDocument.js.map +1 -0
- package/dist/components/RadioWithDefault.d.ts +17 -0
- package/dist/components/RadioWithDefault.d.ts.map +1 -0
- package/dist/components/RadioWithDefault.js +29 -0
- package/dist/components/RadioWithDefault.js.map +1 -0
- package/dist/components/auth/AuthNavbar.d.ts +18 -0
- package/dist/components/auth/AuthNavbar.d.ts.map +1 -0
- package/dist/components/auth/AuthNavbar.js +15 -0
- package/dist/components/auth/AuthNavbar.js.map +1 -0
- package/dist/components/auth/AuthStatus.d.ts +27 -0
- package/dist/components/auth/AuthStatus.d.ts.map +1 -0
- package/dist/components/auth/AuthStatus.js +82 -0
- package/dist/components/auth/AuthStatus.js.map +1 -0
- package/dist/components/auth/AuthStatusWrapper.d.ts +15 -0
- package/dist/components/auth/AuthStatusWrapper.d.ts.map +1 -0
- package/dist/components/auth/AuthStatusWrapper.js +39 -0
- package/dist/components/auth/AuthStatusWrapper.js.map +1 -0
- package/dist/components/auth/MigrationPrompt.d.ts +20 -0
- package/dist/components/auth/MigrationPrompt.d.ts.map +1 -0
- package/dist/components/auth/MigrationPrompt.js +16 -0
- package/dist/components/auth/MigrationPrompt.js.map +1 -0
- package/dist/components/auth/MigrationPromptWrapper.d.ts +14 -0
- package/dist/components/auth/MigrationPromptWrapper.d.ts.map +1 -0
- package/dist/components/auth/MigrationPromptWrapper.js +16 -0
- package/dist/components/auth/MigrationPromptWrapper.js.map +1 -0
- package/dist/components/auth/OAuthCallback.d.ts +20 -0
- package/dist/components/auth/OAuthCallback.d.ts.map +1 -0
- package/dist/components/auth/OAuthCallback.js +12 -0
- package/dist/components/auth/OAuthCallback.js.map +1 -0
- package/dist/components/auth/index.d.ts +15 -0
- package/dist/components/auth/index.d.ts.map +1 -0
- package/dist/components/auth/index.js +12 -0
- package/dist/components/auth/index.js.map +1 -0
- package/dist/components/config/LocaleConfigTool.d.ts +17 -0
- package/dist/components/config/LocaleConfigTool.d.ts.map +1 -0
- package/dist/components/config/LocaleConfigTool.js +186 -0
- package/dist/components/config/LocaleConfigTool.js.map +1 -0
- package/dist/components/config/LocaleConfigToolWrapper.d.ts +13 -0
- package/dist/components/config/LocaleConfigToolWrapper.d.ts.map +1 -0
- package/dist/components/config/LocaleConfigToolWrapper.js +26 -0
- package/dist/components/config/LocaleConfigToolWrapper.js.map +1 -0
- package/dist/components/config/OAuthConfig.d.ts +26 -0
- package/dist/components/config/OAuthConfig.d.ts.map +1 -0
- package/dist/components/config/OAuthConfig.js +152 -0
- package/dist/components/config/OAuthConfig.js.map +1 -0
- package/dist/components/config/OAuthConfigWrapper.d.ts +13 -0
- package/dist/components/config/OAuthConfigWrapper.d.ts.map +1 -0
- package/dist/components/config/OAuthConfigWrapper.js +41 -0
- package/dist/components/config/OAuthConfigWrapper.js.map +1 -0
- package/dist/components/config/PasswordInput.d.ts +14 -0
- package/dist/components/config/PasswordInput.d.ts.map +1 -0
- package/dist/components/config/PasswordInput.js +23 -0
- package/dist/components/config/PasswordInput.js.map +1 -0
- package/dist/components/config/index.d.ts +9 -0
- package/dist/components/config/index.d.ts.map +1 -0
- package/dist/components/config/index.js +8 -0
- package/dist/components/config/index.js.map +1 -0
- package/dist/components/config/localeConfigToolDefinition.d.ts +13 -0
- package/dist/components/config/localeConfigToolDefinition.d.ts.map +1 -0
- package/dist/components/config/localeConfigToolDefinition.js +19 -0
- package/dist/components/config/localeConfigToolDefinition.js.map +1 -0
- package/dist/components/config/oauthConfigToolDefinition.d.ts +13 -0
- package/dist/components/config/oauthConfigToolDefinition.d.ts.map +1 -0
- package/dist/components/config/oauthConfigToolDefinition.js +19 -0
- package/dist/components/config/oauthConfigToolDefinition.js.map +1 -0
- package/dist/components/dialogs/ConfirmationDialog.d.ts +21 -0
- package/dist/components/dialogs/ConfirmationDialog.d.ts.map +1 -0
- package/dist/components/dialogs/ConfirmationDialog.js +28 -0
- package/dist/components/dialogs/ConfirmationDialog.js.map +1 -0
- package/dist/components/dialogs/ErrorDialog.d.ts +21 -0
- package/dist/components/dialogs/ErrorDialog.d.ts.map +1 -0
- package/dist/components/dialogs/ErrorDialog.js +28 -0
- package/dist/components/dialogs/ErrorDialog.js.map +1 -0
- package/dist/components/dialogs/LocaleSelectionDialog.d.ts +41 -0
- package/dist/components/dialogs/LocaleSelectionDialog.d.ts.map +1 -0
- package/dist/components/dialogs/LocaleSelectionDialog.js +117 -0
- package/dist/components/dialogs/LocaleSelectionDialog.js.map +1 -0
- package/dist/components/dialogs/SuccessDialog.d.ts +19 -0
- package/dist/components/dialogs/SuccessDialog.d.ts.map +1 -0
- package/dist/components/dialogs/SuccessDialog.js +37 -0
- package/dist/components/dialogs/SuccessDialog.js.map +1 -0
- package/dist/components/dialogs/index.d.ts +12 -0
- package/dist/components/dialogs/index.d.ts.map +1 -0
- package/dist/components/dialogs/index.js +8 -0
- package/dist/components/dialogs/index.js.map +1 -0
- package/dist/components/dnt/DNTFieldBadge.d.ts +16 -0
- package/dist/components/dnt/DNTFieldBadge.d.ts.map +1 -0
- package/dist/components/dnt/DNTFieldBadge.js +56 -0
- package/dist/components/dnt/DNTFieldBadge.js.map +1 -0
- package/dist/components/dnt/DNTFieldComponent.d.ts +17 -0
- package/dist/components/dnt/DNTFieldComponent.d.ts.map +1 -0
- package/dist/components/dnt/DNTFieldComponent.js +21 -0
- package/dist/components/dnt/DNTFieldComponent.js.map +1 -0
- package/dist/components/dnt/DNTFieldInput.d.ts +14 -0
- package/dist/components/dnt/DNTFieldInput.d.ts.map +1 -0
- package/dist/components/dnt/DNTFieldInput.js +76 -0
- package/dist/components/dnt/DNTFieldInput.js.map +1 -0
- package/dist/components/dnt/index.d.ts +7 -0
- package/dist/components/dnt/index.d.ts.map +1 -0
- package/dist/components/dnt/index.js +7 -0
- package/dist/components/dnt/index.js.map +1 -0
- package/dist/config/index.d.ts +6 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +6 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/pluginConfig.d.ts +163 -0
- package/dist/config/pluginConfig.d.ts.map +1 -0
- package/dist/config/pluginConfig.js +548 -0
- package/dist/config/pluginConfig.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin.d.ts +3 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +137 -0
- package/dist/plugin.js.map +1 -0
- package/dist/services/authStateManager.d.ts +94 -0
- package/dist/services/authStateManager.d.ts.map +1 -0
- package/dist/services/authStateManager.js +208 -0
- package/dist/services/authStateManager.js.map +1 -0
- package/dist/services/contentExtractor.d.ts +95 -0
- package/dist/services/contentExtractor.d.ts.map +1 -0
- package/dist/services/contentExtractor.js +516 -0
- package/dist/services/contentExtractor.js.map +1 -0
- package/dist/services/dialogService.d.ts +96 -0
- package/dist/services/dialogService.d.ts.map +1 -0
- package/dist/services/dialogService.js +244 -0
- package/dist/services/dialogService.js.map +1 -0
- package/dist/services/dntServiceManager.d.ts +44 -0
- package/dist/services/dntServiceManager.d.ts.map +1 -0
- package/dist/services/dntServiceManager.js +74 -0
- package/dist/services/dntServiceManager.js.map +1 -0
- package/dist/services/dntStorageAdapter.d.ts +73 -0
- package/dist/services/dntStorageAdapter.d.ts.map +1 -0
- package/dist/services/dntStorageAdapter.js +192 -0
- package/dist/services/dntStorageAdapter.js.map +1 -0
- package/dist/services/documentCreationService.d.ts +139 -0
- package/dist/services/documentCreationService.d.ts.map +1 -0
- package/dist/services/documentCreationService.js +938 -0
- package/dist/services/documentCreationService.js.map +1 -0
- package/dist/services/localeService.d.ts +160 -0
- package/dist/services/localeService.d.ts.map +1 -0
- package/dist/services/localeService.js +300 -0
- package/dist/services/localeService.js.map +1 -0
- package/dist/services/localeStorageAdapter.d.ts +42 -0
- package/dist/services/localeStorageAdapter.d.ts.map +1 -0
- package/dist/services/localeStorageAdapter.js +107 -0
- package/dist/services/localeStorageAdapter.js.map +1 -0
- package/dist/services/oauthConfigStorage.d.ts +46 -0
- package/dist/services/oauthConfigStorage.d.ts.map +1 -0
- package/dist/services/oauthConfigStorage.js +122 -0
- package/dist/services/oauthConfigStorage.js.map +1 -0
- package/dist/services/oauthService.d.ts +48 -0
- package/dist/services/oauthService.d.ts.map +1 -0
- package/dist/services/oauthService.js +71 -0
- package/dist/services/oauthService.js.map +1 -0
- package/dist/services/oauthServiceManager.d.ts +189 -0
- package/dist/services/oauthServiceManager.d.ts.map +1 -0
- package/dist/services/oauthServiceManager.js +380 -0
- package/dist/services/oauthServiceManager.js.map +1 -0
- package/dist/services/tokenStorage.d.ts +54 -0
- package/dist/services/tokenStorage.d.ts.map +1 -0
- package/dist/services/tokenStorage.js +140 -0
- package/dist/services/tokenStorage.js.map +1 -0
- package/dist/services/translationService.d.ts +374 -0
- package/dist/services/translationService.d.ts.map +1 -0
- package/dist/services/translationService.js +687 -0
- package/dist/services/translationService.js.map +1 -0
- package/dist/services/unifiedConfigStorage.d.ts +124 -0
- package/dist/services/unifiedConfigStorage.d.ts.map +1 -0
- package/dist/services/unifiedConfigStorage.js +304 -0
- package/dist/services/unifiedConfigStorage.js.map +1 -0
- package/dist/test-utils.d.ts +9 -0
- package/dist/test-utils.d.ts.map +1 -0
- package/dist/test-utils.js +13 -0
- package/dist/test-utils.js.map +1 -0
- package/dist/types/dialog.d.ts +107 -0
- package/dist/types/dialog.d.ts.map +1 -0
- package/dist/types/dialog.js +6 -0
- package/dist/types/dialog.js.map +1 -0
- package/dist/types/dnt.d.ts +84 -0
- package/dist/types/dnt.d.ts.map +1 -0
- package/dist/types/dnt.js +5 -0
- package/dist/types/dnt.js.map +1 -0
- package/dist/types/index.d.ts +12 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/locale.d.ts +116 -0
- package/dist/types/locale.d.ts.map +1 -0
- package/dist/types/locale.js +189 -0
- package/dist/types/locale.js.map +1 -0
- package/dist/types/oauth.d.ts +90 -0
- package/dist/types/oauth.d.ts.map +1 -0
- package/dist/types/oauth.js +62 -0
- package/dist/types/oauth.js.map +1 -0
- package/dist/types/pluginConfig.d.ts +45 -0
- package/dist/types/pluginConfig.d.ts.map +1 -0
- package/dist/types/pluginConfig.js +6 -0
- package/dist/types/pluginConfig.js.map +1 -0
- package/dist/types/translation.d.ts +122 -0
- package/dist/types/translation.d.ts.map +1 -0
- package/dist/types/translation.js +6 -0
- package/dist/types/translation.js.map +1 -0
- package/dist/utils/htmlFormatter.d.ts +66 -0
- package/dist/utils/htmlFormatter.d.ts.map +1 -0
- package/dist/utils/htmlFormatter.js +191 -0
- package/dist/utils/htmlFormatter.js.map +1 -0
- package/dist/utils/index.d.ts +15 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +16 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +105 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +229 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/oauthErrorFeedback.d.ts +76 -0
- package/dist/utils/oauthErrorFeedback.d.ts.map +1 -0
- package/dist/utils/oauthErrorFeedback.js +134 -0
- package/dist/utils/oauthErrorFeedback.js.map +1 -0
- package/dist/utils/oauthLogger.d.ts +176 -0
- package/dist/utils/oauthLogger.d.ts.map +1 -0
- package/dist/utils/oauthLogger.js +282 -0
- package/dist/utils/oauthLogger.js.map +1 -0
- package/dist/utils/validator.d.ts +67 -0
- package/dist/utils/validator.d.ts.map +1 -0
- package/dist/utils/validator.js +390 -0
- package/dist/utils/validator.js.map +1 -0
- package/package.json +80 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Sanity Translation Plugin
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
# Sanity Translation Plugin
|
|
2
|
+
|
|
3
|
+
A Sanity Studio plugin that enables document translation functionality with support for single and bulk operations. The plugin extracts document content as HTML and prepares translation requests for external translation services.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Single Document Translation**: Translate individual documents with user confirmation
|
|
8
|
+
- **Bulk Translation**: Translate multiple documents in batch operations
|
|
9
|
+
- **Document Creation**: Automatically create new translated documents
|
|
10
|
+
- **HTML Content Extraction**: Convert Sanity portable text to HTML format
|
|
11
|
+
- **Portable Text Conversion**: Convert HTML responses back to Sanity portable text
|
|
12
|
+
- **Translation-Invariant Fields**: Mark specific fields as non-translatable using the `dnt` (Do Not Translate) flag
|
|
13
|
+
- **DNT Field Management UI**: User-friendly document action to manage which fields should not be translated
|
|
14
|
+
- **Comprehensive Validation**: Multi-layer validation and error handling
|
|
15
|
+
- **Progress Tracking**: Real-time progress updates for bulk operations
|
|
16
|
+
- **Error Handling**: Detailed error reporting and rollback support
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
Install the plugin in your Sanity Studio project:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install sanity-translation-plugin
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Add the plugin to your `sanity.config.ts` file:
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { defineConfig } from 'sanity'
|
|
30
|
+
import translationPlugin from 'sanity-translation-plugin'
|
|
31
|
+
|
|
32
|
+
export default defineConfig({
|
|
33
|
+
// ... your other config
|
|
34
|
+
plugins: [
|
|
35
|
+
// ... your other plugins
|
|
36
|
+
translationPlugin()
|
|
37
|
+
]
|
|
38
|
+
})
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Configuration
|
|
42
|
+
|
|
43
|
+
The plugin works with a placeholder endpoint by default for testing purposes. In production, you'll need to configure it with your translation service endpoint.
|
|
44
|
+
|
|
45
|
+
### Basic Configuration
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
import translationPlugin from 'sanity-translation-plugin'
|
|
49
|
+
|
|
50
|
+
export default defineConfig({
|
|
51
|
+
plugins: [
|
|
52
|
+
translationPlugin({
|
|
53
|
+
// Plugin configuration options will be available in future versions
|
|
54
|
+
// Currently uses placeholder endpoint for testing
|
|
55
|
+
})
|
|
56
|
+
]
|
|
57
|
+
})
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Translation Service Requirements
|
|
61
|
+
|
|
62
|
+
Your translation service should accept POST requests with the following payload structure:
|
|
63
|
+
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"content": "<h1>Document content in HTML format</h1>",
|
|
67
|
+
"format": "html",
|
|
68
|
+
"metadata": {
|
|
69
|
+
"documentId": "document-id",
|
|
70
|
+
"documentType": "document-type",
|
|
71
|
+
"title": "Document Title",
|
|
72
|
+
"sourceLanguage": "en",
|
|
73
|
+
"targetLanguage": "es"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
And return responses in this format:
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"success": true,
|
|
83
|
+
"translatedContent": {
|
|
84
|
+
"body": "<h1>Translated HTML content</h1>",
|
|
85
|
+
"title": "Translated Title",
|
|
86
|
+
"slug": "translated-slug",
|
|
87
|
+
"fields": {}
|
|
88
|
+
},
|
|
89
|
+
"requestId": "optional-request-id"
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Translation Service Integration
|
|
94
|
+
|
|
95
|
+
This plugin requires an external translation service that implements the specified API format.
|
|
96
|
+
|
|
97
|
+
### Quick Start with Example Service
|
|
98
|
+
|
|
99
|
+
1. **Start the example translation service:**
|
|
100
|
+
```bash
|
|
101
|
+
cd examples
|
|
102
|
+
npm install
|
|
103
|
+
npm start
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
2. **Configure the plugin** to use `http://localhost:8275/translate` as the endpoint
|
|
107
|
+
|
|
108
|
+
3. **Test translation** using the document actions in Sanity Studio
|
|
109
|
+
|
|
110
|
+
### Documentation
|
|
111
|
+
|
|
112
|
+
- **[Translation Service API Documentation](./docs/translation-service-api.md)** - Complete API specification
|
|
113
|
+
- **[JSON Schema](./docs/translation-response-schema.json)** - Response format validation
|
|
114
|
+
- **[Example Implementation](./examples/)** - Working example service
|
|
115
|
+
- **[Documentation Overview](./docs/README.md)** - All documentation files
|
|
116
|
+
|
|
117
|
+
### Expected Response Format
|
|
118
|
+
|
|
119
|
+
Your translation service must return responses in this format:
|
|
120
|
+
|
|
121
|
+
**Success Response:**
|
|
122
|
+
```json
|
|
123
|
+
{
|
|
124
|
+
"success": true,
|
|
125
|
+
"translatedContent": {
|
|
126
|
+
"body": "<h1>Translated HTML content</h1>",
|
|
127
|
+
"title": "Translated Title",
|
|
128
|
+
"slug": "translated-slug",
|
|
129
|
+
"fields": {}
|
|
130
|
+
},
|
|
131
|
+
"requestId": "optional-request-id"
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Error Response:**
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"success": false,
|
|
139
|
+
"error": "Error message describing the failure",
|
|
140
|
+
"requestId": "optional-request-id"
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Usage
|
|
145
|
+
|
|
146
|
+
### Single Document Translation
|
|
147
|
+
|
|
148
|
+
1. **Open a document** in Sanity Studio that you want to translate
|
|
149
|
+
2. **Click the "Translate" action** button in the document toolbar (appears as a translate icon)
|
|
150
|
+
3. **Review the confirmation dialog** showing the document details
|
|
151
|
+
4. **Click "Translate"** to proceed with the translation
|
|
152
|
+
5. **Monitor the progress** - the plugin will show loading states during processing
|
|
153
|
+
6. **View results** - translation requests are logged to the browser console for testing
|
|
154
|
+
|
|
155
|
+
**Example workflow:**
|
|
156
|
+
```
|
|
157
|
+
Document: "Welcome Post" (blog post)
|
|
158
|
+
↓ Extract content as HTML
|
|
159
|
+
↓ Prepare translation request
|
|
160
|
+
↓ Log request to console (for testing)
|
|
161
|
+
↓ Show success confirmation
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Bulk Translation
|
|
165
|
+
|
|
166
|
+
1. **Open the "Bulk Translate" tool** from the Sanity Studio tools menu
|
|
167
|
+
2. **Select document types** you want to translate (e.g., "post", "page")
|
|
168
|
+
3. **Choose specific documents** from the filtered list
|
|
169
|
+
4. **Click "Translate X Documents"** where X is the number of selected documents
|
|
170
|
+
5. **Confirm the bulk operation** in the dialog
|
|
171
|
+
6. **Monitor progress** with the real-time progress indicator
|
|
172
|
+
7. **Review results** in the summary report
|
|
173
|
+
|
|
174
|
+
**Example workflow:**
|
|
175
|
+
```
|
|
176
|
+
Selected: 5 blog posts
|
|
177
|
+
↓ Extract content from each document
|
|
178
|
+
↓ Prepare 5 translation requests
|
|
179
|
+
↓ Process requests (logged to console)
|
|
180
|
+
↓ Show summary: "5 documents processed successfully"
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Testing the Plugin
|
|
184
|
+
|
|
185
|
+
Since the plugin uses a placeholder endpoint for testing:
|
|
186
|
+
|
|
187
|
+
1. **Open browser developer tools** to view the console
|
|
188
|
+
2. **Perform translation actions** (single or bulk)
|
|
189
|
+
3. **Check console logs** to see the prepared translation requests
|
|
190
|
+
4. **Verify request format** matches your translation service expectations
|
|
191
|
+
|
|
192
|
+
**Console output example:**
|
|
193
|
+
```javascript
|
|
194
|
+
[Translation Plugin] Request prepared for document: welcome-post
|
|
195
|
+
{
|
|
196
|
+
"content": "<h1>Welcome to our blog</h1><p>This is our first post...</p>",
|
|
197
|
+
"format": "html",
|
|
198
|
+
"metadata": {
|
|
199
|
+
"documentId": "welcome-post",
|
|
200
|
+
"documentType": "post",
|
|
201
|
+
"title": "Welcome to our blog"
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Development
|
|
207
|
+
|
|
208
|
+
### Building the Plugin
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
# Install dependencies
|
|
212
|
+
npm install
|
|
213
|
+
|
|
214
|
+
# Build the plugin
|
|
215
|
+
npm run build
|
|
216
|
+
|
|
217
|
+
# Build and watch for changes
|
|
218
|
+
npm run dev
|
|
219
|
+
|
|
220
|
+
# Run tests
|
|
221
|
+
npm run test
|
|
222
|
+
|
|
223
|
+
# Run tests with coverage
|
|
224
|
+
npm run test:coverage
|
|
225
|
+
|
|
226
|
+
# Lint code
|
|
227
|
+
npm run lint
|
|
228
|
+
|
|
229
|
+
# Fix linting issues
|
|
230
|
+
npm run lint:fix
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Project Structure
|
|
234
|
+
|
|
235
|
+
```
|
|
236
|
+
sanity-translation-plugin/
|
|
237
|
+
├── src/
|
|
238
|
+
│ ├── index.ts # Plugin entry point
|
|
239
|
+
│ ├── plugin.ts # Main plugin definition
|
|
240
|
+
│ ├── actions/
|
|
241
|
+
│ │ ├── translateDocument.ts # Single document translation
|
|
242
|
+
│ │ └── bulkTranslate.ts # Bulk translation tool
|
|
243
|
+
│ ├── services/
|
|
244
|
+
│ │ ├── contentExtractor.ts # HTML content extraction
|
|
245
|
+
│ │ ├── translationService.ts # Translation request handling
|
|
246
|
+
│ │ └── documentCreationService.ts # Document creation
|
|
247
|
+
│ └── utils/
|
|
248
|
+
│ ├── htmlFormatter.ts # HTML formatting utilities
|
|
249
|
+
│ └── logger.ts # Logging utilities
|
|
250
|
+
├── dist/ # Built plugin files
|
|
251
|
+
├── docs/ # Documentation
|
|
252
|
+
└── examples/ # Example implementations
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Architecture
|
|
256
|
+
|
|
257
|
+
The plugin follows a modular architecture with clear separation of concerns:
|
|
258
|
+
|
|
259
|
+
### Core Services
|
|
260
|
+
|
|
261
|
+
- **ContentExtractor** (`src/services/contentExtractor.ts`)
|
|
262
|
+
- Extracts content from Sanity documents
|
|
263
|
+
- Converts portable text to HTML format
|
|
264
|
+
- Handles various field types (text, images, references)
|
|
265
|
+
|
|
266
|
+
- **TranslationService** (`src/services/translationService.ts`)
|
|
267
|
+
- Prepares translation request payloads
|
|
268
|
+
- Handles request logging for testing
|
|
269
|
+
- Manages bulk translation processing
|
|
270
|
+
|
|
271
|
+
- **DocumentCreationService** (`src/services/documentCreationService.ts`)
|
|
272
|
+
- Creates new Sanity documents from translation responses
|
|
273
|
+
- Converts HTML back to portable text format
|
|
274
|
+
- Handles document validation and error recovery
|
|
275
|
+
|
|
276
|
+
### User Interface Components
|
|
277
|
+
|
|
278
|
+
- **Document Actions** (`src/actions/translateDocument.ts`)
|
|
279
|
+
- Adds translate button to document toolbar
|
|
280
|
+
- Handles single document translation workflow
|
|
281
|
+
- Provides user feedback and error handling
|
|
282
|
+
|
|
283
|
+
- **Bulk Translation Tool** (`src/actions/bulkTranslate.ts`)
|
|
284
|
+
- Provides bulk translation interface
|
|
285
|
+
- Document selection and filtering
|
|
286
|
+
- Progress tracking and result reporting
|
|
287
|
+
|
|
288
|
+
### Utilities
|
|
289
|
+
|
|
290
|
+
- **HTML Formatter** (`src/utils/htmlFormatter.ts`)
|
|
291
|
+
- HTML formatting and validation utilities
|
|
292
|
+
- Content structure preservation
|
|
293
|
+
|
|
294
|
+
- **Logger** (`src/utils/logger.ts`)
|
|
295
|
+
- Structured logging for debugging
|
|
296
|
+
- Request/response tracking
|
|
297
|
+
|
|
298
|
+
## Requirements
|
|
299
|
+
|
|
300
|
+
- **Sanity Studio**: v3.0.0 or higher
|
|
301
|
+
- **Node.js**: 16.0.0 or higher
|
|
302
|
+
- **React**: 18.0.0 or higher
|
|
303
|
+
- **TypeScript**: 5.0.0 or higher (for development)
|
|
304
|
+
|
|
305
|
+
## Troubleshooting
|
|
306
|
+
|
|
307
|
+
### Common Issues
|
|
308
|
+
|
|
309
|
+
**Plugin not appearing in Studio**
|
|
310
|
+
- Ensure the plugin is properly installed: `npm list sanity-translation-plugin`
|
|
311
|
+
- Check that the plugin is added to your `sanity.config.ts` file
|
|
312
|
+
- Restart your Sanity Studio development server
|
|
313
|
+
|
|
314
|
+
**Translation action not visible**
|
|
315
|
+
- The translate action only appears for documents with translatable content
|
|
316
|
+
- Check browser console for any JavaScript errors
|
|
317
|
+
- Ensure you're using Sanity Studio v3+
|
|
318
|
+
|
|
319
|
+
**Console logs not appearing**
|
|
320
|
+
- Open browser developer tools (F12)
|
|
321
|
+
- Check the Console tab
|
|
322
|
+
- Ensure log level is set to show all messages
|
|
323
|
+
|
|
324
|
+
**Build errors during development**
|
|
325
|
+
- Run `npm run clean` to clear build cache
|
|
326
|
+
- Delete `node_modules` and run `npm install`
|
|
327
|
+
- Check TypeScript version compatibility
|
|
328
|
+
|
|
329
|
+
### Getting Help
|
|
330
|
+
|
|
331
|
+
- Check the [documentation](./docs/) for detailed API information
|
|
332
|
+
- Review [example implementations](./examples/) for reference
|
|
333
|
+
- Open an issue on GitHub for bug reports or feature requests
|
|
334
|
+
|
|
335
|
+
## API Reference
|
|
336
|
+
|
|
337
|
+
### Plugin Configuration
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
interface TranslationPluginConfig {
|
|
341
|
+
// Future configuration options will be added here
|
|
342
|
+
// Currently uses default placeholder endpoint
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### Content Extraction
|
|
347
|
+
|
|
348
|
+
```typescript
|
|
349
|
+
interface DocumentContent {
|
|
350
|
+
documentId: string;
|
|
351
|
+
documentType: string;
|
|
352
|
+
title: string;
|
|
353
|
+
htmlContent: string;
|
|
354
|
+
extractedAt: Date;
|
|
355
|
+
}
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### Translation Request Format
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
interface TranslationRequest {
|
|
362
|
+
content: string;
|
|
363
|
+
format: 'html';
|
|
364
|
+
metadata: {
|
|
365
|
+
documentId: string;
|
|
366
|
+
documentType: string;
|
|
367
|
+
title: string;
|
|
368
|
+
sourceLanguage?: string;
|
|
369
|
+
targetLanguage?: string;
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Translation Response Format
|
|
375
|
+
|
|
376
|
+
```typescript
|
|
377
|
+
interface TranslationResponse {
|
|
378
|
+
success: boolean;
|
|
379
|
+
translatedContent?: {
|
|
380
|
+
body: string;
|
|
381
|
+
title?: string;
|
|
382
|
+
slug?: string;
|
|
383
|
+
fields?: Record<string, any>;
|
|
384
|
+
};
|
|
385
|
+
error?: string;
|
|
386
|
+
requestId?: string;
|
|
387
|
+
}
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### Translation-Invariant Fields
|
|
391
|
+
|
|
392
|
+
The plugin now supports marking specific fields as translation-invariant using the `dnt` (Do Not Translate) flag. This is useful for fields that should not be translated, such as product IDs, dates, URLs, and other technical identifiers.
|
|
393
|
+
|
|
394
|
+
```typescript
|
|
395
|
+
import { ExtendedDocumentContent, TranslatableField } from 'sanity-translation-plugin';
|
|
396
|
+
|
|
397
|
+
const content: ExtendedDocumentContent = {
|
|
398
|
+
documentId: 'product-123',
|
|
399
|
+
title: 'Premium Headphones',
|
|
400
|
+
htmlContent: '<p>High-quality wireless headphones</p>',
|
|
401
|
+
slug: 'premium-headphones',
|
|
402
|
+
fields: {
|
|
403
|
+
// Translatable field
|
|
404
|
+
description: {
|
|
405
|
+
value: 'Premium audio quality',
|
|
406
|
+
dnt: false
|
|
407
|
+
},
|
|
408
|
+
// Translation-invariant field
|
|
409
|
+
sku: {
|
|
410
|
+
value: 'HDPHN-001',
|
|
411
|
+
dnt: true // This field will NOT be translated
|
|
412
|
+
},
|
|
413
|
+
price: {
|
|
414
|
+
value: 299.99,
|
|
415
|
+
dnt: true
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
For backward compatibility, flat field values are automatically converted to the new structure with `dnt: false`.
|
|
422
|
+
|
|
423
|
+
**See the [Translation-Invariant Fields Guide](./docs/translation-invariant-fields.md) for detailed documentation and examples.**
|
|
424
|
+
|
|
425
|
+
#### Managing DNT Fields via Inline Badges
|
|
426
|
+
|
|
427
|
+
The plugin displays **inline badges** on each translatable field in the document editor, allowing you to toggle DNT status with a single click:
|
|
428
|
+
|
|
429
|
+
**Visual indicators appear below each field:**
|
|
430
|
+
- **Green "Will Translate" badge** - Field will be translated ✓
|
|
431
|
+
- **Red "Do Not Translate" badge** - Field will NOT be translated ⊘
|
|
432
|
+
|
|
433
|
+
Simply click the badge to toggle the DNT status. Changes save automatically and apply during translation.
|
|
434
|
+
|
|
435
|
+
**Supported field types**: string, text, number, url, email
|
|
436
|
+
|
|
437
|
+
**See the [Inline DNT Badges Guide](./docs/inline-dnt-badges.md) for visual examples and detailed instructions.**
|
|
438
|
+
|
|
439
|
+
#### Additional DNT Management
|
|
440
|
+
|
|
441
|
+
For bulk operations, use the **"Manage Translation Fields" document action**:
|
|
442
|
+
|
|
443
|
+
1. Open any document in Sanity Studio
|
|
444
|
+
2. Click the document menu (three dots)
|
|
445
|
+
3. Select "Manage Translation Fields"
|
|
446
|
+
4. View all fields and clear DNT preferences if needed
|
|
447
|
+
|
|
448
|
+
**See the [DNT Field Management Guide](./docs/dnt-field-management.md) for complete documentation.**
|
|
449
|
+
|
|
450
|
+
## Contributing
|
|
451
|
+
|
|
452
|
+
We welcome contributions! Please follow these steps:
|
|
453
|
+
|
|
454
|
+
1. **Fork the repository** and create a feature branch
|
|
455
|
+
2. **Install dependencies**: `npm install`
|
|
456
|
+
3. **Make your changes** with appropriate tests
|
|
457
|
+
4. **Run the test suite**: `npm test`
|
|
458
|
+
5. **Lint your code**: `npm run lint`
|
|
459
|
+
6. **Build the plugin**: `npm run build`
|
|
460
|
+
7. **Submit a pull request** with a clear description
|
|
461
|
+
|
|
462
|
+
### Development Guidelines
|
|
463
|
+
|
|
464
|
+
- Follow TypeScript best practices
|
|
465
|
+
- Add unit tests for new functionality
|
|
466
|
+
- Update documentation for API changes
|
|
467
|
+
- Use conventional commit messages
|
|
468
|
+
- Ensure all tests pass before submitting
|
|
469
|
+
|
|
470
|
+
## License
|
|
471
|
+
|
|
472
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
473
|
+
|
|
474
|
+
## Changelog
|
|
475
|
+
|
|
476
|
+
### v1.0.0
|
|
477
|
+
- Initial release
|
|
478
|
+
- Single document translation support
|
|
479
|
+
- Bulk translation functionality
|
|
480
|
+
- HTML content extraction
|
|
481
|
+
- Portable text conversion
|
|
482
|
+
- Comprehensive test coverage
|