sanity-plugin-studio-smartling 4.3.3 → 5.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 CHANGED
@@ -1,12 +1,9 @@
1
-
2
1
  ## Installation
3
2
 
4
3
  ```sh
5
4
  npm install sanity-plugin-studio-smartling
6
5
  ```
7
6
 
8
- ## Usage
9
-
10
7
  # Studio Plugin for Sanity & Smartling
11
8
 
12
9
  ![smartling gif](https://user-images.githubusercontent.com/3969996/125689321-bf37021f-ba55-4147-83eb-1745eb8acb1f.gif)
@@ -59,7 +56,7 @@ client.createOrReplace({
59
56
  organization: 'YOUR_SMARTLING_ORGANIZATION_HERE',
60
57
  project: 'YOUR_SMARTLING_PROJECT_HERE',
61
58
  secret: '{"userIdentifier":"xxxxxx","userSecret":"xxxx"}', //in this format from Smartling when you press the button "copy token" on creation
62
- proxy: 'my-proxy-endpoint.com/api/proxy' //the endpoint you set up in step 2
59
+ proxy: 'my-proxy-endpoint.com/api/proxy', //the endpoint you set up in step 2
63
60
  })
64
61
  ```
65
62
 
@@ -126,7 +123,6 @@ Since we often find users want to use the [Document internationalization plugin]
126
123
 
127
124
  _Important_: The above is true if you are using the Document Internationalization Plugin at version 2 or above. If you are using version 1 please use the `legacyDocumentLevelConfig` configuration exported from this plugin. This configuration assumes your translations follow the pattern `{id-of-base-language-document}__i18n_{locale}`
128
125
 
129
-
130
126
  ### Final note
131
127
 
132
128
  It's okay if your data doesn't follow these patterns and you don't want to change them! You will simply have to override how the plugin gets and patches back information from your documents. Please see [Overriding defaults](#overriding-defaults).
package/dist/index.d.ts CHANGED
@@ -1,47 +1,7 @@
1
- import {Adapter} from 'sanity-translations-tab'
2
- import {BaseDocumentDeserializer} from 'sanity-translations-tab'
3
- import {BaseDocumentMerger} from 'sanity-translations-tab'
4
- import {BaseDocumentSerializer} from 'sanity-translations-tab'
5
- import {customSerializers} from 'sanity-translations-tab'
6
- import {defaultStopTypes} from 'sanity-translations-tab'
7
- import {documentLevelPatch} from 'sanity-translations-tab'
8
- import {fieldLevelPatch} from 'sanity-translations-tab'
9
- import {findLatestDraft} from 'sanity-translations-tab'
10
- import {legacyDocumentLevelPatch} from 'sanity-translations-tab'
11
- import {TranslationFunctionContext} from 'sanity-translations-tab'
12
- import {TranslationsTab} from 'sanity-translations-tab'
13
- import {TranslationsTabConfigOptions} from 'sanity-translations-tab'
14
-
15
- export {BaseDocumentDeserializer}
16
-
17
- export {BaseDocumentMerger}
18
-
19
- export {BaseDocumentSerializer}
20
-
21
- export {customSerializers}
22
-
23
- export declare const defaultDocumentLevelConfig: TranslationsTabConfigOptions
24
-
25
- export declare const defaultFieldLevelConfig: TranslationsTabConfigOptions
26
-
27
- export {defaultStopTypes}
28
-
29
- export {documentLevelPatch}
30
-
31
- export {fieldLevelPatch}
32
-
33
- export {findLatestDraft}
34
-
35
- export declare const legacyDocumentLevelConfig: TranslationsTabConfigOptions
36
-
37
- export {legacyDocumentLevelPatch}
38
-
39
- export declare const SmartlingAdapter: Adapter
40
-
41
- export {TranslationFunctionContext}
42
-
43
- export {TranslationsTab}
44
-
45
- export {TranslationsTabConfigOptions}
46
-
47
- export {}
1
+ import { Adapter, BaseDocumentDeserializer, BaseDocumentMerger, BaseDocumentSerializer, TranslationFunctionContext, TranslationsTab, TranslationsTabConfigOptions, TranslationsTabConfigOptions as TranslationsTabConfigOptions$1, customSerializers, defaultStopTypes, documentLevelPatch, fieldLevelPatch, findLatestDraft, legacyDocumentLevelPatch } from "sanity-translations-tab";
2
+ declare const SmartlingAdapter: Adapter;
3
+ declare const defaultDocumentLevelConfig: TranslationsTabConfigOptions$1;
4
+ declare const legacyDocumentLevelConfig: TranslationsTabConfigOptions$1;
5
+ declare const defaultFieldLevelConfig: TranslationsTabConfigOptions$1;
6
+ export { BaseDocumentDeserializer, BaseDocumentMerger, BaseDocumentSerializer, SmartlingAdapter, type TranslationFunctionContext, TranslationsTab, type TranslationsTabConfigOptions, customSerializers, defaultDocumentLevelConfig, defaultFieldLevelConfig, defaultStopTypes, documentLevelPatch, fieldLevelPatch, findLatestDraft, legacyDocumentLevelConfig, legacyDocumentLevelPatch };
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/adapter/index.ts","../src/index.ts"],"mappings":";cAOa,gBAAA,EAAkB,OAK9B;AAAA,cCcK,0BAAA,EAA4B,8BAGjC;AAAA,cAEK,yBAAA,EAA2B,8BAGhC;AAAA,cAEK,uBAAA,EAAyB,8BAG9B"}
package/dist/index.js CHANGED
@@ -1,50 +1,36 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', {
4
- value: true
5
- });
6
- var sanityTranslationsTab = require('sanity-translations-tab');
7
- var buffer = require('buffer');
8
- const authenticate = secrets => {
9
- const url = "https://api.smartling.com/auth-api/v2/authenticate";
1
+ import { baseDocumentLevelConfig, baseFieldLevelConfig, legacyDocumentLevelConfig as legacyDocumentLevelConfig$1 } from "sanity-translations-tab";
2
+ import { BaseDocumentDeserializer, BaseDocumentMerger, BaseDocumentSerializer, TranslationsTab, customSerializers, defaultStopTypes, documentLevelPatch, fieldLevelPatch, findLatestDraft, legacyDocumentLevelPatch } from "sanity-translations-tab";
3
+ const authenticate = (secrets) => {
10
4
  const headers = {
11
5
  "content-type": "application/json",
12
- "X-URL": url
13
- };
14
- const {
6
+ "X-URL": "https://api.smartling.com/auth-api/v2/authenticate"
7
+ }, {
15
8
  secret,
16
9
  proxy
17
10
  } = secrets;
18
- if (!secret || !proxy) {
11
+ if (!secret || !proxy)
19
12
  throw new Error("The Smartling adapter requires a secret key and a proxy URL. Please check your secrets document in this dataset, per the plugin documentation.");
20
- }
21
13
  return fetch(proxy, {
22
14
  headers,
23
15
  method: "POST",
24
16
  body: JSON.stringify(secret)
25
- }).then(res => res.json()).then(res => res.response.data.accessToken);
26
- };
27
- const getHeaders = (url, accessToken) => ({
28
- Authorization: "Bearer ".concat(accessToken),
17
+ }).then((res) => res.json()).then((res) => res.response.data.accessToken);
18
+ }, getHeaders = (url, accessToken) => ({
19
+ Authorization: `Bearer ${accessToken}`,
29
20
  "X-URL": url
30
- });
31
- const findExistingJob = async (documentId, secrets, accessToken) => {
21
+ }), findExistingJob = async (documentId, secrets, accessToken) => {
32
22
  const {
33
23
  project,
34
24
  proxy
35
25
  } = secrets;
36
- if (!project || !proxy) {
26
+ if (!project || !proxy)
37
27
  throw new Error("The Smartling adapter requires a Smartling project identifier and a proxy URL. Please check your secrets document in this dataset, per the plugin documentation.");
38
- }
39
- const url = "https://api.smartling.com/jobs-api/v3/projects/".concat(project, "/jobs?jobName=").concat(documentId);
28
+ const url = `https://api.smartling.com/jobs-api/v3/projects/${project}/jobs?jobName=${documentId}`;
40
29
  let items = await fetch(proxy, {
41
30
  headers: getHeaders(url, accessToken)
42
- }).then(res => res.json()).then(res => {
43
- var _a, _b;
44
- return (_b = (_a = res == null ? void 0 : res.response) == null ? void 0 : _a.data) == null ? void 0 : _b.items;
45
- });
31
+ }).then((res) => res.json()).then((res) => res?.response?.data?.items);
46
32
  if (!items || !items.length) {
47
- const refUrl = "https://api.smartling.com/jobs-api/v3/projects/".concat(project, "/jobs/search");
33
+ const refUrl = `https://api.smartling.com/jobs-api/v3/projects/${project}/jobs/search`;
48
34
  items = await fetch(proxy, {
49
35
  headers: {
50
36
  ...getHeaders(refUrl, accessToken),
@@ -54,97 +40,62 @@ const findExistingJob = async (documentId, secrets, accessToken) => {
54
40
  body: JSON.stringify({
55
41
  fileUris: [documentId]
56
42
  })
57
- }).then(res => res.json()).then(res => {
58
- var _a, _b;
59
- return (_b = (_a = res == null ? void 0 : res.response) == null ? void 0 : _a.data) == null ? void 0 : _b.items;
60
- });
43
+ }).then((res) => res.json()).then((res) => res?.response?.data?.items);
61
44
  }
