@lokalise/polyglot-sdk 1.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.
@@ -0,0 +1 @@
1
+ export declare function add(a: number, b: number): number;
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.add = void 0;
4
+ function add(a, b) {
5
+ return a + b;
6
+ }
7
+ exports.add = add;
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,SAAgB,GAAG,CAAC,CAAS,EAAE,CAAS;IACtC,OAAO,CAAC,GAAG,CAAC,CAAA;AACd,CAAC;AAFD,kBAEC"}
@@ -0,0 +1,34 @@
1
+ import type { ClientOptions, PolyglotClientConfig } from './types/client';
2
+ import type { GenerateVariantsRequest, LqaSyncRequest, TranslateSyncRequest } from './types/requests';
3
+ import type { ContentUnitLqaResponse, ContentUnitTranslationResponse, PolyglotClientSyncIterativeResponse } from './types/responses';
4
+ export declare class PolyglotClient {
5
+ private readonly client;
6
+ private readonly clientHeaders;
7
+ private readonly retryConfig;
8
+ private readonly logger?;
9
+ constructor({ baseUrl, jwtToken, retryConfig, logger }: PolyglotClientConfig);
10
+ /**
11
+ * Translates segments in content units via /translate-sync API. Will chunk the request automatically into batches if
12
+ * the amount of segments exceeds synchronous API limits and will yield the results separately.
13
+ */
14
+ translateSyncIterative(request: TranslateSyncRequest, options?: ClientOptions): AsyncGenerator<PolyglotClientSyncIterativeResponse<ContentUnitTranslationResponse>>;
15
+ /**
16
+ * Reviews segment translations via LQA process with /lqa-sync API. Will chunk the request automatically into batches if
17
+ * the amount of segments exceeds synchronous API limits and will yield the results separately.
18
+ */
19
+ lqaSyncIterative(request: LqaSyncRequest, options?: ClientOptions): AsyncGenerator<PolyglotClientSyncIterativeResponse<ContentUnitLqaResponse>>;
20
+ /**
21
+ * Re-translates a given translation pair and provides several different variants. Can take previously generated
22
+ * variants as an input - in attempt to avoid repetition.
23
+ */
24
+ generateVariants(request: GenerateVariantsRequest, { fakeProcessing, metadata, reqContext }?: ClientOptions): Promise<string[]>;
25
+ private callTranslateSyncApi;
26
+ private callLqaSyncApi;
27
+ /**
28
+ * Calls the provided request function and wraps its execution within NewRelic transaction (if manager is available)
29
+ * and logs the execution time and metadata with the provided logger
30
+ * @private
31
+ */
32
+ private wrapWithInstrumentation;
33
+ private wrapError;
34
+ }
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PolyglotClient = void 0;
4
+ const node_core_1 = require("@lokalise/node-core");
5
+ const PolyglotError_1 = require("./errors/PolyglotError");
6
+ const polyglotChunkHandler_1 = require("./polyglotChunkHandler");
7
+ const DEFAULT_CLIENT_OPTIONS = {};
8
+ class PolyglotClient {
9
+ client;
10
+ clientHeaders;
11
+ retryConfig;
12
+ logger;
13
+ constructor({ baseUrl, jwtToken, retryConfig, logger }) {
14
+ this.client = (0, node_core_1.buildClient)(baseUrl);
15
+ this.clientHeaders = {
16
+ 'Content-Type': 'application/json',
17
+ Authorization: `Bearer ${jwtToken}`,
18
+ };
19
+ this.retryConfig = {
20
+ retryOnTimeout: false,
21
+ maxAttempts: 5,
22
+ delayBetweenAttemptsInMsecs: 250,
23
+ statusCodesToRetry: [
24
+ 408, // Request timeout
25
+ 423, // Resource is blocked
26
+ 429, // Too Many requests
27
+ 500, // Internal server error
28
+ 503, // Service unavailable
29
+ 504, // Gateway timeout,
30
+ ],
31
+ ...retryConfig,
32
+ };
33
+ this.logger = logger;
34
+ }
35
+ /**
36
+ * Translates segments in content units via /translate-sync API. Will chunk the request automatically into batches if
37
+ * the amount of segments exceeds synchronous API limits and will yield the results separately.
38
+ */
39
+ async *translateSyncIterative(request, options = DEFAULT_CLIENT_OPTIONS) {
40
+ const chunks = (0, polyglotChunkHandler_1.getChunkedTranslationRequest)(request);
41
+ for (const requestChunked of chunks) {
42
+ yield {
43
+ response: await this.callTranslateSyncApi(requestChunked, options),
44
+ segmentIdsProcessedByContentUnitId: requestChunked.contentUnits.reduce((acc, cu) => {
45
+ if (!acc[cu.id])
46
+ acc[cu.id] = [];
47
+ acc[cu.id].push(...cu.segments.map((s) => s.id));
48
+ return acc;
49
+ }, {}),
50
+ };
51
+ }
52
+ }
53
+ /**
54
+ * Reviews segment translations via LQA process with /lqa-sync API. Will chunk the request automatically into batches if
55
+ * the amount of segments exceeds synchronous API limits and will yield the results separately.
56
+ */
57
+ async *lqaSyncIterative(request, options = DEFAULT_CLIENT_OPTIONS) {
58
+ const chunks = (0, polyglotChunkHandler_1.getChunkedLqaRequest)(request);
59
+ for (const requestChunked of chunks) {
60
+ yield {
61
+ response: await this.callLqaSyncApi(requestChunked, options),
62
+ segmentIdsProcessedByContentUnitId: requestChunked.contentUnits.reduce((acc, cu) => {
63
+ if (!acc[cu.id])
64
+ acc[cu.id] = [];
65
+ acc[cu.id].push(...cu.segments.flatMap((s) => s.translations).map((t) => t.id));
66
+ return acc;
67
+ }, {}),
68
+ };
69
+ }
70
+ }
71
+ /**
72
+ * Re-translates a given translation pair and provides several different variants. Can take previously generated
73
+ * variants as an input - in attempt to avoid repetition.
74
+ */
75
+ async generateVariants(request, { fakeProcessing, metadata, reqContext } = DEFAULT_CLIENT_OPTIONS) {
76
+ if (request.sourceValue.trim() === '' || request.targetValue.trim() === '') {
77
+ return [];
78
+ }
79
+ const requestLabel = 'Generate variants (Polyglot)';
80
+ const response = await this.wrapWithInstrumentation(() => {
81
+ return (0, node_core_1.sendPost)(this.client, '/v1/content/actions/generate-variants', request, {
82
+ reqContext,
83
+ retryConfig: this.retryConfig,
84
+ headers: {
85
+ ...this.clientHeaders,
86
+ 'x-fake-processing': fakeProcessing ? 'true' : undefined,
87
+ },
88
+ requestLabel,
89
+ });
90
+ }, {
91
+ requestLabel,
92
+ callMetadata: {
93
+ ...metadata,
94
+ reqContext: JSON.stringify(reqContext),
95
+ },
96
+ });
97
+ return response.body.variants;
98
+ }
99
+ async callTranslateSyncApi(request, { fakeProcessing, metadata, reqContext }) {
100
+ const requestLabel = 'Translate synchronously (Polyglot)';
101
+ const result = await this.wrapWithInstrumentation(() => {
102
+ return (0, node_core_1.sendPost)(this.client, '/v1/content/actions/translate-sync', request, {
103
+ reqContext,
104
+ retryConfig: this.retryConfig,
105
+ headers: {
106
+ ...this.clientHeaders,
107
+ 'x-fake-processing': fakeProcessing ? 'true' : undefined,
108
+ },
109
+ requestLabel,
110
+ });
111
+ }, {
112
+ requestLabel,
113
+ callMetadata: {
114
+ ...metadata,
115
+ reqContext: JSON.stringify(reqContext),
116
+ },
117
+ });
118
+ return result.body.contentUnits;
119
+ }
120
+ async callLqaSyncApi(request, { fakeProcessing, metadata, reqContext }) {
121
+ const requestLabel = 'Review with LQA synchronously (Polyglot)';
122
+ const result = await this.wrapWithInstrumentation(() => {
123
+ return (0, node_core_1.sendPost)(this.client, '/v1/content/actions/lqa-sync', request, {
124
+ reqContext,
125
+ retryConfig: this.retryConfig,
126
+ headers: {
127
+ ...this.clientHeaders,
128
+ 'x-fake-processing': fakeProcessing ? 'true' : undefined,
129
+ },
130
+ requestLabel,
131
+ });
132
+ }, {
133
+ requestLabel,
134
+ callMetadata: {
135
+ ...metadata,
136
+ reqContext: JSON.stringify(reqContext),
137
+ },
138
+ });
139
+ return result.body.contentUnits;
140
+ }
141
+ /**
142
+ * Calls the provided request function and wraps its execution within NewRelic transaction (if manager is available)
143
+ * and logs the execution time and metadata with the provided logger
144
+ * @private
145
+ */
146
+ async wrapWithInstrumentation(innerFn, { callMetadata, requestLabel }) {
147
+ let successful = false;
148
+ const startTime = performance.now();
149
+ try {
150
+ const { result, error } = await innerFn();
151
+ // We might receive an non-satisfactory response, but it might not be an Error object - so we have to wrap it
152
+ if (error) {
153
+ // noinspection ExceptionCaughtLocallyJS
154
+ throw error;
155
+ }
156
+ successful = true;
157
+ return result;
158
+ }
159
+ catch (e) {
160
+ throw this.wrapError(e);
161
+ }
162
+ finally {
163
+ this.logger?.info({
164
+ ...callMetadata,
165
+ successful,
166
+ msg: `Completed ${requestLabel}`,
167
+ duration: performance.now() - startTime,
168
+ });
169
+ }
170
+ }
171
+ wrapError(e) {
172
+ let error;
173
+ if (e instanceof Error) {
174
+ error = (0, node_core_1.isResponseStatusError)(e) ? new PolyglotError_1.PolyglotError(e) : e;
175
+ }
176
+ else {
177
+ error = new node_core_1.InternalError({
178
+ message: 'Unknown error',
179
+ errorCode: 'UNKNOWN_ERROR',
180
+ details: { error: JSON.stringify(e) },
181
+ });
182
+ }
183
+ return error;
184
+ }
185
+ }
186
+ exports.PolyglotClient = PolyglotClient;
187
+ //# sourceMappingURL=PolyglotClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PolyglotClient.js","sourceRoot":"","sources":["../../src/sdk/PolyglotClient.ts"],"names":[],"mappings":";;;AAAA,mDAAiG;AAMjG,0DAAsD;AACtD,iEAA2F;AAe3F,MAAM,sBAAsB,GAAkB,EAAE,CAAA;AAEhD,MAAa,cAAc;IACR,MAAM,CAAQ;IACd,aAAa,CAAyB;IACtC,WAAW,CAAa;IACxB,MAAM,CAAS;IAEhC,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAwB;QAC1E,IAAI,CAAC,MAAM,GAAG,IAAA,uBAAW,EAAC,OAAO,CAAC,CAAA;QAClC,IAAI,CAAC,aAAa,GAAG;YACnB,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,UAAU,QAAQ,EAAE;SACpC,CAAA;QACD,IAAI,CAAC,WAAW,GAAG;YACjB,cAAc,EAAE,KAAK;YACrB,WAAW,EAAE,CAAC;YACd,2BAA2B,EAAE,GAAG;YAChC,kBAAkB,EAAE;gBAClB,GAAG,EAAE,kBAAkB;gBACvB,GAAG,EAAE,sBAAsB;gBAC3B,GAAG,EAAE,oBAAoB;gBACzB,GAAG,EAAE,wBAAwB;gBAC7B,GAAG,EAAE,sBAAsB;gBAC3B,GAAG,EAAE,mBAAmB;aACzB;YACD,GAAG,WAAW;SACf,CAAA;QACD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,CAAC,sBAAsB,CAC3B,OAA6B,EAC7B,UAAyB,sBAAsB;QAE/C,MAAM,MAAM,GAAG,IAAA,mDAA4B,EAAC,OAAO,CAAC,CAAA;QAEpD,KAAK,MAAM,cAAc,IAAI,MAAM,EAAE,CAAC;YACpC,MAAM;gBACJ,QAAQ,EAAE,MAAM,IAAI,CAAC,oBAAoB,CAAC,cAAc,EAAE,OAAO,CAAC;gBAClE,kCAAkC,EAAE,cAAc,CAAC,YAAY,CAAC,MAAM,CACpE,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE;oBACV,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;wBAAE,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAA;oBAChC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;oBAChD,OAAO,GAAG,CAAA;gBACZ,CAAC,EACD,EAA8B,CAC/B;aACF,CAAA;QACH,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,CAAC,gBAAgB,CACrB,OAAuB,EACvB,UAAyB,sBAAsB;QAE/C,MAAM,MAAM,GAAG,IAAA,2CAAoB,EAAC,OAAO,CAAC,CAAA;QAE5C,KAAK,MAAM,cAAc,IAAI,MAAM,EAAE,CAAC;YACpC,MAAM;gBACJ,QAAQ,EAAE,MAAM,IAAI,CAAC,cAAc,CAAC,cAAc,EAAE,OAAO,CAAC;gBAC5D,kCAAkC,EAAE,cAAc,CAAC,YAAY,CAAC,MAAM,CACpE,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE;oBACV,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;wBAAE,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAA;oBAChC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;oBAC/E,OAAO,GAAG,CAAA;gBACZ,CAAC,EACD,EAA8B,CAC/B;aACF,CAAA;QACH,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,gBAAgB,CACpB,OAAgC,EAChC,EAAE,cAAc,EAAE,QAAQ,EAAE,UAAU,KAAoB,sBAAsB;QAEhF,IAAI,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC3E,OAAO,EAAE,CAAA;QACX,CAAC;QAED,MAAM,YAAY,GAAG,8BAA8B,CAAA;QACnD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,uBAAuB,CACjD,GAAG,EAAE;YACH,OAAO,IAAA,oBAAQ,EACb,IAAI,CAAC,MAAM,EACX,uCAAuC,EACvC,OAAO,EACP;gBACE,UAAU;gBACV,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,OAAO,EAAE;oBACP,GAAG,IAAI,CAAC,aAAa;oBACrB,mBAAmB,EAAE,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;iBACzD;gBACD,YAAY;aACb,CACF,CAAA;QACH,CAAC,EACD;YACE,YAAY;YACZ,YAAY,EAAE;gBACZ,GAAG,QAAQ;gBACX,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;aACvC;SACF,CACF,CAAA;QAED,OAAO,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAA;IAC/B,CAAC;IAEO,KAAK,CAAC,oBAAoB,CAChC,OAA6B,EAC7B,EAAE,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAiB;QAEvD,MAAM,YAAY,GAAG,oCAAoC,CAAA;QACzD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAC/C,GAAG,EAAE;YACH,OAAO,IAAA,oBAAQ,EACb,IAAI,CAAC,MAAM,EACX,oCAAoC,EACpC,OAAO,EACP;gBACE,UAAU;gBACV,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,OAAO,EAAE;oBACP,GAAG,IAAI,CAAC,aAAa;oBACrB,mBAAmB,EAAE,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;iBACzD;gBACD,YAAY;aACb,CACF,CAAA;QACH,CAAC,EACD;YACE,YAAY;YACZ,YAAY,EAAE;gBACZ,GAAG,QAAQ;gBACX,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;aACvC;SACF,CACF,CAAA;QAED,OAAO,MAAM,CAAC,IAAI,CAAC,YAAY,CAAA;IACjC,CAAC;IAEO,KAAK,CAAC,cAAc,CAC1B,OAAuB,EACvB,EAAE,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAiB;QAEvD,MAAM,YAAY,GAAG,0CAA0C,CAAA;QAC/D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAC/C,GAAG,EAAE;YACH,OAAO,IAAA,oBAAQ,EACb,IAAI,CAAC,MAAM,EACX,8BAA8B,EAC9B,OAAO,EACP;gBACE,UAAU;gBACV,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,OAAO,EAAE;oBACP,GAAG,IAAI,CAAC,aAAa;oBACrB,mBAAmB,EAAE,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;iBACzD;gBACD,YAAY;aACb,CACF,CAAA;QACH,CAAC,EACD;YACE,YAAY;YACZ,YAAY,EAAE;gBACZ,GAAG,QAAQ;gBACX,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;aACvC;SACF,CACF,CAAA;QAED,OAAO,MAAM,CAAC,IAAI,CAAC,YAAY,CAAA;IACjC,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,uBAAuB,CACnC,OAAgF,EAChF,EAAE,YAAY,EAAE,YAAY,EAA0B;QAEtD,IAAI,UAAU,GAAG,KAAK,CAAA;QACtB,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;QAEnC,IAAI,CAAC;YACH,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,OAAO,EAAE,CAAA;YAEzC,6GAA6G;YAC7G,IAAI,KAAK,EAAE,CAAC;gBACV,wCAAwC;gBACxC,MAAM,KAAK,CAAA;YACb,CAAC;YAED,UAAU,GAAG,IAAI,CAAA;YACjB,OAAO,MAAM,CAAA;QACf,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;QACzB,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;gBAChB,GAAG,YAAY;gBACf,UAAU;gBACV,GAAG,EAAE,aAAa,YAAY,EAAE;gBAChC,QAAQ,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS;aACxC,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAEO,SAAS,CAAC,CAAU;QAC1B,IAAI,KAAwB,CAAA;QAC5B,IAAI,CAAC,YAAY,KAAK,EAAE,CAAC;YACvB,KAAK,GAAG,IAAA,iCAAqB,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,6BAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAC7D,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,IAAI,yBAAa,CAAC;gBACxB,OAAO,EAAE,eAAe;gBACxB,SAAS,EAAE,eAAe;gBAC1B,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE;aACtC,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,KAAK,CAAA;IACd,CAAC;CACF;AA9OD,wCA8OC"}
@@ -0,0 +1,5 @@
1
+ import type { ResponseStatusError } from '@lokalise/node-core';
2
+ import { InternalError } from '@lokalise/node-core';
3
+ export declare class PolyglotError extends InternalError {
4
+ constructor(error: ResponseStatusError);
5
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PolyglotError = void 0;
4
+ const node_core_1 = require("@lokalise/node-core");
5
+ class PolyglotError extends node_core_1.InternalError {
6
+ constructor(error) {
7
+ super({
8
+ message: `Polyglot service failed with error: ${error.message}`,
9
+ details: {
10
+ responseBody: JSON.stringify(error.response.body),
11
+ details: error.details,
12
+ },
13
+ errorCode: error.errorCode,
14
+ });
15
+ }
16
+ }
17
+ exports.PolyglotError = PolyglotError;
18
+ //# sourceMappingURL=PolyglotError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PolyglotError.js","sourceRoot":"","sources":["../../../src/sdk/errors/PolyglotError.ts"],"names":[],"mappings":";;;AACA,mDAAmD;AAEnD,MAAa,aAAc,SAAQ,yBAAa;IAC9C,YAAY,KAA0B;QACpC,KAAK,CAAC;YACJ,OAAO,EAAE,uCAAuC,KAAK,CAAC,OAAO,EAAE;YAC/D,OAAO,EAAE;gBACP,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;gBACjD,OAAO,EAAE,KAAK,CAAC,OAAO;aACvB;YACD,SAAS,EAAE,KAAK,CAAC,SAAS;SAC3B,CAAC,CAAA;IACJ,CAAC;CACF;AAXD,sCAWC"}
@@ -0,0 +1,16 @@
1
+ import type { LqaSyncRequest, TranslateSyncRequest } from './types/requests';
2
+ /**
3
+ * Polyglot synchronous APIs are limited to X items at once - to keep the response time reasonable and not hit
4
+ * any sort of API gateway timeouts.
5
+ */
6
+ export declare const REQUEST_SIZE_LIMIT_TRANSLATE_SYNC = 15;
7
+ export declare const REQUEST_SIZE_LIMIT_LQA_SYNC = 15;
8
+ export type ContentUnitSegment = {
9
+ id: string;
10
+ };
11
+ export type ContentUnitResponse<T extends ContentUnitSegment> = {
12
+ id: string;
13
+ segments: T[];
14
+ };
15
+ export declare function getChunkedTranslationRequest(request: TranslateSyncRequest, polyglotSegmentMaxProcessLimit?: number): Generator<TranslateSyncRequest>;
16
+ export declare function getChunkedLqaRequest(request: LqaSyncRequest, polyglotSegmentMaxProcessLimit?: number): Generator<LqaSyncRequest>;
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getChunkedLqaRequest = exports.getChunkedTranslationRequest = exports.REQUEST_SIZE_LIMIT_LQA_SYNC = exports.REQUEST_SIZE_LIMIT_TRANSLATE_SYNC = void 0;
4
+ const node_core_1 = require("@lokalise/node-core");
5
+ /**
6
+ * Polyglot synchronous APIs are limited to X items at once - to keep the response time reasonable and not hit
7
+ * any sort of API gateway timeouts.
8
+ */
9
+ exports.REQUEST_SIZE_LIMIT_TRANSLATE_SYNC = 15;
10
+ exports.REQUEST_SIZE_LIMIT_LQA_SYNC = 15;
11
+ // TODO: AP-1395 - Look at refactoring the chunk methods into smaller alternatives
12
+ // eslint-disable-next-line max-statements
13
+ function* getChunkedTranslationRequest(request, polyglotSegmentMaxProcessLimit = exports.REQUEST_SIZE_LIMIT_TRANSLATE_SYNC) {
14
+ const contentUnits = request.contentUnits.filter((contentUnit) => contentUnit.segments.length > 0);
15
+ if (contentUnits.length === 0) {
16
+ return;
17
+ }
18
+ const chunkedRequest = {
19
+ context: request.context,
20
+ sourceLocale: request.sourceLocale,
21
+ targetLocale: request.targetLocale,
22
+ contentUnits: [],
23
+ };
24
+ let totalSegmentsInRequest = 0;
25
+ for (const contentUnit of contentUnits) {
26
+ let segmentsChunked = [];
27
+ let startOffset = 0;
28
+ do {
29
+ segmentsChunked = contentUnit.segments.slice(startOffset, polyglotSegmentMaxProcessLimit + startOffset - totalSegmentsInRequest);
30
+ startOffset += polyglotSegmentMaxProcessLimit - totalSegmentsInRequest;
31
+ if (segmentsChunked.length === 0) {
32
+ startOffset = 0;
33
+ continue;
34
+ }
35
+ totalSegmentsInRequest += segmentsChunked.length;
36
+ chunkedRequest.contentUnits.push({ ...contentUnit, segments: segmentsChunked });
37
+ if (totalSegmentsInRequest === polyglotSegmentMaxProcessLimit) {
38
+ yield (0, node_core_1.deepClone)(chunkedRequest);
39
+ chunkedRequest.contentUnits = [];
40
+ totalSegmentsInRequest = 0;
41
+ }
42
+ } while (segmentsChunked.length !== 0);
43
+ }
44
+ if (chunkedRequest.contentUnits.length) {
45
+ yield (0, node_core_1.deepClone)(chunkedRequest);
46
+ }
47
+ }
48
+ exports.getChunkedTranslationRequest = getChunkedTranslationRequest;
49
+ // TODO: AP-1395 - Look at refactoring the chunk methods into smaller alternatives
50
+ // eslint-disable-next-line max-statements
51
+ function* getChunkedLqaRequest(request, polyglotSegmentMaxProcessLimit = exports.REQUEST_SIZE_LIMIT_LQA_SYNC) {
52
+ const contentUnits = request.contentUnits.filter((contentUnit) => contentUnit.segments.length > 0);
53
+ if (contentUnits.length === 0) {
54
+ return;
55
+ }
56
+ const chunkedRequest = {
57
+ sourceLocale: request.sourceLocale,
58
+ contentUnits: [],
59
+ assets: request.assets,
60
+ };
61
+ let chunkedContentUnit = {
62
+ id: '',
63
+ segments: [],
64
+ };
65
+ let totalTranslationsInRequest = 0;
66
+ for (const contentUnit of contentUnits) {
67
+ let translationsChunked = [];
68
+ let startOffset = 0;
69
+ // ** We have existing translations from a previous contentUnit. Add it to the chunkRequest.
70
+ if (totalTranslationsInRequest !== 0) {
71
+ chunkedRequest.contentUnits.push(chunkedContentUnit);
72
+ }
73
+ // Start a new chunkedContentUnit.
74
+ chunkedContentUnit = {
75
+ id: contentUnit.id,
76
+ segments: [],
77
+ };
78
+ // Cycle through a contentUnit's segment assigning it to translationsChunked until we cannot extract anything
79
+ // further from that segment array.
80
+ for (const segment of contentUnit.segments) {
81
+ do {
82
+ if (!segment.translations || segment.translations.length === 0) {
83
+ continue;
84
+ }
85
+ // Grab translations based off a start index, and it's length calculated by how many translations we
86
+ // have already fetched e.g. We are on the first segment, and we have collected nothing. As a result it
87
+ // will start: 0, end: 15. However, this segment only has four translations, so we add this to the
88
+ // chunkedContentUnit and get out of the current loop and move onto the next segment within the current
89
+ // contentUnit. That next segment has 20 translations. We fetch the next batch of translations
90
+ // start: 0, end: (15 - 4) and add this to the chunkedContentUnit array.
91
+ //
92
+ // We have now reached the limit to chunk-by we yield chunkedContentUnit with the contentUnits with
93
+ // segments and it's translations, reset the start index and stay within the loop because the current
94
+ // segment still has translations to process.
95
+ //
96
+ // If we haven't reached the limit for translations within a contentUnit, we persist it further up in
97
+ // the previous loop **
98
+ //
99
+ // Rinse, wash, and repeat
100
+ translationsChunked = segment.translations.slice(startOffset, polyglotSegmentMaxProcessLimit + startOffset - totalTranslationsInRequest);
101
+ startOffset += polyglotSegmentMaxProcessLimit - totalTranslationsInRequest;
102
+ if (translationsChunked.length === 0) {
103
+ startOffset = 0;
104
+ continue;
105
+ }
106
+ // Any translations that do not have a locale will be removed
107
+ translationsChunked = filterTranslationsWithoutLanguages(translationsChunked);
108
+ totalTranslationsInRequest += translationsChunked.length;
109
+ if (translationsChunked) {
110
+ chunkedContentUnit.segments.push({
111
+ position: segment.position,
112
+ sourceValue: segment.sourceValue,
113
+ translations: translationsChunked,
114
+ });
115
+ }
116
+ // If we have reached the limit of the number of translations, yield the result and reset everything,
117
+ // except translationChunked.
118
+ if (totalTranslationsInRequest === polyglotSegmentMaxProcessLimit) {
119
+ chunkedRequest.contentUnits.push(chunkedContentUnit);
120
+ yield (0, node_core_1.deepClone)(chunkedRequest);
121
+ chunkedContentUnit = {
122
+ id: contentUnit.id,
123
+ segments: [],
124
+ };
125
+ chunkedRequest.contentUnits = [];
126
+ totalTranslationsInRequest = 0;
127
+ }
128
+ // Did we manage to find any translations from the slice? If not, that means the segment no longer has
129
+ // anything more, move onto the next segment keep whatever chunkedContentUnit we have, persist it
130
+ // further up in the method **.
131
+ } while (translationsChunked.length !== 0);
132
+ }
133
+ }
134
+ // In the possibility we have anything left over yield it back.
135
+ if (totalTranslationsInRequest !== 0) {
136
+ chunkedRequest.contentUnits.push(chunkedContentUnit);
137
+ yield (0, node_core_1.deepClone)(chunkedRequest);
138
+ }
139
+ }
140
+ exports.getChunkedLqaRequest = getChunkedLqaRequest;
141
+ const filterTranslationsWithoutLanguages = (translations) => {
142
+ return translations.filter((translation) => translation.locale && translation.locale.length !== 0);
143
+ };
144
+ //# sourceMappingURL=polyglotChunkHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polyglotChunkHandler.js","sourceRoot":"","sources":["../../src/sdk/polyglotChunkHandler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { RequestContext } from '@lokalise/fastify-extras';
2
+ import type { Logger } from 'pino';
3
+ import type { RetryConfig } from 'undici-retry';
4
+ export type ClientOptions = {
5
+ fakeProcessing?: boolean;
6
+ reqContext?: RequestContext;
7
+ metadata?: Record<string, string>;
8
+ };
9
+ export type InstrumentationOptions = {
10
+ requestLabel: string;
11
+ callMetadata?: Record<string, string>;
12
+ };
13
+ export type PolyglotClientConfig = {
14
+ baseUrl: string;
15
+ jwtToken: string;
16
+ isEnabled?: boolean;
17
+ retryConfig?: Partial<RetryConfig>;
18
+ logger?: Logger;
19
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/sdk/types/client.ts"],"names":[],"mappings":""}
@@ -0,0 +1,70 @@
1
+ export type TranslateSyncRequest = {
2
+ sourceLocale: string;
3
+ targetLocale: string;
4
+ contentUnits: TranslateSyncContentUnits[];
5
+ context?: PolyglotAssetsRequest;
6
+ };
7
+ export type TranslateSyncContentUnits = {
8
+ id: string;
9
+ segments: {
10
+ id: string;
11
+ position: number;
12
+ value: string;
13
+ }[];
14
+ };
15
+ export type LqaSyncRequest = {
16
+ sourceLocale: string;
17
+ assets?: Omit<PolyglotAssetsRequest, 'styleGuide'>;
18
+ contentUnits: LqaContentUnit[];
19
+ };
20
+ export type LqaContentUnit = {
21
+ id: string;
22
+ segments: LqaSegment[];
23
+ };
24
+ export type LqaSegment = {
25
+ sourceValue: string;
26
+ position: number;
27
+ translations: LqaTranslation[];
28
+ };
29
+ export type LqaTranslation = {
30
+ id: string;
31
+ locale: string;
32
+ value: string;
33
+ };
34
+ type SegmentVariantsMode = 'REPHRASE' | 'SHORTEN';
35
+ type SegmentVariantsHistory = {
36
+ values: string[];
37
+ mode: SegmentVariantsMode;
38
+ };
39
+ export type GenerateVariantsRequest = {
40
+ mode: SegmentVariantsMode;
41
+ sourceLocale: string;
42
+ sourceValue: string;
43
+ targetLocale: string;
44
+ targetValue: string;
45
+ history?: SegmentVariantsHistory[];
46
+ assets?: PolyglotAssetsRequest;
47
+ };
48
+ export type StyleGuideAnswers = {
49
+ targetAudience: string;
50
+ toneOfVoice: string;
51
+ levelOfFormality: string;
52
+ generalRule: string;
53
+ };
54
+ export type PolyglotAssetsRequest = {
55
+ description?: string;
56
+ styleGuide?: StyleGuideAnswers;
57
+ glossary?: PolyglotGlossaryTermRequest[];
58
+ };
59
+ export type PolyglotGlossaryTermRequest = {
60
+ term: string;
61
+ description?: string;
62
+ translatable: boolean;
63
+ caseSensitive: boolean;
64
+ translations: {
65
+ locale: string;
66
+ translation: string;
67
+ description?: string;
68
+ }[];
69
+ };
70
+ export {};
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=requests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requests.js","sourceRoot":"","sources":["../../../src/sdk/types/requests.ts"],"names":[],"mappings":""}
@@ -0,0 +1,38 @@
1
+ export type PolyglotClientSyncIterativeResponse<T extends ContentUnitLqaResponse | ContentUnitTranslationResponse> = {
2
+ segmentIdsProcessedByContentUnitId: Record<string, string[]>;
3
+ response: T[];
4
+ };
5
+ export type PolyglotSyncResponse<T extends object> = {
6
+ generatedAt: string;
7
+ sourceLocale: string;
8
+ contentUnits: T[];
9
+ };
10
+ export type ContentUnitTranslationResponse = {
11
+ id: string;
12
+ segments: {
13
+ id: string;
14
+ locale: string;
15
+ position: number;
16
+ translation: string;
17
+ engine: string;
18
+ }[];
19
+ };
20
+ export type LqaSeverityResponse = 'neutral' | 'minor' | 'major' | 'critical';
21
+ export type LqaCategoryResponse = 'accuracy' | 'fluency' | 'terminology' | 'locale convention' | 'style' | 'consistency' | 'coherence' | 'design' | 'markup' | 'internationalization' | 'verity';
22
+ export type ContentUnitLqaResponse = {
23
+ id: string;
24
+ segments: SegmentLqaResponse[];
25
+ };
26
+ export type SegmentLqaResponse = {
27
+ id: string;
28
+ value: string;
29
+ issues: {
30
+ severity: LqaSeverityResponse;
31
+ category: LqaCategoryResponse;
32
+ comment?: string;
33
+ }[];
34
+ suggestion?: string;
35
+ };
36
+ export type PolyglotGenerateVariantsResponse = {
37
+ variants: string[];
38
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=responses.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responses.js","sourceRoot":"","sources":["../../../src/sdk/types/responses.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@lokalise/polyglot-sdk",
3
+ "version": "1.0.1",
4
+ "author": {
5
+ "name": "Lokalise",
6
+ "url": "https://lokalise.com/"
7
+ },
8
+ "description": "REST API client for the Lokalise Polyglot service",
9
+ "license": "Apache-2.0",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git://github.com/lokalise/polyglot-service.git"
13
+ },
14
+ "files": [
15
+ "dist/**"
16
+ ],
17
+ "main": "dist/index.js",
18
+ "types": "dist/index.d.ts",
19
+ "type": "commonjs",
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
23
+ "scripts": {
24
+ "build": "shx rm -rf ./dist && tsc",
25
+ "build:publish": "shx rm -rf ./dist && tsc -p tsconfig.publish.json",
26
+ "lint": "eslint . --ext .ts",
27
+ "lint:fix": "eslint . --ext .ts --fix",
28
+ "test": "vitest",
29
+ "test:coverage": "npm test -- --coverage",
30
+ "test:ci": "npm run test:coverage",
31
+ "prepublishOnly": "npm run build:publish"
32
+ },
33
+ "dependencies": {
34
+ "@amplitude/analytics-types": "^2.5.0",
35
+ "@lokalise/fastify-extras": "^16.5.0",
36
+ "@lokalise/id-utils": "^1.0.0",
37
+ "@lokalise/node-core": "^9.10.1",
38
+ "@lokalise/zod-extras": "^2.0.1",
39
+ "undici": "^6.6.2",
40
+ "undici-retry": "^5.0.2",
41
+ "zod": "^3.22.4"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^20.11.2",
45
+ "@typescript-eslint/eslint-plugin": "^7.1.0",
46
+ "@typescript-eslint/parser": "^7.1.0",
47
+ "@vitest/coverage-v8": "^0.34.6",
48
+ "auto-changelog": "^2.4.0",
49
+ "eslint": "^8.57.0",
50
+ "eslint-config-prettier": "^9.1.0",
51
+ "eslint-plugin-import": "^2.29.1",
52
+ "eslint-plugin-prettier": "^5.1.3",
53
+ "eslint-plugin-vitest": "^0.3.22",
54
+ "mockttp": "^3.10.1",
55
+ "prettier": "^3.2.5",
56
+ "shx": "^0.3.4",
57
+ "ts-deepmerge": "^7.0.0",
58
+ "typescript": "5.3.3",
59
+ "vitest": "^0.34.6"
60
+ }
61
+ }