@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.
Files changed (244) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +482 -0
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/actions/bulkTranslate.d.ts +7 -0
  5. package/dist/actions/bulkTranslate.d.ts.map +1 -0
  6. package/dist/actions/bulkTranslate.js +543 -0
  7. package/dist/actions/bulkTranslate.js.map +1 -0
  8. package/dist/actions/manageDNTFields.d.ts +12 -0
  9. package/dist/actions/manageDNTFields.d.ts.map +1 -0
  10. package/dist/actions/manageDNTFields.js +100 -0
  11. package/dist/actions/manageDNTFields.js.map +1 -0
  12. package/dist/actions/translateDocument.d.ts +7 -0
  13. package/dist/actions/translateDocument.d.ts.map +1 -0
  14. package/dist/actions/translateDocument.js +256 -0
  15. package/dist/actions/translateDocument.js.map +1 -0
  16. package/dist/components/RadioWithDefault.d.ts +17 -0
  17. package/dist/components/RadioWithDefault.d.ts.map +1 -0
  18. package/dist/components/RadioWithDefault.js +29 -0
  19. package/dist/components/RadioWithDefault.js.map +1 -0
  20. package/dist/components/auth/AuthNavbar.d.ts +18 -0
  21. package/dist/components/auth/AuthNavbar.d.ts.map +1 -0
  22. package/dist/components/auth/AuthNavbar.js +15 -0
  23. package/dist/components/auth/AuthNavbar.js.map +1 -0
  24. package/dist/components/auth/AuthStatus.d.ts +27 -0
  25. package/dist/components/auth/AuthStatus.d.ts.map +1 -0
  26. package/dist/components/auth/AuthStatus.js +82 -0
  27. package/dist/components/auth/AuthStatus.js.map +1 -0
  28. package/dist/components/auth/AuthStatusWrapper.d.ts +15 -0
  29. package/dist/components/auth/AuthStatusWrapper.d.ts.map +1 -0
  30. package/dist/components/auth/AuthStatusWrapper.js +39 -0
  31. package/dist/components/auth/AuthStatusWrapper.js.map +1 -0
  32. package/dist/components/auth/MigrationPrompt.d.ts +20 -0
  33. package/dist/components/auth/MigrationPrompt.d.ts.map +1 -0
  34. package/dist/components/auth/MigrationPrompt.js +16 -0
  35. package/dist/components/auth/MigrationPrompt.js.map +1 -0
  36. package/dist/components/auth/MigrationPromptWrapper.d.ts +14 -0
  37. package/dist/components/auth/MigrationPromptWrapper.d.ts.map +1 -0
  38. package/dist/components/auth/MigrationPromptWrapper.js +16 -0
  39. package/dist/components/auth/MigrationPromptWrapper.js.map +1 -0
  40. package/dist/components/auth/OAuthCallback.d.ts +20 -0
  41. package/dist/components/auth/OAuthCallback.d.ts.map +1 -0
  42. package/dist/components/auth/OAuthCallback.js +12 -0
  43. package/dist/components/auth/OAuthCallback.js.map +1 -0
  44. package/dist/components/auth/index.d.ts +15 -0
  45. package/dist/components/auth/index.d.ts.map +1 -0
  46. package/dist/components/auth/index.js +12 -0
  47. package/dist/components/auth/index.js.map +1 -0
  48. package/dist/components/config/LocaleConfigTool.d.ts +17 -0
  49. package/dist/components/config/LocaleConfigTool.d.ts.map +1 -0
  50. package/dist/components/config/LocaleConfigTool.js +186 -0
  51. package/dist/components/config/LocaleConfigTool.js.map +1 -0
  52. package/dist/components/config/LocaleConfigToolWrapper.d.ts +13 -0
  53. package/dist/components/config/LocaleConfigToolWrapper.d.ts.map +1 -0
  54. package/dist/components/config/LocaleConfigToolWrapper.js +26 -0
  55. package/dist/components/config/LocaleConfigToolWrapper.js.map +1 -0
  56. package/dist/components/config/OAuthConfig.d.ts +26 -0
  57. package/dist/components/config/OAuthConfig.d.ts.map +1 -0
  58. package/dist/components/config/OAuthConfig.js +152 -0
  59. package/dist/components/config/OAuthConfig.js.map +1 -0
  60. package/dist/components/config/OAuthConfigWrapper.d.ts +13 -0
  61. package/dist/components/config/OAuthConfigWrapper.d.ts.map +1 -0
  62. package/dist/components/config/OAuthConfigWrapper.js +41 -0
  63. package/dist/components/config/OAuthConfigWrapper.js.map +1 -0
  64. package/dist/components/config/PasswordInput.d.ts +14 -0
  65. package/dist/components/config/PasswordInput.d.ts.map +1 -0
  66. package/dist/components/config/PasswordInput.js +23 -0
  67. package/dist/components/config/PasswordInput.js.map +1 -0
  68. package/dist/components/config/index.d.ts +9 -0
  69. package/dist/components/config/index.d.ts.map +1 -0
  70. package/dist/components/config/index.js +8 -0
  71. package/dist/components/config/index.js.map +1 -0
  72. package/dist/components/config/localeConfigToolDefinition.d.ts +13 -0
  73. package/dist/components/config/localeConfigToolDefinition.d.ts.map +1 -0
  74. package/dist/components/config/localeConfigToolDefinition.js +19 -0
  75. package/dist/components/config/localeConfigToolDefinition.js.map +1 -0
  76. package/dist/components/config/oauthConfigToolDefinition.d.ts +13 -0
  77. package/dist/components/config/oauthConfigToolDefinition.d.ts.map +1 -0
  78. package/dist/components/config/oauthConfigToolDefinition.js +19 -0
  79. package/dist/components/config/oauthConfigToolDefinition.js.map +1 -0
  80. package/dist/components/dialogs/ConfirmationDialog.d.ts +21 -0
  81. package/dist/components/dialogs/ConfirmationDialog.d.ts.map +1 -0
  82. package/dist/components/dialogs/ConfirmationDialog.js +28 -0
  83. package/dist/components/dialogs/ConfirmationDialog.js.map +1 -0
  84. package/dist/components/dialogs/ErrorDialog.d.ts +21 -0
  85. package/dist/components/dialogs/ErrorDialog.d.ts.map +1 -0
  86. package/dist/components/dialogs/ErrorDialog.js +28 -0
  87. package/dist/components/dialogs/ErrorDialog.js.map +1 -0
  88. package/dist/components/dialogs/LocaleSelectionDialog.d.ts +41 -0
  89. package/dist/components/dialogs/LocaleSelectionDialog.d.ts.map +1 -0
  90. package/dist/components/dialogs/LocaleSelectionDialog.js +117 -0
  91. package/dist/components/dialogs/LocaleSelectionDialog.js.map +1 -0
  92. package/dist/components/dialogs/SuccessDialog.d.ts +19 -0
  93. package/dist/components/dialogs/SuccessDialog.d.ts.map +1 -0
  94. package/dist/components/dialogs/SuccessDialog.js +37 -0
  95. package/dist/components/dialogs/SuccessDialog.js.map +1 -0
  96. package/dist/components/dialogs/index.d.ts +12 -0
  97. package/dist/components/dialogs/index.d.ts.map +1 -0
  98. package/dist/components/dialogs/index.js +8 -0
  99. package/dist/components/dialogs/index.js.map +1 -0
  100. package/dist/components/dnt/DNTFieldBadge.d.ts +16 -0
  101. package/dist/components/dnt/DNTFieldBadge.d.ts.map +1 -0
  102. package/dist/components/dnt/DNTFieldBadge.js +56 -0
  103. package/dist/components/dnt/DNTFieldBadge.js.map +1 -0
  104. package/dist/components/dnt/DNTFieldComponent.d.ts +17 -0
  105. package/dist/components/dnt/DNTFieldComponent.d.ts.map +1 -0
  106. package/dist/components/dnt/DNTFieldComponent.js +21 -0
  107. package/dist/components/dnt/DNTFieldComponent.js.map +1 -0
  108. package/dist/components/dnt/DNTFieldInput.d.ts +14 -0
  109. package/dist/components/dnt/DNTFieldInput.d.ts.map +1 -0
  110. package/dist/components/dnt/DNTFieldInput.js +76 -0
  111. package/dist/components/dnt/DNTFieldInput.js.map +1 -0
  112. package/dist/components/dnt/index.d.ts +7 -0
  113. package/dist/components/dnt/index.d.ts.map +1 -0
  114. package/dist/components/dnt/index.js +7 -0
  115. package/dist/components/dnt/index.js.map +1 -0
  116. package/dist/config/index.d.ts +6 -0
  117. package/dist/config/index.d.ts.map +1 -0
  118. package/dist/config/index.js +6 -0
  119. package/dist/config/index.js.map +1 -0
  120. package/dist/config/pluginConfig.d.ts +163 -0
  121. package/dist/config/pluginConfig.d.ts.map +1 -0
  122. package/dist/config/pluginConfig.js +548 -0
  123. package/dist/config/pluginConfig.js.map +1 -0
  124. package/dist/index.d.ts +12 -0
  125. package/dist/index.d.ts.map +1 -0
  126. package/dist/index.js +12 -0
  127. package/dist/index.js.map +1 -0
  128. package/dist/plugin.d.ts +3 -0
  129. package/dist/plugin.d.ts.map +1 -0
  130. package/dist/plugin.js +137 -0
  131. package/dist/plugin.js.map +1 -0
  132. package/dist/services/authStateManager.d.ts +94 -0
  133. package/dist/services/authStateManager.d.ts.map +1 -0
  134. package/dist/services/authStateManager.js +208 -0
  135. package/dist/services/authStateManager.js.map +1 -0
  136. package/dist/services/contentExtractor.d.ts +95 -0
  137. package/dist/services/contentExtractor.d.ts.map +1 -0
  138. package/dist/services/contentExtractor.js +516 -0
  139. package/dist/services/contentExtractor.js.map +1 -0
  140. package/dist/services/dialogService.d.ts +96 -0
  141. package/dist/services/dialogService.d.ts.map +1 -0
  142. package/dist/services/dialogService.js +244 -0
  143. package/dist/services/dialogService.js.map +1 -0
  144. package/dist/services/dntServiceManager.d.ts +44 -0
  145. package/dist/services/dntServiceManager.d.ts.map +1 -0
  146. package/dist/services/dntServiceManager.js +74 -0
  147. package/dist/services/dntServiceManager.js.map +1 -0
  148. package/dist/services/dntStorageAdapter.d.ts +73 -0
  149. package/dist/services/dntStorageAdapter.d.ts.map +1 -0
  150. package/dist/services/dntStorageAdapter.js +192 -0
  151. package/dist/services/dntStorageAdapter.js.map +1 -0
  152. package/dist/services/documentCreationService.d.ts +139 -0
  153. package/dist/services/documentCreationService.d.ts.map +1 -0
  154. package/dist/services/documentCreationService.js +938 -0
  155. package/dist/services/documentCreationService.js.map +1 -0
  156. package/dist/services/localeService.d.ts +160 -0
  157. package/dist/services/localeService.d.ts.map +1 -0
  158. package/dist/services/localeService.js +300 -0
  159. package/dist/services/localeService.js.map +1 -0
  160. package/dist/services/localeStorageAdapter.d.ts +42 -0
  161. package/dist/services/localeStorageAdapter.d.ts.map +1 -0
  162. package/dist/services/localeStorageAdapter.js +107 -0
  163. package/dist/services/localeStorageAdapter.js.map +1 -0
  164. package/dist/services/oauthConfigStorage.d.ts +46 -0
  165. package/dist/services/oauthConfigStorage.d.ts.map +1 -0
  166. package/dist/services/oauthConfigStorage.js +122 -0
  167. package/dist/services/oauthConfigStorage.js.map +1 -0
  168. package/dist/services/oauthService.d.ts +48 -0
  169. package/dist/services/oauthService.d.ts.map +1 -0
  170. package/dist/services/oauthService.js +71 -0
  171. package/dist/services/oauthService.js.map +1 -0
  172. package/dist/services/oauthServiceManager.d.ts +189 -0
  173. package/dist/services/oauthServiceManager.d.ts.map +1 -0
  174. package/dist/services/oauthServiceManager.js +380 -0
  175. package/dist/services/oauthServiceManager.js.map +1 -0
  176. package/dist/services/tokenStorage.d.ts +54 -0
  177. package/dist/services/tokenStorage.d.ts.map +1 -0
  178. package/dist/services/tokenStorage.js +140 -0
  179. package/dist/services/tokenStorage.js.map +1 -0
  180. package/dist/services/translationService.d.ts +374 -0
  181. package/dist/services/translationService.d.ts.map +1 -0
  182. package/dist/services/translationService.js +687 -0
  183. package/dist/services/translationService.js.map +1 -0
  184. package/dist/services/unifiedConfigStorage.d.ts +124 -0
  185. package/dist/services/unifiedConfigStorage.d.ts.map +1 -0
  186. package/dist/services/unifiedConfigStorage.js +304 -0
  187. package/dist/services/unifiedConfigStorage.js.map +1 -0
  188. package/dist/test-utils.d.ts +9 -0
  189. package/dist/test-utils.d.ts.map +1 -0
  190. package/dist/test-utils.js +13 -0
  191. package/dist/test-utils.js.map +1 -0
  192. package/dist/types/dialog.d.ts +107 -0
  193. package/dist/types/dialog.d.ts.map +1 -0
  194. package/dist/types/dialog.js +6 -0
  195. package/dist/types/dialog.js.map +1 -0
  196. package/dist/types/dnt.d.ts +84 -0
  197. package/dist/types/dnt.d.ts.map +1 -0
  198. package/dist/types/dnt.js +5 -0
  199. package/dist/types/dnt.js.map +1 -0
  200. package/dist/types/index.d.ts +12 -0
  201. package/dist/types/index.d.ts.map +1 -0
  202. package/dist/types/index.js +6 -0
  203. package/dist/types/index.js.map +1 -0
  204. package/dist/types/locale.d.ts +116 -0
  205. package/dist/types/locale.d.ts.map +1 -0
  206. package/dist/types/locale.js +189 -0
  207. package/dist/types/locale.js.map +1 -0
  208. package/dist/types/oauth.d.ts +90 -0
  209. package/dist/types/oauth.d.ts.map +1 -0
  210. package/dist/types/oauth.js +62 -0
  211. package/dist/types/oauth.js.map +1 -0
  212. package/dist/types/pluginConfig.d.ts +45 -0
  213. package/dist/types/pluginConfig.d.ts.map +1 -0
  214. package/dist/types/pluginConfig.js +6 -0
  215. package/dist/types/pluginConfig.js.map +1 -0
  216. package/dist/types/translation.d.ts +122 -0
  217. package/dist/types/translation.d.ts.map +1 -0
  218. package/dist/types/translation.js +6 -0
  219. package/dist/types/translation.js.map +1 -0
  220. package/dist/utils/htmlFormatter.d.ts +66 -0
  221. package/dist/utils/htmlFormatter.d.ts.map +1 -0
  222. package/dist/utils/htmlFormatter.js +191 -0
  223. package/dist/utils/htmlFormatter.js.map +1 -0
  224. package/dist/utils/index.d.ts +15 -0
  225. package/dist/utils/index.d.ts.map +1 -0
  226. package/dist/utils/index.js +16 -0
  227. package/dist/utils/index.js.map +1 -0
  228. package/dist/utils/logger.d.ts +105 -0
  229. package/dist/utils/logger.d.ts.map +1 -0
  230. package/dist/utils/logger.js +229 -0
  231. package/dist/utils/logger.js.map +1 -0
  232. package/dist/utils/oauthErrorFeedback.d.ts +76 -0
  233. package/dist/utils/oauthErrorFeedback.d.ts.map +1 -0
  234. package/dist/utils/oauthErrorFeedback.js +134 -0
  235. package/dist/utils/oauthErrorFeedback.js.map +1 -0
  236. package/dist/utils/oauthLogger.d.ts +176 -0
  237. package/dist/utils/oauthLogger.d.ts.map +1 -0
  238. package/dist/utils/oauthLogger.js +282 -0
  239. package/dist/utils/oauthLogger.js.map +1 -0
  240. package/dist/utils/validator.d.ts +67 -0
  241. package/dist/utils/validator.d.ts.map +1 -0
  242. package/dist/utils/validator.js +390 -0
  243. package/dist/utils/validator.js.map +1 -0
  244. 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