Skip to content

Commit da950f2

Browse files
authored
New Components - crowdin (#14447)
* crowdin init * [Components] crowdin #13242 Sources - New Comment Issue (Instant) - File Approved (Instant) - New Directory Actions - Create Project - Upload File - Translate Via Machine Translation * pnpm update * some adjusts * pnpm update
1 parent 776eed2 commit da950f2

File tree

18 files changed

+1330
-20
lines changed

18 files changed

+1330
-20
lines changed

components/crowdin/.gitignore

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import fs from "fs";
2+
import { TYPE_OPTIONS } from "../../common/constants.mjs";
3+
import {
4+
checkTmp,
5+
parseObject,
6+
} from "../../common/utils.mjs";
7+
import crowdin from "../../crowdin.app.mjs";
8+
9+
export default {
10+
key: "crowdin-add-file",
11+
name: "Add File to Project",
12+
description: "Adds a file into the created project. [See the documentation](https://developer.crowdin.com/api/v2/#tag/source-files/operation/api.projects.files.post)",
13+
version: "0.0.1",
14+
type: "action",
15+
props: {
16+
crowdin,
17+
projectId: {
18+
propDefinition: [
19+
crowdin,
20+
"projectId",
21+
],
22+
},
23+
file: {
24+
type: "string",
25+
label: "File",
26+
description: "The path to the file saved to the `/tmp` directory (e.g. `/tmp/example.jpg`) to process. [See the documentation](https://pipedream.com/docs/workflows/steps/code/nodejs/working-with-files/#the-tmp-directory).",
27+
},
28+
name: {
29+
type: "string",
30+
label: "Name",
31+
description: "The name of the file in Crowdin. **Note:** Can't contain `\\ / : * ? \" < > |` symbols. `ZIP` files are not allowed.",
32+
},
33+
branchId: {
34+
propDefinition: [
35+
crowdin,
36+
"branchId",
37+
(c) => ({
38+
projectId: c.projectId,
39+
}),
40+
],
41+
},
42+
directoryId: {
43+
propDefinition: [
44+
crowdin,
45+
"directoryId",
46+
(c) => ({
47+
projectId: c.projectId,
48+
}),
49+
],
50+
},
51+
title: {
52+
type: "string",
53+
label: "Title",
54+
description: "Use to provide more details for translators. Title is available in UI only",
55+
optional: true,
56+
},
57+
context: {
58+
type: "string",
59+
label: "Context",
60+
description: "Use to provide context about whole file",
61+
optional: true,
62+
},
63+
type: {
64+
type: "string",
65+
label: "File Type",
66+
description: "The type of the file. **Note:** Use `docx` type to import each cell as a separate source string for XLSX file. Default is `auto`",
67+
options: TYPE_OPTIONS,
68+
optional: true,
69+
},
70+
parserVersion: {
71+
type: "integer",
72+
label: "Parser Version",
73+
description: "Using latest parser version by default. **Note:** Must be used together with `type`.",
74+
optional: true,
75+
},
76+
attachLabelIds: {
77+
propDefinition: [
78+
crowdin,
79+
"attachLabelIds",
80+
(c) => ({
81+
projectId: c.projectId,
82+
}),
83+
],
84+
},
85+
},
86+
async run({ $ }) {
87+
const {
88+
crowdin,
89+
attachLabelIds,
90+
projectId,
91+
file,
92+
...data
93+
} = this;
94+
95+
const fileBinary = fs.readFileSync(checkTmp(file));
96+
const crowdinFilename = file.startsWith("/tmp/")
97+
? file.slice(5)
98+
: file;
99+
100+
const fileResponse = await crowdin.createStorage({
101+
data: Buffer.from(fileBinary, "binary"),
102+
headers: {
103+
"Crowdin-API-FileName": encodeURI(crowdinFilename),
104+
"Content-Type": "application/octet-stream",
105+
},
106+
});
107+
108+
const response = await crowdin.uploadFileToProject({
109+
$,
110+
projectId,
111+
data: {
112+
...data,
113+
storageId: fileResponse.data.id,
114+
attachLabelIds: parseObject(attachLabelIds),
115+
},
116+
});
117+
$.export("$summary", `Successfully uploaded file: ${this.name}`);
118+
return response;
119+
},
120+
};
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
import { ConfigurationError } from "@pipedream/platform";
2+
import {
3+
LANGUAGE_ACCESS_POLICY_OPTIONS,
4+
TAGS_DETECTION_OPTIONS,
5+
VISIBILITY_OPTIONS,
6+
} from "../../common/constants.mjs";
7+
import { parseObject } from "../../common/utils.mjs";
8+
import crowdin from "../../crowdin.app.mjs";
9+
10+
export default {
11+
key: "crowdin-create-project",
12+
name: "Create Project",
13+
description: "Creates a new project within Crowdin. [See the documentation](https://support.crowdin.com/developer/api/v2/#/projects-api/create-project)",
14+
version: "0.0.1",
15+
type: "action",
16+
props: {
17+
crowdin,
18+
name: {
19+
type: "string",
20+
label: "Project Name",
21+
description: "The name of the project to be created",
22+
},
23+
sourceLanguageId: {
24+
propDefinition: [
25+
crowdin,
26+
"sourceLanguageId",
27+
],
28+
},
29+
targetLanguageIds: {
30+
propDefinition: [
31+
crowdin,
32+
"sourceLanguageId",
33+
],
34+
type: "string[]",
35+
label: "Target Language IDs",
36+
description: "Array of target language IDs",
37+
optional: true,
38+
},
39+
identifier: {
40+
type: "string",
41+
label: "Identifier",
42+
description: "A custom identifier for the project",
43+
optional: true,
44+
},
45+
visibility: {
46+
type: "string",
47+
label: "Visibility",
48+
description: "Defines how users can join the project.",
49+
options: VISIBILITY_OPTIONS,
50+
optional: true,
51+
},
52+
languageAccessPolicy: {
53+
type: "string",
54+
label: "Language Access Policy",
55+
description: "Defines access to project languages.",
56+
optional: true,
57+
options: LANGUAGE_ACCESS_POLICY_OPTIONS,
58+
},
59+
cname: {
60+
type: "string",
61+
label: "Custom Domain Name",
62+
description: "Custom domain name for the project.",
63+
optional: true,
64+
},
65+
description: {
66+
type: "string",
67+
label: "Project Description",
68+
description: "The description of the project.",
69+
optional: true,
70+
},
71+
tagsDetection: {
72+
type: "string",
73+
label: "Tags Detection",
74+
description: "The type of the tags detection.",
75+
options: TAGS_DETECTION_OPTIONS,
76+
optional: true,
77+
},
78+
isMtAllowed: {
79+
type: "boolean",
80+
label: "Allow Machine Translation",
81+
description: "Allows machine translations to be visible for translators. Default is **true**.",
82+
optional: true,
83+
},
84+
taskBasedAccessControl: {
85+
type: "boolean",
86+
label: "Task Based Access Control",
87+
description: "Allow project members to work with tasks they're assigned to. Default is **false**.",
88+
optional: true,
89+
default: false,
90+
},
91+
autoSubstitution: {
92+
type: "boolean",
93+
label: "Auto Substitution",
94+
description: "Allows auto-substitution. Default is **true**.",
95+
optional: true,
96+
default: true,
97+
},
98+
autoTranslateDialects: {
99+
type: "boolean",
100+
label: "Auto Translate Dialects",
101+
description: "Automatically fill in regional dialects. Default is **false**.",
102+
optional: true,
103+
},
104+
publicDownloads: {
105+
type: "boolean",
106+
label: "Public Downloads",
107+
description: "Allows translators to download source files. Default is **true**.",
108+
optional: true,
109+
},
110+
hiddenStringsProofreadersAccess: {
111+
type: "boolean",
112+
label: "Hidden Strings Proofreaders Access",
113+
description: "Allows proofreaders to work with hidden strings. Default is **true**.",
114+
optional: true,
115+
default: true,
116+
},
117+
useGlobalTm: {
118+
type: "boolean",
119+
label: "Use Global Translation Memory",
120+
description: "If true, machine translations from connected MT engines will appear as suggestions. Default is **true**.",
121+
optional: true,
122+
},
123+
showTmSuggestionsDialects: {
124+
type: "boolean",
125+
label: "Show TM Suggestions for Dialects",
126+
description: "Show primary language TM suggestions for dialects if there are no dialect-specific ones. Default is **true**.",
127+
optional: true,
128+
default: true,
129+
},
130+
skipUntranslatedStrings: {
131+
type: "boolean",
132+
label: "Skip Untranslated Strings",
133+
description: "Defines whether to skip untranslated strings.",
134+
optional: true,
135+
},
136+
exportApprovedOnly: {
137+
type: "boolean",
138+
label: "Export Approved Only",
139+
description: "Defines whether to export only approved strings.",
140+
optional: true,
141+
},
142+
qaCheckIsActive: {
143+
type: "boolean",
144+
label: "QA Check Is Active",
145+
description: "If true, QA checks are active. Default is **true**.",
146+
optional: true,
147+
},
148+
type: {
149+
type: "string",
150+
label: "Type",
151+
description: "Defines the project type. To create a file-based project, use 0.",
152+
options: [
153+
"0",
154+
"1",
155+
],
156+
optional: true,
157+
},
158+
},
159+
async run({ $ }) {
160+
try {
161+
const {
162+
crowdin,
163+
type,
164+
targetLanguageIds,
165+
tagsDetection,
166+
...data
167+
} = this;
168+
169+
const response = await crowdin.createProject({
170+
$,
171+
data: {
172+
...data,
173+
type: parseInt(type),
174+
targetLanguageIds: parseObject(targetLanguageIds),
175+
tagsDetection: parseInt(tagsDetection),
176+
},
177+
});
178+
$.export("$summary", `Project created successfully with Id: ${response.data.id}`);
179+
return response;
180+
} catch ({ response }) {
181+
throw new ConfigurationError(response.data.errors[0]?.error?.errors[0]?.message);
182+
}
183+
},
184+
};
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { LANGUAGE_R_PROVIDER_OPTIONS } from "../../common/constants.mjs";
2+
import crowdin from "../../crowdin.app.mjs";
3+
4+
export default {
5+
key: "crowdin-translate-via-machine-translation",
6+
name: "Translate via Machine Translation",
7+
description: "Performs machine translation of the uploaded files. [See the documentation](https://support.crowdin.com/developer/api/v2/)",
8+
version: "0.0.1",
9+
type: "action",
10+
props: {
11+
crowdin,
12+
mtId: {
13+
propDefinition: [
14+
crowdin,
15+
"mtId",
16+
],
17+
},
18+
targetLanguageId: {
19+
propDefinition: [
20+
crowdin,
21+
"sourceLanguageId",
22+
],
23+
type: "string",
24+
label: "Target Language ID",
25+
description: "The language ID for the target translation language",
26+
},
27+
languageRecognitionProvider: {
28+
type: "string",
29+
label: "Language Recognition Provider",
30+
description: "Select a provider for language recognition **Note:** Is required if the source language is not selected",
31+
options: LANGUAGE_R_PROVIDER_OPTIONS,
32+
},
33+
sourceLanguageId: {
34+
propDefinition: [
35+
crowdin,
36+
"sourceLanguageId",
37+
],
38+
},
39+
strings: {
40+
type: "string[]",
41+
label: "Strings",
42+
description: "Array of strings to be translated. **Note:** You can translate up to 100 strings at a time.",
43+
},
44+
},
45+
async run({ $ }) {
46+
const response = await this.crowdin.performMachineTranslation({
47+
$,
48+
mtId: this.mtId,
49+
data: {
50+
targetLanguageId: this.targetLanguageId,
51+
strings: this.strings,
52+
languageRecognitionProvider: this.languageRecognitionProvider,
53+
sourceLanguageId: this.sourceLanguageId,
54+
},
55+
});
56+
57+
$.export("$summary", "Successfully performed machine translation");
58+
return response;
59+
},
60+
};

components/crowdin/app/crowdin.app.ts

Lines changed: 0 additions & 13 deletions
This file was deleted.

0 commit comments

Comments
 (0)