62
45
  if (items.length) {
63
- const correctJob = items.filter(item => item.jobStatus !== "DELETED").find(item => item.jobName && item.jobName === documentId || item.referenceNumber && item.referenceNumber === documentId);
64
- if (correctJob) {
46
+ const correctJob = items.filter((item) => item.jobStatus !== "DELETED").find((item) => item.jobName && item.jobName === documentId || item.referenceNumber && item.referenceNumber === documentId);
47
+ if (correctJob)
65
48
  return correctJob.translationJobUid;
66
- }
67
49
  }
68
50
  return "";
69
- };
70
- const getLocales = async secrets => {
71
- if (!(secrets == null ? void 0 : secrets.project) || !(secrets == null ? void 0 : secrets.secret) || !(secrets == null ? void 0 : secrets.proxy)) {
72
- return [];
73
- }
74
- const {
75
- project,
76
- proxy
77
- } = secrets;
78
- const url = "https://api.smartling.com/projects-api/v2/projects/".concat(project);
79
- const accessToken = await authenticate(secrets);
80
- return fetch(proxy, {
81
- method: "GET",
82
- headers: getHeaders(url, accessToken)
83
- }).then(res => res.json()).then(res => res.response.data.targetLocales);
84
- };
85
- const getTranslationTask = async (documentId, secrets) => {
86
- if (!(secrets == null ? void 0 : secrets.project) || !(secrets == null ? void 0 : secrets.secret) || !(secrets == null ? void 0 : secrets.proxy)) {
51
+ }, getTranslationTask = async (documentId, secrets) => {
52
+ if (!secrets?.project || !secrets?.secret || !secrets?.proxy)
87
53
  return {
88
54
  documentId,
89
55
  taskId: documentId,
90
56
  locales: []
91
57
  };
92
- }
93
58
  const {
94
59
  project,
95
60
  proxy
96
- } = secrets;
97
- const accessToken = await authenticate(secrets);
98
- const taskId = await findExistingJob(documentId, secrets, accessToken);
99
- if (!taskId) {
61
+ } = secrets, accessToken = await authenticate(secrets), taskId = await findExistingJob(documentId, secrets, accessToken);
62
+ if (!taskId)
100
63
  return {
101
64
  documentId,
102
65
  taskId: documentId,
103
66
  locales: []
104
67
  };
105
- }
106
- const progressUrl = "https://api.smartling.com/jobs-api/v3/projects/".concat(project, "/jobs/").concat(taskId, "/progress");
107
- const smartlingTask = await fetch(proxy, {
68
+ const progressUrl = `https://api.smartling.com/jobs-api/v3/projects/${project}/jobs/${taskId}/progress`, smartlingTask = await fetch(proxy, {
108
69
  method: "GET",
109
70
  headers: getHeaders(progressUrl, accessToken)
110
- }).then(res => res.json()).then(res => res.response.data);
71
+ }).then((res) => res.json()).then((res) => res.response.data);
111
72
  let locales = [];
