smartling-api-sdk-nodejs 2.18.0 → 2.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.scannerwork/report-task.txt +2 -2
- package/api/auth/index.ts +1 -1
- package/api/mt/dto/translation-text-item-dto.ts +6 -0
- package/api/mt/index.ts +25 -0
- package/api/mt/params/smartling-mt-parameters.ts +40 -0
- package/api/mt/params/source-text-item.ts +6 -0
- package/built/api/auth/index.js +1 -1
- package/built/api/auth/index.js.map +1 -1
- package/built/api/mt/dto/translation-text-item-dto.d.ts +5 -0
- package/built/api/mt/dto/translation-text-item-dto.js +3 -0
- package/built/api/mt/dto/translation-text-item-dto.js.map +1 -0
- package/built/api/mt/index.d.ts +10 -0
- package/built/api/mt/index.js +27 -0
- package/built/api/mt/index.js.map +1 -0
- package/built/api/mt/params/smartling-mt-parameters.d.ts +5 -0
- package/built/api/mt/params/smartling-mt-parameters.js +38 -0
- package/built/api/mt/params/smartling-mt-parameters.js.map +1 -0
- package/built/api/mt/params/source-text-item.d.ts +5 -0
- package/built/api/mt/params/source-text-item.js +3 -0
- package/built/api/mt/params/source-text-item.js.map +1 -0
- package/built/index.d.ts +4 -0
- package/built/index.js +4 -0
- package/built/index.js.map +1 -1
- package/built/package.json +1 -1
- package/index.ts +4 -0
- package/package.json +1 -1
- package/test/base.spec.ts +18 -0
- package/test/files.spec.ts +0 -1
- package/test/mt.spec.ts +165 -0
|
@@ -2,5 +2,5 @@ projectKey=smartling-api-sdk-nodejs
|
|
|
2
2
|
serverUrl=https://sonar-next.connectors.stg.smartling.net
|
|
3
3
|
serverVersion=8.6.1.40680
|
|
4
4
|
dashboardUrl=https://sonar-next.connectors.stg.smartling.net/dashboard?id=smartling-api-sdk-nodejs
|
|
5
|
-
ceTaskId=
|
|
6
|
-
ceTaskUrl=https://sonar-next.connectors.stg.smartling.net/api/ce/task?id=
|
|
5
|
+
ceTaskId=AZdZXS4fkyrPHCPOkvjq
|
|
6
|
+
ceTaskUrl=https://sonar-next.connectors.stg.smartling.net/api/ce/task?id=AZdZXS4fkyrPHCPOkvjq
|
package/api/auth/index.ts
CHANGED
|
@@ -49,7 +49,7 @@ export class SmartlingAuthApi extends SmartlingBaseApi {
|
|
|
49
49
|
);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
this.logger.debug(`Can't refresh, doing re-auth with: ${JSON.stringify(this.response)}`);
|
|
52
|
+
this.logger.debug(`Can't refresh, doing re-auth with: ${JSON.stringify(this.response, SmartlingBaseApi.sensitiveReplacer)}`);
|
|
53
53
|
|
|
54
54
|
return await this.authenticate();
|
|
55
55
|
}
|
package/api/mt/index.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { SmartlingBaseApi } from "../base/index";
|
|
2
|
+
import { SmartlingAuthApi } from "../auth/index";
|
|
3
|
+
import { Logger } from "../logger";
|
|
4
|
+
import { SmartlingMTParameters } from "./params/smartling-mt-parameters";
|
|
5
|
+
import { SmartlingListResponse } from "../http/smartling-list-response";
|
|
6
|
+
import { TranslationTextItemDto } from "./dto/translation-text-item-dto";
|
|
7
|
+
|
|
8
|
+
export class SmartlingMachineTranslationsApi extends SmartlingBaseApi {
|
|
9
|
+
constructor(smartlingApiBaseUrl: string, authApi: SmartlingAuthApi, logger: Logger) {
|
|
10
|
+
super(logger);
|
|
11
|
+
this.authApi = authApi;
|
|
12
|
+
this.entrypoint = `${smartlingApiBaseUrl}/mt-router-api/v2/accounts`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async translate(
|
|
16
|
+
accountUid: string,
|
|
17
|
+
params: SmartlingMTParameters
|
|
18
|
+
): Promise<SmartlingListResponse<TranslationTextItemDto>> {
|
|
19
|
+
return await this.makeRequest(
|
|
20
|
+
"post",
|
|
21
|
+
`${this.entrypoint}/${accountUid}/smartling-mt`,
|
|
22
|
+
JSON.stringify(params.export())
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { SmartlingException } from "../../exception";
|
|
2
|
+
import { BaseParameters } from "../../parameters";
|
|
3
|
+
import { SourceTextItem } from "./source-text-item";
|
|
4
|
+
|
|
5
|
+
const MAX_ALLOWED_SOURCE_ITEMS = 1000;
|
|
6
|
+
const MAX_ALLOWED_KEY_LENGTH = 255;
|
|
7
|
+
const MAX_ALLOWED_SOURCE_TEXT_LENGTH = 64 * 1024;
|
|
8
|
+
|
|
9
|
+
export class SmartlingMTParameters extends BaseParameters {
|
|
10
|
+
constructor(sourceLocaleId: string, targetLocaleId: string, items: SourceTextItem[]) {
|
|
11
|
+
super();
|
|
12
|
+
|
|
13
|
+
if (!items.length) {
|
|
14
|
+
throw new SmartlingException("At least one source text item is required.");
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (items.length > MAX_ALLOWED_SOURCE_ITEMS) {
|
|
18
|
+
throw new SmartlingException(`The request contains too many source text items: ${items.length}. Maximum allowed items number is ${MAX_ALLOWED_SOURCE_ITEMS}.`);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
items.forEach((sourceTextItem, index) => {
|
|
22
|
+
if (!sourceTextItem.key.length) {
|
|
23
|
+
throw new SmartlingException(`The key is requred for items[${index}].`);
|
|
24
|
+
}
|
|
25
|
+
if (sourceTextItem.key.length > MAX_ALLOWED_KEY_LENGTH) {
|
|
26
|
+
throw new SmartlingException(`The key is too long for items[${index}]: ${sourceTextItem.key.length}. Maximum allowed key length is ${MAX_ALLOWED_KEY_LENGTH}.`);
|
|
27
|
+
}
|
|
28
|
+
if (!sourceTextItem.sourceText.length) {
|
|
29
|
+
throw new SmartlingException(`The source text is requred for items[${index}].`);
|
|
30
|
+
}
|
|
31
|
+
if (sourceTextItem.sourceText.length > MAX_ALLOWED_SOURCE_TEXT_LENGTH) {
|
|
32
|
+
throw new SmartlingException(`The source text is too long for items[${index}]: ${sourceTextItem.sourceText.length}. Maximum allowed source text length is ${MAX_ALLOWED_SOURCE_TEXT_LENGTH}.`);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
this.set("sourceLocaleId", sourceLocaleId);
|
|
37
|
+
this.set("targetLocaleId", targetLocaleId);
|
|
38
|
+
this.set("items", items);
|
|
39
|
+
}
|
|
40
|
+
}
|
package/built/api/auth/index.js
CHANGED
|
@@ -39,7 +39,7 @@ class SmartlingAuthApi extends index_1.SmartlingBaseApi {
|
|
|
39
39
|
refreshToken: this.response.refreshToken
|
|
40
40
|
}));
|
|
41
41
|
}
|
|
42
|
-
this.logger.debug(`Can't refresh, doing re-auth with: ${JSON.stringify(this.response)}`);
|
|
42
|
+
this.logger.debug(`Can't refresh, doing re-auth with: ${JSON.stringify(this.response, index_1.SmartlingBaseApi.sensitiveReplacer)}`);
|
|
43
43
|
return yield this.authenticate();
|
|
44
44
|
});
|
|
45
45
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../api/auth/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,yCAAiD;AACjD,8CAAwD;AAIxD,MAAa,gBAAiB,SAAQ,wBAAgB;IAOlD,YACI,mBAA2B,EAAE,cAAsB,EAAE,WAAmB,EAAE,MAAc;QAExF,KAAK,CAAC,MAAM,CAAC,CAAC;QACd,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,UAAU,GAAG,GAAG,mBAAmB,cAAc,CAAC;QACvD,IAAI,CAAC,UAAU,EAAE,CAAC;IACtB,CAAC;IAEK,YAAY;;YACd,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAE7B,OAAO,MAAM,IAAI,CAAC,WAAW,CACzB,MAAM,EACN,GAAG,IAAI,CAAC,UAAU,eAAe,EACjC,IAAI,CAAC,SAAS,CAAC;gBACX,cAAc,EAAE,IAAI,CAAC,cAAc;gBACnC,UAAU,EAAE,IAAI,CAAC,WAAW;aAC/B,CAAC,CACL,CAAC;QACN,CAAC;KAAA;IAEK,YAAY;;YACd,IAAI,IAAI,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,iBAAiB,EAAE,EAAE;gBAChD,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBAE7B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,wBAAgB,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;gBAE9G,OAAO,MAAM,IAAI,CAAC,WAAW,CACzB,MAAM,EACN,GAAG,IAAI,CAAC,UAAU,uBAAuB,EACzC,IAAI,CAAC,SAAS,CAAC;oBACX,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY;iBAC3C,CAAC,CACL,CAAC;aACL;YAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sCAAsC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../api/auth/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translation-text-item-dto.js","sourceRoot":"","sources":["../../../../api/mt/dto/translation-text-item-dto.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { SmartlingBaseApi } from "../base/index";
|
|
2
|
+
import { SmartlingAuthApi } from "../auth/index";
|
|
3
|
+
import { Logger } from "../logger";
|
|
4
|
+
import { SmartlingMTParameters } from "./params/smartling-mt-parameters";
|
|
5
|
+
import { SmartlingListResponse } from "../http/smartling-list-response";
|
|
6
|
+
import { TranslationTextItemDto } from "./dto/translation-text-item-dto";
|
|
7
|
+
export declare class SmartlingMachineTranslationsApi extends SmartlingBaseApi {
|
|
8
|
+
constructor(smartlingApiBaseUrl: string, authApi: SmartlingAuthApi, logger: Logger);
|
|
9
|
+
translate(accountUid: string, params: SmartlingMTParameters): Promise<SmartlingListResponse<TranslationTextItemDto>>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.SmartlingMachineTranslationsApi = void 0;
|
|
13
|
+
const index_1 = require("../base/index");
|
|
14
|
+
class SmartlingMachineTranslationsApi extends index_1.SmartlingBaseApi {
|
|
15
|
+
constructor(smartlingApiBaseUrl, authApi, logger) {
|
|
16
|
+
super(logger);
|
|
17
|
+
this.authApi = authApi;
|
|
18
|
+
this.entrypoint = `${smartlingApiBaseUrl}/mt-router-api/v2/accounts`;
|
|
19
|
+
}
|
|
20
|
+
translate(accountUid, params) {
|
|
21
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
22
|
+
return yield this.makeRequest("post", `${this.entrypoint}/${accountUid}/smartling-mt`, JSON.stringify(params.export()));
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.SmartlingMachineTranslationsApi = SmartlingMachineTranslationsApi;
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../api/mt/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,yCAAiD;AAOjD,MAAa,+BAAgC,SAAQ,wBAAgB;IACjE,YAAY,mBAA2B,EAAE,OAAyB,EAAE,MAAc;QAC9E,KAAK,CAAC,MAAM,CAAC,CAAC;QACd,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,GAAG,mBAAmB,4BAA4B,CAAC;IACzE,CAAC;IAEK,SAAS,CACX,UAAkB,EAClB,MAA6B;;YAE7B,OAAO,MAAM,IAAI,CAAC,WAAW,CACzB,MAAM,EACN,GAAG,IAAI,CAAC,UAAU,IAAI,UAAU,eAAe,EAC/C,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAClC,CAAC;QACN,CAAC;KAAA;CACJ;AAjBD,0EAiBC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SmartlingMTParameters = void 0;
|
|
4
|
+
const exception_1 = require("../../exception");
|
|
5
|
+
const parameters_1 = require("../../parameters");
|
|
6
|
+
const MAX_ALLOWED_SOURCE_ITEMS = 1000;
|
|
7
|
+
const MAX_ALLOWED_KEY_LENGTH = 255;
|
|
8
|
+
const MAX_ALLOWED_SOURCE_TEXT_LENGTH = 64 * 1024;
|
|
9
|
+
class SmartlingMTParameters extends parameters_1.BaseParameters {
|
|
10
|
+
constructor(sourceLocaleId, targetLocaleId, items) {
|
|
11
|
+
super();
|
|
12
|
+
if (!items.length) {
|
|
13
|
+
throw new exception_1.SmartlingException("At least one source text item is required.");
|
|
14
|
+
}
|
|
15
|
+
if (items.length > MAX_ALLOWED_SOURCE_ITEMS) {
|
|
16
|
+
throw new exception_1.SmartlingException(`The request contains too many source text items: ${items.length}. Maximum allowed items number is ${MAX_ALLOWED_SOURCE_ITEMS}.`);
|
|
17
|
+
}
|
|
18
|
+
items.forEach((sourceTextItem, index) => {
|
|
19
|
+
if (!sourceTextItem.key.length) {
|
|
20
|
+
throw new exception_1.SmartlingException(`The key is requred for items[${index}].`);
|
|
21
|
+
}
|
|
22
|
+
if (sourceTextItem.key.length > MAX_ALLOWED_KEY_LENGTH) {
|
|
23
|
+
throw new exception_1.SmartlingException(`The key is too long for items[${index}]: ${sourceTextItem.key.length}. Maximum allowed key length is ${MAX_ALLOWED_KEY_LENGTH}.`);
|
|
24
|
+
}
|
|
25
|
+
if (!sourceTextItem.sourceText.length) {
|
|
26
|
+
throw new exception_1.SmartlingException(`The source text is requred for items[${index}].`);
|
|
27
|
+
}
|
|
28
|
+
if (sourceTextItem.sourceText.length > MAX_ALLOWED_SOURCE_TEXT_LENGTH) {
|
|
29
|
+
throw new exception_1.SmartlingException(`The source text is too long for items[${index}]: ${sourceTextItem.sourceText.length}. Maximum allowed source text length is ${MAX_ALLOWED_SOURCE_TEXT_LENGTH}.`);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
this.set("sourceLocaleId", sourceLocaleId);
|
|
33
|
+
this.set("targetLocaleId", targetLocaleId);
|
|
34
|
+
this.set("items", items);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.SmartlingMTParameters = SmartlingMTParameters;
|
|
38
|
+
//# sourceMappingURL=smartling-mt-parameters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smartling-mt-parameters.js","sourceRoot":"","sources":["../../../../api/mt/params/smartling-mt-parameters.ts"],"names":[],"mappings":";;;AAAA,+CAAqD;AACrD,iDAAkD;AAGlD,MAAM,wBAAwB,GAAG,IAAI,CAAC;AACtC,MAAM,sBAAsB,GAAG,GAAG,CAAC;AACnC,MAAM,8BAA8B,GAAG,EAAE,GAAG,IAAI,CAAC;AAEjD,MAAa,qBAAsB,SAAQ,2BAAc;IACrD,YAAY,cAAsB,EAAE,cAAsB,EAAE,KAAuB;QAC/E,KAAK,EAAE,CAAC;QAER,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YACf,MAAM,IAAI,8BAAkB,CAAC,4CAA4C,CAAC,CAAC;SAC9E;QAED,IAAI,KAAK,CAAC,MAAM,GAAG,wBAAwB,EAAE;YACzC,MAAM,IAAI,8BAAkB,CAAC,oDAAoD,KAAK,CAAC,MAAM,qCAAqC,wBAAwB,GAAG,CAAC,CAAC;SAClK;QAED,KAAK,CAAC,OAAO,CAAC,CAAC,cAAc,EAAE,KAAK,EAAE,EAAE;YACpC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE;gBAC5B,MAAM,IAAI,8BAAkB,CAAC,gCAAgC,KAAK,IAAI,CAAC,CAAC;aAC3E;YACD,IAAI,cAAc,CAAC,GAAG,CAAC,MAAM,GAAG,sBAAsB,EAAE;gBACpD,MAAM,IAAI,8BAAkB,CAAC,iCAAiC,KAAK,MAAM,cAAc,CAAC,GAAG,CAAC,MAAM,mCAAmC,sBAAsB,GAAG,CAAC,CAAC;aACnK;YACD,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,MAAM,EAAE;gBACnC,MAAM,IAAI,8BAAkB,CAAC,wCAAwC,KAAK,IAAI,CAAC,CAAC;aACnF;YACD,IAAI,cAAc,CAAC,UAAU,CAAC,MAAM,GAAG,8BAA8B,EAAE;gBACnE,MAAM,IAAI,8BAAkB,CAAC,yCAAyC,KAAK,MAAM,cAAc,CAAC,UAAU,CAAC,MAAM,2CAA2C,8BAA8B,GAAG,CAAC,CAAC;aAClM;QACL,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,cAAc,CAAC,CAAC;QAC3C,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,cAAc,CAAC,CAAC;QAC3C,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC7B,CAAC;CACJ;AA/BD,sDA+BC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-text-item.js","sourceRoot":"","sources":["../../../../api/mt/params/source-text-item.ts"],"names":[],"mappings":""}
|
package/built/index.d.ts
CHANGED
|
@@ -110,3 +110,7 @@ export * from "./api/locales/dto/direction";
|
|
|
110
110
|
export * from "./api/locales/dto/word-delimeter";
|
|
111
111
|
export * from "./api/locales/params/get-locales-parameters";
|
|
112
112
|
export * from "./api/locales/index";
|
|
113
|
+
export * from "./api/mt/index";
|
|
114
|
+
export * from "./api/mt/params/smartling-mt-parameters";
|
|
115
|
+
export * from "./api/mt/params/source-text-item";
|
|
116
|
+
export * from "./api/mt/dto/translation-text-item-dto";
|
package/built/index.js
CHANGED
|
@@ -126,4 +126,8 @@ __exportStar(require("./api/locales/dto/direction"), exports);
|
|
|
126
126
|
__exportStar(require("./api/locales/dto/word-delimeter"), exports);
|
|
127
127
|
__exportStar(require("./api/locales/params/get-locales-parameters"), exports);
|
|
128
128
|
__exportStar(require("./api/locales/index"), exports);
|
|
129
|
+
__exportStar(require("./api/mt/index"), exports);
|
|
130
|
+
__exportStar(require("./api/mt/params/smartling-mt-parameters"), exports);
|
|
131
|
+
__exportStar(require("./api/mt/params/source-text-item"), exports);
|
|
132
|
+
__exportStar(require("./api/mt/dto/translation-text-item-dto"), exports);
|
|
129
133
|
//# sourceMappingURL=index.js.map
|
package/built/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mDAAiC;AACjC,kEAAgD;AAChD,mDAAiC;AACjC,sDAAoC;AACpC,sDAAoC;AACpC,wEAAsD;AACtD,6EAA2D;AAC3D,gEAA8C;AAC9C,4EAA0D;AAC1D,uEAAqD;AACrD,0FAAwE;AACxE,oEAAkD;AAClD,iFAA+D;AAC/D,kFAAgE;AAChE,uEAAqD;AACrD,sEAAoD;AACpD,wDAAsC;AACtC,gEAA8C;AAC9C,wFAAsE;AACtE,qFAAmE;AACnE,4FAA0E;AAC1E,+FAA6E;AAC7E,2FAAyE;AACzE,oEAAkD;AAClD,oFAAkE;AAClE,qFAAmE;AACnE,uFAAqE;AACrE,4FAA0E;AAC1E,2EAAyD;AACzD,uEAAqD;AACrD,8EAA4D;AAC5D,4FAA0E;AAC1E,qFAAmE;AACnE,oDAAkC;AAClC,8EAA4D;AAC5D,6EAA2D;AAC3D,oEAAkD;AAClD,+DAA6C;AAC7C,4EAA0D;AAC1D,kFAAgE;AAChE,kFAAgE;AAChE,+EAA6D;AAC7D,oEAAkD;AAClD,qEAAmD;AACnD,0DAAwC;AACxC,kEAAgD;AAChD,uEAAqD;AACrD,yEAAuD;AACvD,yEAAuD;AACvD,4EAA0D;AAC1D,oFAAkE;AAClE,oFAAkE;AAClE,mFAAiE;AACjE,kFAAgE;AAChE,wFAAsE;AACtE,2FAAyE;AACzE,wFAAsE;AACtE,0FAAwE;AACxE,wEAAsD;AACtD,wEAAsD;AACtD,mFAAiE;AACjE,6EAA2D;AAC3D,mDAAiC;AACjC,8DAA4C;AAC5C,kFAAgE;AAChE,kEAAgD;AAChD,mEAAiD;AACjD,sEAAoD;AACpD,iEAA+C;AAC/C,yDAAuC;AACvC,iEAA+C;AAC/C,mFAAiE;AACjE,uFAAqE;AACrE,kEAAgD;AAChD,mEAAiD;AACjD,yEAAuD;AACvD,kEAAgD;AAChD,oEAAkD;AAClD,0EAAwD;AACxD,6EAA2D;AAC3D,4EAA0D;AAC1D,+DAA6C;AAC7C,8EAA4D;AAC5D,yEAAuD;AACvD,2EAAyD;AACzD,0EAAwD;AACxD,yEAAuD;AACvD,2EAAyD;AACzD,0EAAwD;AACxD,yDAAuC;AACvC,yDAAuC;AACvC,uDAAqC;AACrC,iEAA+C;AAC/C,gEAA8C;AAC9C,8DAA4C;AAC5C,+EAA6D;AAC7D,mGAAiF;AACjF,sDAAoC;AACpC,sEAAoD;AACpD,0EAAwD;AACxD,uFAAqE;AACrE,+CAA6B;AAC7B,wEAAsD;AACtD,+FAA6E;AAC7E,6EAA2D;AAC3D,gEAA8C;AAC9C,2EAAyD;AACzD,yEAAuD;AACvD,8DAA4C;AAC5C,mEAAiD;AACjD,8EAA4D;AAC5D,sDAAoC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mDAAiC;AACjC,kEAAgD;AAChD,mDAAiC;AACjC,sDAAoC;AACpC,sDAAoC;AACpC,wEAAsD;AACtD,6EAA2D;AAC3D,gEAA8C;AAC9C,4EAA0D;AAC1D,uEAAqD;AACrD,0FAAwE;AACxE,oEAAkD;AAClD,iFAA+D;AAC/D,kFAAgE;AAChE,uEAAqD;AACrD,sEAAoD;AACpD,wDAAsC;AACtC,gEAA8C;AAC9C,wFAAsE;AACtE,qFAAmE;AACnE,4FAA0E;AAC1E,+FAA6E;AAC7E,2FAAyE;AACzE,oEAAkD;AAClD,oFAAkE;AAClE,qFAAmE;AACnE,uFAAqE;AACrE,4FAA0E;AAC1E,2EAAyD;AACzD,uEAAqD;AACrD,8EAA4D;AAC5D,4FAA0E;AAC1E,qFAAmE;AACnE,oDAAkC;AAClC,8EAA4D;AAC5D,6EAA2D;AAC3D,oEAAkD;AAClD,+DAA6C;AAC7C,4EAA0D;AAC1D,kFAAgE;AAChE,kFAAgE;AAChE,+EAA6D;AAC7D,oEAAkD;AAClD,qEAAmD;AACnD,0DAAwC;AACxC,kEAAgD;AAChD,uEAAqD;AACrD,yEAAuD;AACvD,yEAAuD;AACvD,4EAA0D;AAC1D,oFAAkE;AAClE,oFAAkE;AAClE,mFAAiE;AACjE,kFAAgE;AAChE,wFAAsE;AACtE,2FAAyE;AACzE,wFAAsE;AACtE,0FAAwE;AACxE,wEAAsD;AACtD,wEAAsD;AACtD,mFAAiE;AACjE,6EAA2D;AAC3D,mDAAiC;AACjC,8DAA4C;AAC5C,kFAAgE;AAChE,kEAAgD;AAChD,mEAAiD;AACjD,sEAAoD;AACpD,iEAA+C;AAC/C,yDAAuC;AACvC,iEAA+C;AAC/C,mFAAiE;AACjE,uFAAqE;AACrE,kEAAgD;AAChD,mEAAiD;AACjD,yEAAuD;AACvD,kEAAgD;AAChD,oEAAkD;AAClD,0EAAwD;AACxD,6EAA2D;AAC3D,4EAA0D;AAC1D,+DAA6C;AAC7C,8EAA4D;AAC5D,yEAAuD;AACvD,2EAAyD;AACzD,0EAAwD;AACxD,yEAAuD;AACvD,2EAAyD;AACzD,0EAAwD;AACxD,yDAAuC;AACvC,yDAAuC;AACvC,uDAAqC;AACrC,iEAA+C;AAC/C,gEAA8C;AAC9C,8DAA4C;AAC5C,+EAA6D;AAC7D,mGAAiF;AACjF,sDAAoC;AACpC,sEAAoD;AACpD,0EAAwD;AACxD,uFAAqE;AACrE,+CAA6B;AAC7B,wEAAsD;AACtD,+FAA6E;AAC7E,6EAA2D;AAC3D,gEAA8C;AAC9C,2EAAyD;AACzD,yEAAuD;AACvD,8DAA4C;AAC5C,mEAAiD;AACjD,8EAA4D;AAC5D,sDAAoC;AACpC,iDAA+B;AAC/B,0EAAwD;AACxD,mEAAiD;AACjD,yEAAuD"}
|
package/built/package.json
CHANGED
package/index.ts
CHANGED
|
@@ -110,3 +110,7 @@ export * from "./api/locales/dto/direction";
|
|
|
110
110
|
export * from "./api/locales/dto/word-delimeter";
|
|
111
111
|
export * from "./api/locales/params/get-locales-parameters";
|
|
112
112
|
export * from "./api/locales/index";
|
|
113
|
+
export * from "./api/mt/index";
|
|
114
|
+
export * from "./api/mt/params/smartling-mt-parameters";
|
|
115
|
+
export * from "./api/mt/params/source-text-item";
|
|
116
|
+
export * from "./api/mt/dto/translation-text-item-dto";
|
package/package.json
CHANGED
package/test/base.spec.ts
CHANGED
|
@@ -643,4 +643,22 @@ describe("Base class tests.", () => {
|
|
|
643
643
|
}
|
|
644
644
|
});
|
|
645
645
|
});
|
|
646
|
+
|
|
647
|
+
it("Check sensitive info replacer", async () => {
|
|
648
|
+
const json = {
|
|
649
|
+
foo: "bar_test",
|
|
650
|
+
userIdentifier: "userIdentifier_test",
|
|
651
|
+
userSecret: "userSecret_test",
|
|
652
|
+
accessToken: "accessToken_test",
|
|
653
|
+
refreshToken: "refreshToken_test"
|
|
654
|
+
};
|
|
655
|
+
|
|
656
|
+
assert.equal(JSON.stringify(json, SmartlingBaseApi.sensitiveReplacer), JSON.stringify({
|
|
657
|
+
foo: "bar_test",
|
|
658
|
+
userIdentifier: "userIdentixxxxx",
|
|
659
|
+
userSecret: "userSecretxxxxx",
|
|
660
|
+
accessToken: "accessTokexxxxx",
|
|
661
|
+
refreshToken: "refreshTokxxxxx"
|
|
662
|
+
}));
|
|
663
|
+
});
|
|
646
664
|
});
|
package/test/files.spec.ts
CHANGED
|
@@ -11,7 +11,6 @@ import { FileType } from "../api/files/params/file-type";
|
|
|
11
11
|
import { streamToString } from "./stream-to-string";
|
|
12
12
|
import { DownloadFileAllTranslationsParameters } from "../api/files/params/download-file-all-translations-parameters";
|
|
13
13
|
import { RecentlyUploadedFilesParameters } from "../api/files/params/recently-uploaded-files";
|
|
14
|
-
import { ResponseBodyType } from "../api/base/enum/response-body-type";
|
|
15
14
|
|
|
16
15
|
describe("SmartlingFilesApi class tests.", () => {
|
|
17
16
|
const projectId = "testProjectId";
|
package/test/mt.spec.ts
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import sinon from "sinon";
|
|
2
|
+
import assert from "assert";
|
|
3
|
+
import { SmartlingMachineTranslationsApi } from "../api/mt";
|
|
4
|
+
import { SmartlingMTParameters } from "../api/mt/params/smartling-mt-parameters";
|
|
5
|
+
import { SmartlingAuthApi } from "../api/auth/index";
|
|
6
|
+
import { SmartlingException } from "../api/exception/index";
|
|
7
|
+
import { loggerMock, authMock, responseMock } from "./mock";
|
|
8
|
+
|
|
9
|
+
describe("SmartlinMachineTranslationsApi class tests.", () => {
|
|
10
|
+
const accountUid = "testAccountUid";
|
|
11
|
+
let mtApi;
|
|
12
|
+
let mtApiFetchStub;
|
|
13
|
+
let mtApiUaStub;
|
|
14
|
+
let responseMockTextStub;
|
|
15
|
+
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
mtApi = new SmartlingMachineTranslationsApi("https://test.com", authMock as unknown as SmartlingAuthApi, loggerMock);
|
|
18
|
+
|
|
19
|
+
mtApiFetchStub = sinon.stub(mtApi, "fetch");
|
|
20
|
+
mtApiUaStub = sinon.stub(mtApi, "ua");
|
|
21
|
+
responseMockTextStub = sinon.stub(responseMock, "text");
|
|
22
|
+
|
|
23
|
+
mtApiUaStub.returns("test_user_agent");
|
|
24
|
+
mtApiFetchStub.returns(responseMock);
|
|
25
|
+
responseMockTextStub.returns("{\"response\": {}}");
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
afterEach(() => {
|
|
29
|
+
mtApiFetchStub.restore();
|
|
30
|
+
responseMockTextStub.restore();
|
|
31
|
+
mtApiUaStub.restore();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("Translate using Smartling MT", async () => {
|
|
35
|
+
const params = new SmartlingMTParameters(
|
|
36
|
+
"en-US",
|
|
37
|
+
"es-ES",
|
|
38
|
+
[{
|
|
39
|
+
key: "text.key",
|
|
40
|
+
sourceText: "This is text for translation"
|
|
41
|
+
}]
|
|
42
|
+
);
|
|
43
|
+
await mtApi.translate(accountUid, params);
|
|
44
|
+
|
|
45
|
+
sinon.assert.calledOnce(mtApiFetchStub);
|
|
46
|
+
sinon.assert.calledWithExactly(
|
|
47
|
+
mtApiFetchStub,
|
|
48
|
+
`https://test.com/mt-router-api/v2/accounts/${accountUid}/smartling-mt`, {
|
|
49
|
+
headers: {
|
|
50
|
+
Authorization: "test_token_type test_access_token",
|
|
51
|
+
"Content-Type": "application/json",
|
|
52
|
+
"User-Agent": "test_user_agent"
|
|
53
|
+
},
|
|
54
|
+
method: "post",
|
|
55
|
+
body: JSON.stringify({
|
|
56
|
+
sourceLocaleId: "en-US",
|
|
57
|
+
targetLocaleId: "es-ES",
|
|
58
|
+
items: [{
|
|
59
|
+
key: "text.key",
|
|
60
|
+
sourceText: "This is text for translation"
|
|
61
|
+
}]
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("Validation of MT parameters throws error when no source items specified", async () => {
|
|
68
|
+
try {
|
|
69
|
+
// eslint-disable-next-line no-new
|
|
70
|
+
new SmartlingMTParameters(
|
|
71
|
+
"en-US",
|
|
72
|
+
"es-ES",
|
|
73
|
+
[]
|
|
74
|
+
);
|
|
75
|
+
assert.fail("must throw SmartlingException");
|
|
76
|
+
} catch (e) {
|
|
77
|
+
assert.ok(e instanceof SmartlingException);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("Validation of MT parameters throws error when number of source items exceeds limit", async () => {
|
|
82
|
+
try {
|
|
83
|
+
// eslint-disable-next-line no-new
|
|
84
|
+
new SmartlingMTParameters(
|
|
85
|
+
"en-US",
|
|
86
|
+
"es-ES",
|
|
87
|
+
Array(1001).fill({
|
|
88
|
+
key: "key",
|
|
89
|
+
sourceText: "string for translation"
|
|
90
|
+
})
|
|
91
|
+
);
|
|
92
|
+
assert.fail("must throw SmartlingException");
|
|
93
|
+
} catch (e) {
|
|
94
|
+
assert.ok(e instanceof SmartlingException);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("Validation of MT parameters throws error when source item has empty key", async () => {
|
|
99
|
+
try {
|
|
100
|
+
// eslint-disable-next-line no-new
|
|
101
|
+
new SmartlingMTParameters(
|
|
102
|
+
"en-US",
|
|
103
|
+
"es-ES",
|
|
104
|
+
[{
|
|
105
|
+
key: "",
|
|
106
|
+
sourceText: "text"
|
|
107
|
+
}]
|
|
108
|
+
);
|
|
109
|
+
assert.fail("must throw SmartlingException");
|
|
110
|
+
} catch (e) {
|
|
111
|
+
assert.ok(e instanceof SmartlingException);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it("Validation of MT parameters throws error when source item has long key", async () => {
|
|
116
|
+
try {
|
|
117
|
+
// eslint-disable-next-line no-new
|
|
118
|
+
new SmartlingMTParameters(
|
|
119
|
+
"en-US",
|
|
120
|
+
"es-ES",
|
|
121
|
+
[{
|
|
122
|
+
key: "A".repeat(256),
|
|
123
|
+
sourceText: "text"
|
|
124
|
+
}]
|
|
125
|
+
);
|
|
126
|
+
assert.fail("must throw SmartlingException");
|
|
127
|
+
} catch (e) {
|
|
128
|
+
assert.ok(e instanceof SmartlingException);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("Validation of MT parameters throws error when source item has empty text", async () => {
|
|
133
|
+
try {
|
|
134
|
+
// eslint-disable-next-line no-new
|
|
135
|
+
new SmartlingMTParameters(
|
|
136
|
+
"en-US",
|
|
137
|
+
"es-ES",
|
|
138
|
+
[{
|
|
139
|
+
key: "key",
|
|
140
|
+
sourceText: ""
|
|
141
|
+
}]
|
|
142
|
+
);
|
|
143
|
+
assert.fail("must throw SmartlingException");
|
|
144
|
+
} catch (e) {
|
|
145
|
+
assert.ok(e instanceof SmartlingException);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it("Validation of MT parameters throws error when source item has long text", async () => {
|
|
150
|
+
try {
|
|
151
|
+
// eslint-disable-next-line no-new
|
|
152
|
+
new SmartlingMTParameters(
|
|
153
|
+
"en-US",
|
|
154
|
+
"es-ES",
|
|
155
|
+
[{
|
|
156
|
+
key: "key",
|
|
157
|
+
sourceText: "A".repeat((64 * 1024) + 1)
|
|
158
|
+
}]
|
|
159
|
+
);
|
|
160
|
+
assert.fail("must throw SmartlingException");
|
|
161
|
+
} catch (e) {
|
|
162
|
+
assert.ok(e instanceof SmartlingException);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
});
|