112
- if (smartlingTask && smartlingTask.contentProgressReport) {
113
- locales = smartlingTask.contentProgressReport.map(item => {
114
- var _a;
115
- let progress = item.progress ? item.progress.percentComplete : 0;
116
- if (item.workflowProgressReportList && item.workflowProgressReportList.length > 0 && item.progress) {
117
- const progressItem = item.workflowProgressReportList[0];
118
- if (progressItem.workflowStepSummaryReportItemList && progressItem.workflowStepSummaryReportItemList.length > 1) {
119
- const lastStep = progressItem.workflowStepSummaryReportItemList.at(-1);
120
- if (lastStep && lastStep.wordCount >= 0) {
121
- progress = (_a = Math.floor(lastStep.wordCount / item.progress.totalWordCount * 100)) != null ? _a : 0;
122
- }
123
- }
124
- }
125
- return {
126
- localeId: item.targetLocaleId,
127
- progress
128
- };
129
- });
130
- }
131
- return {
73
+ return smartlingTask && smartlingTask.contentProgressReport && (locales = smartlingTask.contentProgressReport.map((item) => {
74
+ let progress = item.progress ? item.progress.percentComplete : 0;
75
+ const progressItem = item.workflowProgressReportList?.[0];
76
+ if (progressItem && item.progress && progressItem.workflowStepSummaryReportItemList && progressItem.workflowStepSummaryReportItemList.length > 1) {
77
+ const lastStep = progressItem.workflowStepSummaryReportItemList.at(-1);
78
+ lastStep && lastStep.wordCount >= 0 && (progress = Math.floor(lastStep.wordCount / item.progress.totalWordCount * 100) ?? 0);
79
+ }
80
+ return {
81
+ localeId: item.targetLocaleId,
82
+ progress
83
+ };
84
+ })), {
132
85
  documentId,
133
86
  locales,
134
87
  //since our download is tied to document id for smartling, keep track of it as a task
135
88
  taskId: documentId,
136
- linkToVendorTask: "https://dashboard.smartling.com/app/projects/".concat(project, "/account-jobs/").concat(project, ":").concat(taskId)
89
+ linkToVendorTask: `https://dashboard.smartling.com/app/projects/${project}/account-jobs/${project}:${taskId}`
137
90
  };
138
- };
139
- const createJob = (jobName, secrets, localeIds, accessToken, documentId) => {
91
+ }, createJob = (jobName, secrets, localeIds, accessToken, documentId) => {
140
92
  const {
141
93
  project,
142
94
  proxy
143
95
  } = secrets;
144
- if (!project || !proxy) {
96
+ if (!project || !proxy)
145
97
  throw new Error("The Smartling adapter requires a Smartling project identifier and a proxy URL. Please check your secrets document in this dataset, per the plugin documentation.");
146
- }
147
- const url = "https://api.smartling.com/jobs-api/v3/projects/".concat(project, "/jobs");
98
+ const url = `https://api.smartling.com/jobs-api/v3/projects/${project}/jobs`;
148
99
  return fetch(proxy, {
149
100
  method: "POST",
150
101
  headers: {
@@ -156,180 +107,110 @@ const createJob = (jobName, secrets, localeIds, accessToken, documentId) => {
156
107
  targetLocaleIds: localeIds,
157
108
  referenceNumber: documentId
158
109
  })
159
- }).then(res => res.json()).then(res => res.response.data.translationJobUid);
160
- };
161
- const createJobBatch = (jobId, secrets, documentId, accessToken, localeIds, workflowUid) => {
110
+ }).then((res) => res.json()).then((res) => res.response.data.translationJobUid);
111
+ }, createJobBatch = (jobId, secrets, documentId, accessToken, localeIds, workflowUid) => {
162
112
  const {
163
113
  project,
164
114
  proxy
165
115
  } = secrets;
166
- if (!project || !proxy) {
116
+ if (!project || !proxy)
167
117
  throw new Error("The Smartling adapter requires a Smartling project identifier and a proxy URL. Please check your secrets document in this dataset, per the plugin documentation.");
168
- }
169
- const url = "https://api.smartling.com/job-batches-api/v2/projects/".concat(project, "/batches");
170
- const reqBody = {
171
- authorize: true,
118
+ const url = `https://api.smartling.com/job-batches-api/v2/projects/${project}/batches`, reqBody = {
119
+ authorize: !0,
172
120
  translationJobUid: jobId,
173
121
  fileUris: [documentId]
174
122
  };
175
- if (workflowUid) {
176
- reqBody.localeWorkflows = localeIds.map(l => ({
177
- targetLocaleId: l,
178
- workflowUid
179
- }));
180
- }
181
- return fetch(proxy, {
123
+ return workflowUid && (reqBody.localeWorkflows = localeIds.map((l) => ({
124
+ targetLocaleId: l,
125
+ workflowUid
126
+ }))), fetch(proxy, {
182
127
  method: "POST",
183
128
  headers: {
184
129
  ...getHeaders(url, accessToken),
185
130
  "content-type": "application/json"
186
131
  },
187
132
  body: JSON.stringify(reqBody)
188
- }).then(res => res.json()).then(res => res.response.data.batchUid);
189
- };
190
- const uploadFileToBatch = (batchUid, documentId, document, secrets, localeIds, accessToken, callbackUrl) => {
133
+ }).then((res) => res.json()).then((res) => res.response.data.batchUid);
134
+ }, uploadFileToBatch = (batchUid, documentId, document, secrets, localeIds, accessToken, callbackUrl) => {
191
135
  const {
192
136
  project,
193
137
  proxy
194
138
  } = secrets;
195
- if (!project || !proxy) {
139
+ if (!project || !proxy)
196
140
  throw new Error("The Smartling adapter requires a Smartling project identifier and a proxy URL. Please check your secrets document in this dataset, per the plugin documentation.");
197
- }
198
- const url = "https://api.smartling.com/job-batches-api/v2/projects/".concat(project, "/batches/").concat(batchUid, "/file");
199
- const formData = new FormData();
200
- formData.append("fileUri", documentId);
201
- formData.append("fileType", "html");
202
- const htmlBuffer = buffer.Buffer.from(document.content, "utf-8");
203
- formData.append("file", new Blob([htmlBuffer]), "".concat(document.name, ".html"));
204
- localeIds.forEach(localeId => formData.append("localeIdsToAuthorize[]", localeId));
205
- if (callbackUrl) {
206
- formData.append("callbackUrl", callbackUrl);
207
- }
208
- return fetch(proxy, {
141
+ const url = `https://api.smartling.com/job-batches-api/v2/projects/${project}/batches/${batchUid}/file`, formData = new FormData();
142
+ return formData.append("fileUri", documentId), formData.append("fileType", "html"), formData.append("file", new Blob([document.content]), `${document.name}.html`), localeIds.forEach((localeId) => formData.append("localeIdsToAuthorize[]", localeId)), callbackUrl && formData.append("callbackUrl", callbackUrl), fetch(proxy, {
209
143
  method: "POST",
210
144
  headers: getHeaders(url, accessToken),
211
145
  body: formData
212
- }).then(res => res.json());
213
- };
214
- const createTask = async (documentId, document, localeIds, secrets, workflowUid, callbackUrl) => {
215
- if (!(secrets == null ? void 0 : secrets.project) || !(secrets == null ? void 0 : secrets.secret) || !(secrets == null ? void 0 : secrets.proxy)) {
146
+ }).then((res) => res.json());
147
+ }, createTask = async (documentId, document, localeIds, secrets, workflowUid, callbackUrl) => {
148
+ if (!secrets?.project || !secrets?.secret || !secrets?.proxy)
216
149
  throw new Error("The Smartling adapter requires a project ID, a secret key, and a proxy URL. Please check your secrets document in this dataset, per the plugin documentation.");
217
- }
218
150
  const accessToken = await authenticate(secrets);
219
151
  let taskId = await findExistingJob(document.name, secrets, accessToken);
220
- if (!taskId) {
221
- taskId = await createJob(document.name, secrets, localeIds, accessToken, documentId);
222
- }
152
+ taskId || (taskId = await createJob(document.name, secrets, localeIds, accessToken, documentId));
223
153
  const batchUid = await createJobBatch(taskId, secrets, documentId, accessToken, localeIds, workflowUid);
224
- const uploadFileRes = await uploadFileToBatch(batchUid, documentId, document, secrets, localeIds, accessToken, callbackUrl);
225
- console.info("Upload status from Smartling: ", uploadFileRes);
226
- return getTranslationTask(documentId, secrets);
227
- };
228
- const getTranslation = async (taskId, localeId, secrets) => {
229
- if (!(secrets == null ? void 0 : secrets.project) || !(secrets == null ? void 0 : secrets.secret) || !(secrets == null ? void 0 : secrets.proxy)) {
154
+ return await uploadFileToBatch(batchUid, documentId, document, secrets, localeIds, accessToken, callbackUrl), getTranslationTask(documentId, secrets);
155
+ }, getLocales = async (secrets) => {
156
+ if (!secrets?.project || !secrets?.secret || !secrets?.proxy)
157
+ return [];
158
+ const {
159
+ project,
160
+ proxy
161
+ } = secrets, url = `https://api.smartling.com/projects-api/v2/projects/${project}`, accessToken = await authenticate(secrets);
162
+ return fetch(proxy, {
163
+ method: "GET",
164
+ headers: getHeaders(url, accessToken)
165
+ }).then((res) => res.json()).then((res) => res.response.data.targetLocales);
166
+ }, getTranslation = async (taskId, localeId, secrets) => {
167
+ if (!secrets?.project || !secrets?.secret || !secrets?.proxy)
230
168
  throw new Error("The Smartling adapter requires a project ID, a secret key, and a proxy URL. Please check your secrets document in this dataset, per the plugin documentation.");
231
- }
232
169
  const {
233
170
  project,
234
171
  proxy
235
- } = secrets;
236
- const url = "https://api.smartling.com/files-api/v2/projects/".concat(project, "/locales/").concat(localeId, "/file?fileUri=").concat(taskId, "&retrievalType=pending");
237
- const accessToken = await authenticate(secrets);
238
- const translatedHTML = await fetch(proxy, {
172
+ } = secrets, url = `https://api.smartling.com/files-api/v2/projects/${project}/locales/${localeId}/file?fileUri=${taskId}&retrievalType=pending`, accessToken = await authenticate(secrets);
173
+ return await fetch(proxy, {
239
174
  method: "GET",
240
175
  headers: getHeaders(url, accessToken)
241
- }).then(res => res.json()).then(res => {
242
- var _a;
243
- if (res.body) {
176
+ }).then((res) => res.json()).then((res) => {
177
+ if (res.body)
244
178
  return res.body;
245
- } else if (res.response.errors) {
246
- const errMsg = ((_a = res.response.errors[0]) == null ? void 0 : _a.message) || "Error retrieving translation from Smartling";
179
+ if (res.response.errors) {
180
+ const errMsg = res.response.errors[0]?.message || "Error retrieving translation from Smartling";
247
181
  throw new Error(errMsg);
248
182
  }
249
183
  return "";
250
184
  });
251
- return translatedHTML;
252
- };
253
- const SmartlingAdapter = {
185
+ }, SmartlingAdapter = {
254
186
  getLocales,
255
187
  getTranslationTask,
256
188
  createTask,
257
189
  getTranslation
258
- };
259
- const defaultDocumentLevelConfig = {
260
- ...sanityTranslationsTab.baseDocumentLevelConfig,
190
+ }, defaultDocumentLevelConfig = {
191
+ ...baseDocumentLevelConfig,
261
192
  adapter: SmartlingAdapter
262
- };
263
- const legacyDocumentLevelConfig = {
264
- ...sanityTranslationsTab.legacyDocumentLevelConfig,
193
+ }, legacyDocumentLevelConfig = {
194
+ ...legacyDocumentLevelConfig$1,
265
195
  adapter: SmartlingAdapter
266
- };
267
- const defaultFieldLevelConfig = {
268
- ...sanityTranslationsTab.baseFieldLevelConfig,
196
+ }, defaultFieldLevelConfig = {
197
+ ...baseFieldLevelConfig,
269
198
  adapter: SmartlingAdapter
270
199
  };
271
- Object.defineProperty(exports, 'BaseDocumentDeserializer', {
272
- enumerable: true,
273
- get: function () {
274
- return sanityTranslationsTab.BaseDocumentDeserializer;
275
- }
276
- });
277
- Object.defineProperty(exports, 'BaseDocumentMerger', {
278
- enumerable: true,
279
- get: function () {
280
- return sanityTranslationsTab.BaseDocumentMerger;
281
- }
282
- });
283
- Object.defineProperty(exports, 'BaseDocumentSerializer', {
284
- enumerable: true,
285
- get: function () {
286
- return sanityTranslationsTab.BaseDocumentSerializer;
287
- }
288
- });
289
- Object.defineProperty(exports, 'TranslationsTab', {
290
- enumerable: true,
291
- get: function () {
292
- return sanityTranslationsTab.TranslationsTab;
293
- }
294
- });
295
- Object.defineProperty(exports, 'customSerializers', {
296
- enumerable: true,
297
- get: function () {
298
- return sanityTranslationsTab.customSerializers;
299
- }
300
- });
301
- Object.defineProperty(exports, 'defaultStopTypes', {
302
- enumerable: true,
303
- get: function () {
304
- return sanityTranslationsTab.defaultStopTypes;
305
- }
306
- });
307
- Object.defineProperty(exports, 'documentLevelPatch', {
308
- enumerable: true,
309
- get: function () {
310
- return sanityTranslationsTab.documentLevelPatch;
311
- }
312
- });
313
- Object.defineProperty(exports, 'fieldLevelPatch', {
314
- enumerable: true,
315
- get: function () {
316
- return sanityTranslationsTab.fieldLevelPatch;
317
- }
318
- });
319
- Object.defineProperty(exports, 'findLatestDraft', {
320
- enumerable: true,
321
- get: function () {
322
- return sanityTranslationsTab.findLatestDraft;
323
- }
324
- });
325
- Object.defineProperty(exports, 'legacyDocumentLevelPatch', {
326
- enumerable: true,
327
- get: function () {
328
- return sanityTranslationsTab.legacyDocumentLevelPatch;
329
- }
330
- });
331
- exports.SmartlingAdapter = SmartlingAdapter;
332
- exports.defaultDocumentLevelConfig = defaultDocumentLevelConfig;
333
- exports.defaultFieldLevelConfig = defaultFieldLevelConfig;
334
- exports.legacyDocumentLevelConfig = legacyDocumentLevelConfig;
200
+ export {
201
+ BaseDocumentDeserializer,
202
+ BaseDocumentMerger,
203
+ BaseDocumentSerializer,
204
+ SmartlingAdapter,
205
+ TranslationsTab,
206
+ customSerializers,
207
+ defaultDocumentLevelConfig,
208
+ defaultFieldLevelConfig,
209
+ defaultStopTypes,
210
+ documentLevelPatch,
211
+ fieldLevelPatch,
212
+ findLatestDraft,
213
+ legacyDocumentLevelConfig,
214
+ legacyDocumentLevelPatch
215
+ };
335
216
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/adapter/helpers.ts","../src/adapter/getLocales.ts","../src/adapter/getTranslationTask.ts","../src/adapter/createTask.ts","../src/adapter/getTranslation.ts","../src/adapter/index.ts","../src/index.ts"],"sourcesContent":["import {Secrets} from 'sanity-translations-tab'\n\ninterface Headers {\n [key: string]: string\n}\n\nexport const authenticate = (secrets: Secrets): Promise<string> => {\n const url = 'https://api.smartling.com/auth-api/v2/authenticate'\n const headers = {\n 'content-type': 'application/json',\n 'X-URL': url,\n }\n const {secret, proxy} = secrets\n if (!secret || !proxy) {\n throw new Error(\n 'The Smartling adapter requires a secret key and a proxy URL. Please check your secrets document in this dataset, per the plugin documentation.',\n )\n }\n return fetch(proxy, {\n headers,\n method: 'POST',\n body: JSON.stringify(secret),\n })\n .then((res) => res.json())\n .then((res) => res.response.data.accessToken)\n}\n\nexport const getHeaders = (url: string, accessToken: string): Headers => ({\n Authorization: `Bearer ${accessToken}`,\n 'X-URL': url,\n})\n\nexport const findExistingJob = async (\n documentId: string,\n secrets: Secrets,\n accessToken: string,\n): Promise<string> => {\n const {project, proxy} = secrets\n if (!project || !proxy) {\n throw new Error(\n 'The Smartling adapter requires a Smartling project identifier and a proxy URL. Please check your secrets document in this dataset, per the plugin documentation.',\n )\n }\n const url = `https://api.smartling.com/jobs-api/v3/projects/${project}/jobs?jobName=${documentId}`\n //first, try fetching from name resolution\n let items = await fetch(proxy, {\n headers: getHeaders(url, accessToken),\n })\n .then((res) => res.json())\n .then((res) => res?.response?.data?.items)\n\n if (!items || !items.length) {\n //if that fails, try fetching by fileUri and check the referenceNumber\n const refUrl = `https://api.smartling.com/jobs-api/v3/projects/${project}/jobs/search`\n items = await fetch(proxy, {\n headers: {\n ...getHeaders(refUrl, accessToken),\n 'content-type': 'application/json',\n },\n method: 'POST',\n body: JSON.stringify({\n fileUris: [documentId],\n }),\n })\n .then((res) => res.json())\n .then((res) => res?.response?.data?.items)\n }\n\n if (items.length) {\n //smartling will fuzzy match job names. We need to be precise.\n const correctJob = items\n .filter((item: {jobStatus: string}) => item.jobStatus !== 'DELETED')\n .find(\n (item: {jobName: string; referenceNumber: string}) =>\n (item.jobName && item.jobName === documentId) ||\n (item.referenceNumber && item.referenceNumber === documentId),\n )\n\n if (correctJob) {\n return correctJob.translationJobUid\n }\n }\n return ''\n}\n","import {authenticate, getHeaders} from './helpers'\nimport {Secrets} from 'sanity-translations-tab'\nimport {Adapter} from 'sanity-translations-tab'\n\nexport const getLocales: Adapter['getLocales'] = async (secrets: Secrets | null) => {\n if (!secrets?.project || !secrets?.secret || !secrets?.proxy) {\n return []\n }\n const {project, proxy} = secrets\n const url = `https://api.smartling.com/projects-api/v2/projects/${project}`\n const accessToken = await authenticate(secrets)\n return fetch(proxy, {\n method: 'GET',\n headers: getHeaders(url, accessToken),\n })\n .then((res) => res.json())\n .then((res) => res.response.data.targetLocales)\n}\n","import {authenticate, getHeaders, findExistingJob} from './helpers'\nimport {Adapter, Secrets} from 'sanity-translations-tab'\n\ninterface WorkflowProgressItem {\n workflowStepSummaryReportItemList: {\n wordCount: number\n }[]\n}\n\ninterface SmartlingProgressItem {\n targetLocaleId: string\n progress: {\n percentComplete: number\n totalWordCount: number\n }\n workflowProgressReportList: WorkflowProgressItem[]\n}\n\nexport const getTranslationTask: Adapter['getTranslationTask'] = async (\n documentId: string,\n secrets: Secrets | null,\n) => {\n if (!secrets?.project || !secrets?.secret || !secrets?.proxy) {\n return {\n documentId,\n taskId: documentId,\n locales: [],\n }\n }\n\n const {project, proxy} = secrets\n\n const accessToken = await authenticate(secrets)\n const taskId = await findExistingJob(documentId, secrets, accessToken)\n if (!taskId) {\n return {\n documentId,\n taskId: documentId,\n locales: [],\n }\n }\n\n const progressUrl = `https://api.smartling.com/jobs-api/v3/projects/${project}/jobs/${taskId}/progress`\n const smartlingTask = await fetch(proxy, {\n method: 'GET',\n headers: getHeaders(progressUrl, accessToken),\n })\n .then((res) => res.json())\n .then((res) => res.response.data)\n\n let locales = []\n if (smartlingTask && smartlingTask.contentProgressReport) {\n locales = smartlingTask.contentProgressReport.map((item: SmartlingProgressItem) => {\n let progress = item.progress ? item.progress.percentComplete : 0\n if (\n item.workflowProgressReportList &&\n item.workflowProgressReportList.length > 0 &&\n item.progress\n ) {\n //default to the first workflow -- it's likely what is being used\n const progressItem = item.workflowProgressReportList[0]\n //this is a list of the various steps in the workflow\n if (\n progressItem.workflowStepSummaryReportItemList &&\n progressItem.workflowStepSummaryReportItemList.length > 1\n ) {\n //get the last step in the workflow -- usually \"published\"\n const lastStep = progressItem.workflowStepSummaryReportItemList.at(-1)\n //get the percentage of how many words have reached the last step\n if (lastStep && lastStep.wordCount >= 0) {\n progress = Math.floor((lastStep.wordCount / item.progress.totalWordCount) * 100) ?? 0\n }\n }\n }\n return {\n localeId: item.targetLocaleId,\n progress,\n }\n })\n }\n\n return {\n documentId,\n locales,\n //since our download is tied to document id for smartling, keep track of it as a task\n taskId: documentId,\n linkToVendorTask: `https://dashboard.smartling.com/app/projects/${project}/account-jobs/${project}:${taskId}`,\n }\n}\n","import {authenticate, getHeaders, findExistingJob} from './helpers'\nimport {Adapter, Secrets, SerializedDocument} from 'sanity-translations-tab'\nimport {getTranslationTask} from './getTranslationTask'\nimport {Buffer} from 'buffer'\n\nconst createJob = (\n jobName: string,\n secrets: Secrets,\n localeIds: string[],\n accessToken: string,\n documentId: string,\n) => {\n const {project, proxy} = secrets\n if (!project || !proxy) {\n throw new Error(\n 'The Smartling adapter requires a Smartling project identifier and a proxy URL. Please check your secrets document in this dataset, per the plugin documentation.',\n )\n }\n\n const url = `https://api.smartling.com/jobs-api/v3/projects/${project}/jobs`\n return fetch(proxy, {\n method: 'POST',\n headers: {\n ...getHeaders(url, accessToken),\n 'content-type': 'application/json',\n },\n body: JSON.stringify({\n jobName,\n targetLocaleIds: localeIds,\n referenceNumber: documentId,\n }),\n })\n .then((res) => res.json())\n .then((res) => res.response.data.translationJobUid)\n}\n\n/* we're using batches here because it eliminates some\n * new string authorization issues for updating existing jobs,\n * and is able to be used for new bulk\n * job functionality.\n */\n\nconst createJobBatch = (\n jobId: string,\n secrets: Secrets,\n documentId: string,\n accessToken: string,\n localeIds: string[],\n workflowUid?: string,\n //eslint-disable-next-line max-params\n) => {\n const {project, proxy} = secrets\n if (!project || !proxy) {\n throw new Error(\n 'The Smartling adapter requires a Smartling project identifier and a proxy URL. Please check your secrets document in this dataset, per the plugin documentation.',\n )\n }\n const url = `https://api.smartling.com/job-batches-api/v2/projects/${project}/batches`\n const reqBody: {\n authorize: boolean\n translationJobUid: string\n fileUris: string[]\n localeWorkflows?: {targetLocaleId: string; workflowUid: string}[]\n } = {\n authorize: true,\n translationJobUid: jobId,\n fileUris: [documentId],\n }\n\n if (workflowUid) {\n reqBody.localeWorkflows = localeIds.map((l) => ({\n targetLocaleId: l,\n workflowUid,\n }))\n }\n\n return fetch(proxy, {\n method: 'POST',\n headers: {\n ...getHeaders(url, accessToken),\n 'content-type': 'application/json',\n },\n body: JSON.stringify(reqBody),\n })\n .then((res) => res.json())\n .then((res) => res.response.data.batchUid)\n}\n\nconst uploadFileToBatch = (\n batchUid: string,\n documentId: string,\n document: SerializedDocument,\n secrets: Secrets,\n localeIds: string[],\n accessToken: string,\n callbackUrl?: string,\n //eslint-disable-next-line max-params\n) => {\n const {project, proxy} = secrets\n if (!project || !proxy) {\n throw new Error(\n 'The Smartling adapter requires a Smartling project identifier and a proxy URL. Please check your secrets document in this dataset, per the plugin documentation.',\n )\n }\n const url = `https://api.smartling.com/job-batches-api/v2/projects/${project}/batches/${batchUid}/file`\n const formData = new FormData()\n formData.append('fileUri', documentId)\n formData.append('fileType', 'html')\n const htmlBuffer = Buffer.from(document.content, 'utf-8')\n formData.append('file', new Blob([htmlBuffer]), `${document.name}.html`)\n localeIds.forEach((localeId) => formData.append('localeIdsToAuthorize[]', localeId))\n if (callbackUrl) {\n formData.append('callbackUrl', callbackUrl)\n }\n\n return fetch(proxy, {\n method: 'POST',\n headers: getHeaders(url, accessToken),\n body: formData,\n }).then((res) => res.json())\n}\n\nexport const createTask: Adapter['createTask'] = async (\n documentId: string,\n document: SerializedDocument,\n localeIds: string[],\n secrets: Secrets | null,\n workflowUid?: string,\n callbackUrl?: string,\n // eslint-disable-next-line max-params\n) => {\n if (!secrets?.project || !secrets?.secret || !secrets?.proxy) {\n throw new Error(\n 'The Smartling adapter requires a project ID, a secret key, and a proxy URL. Please check your secrets document in this dataset, per the plugin documentation.',\n )\n }\n\n const accessToken = await authenticate(secrets)\n\n let taskId = await findExistingJob(document.name, secrets, accessToken)\n if (!taskId) {\n taskId = await createJob(document.name, secrets, localeIds, accessToken, documentId)\n }\n\n const batchUid = await createJobBatch(\n taskId,\n secrets,\n documentId,\n accessToken,\n localeIds,\n workflowUid,\n )\n const uploadFileRes = await uploadFileToBatch(\n batchUid,\n documentId,\n document,\n secrets,\n localeIds,\n accessToken,\n callbackUrl,\n )\n //eslint-disable-next-line no-console -- for developer debugging\n console.info('Upload status from Smartling: ', uploadFileRes)\n\n return getTranslationTask(documentId, secrets)\n}\n","import {authenticate, getHeaders} from './helpers'\nimport {Adapter, Secrets} from 'sanity-translations-tab'\n\nexport const getTranslation: Adapter['getTranslation'] = async (\n taskId: string,\n localeId: string,\n secrets: Secrets | null,\n) => {\n if (!secrets?.project || !secrets?.secret || !secrets?.proxy) {\n throw new Error(\n 'The Smartling adapter requires a project ID, a secret key, and a proxy URL. Please check your secrets document in this dataset, per the plugin documentation.',\n )\n }\n\n const {project, proxy} = secrets\n\n const url = `https://api.smartling.com/files-api/v2/projects/${project}/locales/${localeId}/file?fileUri=${taskId}&retrievalType=pending`\n const accessToken = await authenticate(secrets)\n const translatedHTML = await fetch(proxy, {\n method: 'GET',\n headers: getHeaders(url, accessToken),\n })\n .then((res) => res.json())\n .then((res) => {\n if (res.body) {\n return res.body\n } else if (res.response.errors) {\n const errMsg =\n res.response.errors[0]?.message || 'Error retrieving translation from Smartling'\n throw new Error(errMsg)\n }\n return ''\n })\n\n return translatedHTML\n}\n","import {Adapter} from 'sanity-translations-tab'\nimport {getLocales} from './getLocales'\nimport {getTranslationTask} from './getTranslationTask'\nimport {createTask} from './createTask'\nimport {getTranslation} from './getTranslation'\n\nexport const SmartlingAdapter: Adapter = {\n getLocales,\n getTranslationTask,\n createTask,\n getTranslation,\n}\n","import {\n TranslationsTab,\n baseDocumentLevelConfig,\n legacyDocumentLevelConfig as baseLegacyDocumentLevelConfig,\n baseFieldLevelConfig,\n findLatestDraft,\n BaseDocumentDeserializer,\n BaseDocumentSerializer,\n BaseDocumentMerger,\n defaultStopTypes,\n customSerializers,\n legacyDocumentLevelPatch,\n documentLevelPatch,\n fieldLevelPatch,\n TranslationFunctionContext,\n TranslationsTabConfigOptions,\n} from 'sanity-translations-tab'\nimport {SmartlingAdapter} from './adapter'\n\nconst defaultDocumentLevelConfig: TranslationsTabConfigOptions = {\n ...baseDocumentLevelConfig,\n adapter: SmartlingAdapter,\n}\n\nconst legacyDocumentLevelConfig: TranslationsTabConfigOptions = {\n ...baseLegacyDocumentLevelConfig,\n adapter: SmartlingAdapter,\n}\n\nconst defaultFieldLevelConfig: TranslationsTabConfigOptions = {\n ...baseFieldLevelConfig,\n adapter: SmartlingAdapter,\n}\n\nexport {\n TranslationsTab,\n findLatestDraft,\n legacyDocumentLevelPatch,\n documentLevelPatch,\n fieldLevelPatch,\n BaseDocumentDeserializer,\n BaseDocumentSerializer,\n BaseDocumentMerger,\n defaultStopTypes,\n customSerializers,\n SmartlingAdapter,\n legacyDocumentLevelConfig,\n defaultDocumentLevelConfig,\n defaultFieldLevelConfig,\n}\n\nexport type {TranslationFunctionContext, TranslationsTabConfigOptions}\n"],"names":["authenticate","secrets","url","headers","secret","proxy","Error","fetch","method","body","JSON","stringify","then","res","json","response","data","accessToken","getHeaders","Authorization","concat","findExistingJob","documentId","project","items","_a","_b","length","refUrl","fileUris","correctJob","filter","item","jobStatus","find","jobName","referenceNumber","translationJobUid","getLocales","targetLocales","getTranslationTask","taskId","locales","progressUrl","smartlingTask","contentProgressReport","map","progress","percentComplete","workflowProgressReportList","progressItem","workflowStepSummaryReportItemList","lastStep","at","wordCount","Math","floor","totalWordCount","localeId","targetLocaleId","linkToVendorTask","createJob","localeIds","targetLocaleIds","createJobBatch","jobId","workflowUid","reqBody","authorize","localeWorkflows","l","batchUid","uploadFileToBatch","document","callbackUrl","formData","FormData","append","htmlBuffer","Buffer","from","content","Blob","name","forEach","createTask","uploadFileRes","console","info","getTranslation","translatedHTML","errors","errMsg","message","SmartlingAdapter","defaultDocumentLevelConfig","baseDocumentLevelConfig","adapter","legacyDocumentLevelConfig","baseLegacyDocumentLevelConfig","defaultFieldLevelConfig","baseFieldLevelConfig"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/adapter/helpers.ts","../src/adapter/getTranslationTask.ts","../src/adapter/createTask.ts","../src/adapter/getLocales.ts","../src/adapter/getTranslation.ts","../src/adapter/index.ts","../src/index.ts"],"sourcesContent":["import type {Secrets} from 'sanity-translations-tab'\n\nexport const authenticate = (secrets: Secrets): Promise<string> => {\n const url = 'https://api.smartling.com/auth-api/v2/authenticate'\n const headers = {\n 'content-type': 'application/json',\n 'X-URL': url,\n }\n const {secret, proxy} = secrets\n if (!secret || !proxy) {\n throw new Error(\n 'The Smartling adapter requires a secret key and a proxy URL. Please check your secrets document in this dataset, per the plugin documentation.',\n )\n }\n return fetch(proxy, {\n headers,\n method: 'POST',\n body: JSON.stringify(secret),\n })\n .then((res) => res.json())\n .then((res) => res.response.data.accessToken)\n}\n\nexport const getHeaders = (url: string, accessToken: string): Record<string, string> => ({\n 'Authorization': `Bearer ${accessToken}`,\n 'X-URL': url,\n})\n\nexport const findExistingJob = async (\n documentId: string,\n secrets: Secrets,\n accessToken: string,\n): Promise<string> => {\n const {project, proxy} = secrets\n if (!project || !proxy) {\n throw new Error(\n 'The Smartling adapter requires a Smartling project identifier and a proxy URL. Please check your secrets document in this dataset, per the plugin documentation.',\n )\n }\n const url = `https://api.smartling.com/jobs-api/v3/projects/${project}/jobs?jobName=${documentId}`\n //first, try fetching from name resolution\n let items = await fetch(proxy, {\n headers: getHeaders(url, accessToken),\n })\n .then((res) => res.json())\n .then((res) => res?.response?.data?.items)\n\n if (!items || !items.length) {\n //if that fails, try fetching by fileUri and check the referenceNumber\n const refUrl = `https://api.smartling.com/jobs-api/v3/projects/${project}/jobs/search`\n items = await fetch(proxy, {\n headers: {\n ...getHeaders(refUrl, accessToken),\n 'content-type': 'application/json',\n },\n method: 'POST',\n body: JSON.stringify({\n fileUris: [documentId],\n }),\n })\n .then((res) => res.json())\n .then((res) => res?.response?.data?.items)\n }\n\n if (items.length) {\n //smartling will fuzzy match job names. We need to be precise.\n const correctJob = items\n .filter((item: {jobStatus: string}) => item.jobStatus !== 'DELETED')\n .find(\n (item: {jobName: string; referenceNumber: string}) =>\n (item.jobName && item.jobName === documentId) ||\n (item.referenceNumber && item.referenceNumber === documentId),\n )\n\n if (correctJob) {\n return correctJob.translationJobUid\n }\n }\n return ''\n}\n","import type {Adapter, Secrets} from 'sanity-translations-tab'\n\nimport {authenticate, getHeaders, findExistingJob} from './helpers'\n\ninterface WorkflowProgressItem {\n workflowStepSummaryReportItemList: {\n wordCount: number\n }[]\n}\n\ninterface SmartlingProgressItem {\n targetLocaleId: string\n progress: {\n percentComplete: number\n totalWordCount: number\n }\n workflowProgressReportList: WorkflowProgressItem[]\n}\n\nexport const getTranslationTask: Adapter['getTranslationTask'] = async (\n documentId: string,\n secrets: Secrets | null,\n) => {\n if (!secrets?.project || !secrets?.secret || !secrets?.proxy) {\n return {\n documentId,\n taskId: documentId,\n locales: [],\n }\n }\n\n const {project, proxy} = secrets\n\n const accessToken = await authenticate(secrets)\n const taskId = await findExistingJob(documentId, secrets, accessToken)\n if (!taskId) {\n return {\n documentId,\n taskId: documentId,\n locales: [],\n }\n }\n\n const progressUrl = `https://api.smartling.com/jobs-api/v3/projects/${project}/jobs/${taskId}/progress`\n const smartlingTask = await fetch(proxy, {\n method: 'GET',\n headers: getHeaders(progressUrl, accessToken),\n })\n .then((res) => res.json())\n .then((res) => res.response.data)\n\n let locales = []\n if (smartlingTask && smartlingTask.contentProgressReport) {\n locales = smartlingTask.contentProgressReport.map((item: SmartlingProgressItem) => {\n let progress = item.progress ? item.progress.percentComplete : 0\n //default to the first workflow -- it's likely what is being used\n const progressItem = item.workflowProgressReportList?.[0]\n if (progressItem && item.progress) {\n //this is a list of the various steps in the workflow\n if (\n progressItem.workflowStepSummaryReportItemList &&\n progressItem.workflowStepSummaryReportItemList.length > 1\n ) {\n //get the last step in the workflow -- usually \"published\"\n const lastStep = progressItem.workflowStepSummaryReportItemList.at(-1)\n //get the percentage of how many words have reached the last step\n if (lastStep && lastStep.wordCount >= 0) {\n progress = Math.floor((lastStep.wordCount / item.progress.totalWordCount) * 100) ?? 0\n }\n }\n }\n return {\n localeId: item.targetLocaleId,\n progress,\n }\n })\n }\n\n return {\n documentId,\n locales,\n //since our download is tied to document id for smartling, keep track of it as a task\n taskId: documentId,\n linkToVendorTask: `https://dashboard.smartling.com/app/projects/${project}/account-jobs/${project}:${taskId}`,\n }\n}\n","import type {Adapter, Secrets, SerializedDocument} from 'sanity-translations-tab'\n\nimport {getTranslationTask} from './getTranslationTask'\nimport {authenticate, getHeaders, findExistingJob} from './helpers'\n\nconst createJob = (\n jobName: string,\n secrets: Secrets,\n localeIds: string[],\n accessToken: string,\n documentId: string,\n) => {\n const {project, proxy} = secrets\n if (!project || !proxy) {\n throw new Error(\n 'The Smartling adapter requires a Smartling project identifier and a proxy URL. Please check your secrets document in this dataset, per the plugin documentation.',\n )\n }\n\n const url = `https://api.smartling.com/jobs-api/v3/projects/${project}/jobs`\n return fetch(proxy, {\n method: 'POST',\n headers: {\n ...getHeaders(url, accessToken),\n 'content-type': 'application/json',\n },\n body: JSON.stringify({\n jobName,\n targetLocaleIds: localeIds,\n referenceNumber: documentId,\n }),\n })\n .then((res) => res.json())\n .then((res) => res.response.data.translationJobUid)\n}\n\n/* we're using batches here because it eliminates some\n * new string authorization issues for updating existing jobs,\n * and is able to be used for new bulk\n * job functionality.\n */\n\nconst createJobBatch = (\n jobId: string,\n secrets: Secrets,\n documentId: string,\n accessToken: string,\n localeIds: string[],\n workflowUid?: string,\n) => {\n const {project, proxy} = secrets\n if (!project || !proxy) {\n throw new Error(\n 'The Smartling adapter requires a Smartling project identifier and a proxy URL. Please check your secrets document in this dataset, per the plugin documentation.',\n )\n }\n const url = `https://api.smartling.com/job-batches-api/v2/projects/${project}/batches`\n const reqBody: {\n authorize: boolean\n translationJobUid: string\n fileUris: string[]\n localeWorkflows?: {targetLocaleId: string; workflowUid: string}[]\n } = {\n authorize: true,\n translationJobUid: jobId,\n fileUris: [documentId],\n }\n\n if (workflowUid) {\n reqBody.localeWorkflows = localeIds.map((l) => ({\n targetLocaleId: l,\n workflowUid,\n }))\n }\n\n return fetch(proxy, {\n method: 'POST',\n headers: {\n ...getHeaders(url, accessToken),\n 'content-type': 'application/json',\n },\n body: JSON.stringify(reqBody),\n })\n .then((res) => res.json())\n .then((res) => res.response.data.batchUid)\n}\n\nconst uploadFileToBatch = (\n batchUid: string,\n documentId: string,\n document: SerializedDocument,\n secrets: Secrets,\n localeIds: string[],\n accessToken: string,\n callbackUrl?: string,\n) => {\n const {project, proxy} = secrets\n if (!project || !proxy) {\n throw new Error(\n 'The Smartling adapter requires a Smartling project identifier and a proxy URL. Please check your secrets document in this dataset, per the plugin documentation.',\n )\n }\n const url = `https://api.smartling.com/job-batches-api/v2/projects/${project}/batches/${batchUid}/file`\n const formData = new FormData()\n formData.append('fileUri', documentId)\n formData.append('fileType', 'html')\n formData.append('file', new Blob([document.content]), `${document.name}.html`)\n localeIds.forEach((localeId) => formData.append('localeIdsToAuthorize[]', localeId))\n if (callbackUrl) {\n formData.append('callbackUrl', callbackUrl)\n }\n\n return fetch(proxy, {\n method: 'POST',\n headers: getHeaders(url, accessToken),\n body: formData,\n }).then((res) => res.json())\n}\n\nexport const createTask: Adapter['createTask'] = async (\n documentId: string,\n document: SerializedDocument,\n localeIds: string[],\n secrets: Secrets | null,\n workflowUid?: string,\n callbackUrl?: string,\n) => {\n if (!secrets?.project || !secrets?.secret || !secrets?.proxy) {\n throw new Error(\n 'The Smartling adapter requires a project ID, a secret key, and a proxy URL. Please check your secrets document in this dataset, per the plugin documentation.',\n )\n }\n\n const accessToken = await authenticate(secrets)\n\n let taskId = await findExistingJob(document.name, secrets, accessToken)\n if (!taskId) {\n taskId = await createJob(document.name, secrets, localeIds, accessToken, documentId)\n }\n\n const batchUid = await createJobBatch(\n taskId,\n secrets,\n documentId,\n accessToken,\n localeIds,\n workflowUid,\n )\n await uploadFileToBatch(\n batchUid,\n documentId,\n document,\n secrets,\n localeIds,\n accessToken,\n callbackUrl,\n )\n\n return getTranslationTask(documentId, secrets)\n}\n","import type {Adapter, Secrets} from 'sanity-translations-tab'\n\nimport {authenticate, getHeaders} from './helpers'\n\nexport const getLocales: Adapter['getLocales'] = async (secrets: Secrets | null) => {\n if (!secrets?.project || !secrets?.secret || !secrets?.proxy) {\n return []\n }\n const {project, proxy} = secrets\n const url = `https://api.smartling.com/projects-api/v2/projects/${project}`\n const accessToken = await authenticate(secrets)\n return fetch(proxy, {\n method: 'GET',\n headers: getHeaders(url, accessToken),\n })\n .then((res) => res.json())\n .then((res) => res.response.data.targetLocales)\n}\n","import type {Adapter, Secrets} from 'sanity-translations-tab'\n\nimport {authenticate, getHeaders} from './helpers'\n\nexport const getTranslation: Adapter['getTranslation'] = async (\n taskId: string,\n localeId: string,\n secrets: Secrets | null,\n) => {\n if (!secrets?.project || !secrets?.secret || !secrets?.proxy) {\n throw new Error(\n 'The Smartling adapter requires a project ID, a secret key, and a proxy URL. Please check your secrets document in this dataset, per the plugin documentation.',\n )\n }\n\n const {project, proxy} = secrets\n\n const url = `https://api.smartling.com/files-api/v2/projects/${project}/locales/${localeId}/file?fileUri=${taskId}&retrievalType=pending`\n const accessToken = await authenticate(secrets)\n const translatedHTML = await fetch(proxy, {\n method: 'GET',\n headers: getHeaders(url, accessToken),\n })\n .then((res) => res.json())\n .then((res) => {\n if (res.body) {\n return res.body\n } else if (res.response.errors) {\n const errMsg =\n res.response.errors[0]?.message || 'Error retrieving translation from Smartling'\n throw new Error(errMsg)\n }\n return ''\n })\n\n return translatedHTML\n}\n","import type {Adapter} from 'sanity-translations-tab'\n\nimport {createTask} from './createTask'\nimport {getLocales} from './getLocales'\nimport {getTranslation} from './getTranslation'\nimport {getTranslationTask} from './getTranslationTask'\n\nexport const SmartlingAdapter: Adapter = {\n getLocales,\n getTranslationTask,\n createTask,\n getTranslation,\n}\n","import {\n baseDocumentLevelConfig,\n baseFieldLevelConfig,\n legacyDocumentLevelConfig as baseLegacyDocumentLevelConfig,\n} from 'sanity-translations-tab'\nimport type {TranslationsTabConfigOptions} from 'sanity-translations-tab'\n\nimport {SmartlingAdapter} from './adapter'\n\nexport {\n BaseDocumentDeserializer,\n BaseDocumentMerger,\n BaseDocumentSerializer,\n customSerializers,\n defaultStopTypes,\n documentLevelPatch,\n fieldLevelPatch,\n findLatestDraft,\n legacyDocumentLevelPatch,\n TranslationsTab,\n} from 'sanity-translations-tab'\nexport type {\n TranslationFunctionContext,\n TranslationsTabConfigOptions,\n} from 'sanity-translations-tab'\n\nconst defaultDocumentLevelConfig: TranslationsTabConfigOptions = {\n ...baseDocumentLevelConfig,\n adapter: SmartlingAdapter,\n}\n\nconst legacyDocumentLevelConfig: TranslationsTabConfigOptions = {\n ...baseLegacyDocumentLevelConfig,\n adapter: SmartlingAdapter,\n}\n\nconst defaultFieldLevelConfig: TranslationsTabConfigOptions = {\n ...baseFieldLevelConfig,\n adapter: SmartlingAdapter,\n}\n\nexport {\n defaultDocumentLevelConfig,\n defaultFieldLevelConfig,\n legacyDocumentLevelConfig,\n SmartlingAdapter,\n}\n"],"names":["authenticate","secrets","headers","secret","proxy","Error","fetch","method","body","JSON","stringify","then","res","json","response","data","accessToken","getHeaders","url","findExistingJob","documentId","project","items","length","refUrl","fileUris","correctJob","filter","item","jobStatus","find","jobName","referenceNumber","translationJobUid","getTranslationTask","taskId","locales","progressUrl","smartlingTask","contentProgressReport","map","progress","percentComplete","progressItem","workflowProgressReportList","workflowStepSummaryReportItemList","lastStep","at","wordCount","Math","floor","totalWordCount","localeId","targetLocaleId","linkToVendorTask","createJob","localeIds","targetLocaleIds","createJobBatch","jobId","workflowUid","reqBody","authorize","localeWorkflows","l","batchUid","uploadFileToBatch","document","callbackUrl","formData","FormData","append","Blob","content","name","forEach","createTask","getLocales","targetLocales","getTranslation","errors","errMsg","message","SmartlingAdapter","defaultDocumentLevelConfig","baseDocumentLevelConfig","adapter","legacyDocumentLevelConfig","baseLegacyDocumentLevelConfig","defaultFieldLevelConfig","baseFieldLevelConfig"],"mappings":"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"}