@crowdin/app-project-module 0.23.5 → 0.24.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 +6 -0
- package/out/handlers/crowdin-file-progress.js +1 -1
- package/out/handlers/custom-file-format/process.js +5 -5
- package/out/handlers/custom-mt/translate.js +1 -1
- package/out/handlers/install.js +20 -20
- package/out/handlers/integration-login.js +1 -1
- package/out/handlers/integration-logout.js +1 -1
- package/out/handlers/integration-update.js +2 -2
- package/out/handlers/manifest.js +1 -1
- package/out/handlers/oauth-login.js +1 -1
- package/out/handlers/oauth-url.js +1 -1
- package/out/handlers/subscription-paid.js +1 -1
- package/out/handlers/uninstall.js +1 -1
- package/out/index.js +2 -2
- package/out/models/index.d.ts +2 -2
- package/out/storage/mysql.js +16 -16
- package/out/storage/postgre.js +10 -10
- package/out/storage/sqlite.js +3 -3
- package/out/util/connection.js +12 -11
- package/out/util/cron.js +36 -23
- package/out/util/defaults.js +8 -8
- package/out/views/login.handlebars +2 -2
- package/package.json +15 -5
package/README.md
CHANGED
|
@@ -833,6 +833,12 @@ configuration.jwtValidationOptions = {
|
|
|
833
833
|
};
|
|
834
834
|
```
|
|
835
835
|
|
|
836
|
+
### App authentication type
|
|
837
|
+
|
|
838
|
+
```js
|
|
839
|
+
configuration.authenticationType = 'authorization_code'; //default is "crowdin_app"
|
|
840
|
+
```
|
|
841
|
+
|
|
836
842
|
## Contributing
|
|
837
843
|
|
|
838
844
|
If you want to contribute please read the [Contributing](/CONTRIBUTING.md) guidelines.
|
|
@@ -16,7 +16,7 @@ function handle(config) {
|
|
|
16
16
|
(0, util_1.log)(`Loading translation progress for file ${fileId}`, config.logger);
|
|
17
17
|
const progress = yield req.crowdinApiClient.translationStatusApi.getFileProgress(req.crowdinContext.jwtPayload.context.project_id, fileId);
|
|
18
18
|
(0, util_1.log)(`Translation progress for file ${fileId} ${JSON.stringify(progress.data, null, 2)}`, config.logger);
|
|
19
|
-
res.send({ [fileId]: progress.data.map(e => e.data) });
|
|
19
|
+
res.send({ [fileId]: progress.data.map((e) => e.data) });
|
|
20
20
|
}), config.onError);
|
|
21
21
|
}
|
|
22
22
|
exports.default = handle;
|
|
@@ -135,15 +135,15 @@ function handleParseFile(baseUrl, dataFolder, config, req, client, context, proj
|
|
|
135
135
|
if (res.strings) {
|
|
136
136
|
let strings = res.strings;
|
|
137
137
|
if (config.autoUploadTranslations) {
|
|
138
|
-
strings = strings.map(string => {
|
|
138
|
+
strings = strings.map((string) => {
|
|
139
139
|
const translations = {};
|
|
140
140
|
req.targetLanguages
|
|
141
|
-
.map(targetLanguage => targetLanguage.id)
|
|
142
|
-
.forEach(targetLanguage => (translations[targetLanguage] = { text: string.text }));
|
|
141
|
+
.map((targetLanguage) => targetLanguage.id)
|
|
142
|
+
.forEach((targetLanguage) => (translations[targetLanguage] = { text: string.text }));
|
|
143
143
|
return Object.assign(Object.assign({}, string), { translations });
|
|
144
144
|
});
|
|
145
145
|
}
|
|
146
|
-
const stringsNDJson = strings.map(s => JSON.stringify(s)).join('\n\r');
|
|
146
|
+
const stringsNDJson = strings.map((s) => JSON.stringify(s)).join('\n\r');
|
|
147
147
|
if (Buffer.byteLength(stringsNDJson, 'utf8') < maxSize) {
|
|
148
148
|
response.strings = strings;
|
|
149
149
|
}
|
|
@@ -164,7 +164,7 @@ function handleParseFile(baseUrl, dataFolder, config, req, client, context, proj
|
|
|
164
164
|
}
|
|
165
165
|
function storeFile(fileContent, folder) {
|
|
166
166
|
const fileName = `file${Date.now()}`;
|
|
167
|
-
return new Promise((res, rej) => fs_1.default.writeFile(path_1.default.join(folder, 'custom-file-format', fileName), fileContent, err => {
|
|
167
|
+
return new Promise((res, rej) => fs_1.default.writeFile(path_1.default.join(folder, 'custom-file-format', fileName), fileContent, (err) => {
|
|
168
168
|
if (err) {
|
|
169
169
|
rej(err);
|
|
170
170
|
}
|
|
@@ -15,7 +15,7 @@ function handle(baseConfig, config) {
|
|
|
15
15
|
const source = req.query.source;
|
|
16
16
|
const target = req.query.target;
|
|
17
17
|
const body = req.body;
|
|
18
|
-
(0, util_1.log)('
|
|
18
|
+
(0, util_1.log)('Received request for custom mt', baseConfig.logger);
|
|
19
19
|
(0, util_1.log)(`Source language ${source}, target language ${target}`, baseConfig.logger);
|
|
20
20
|
(0, util_1.log)(`Payload ${JSON.stringify(body, null, 2)}`, baseConfig.logger);
|
|
21
21
|
const projectId = Number(req.query.project_id);
|
package/out/handlers/install.js
CHANGED
|
@@ -13,25 +13,6 @@ const crowdin_apps_functions_1 = require("@crowdin/crowdin-apps-functions");
|
|
|
13
13
|
const models_1 = require("../models");
|
|
14
14
|
const storage_1 = require("../storage");
|
|
15
15
|
const util_1 = require("../util");
|
|
16
|
-
function fetchToken(config, event) {
|
|
17
|
-
var _a, _b;
|
|
18
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
19
|
-
if (config.authenticationType === models_1.AuthenticationType.APP) {
|
|
20
|
-
const token = yield (0, crowdin_apps_functions_1.fetchAppToken)(config.identifier, event.appSecret, config.clientId, config.clientSecret, event.domain || '', event.userId, (_a = config.crowdinUrls) === null || _a === void 0 ? void 0 : _a.accountUrl);
|
|
21
|
-
return {
|
|
22
|
-
accessToken: (0, util_1.encryptData)(config, token.accessToken),
|
|
23
|
-
expiresIn: token.expiresIn,
|
|
24
|
-
refreshToken: '',
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
const token = yield (0, crowdin_apps_functions_1.generateOAuthToken)(config.clientId, config.clientSecret, event.code || '', (_b = config.crowdinUrls) === null || _b === void 0 ? void 0 : _b.accountUrl);
|
|
28
|
-
return {
|
|
29
|
-
accessToken: (0, util_1.encryptData)(config, token.accessToken),
|
|
30
|
-
refreshToken: (0, util_1.encryptData)(config, token.refreshToken),
|
|
31
|
-
expiresIn: token.expiresIn,
|
|
32
|
-
};
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
16
|
function handle(config) {
|
|
36
17
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
37
18
|
const event = req.body;
|
|
@@ -45,7 +26,7 @@ function handle(config) {
|
|
|
45
26
|
baseUrl: event.baseUrl,
|
|
46
27
|
accessToken: token.accessToken,
|
|
47
28
|
refreshToken: token.refreshToken,
|
|
48
|
-
expire: (
|
|
29
|
+
expire: (Date.now() / 1000 + token.expiresIn).toString(),
|
|
49
30
|
type: event.domain ? models_1.AccountType.ENTERPRISE : models_1.AccountType.NORMAL,
|
|
50
31
|
};
|
|
51
32
|
const existingCredentials = yield (0, storage_1.getStorage)().getCrowdinCredentials(credentials.id);
|
|
@@ -61,3 +42,22 @@ function handle(config) {
|
|
|
61
42
|
}), config.onError);
|
|
62
43
|
}
|
|
63
44
|
exports.default = handle;
|
|
45
|
+
function fetchToken(config, event) {
|
|
46
|
+
var _a, _b;
|
|
47
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
48
|
+
if (config.authenticationType === models_1.AuthenticationType.CODE) {
|
|
49
|
+
const token = yield (0, crowdin_apps_functions_1.generateOAuthToken)(config.clientId, config.clientSecret, event.code || '', (_a = config.crowdinUrls) === null || _a === void 0 ? void 0 : _a.accountUrl);
|
|
50
|
+
return {
|
|
51
|
+
accessToken: (0, util_1.encryptData)(config, token.accessToken),
|
|
52
|
+
refreshToken: (0, util_1.encryptData)(config, token.refreshToken),
|
|
53
|
+
expiresIn: token.expiresIn,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const token = yield (0, crowdin_apps_functions_1.fetchAppToken)(config.identifier, event.appSecret, config.clientId, config.clientSecret, event.domain || '', event.userId, (_b = config.crowdinUrls) === null || _b === void 0 ? void 0 : _b.accountUrl);
|
|
57
|
+
return {
|
|
58
|
+
accessToken: (0, util_1.encryptData)(config, token.accessToken),
|
|
59
|
+
expiresIn: token.expiresIn,
|
|
60
|
+
refreshToken: '',
|
|
61
|
+
};
|
|
62
|
+
});
|
|
63
|
+
}
|
|
@@ -13,7 +13,7 @@ const storage_1 = require("../storage");
|
|
|
13
13
|
const util_1 = require("../util");
|
|
14
14
|
function handle(config, integration) {
|
|
15
15
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
16
|
-
(0, util_1.log)('
|
|
16
|
+
(0, util_1.log)('Received integration login request', config.logger);
|
|
17
17
|
if (integration.checkConnection) {
|
|
18
18
|
(0, util_1.log)('Checking the integration credentials', config.logger);
|
|
19
19
|
yield integration.checkConnection(req.body.credentials);
|
|
@@ -14,7 +14,7 @@ const util_1 = require("../util");
|
|
|
14
14
|
const connection_1 = require("../util/connection");
|
|
15
15
|
function handle(config, integration) {
|
|
16
16
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
17
|
-
(0, util_1.log)('
|
|
17
|
+
(0, util_1.log)('Received integration logout request', config.logger);
|
|
18
18
|
if (integration.onLogout) {
|
|
19
19
|
(0, util_1.log)('Invoking onLogout hook', config.logger);
|
|
20
20
|
yield integration.onLogout(req.crowdinContext.jwtPayload.context.project_id, req.crowdinApiClient, req.integrationCredentials, req.integrationSettings);
|
|
@@ -13,10 +13,10 @@ const util_1 = require("../util");
|
|
|
13
13
|
const defaults_1 = require("../util/defaults");
|
|
14
14
|
function handle(config, integration) {
|
|
15
15
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
16
|
-
(0, util_1.log)('
|
|
16
|
+
(0, util_1.log)('Updating integration data', config.logger);
|
|
17
17
|
const rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, req.crowdinApiClient, req.crowdinContext.jwtPayload.context.project_id);
|
|
18
18
|
if (rootFolder) {
|
|
19
|
-
(0, util_1.log)(`
|
|
19
|
+
(0, util_1.log)(`Updating integration data for crowding root folder ${rootFolder.id}`, config.logger);
|
|
20
20
|
}
|
|
21
21
|
const result = yield integration.updateIntegration(req.crowdinContext.jwtPayload.context.project_id, req.crowdinApiClient, req.integrationCredentials, req.body, rootFolder, req.integrationSettings);
|
|
22
22
|
let message;
|
package/out/handlers/manifest.js
CHANGED
|
@@ -123,7 +123,7 @@ function handle(config) {
|
|
|
123
123
|
logo: '/logo.png',
|
|
124
124
|
baseUrl: config.baseUrl,
|
|
125
125
|
authentication: {
|
|
126
|
-
type: config.authenticationType || models_1.AuthenticationType.
|
|
126
|
+
type: config.authenticationType || models_1.AuthenticationType.APP,
|
|
127
127
|
clientId: config.clientId,
|
|
128
128
|
},
|
|
129
129
|
events,
|
|
@@ -22,7 +22,7 @@ function handle(config, integration) {
|
|
|
22
22
|
uid: 'oauth_popup',
|
|
23
23
|
};
|
|
24
24
|
const code = req.query[((_b = (_a = integration.oauthLogin) === null || _a === void 0 ? void 0 : _a.fieldsMapping) === null || _b === void 0 ? void 0 : _b.code) || 'code'];
|
|
25
|
-
(0, util_1.log)(`
|
|
25
|
+
(0, util_1.log)(`Received request from OAuth login callback. Code ${code}`, config.logger);
|
|
26
26
|
try {
|
|
27
27
|
const oauthLogin = integration.oauthLogin;
|
|
28
28
|
let credentials;
|
|
@@ -13,7 +13,7 @@ const util_1 = require("../util");
|
|
|
13
13
|
const defaults_1 = require("../util/defaults");
|
|
14
14
|
function handle(config, integration) {
|
|
15
15
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
16
|
-
(0, util_1.log)('
|
|
16
|
+
(0, util_1.log)('Received OAuth login url request', config.logger);
|
|
17
17
|
const { oauthLogin } = integration;
|
|
18
18
|
if (!oauthLogin) {
|
|
19
19
|
(0, util_1.log)('OAuth login url request is not supported', config.logger);
|
|
@@ -14,7 +14,7 @@ const connection_1 = require("../util/connection");
|
|
|
14
14
|
function handle(config) {
|
|
15
15
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
16
16
|
const organizationId = (req.query || {})['organization_id'] || (req.body || {})['organization_id'];
|
|
17
|
-
(0, util_1.log)(`
|
|
17
|
+
(0, util_1.log)(`Received subscription paid request for organization ${organizationId}`, config.logger);
|
|
18
18
|
(0, connection_1.clearCache)(organizationId);
|
|
19
19
|
res.status(204).end();
|
|
20
20
|
}), config.onError);
|
|
@@ -15,7 +15,7 @@ const connection_1 = require("../util/connection");
|
|
|
15
15
|
function handle(config) {
|
|
16
16
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
17
17
|
const event = req.body;
|
|
18
|
-
(0, util_1.log)(`
|
|
18
|
+
(0, util_1.log)(`Received uninstall request ${JSON.stringify(event, null, 2)}`, config.logger);
|
|
19
19
|
const projectIntegration = config.projectIntegration;
|
|
20
20
|
const organization = (event.domain || event.organizationId).toString();
|
|
21
21
|
if (config.onUninstall) {
|
package/out/index.js
CHANGED
|
@@ -121,7 +121,7 @@ function addCrowdinEndpoints(app, config) {
|
|
|
121
121
|
app.post('/api/oauth-url', json_response_1.default, (0, crowdin_client_1.default)(config, false, false), (0, oauth_url_1.default)(config, integrationLogic));
|
|
122
122
|
}
|
|
123
123
|
if (integrationLogic.cronJobs) {
|
|
124
|
-
integrationLogic.cronJobs.forEach(job => {
|
|
124
|
+
integrationLogic.cronJobs.forEach((job) => {
|
|
125
125
|
cron.schedule(job.expression, () => (0, cron_1.runJob)(config, integrationLogic, job).catch(console.error));
|
|
126
126
|
});
|
|
127
127
|
}
|
|
@@ -184,7 +184,7 @@ function addCrowdinEndpoints(app, config) {
|
|
|
184
184
|
return JSON.parse(integrationCredentials.config);
|
|
185
185
|
}
|
|
186
186
|
}),
|
|
187
|
-
establishCrowdinConnection: jwtToken => (0, crowdin_client_1.prepareCrowdinRequest)(jwtToken, config),
|
|
187
|
+
establishCrowdinConnection: (jwtToken) => (0, crowdin_client_1.prepareCrowdinRequest)(jwtToken, config),
|
|
188
188
|
};
|
|
189
189
|
}
|
|
190
190
|
exports.addCrowdinEndpoints = addCrowdinEndpoints;
|
package/out/models/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { MySQLStorageConfig } from '../storage/mysql';
|
|
|
5
5
|
import { PostgreStorageConfig } from '../storage/postgre';
|
|
6
6
|
export interface Config extends ImagePath {
|
|
7
7
|
/**
|
|
8
|
-
* Authentication Crowdin App type: "authorization_code", "crowdin_app". Default: "
|
|
8
|
+
* Authentication Crowdin App type: "authorization_code", "crowdin_app". Default: "crowdin_app"
|
|
9
9
|
*/
|
|
10
10
|
authenticationType?: AuthenticationType;
|
|
11
11
|
/**
|
|
@@ -589,7 +589,7 @@ export interface IntegrationSyncSettings {
|
|
|
589
589
|
files?: any;
|
|
590
590
|
integrationId: string;
|
|
591
591
|
crowdinId: string;
|
|
592
|
-
provider:
|
|
592
|
+
provider: 'integration' | 'crowdin';
|
|
593
593
|
}
|
|
594
594
|
interface ImagePath {
|
|
595
595
|
/**
|
package/out/storage/mysql.js
CHANGED
|
@@ -108,7 +108,7 @@ class MySQLStorage {
|
|
|
108
108
|
saveCrowdinCredentials(credentials) {
|
|
109
109
|
return __awaiter(this, void 0, void 0, function* () {
|
|
110
110
|
yield this.dbPromise;
|
|
111
|
-
yield this.executeQuery(connection => connection.execute('INSERT INTO crowdin_credentials(id, app_secret, domain, user_id, organization_id, base_url, access_token, refresh_token, expire, type) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [
|
|
111
|
+
yield this.executeQuery((connection) => connection.execute('INSERT INTO crowdin_credentials(id, app_secret, domain, user_id, organization_id, base_url, access_token, refresh_token, expire, type) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [
|
|
112
112
|
credentials.id,
|
|
113
113
|
credentials.appSecret,
|
|
114
114
|
credentials.domain,
|
|
@@ -125,7 +125,7 @@ class MySQLStorage {
|
|
|
125
125
|
updateCrowdinCredentials(credentials) {
|
|
126
126
|
return __awaiter(this, void 0, void 0, function* () {
|
|
127
127
|
yield this.dbPromise;
|
|
128
|
-
yield this.executeQuery(connection => connection.execute('UPDATE crowdin_credentials SET app_secret = ?, domain = ?, user_id = ?, organization_id = ?, base_url = ?, access_token = ?, refresh_token = ?, expire = ? WHERE id = ?', [
|
|
128
|
+
yield this.executeQuery((connection) => connection.execute('UPDATE crowdin_credentials SET app_secret = ?, domain = ?, user_id = ?, organization_id = ?, base_url = ?, access_token = ?, refresh_token = ?, expire = ? WHERE id = ?', [
|
|
129
129
|
credentials.appSecret,
|
|
130
130
|
credentials.domain,
|
|
131
131
|
credentials.userId,
|
|
@@ -142,7 +142,7 @@ class MySQLStorage {
|
|
|
142
142
|
return __awaiter(this, void 0, void 0, function* () {
|
|
143
143
|
yield this.dbPromise;
|
|
144
144
|
return this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
|
|
145
|
-
const [rows
|
|
145
|
+
const [rows] = yield connection.execute('SELECT id, app_secret as "appSecret", domain, user_id as "userId", organization_id as "organizationId", base_url as "baseUrl", access_token as "accessToken", refresh_token as "refreshToken", expire, type FROM crowdin_credentials WHERE id = ?', [id]);
|
|
146
146
|
return (rows || [])[0];
|
|
147
147
|
}));
|
|
148
148
|
});
|
|
@@ -169,7 +169,7 @@ class MySQLStorage {
|
|
|
169
169
|
saveIntegrationCredentials(id, credentials, crowdinId) {
|
|
170
170
|
return __awaiter(this, void 0, void 0, function* () {
|
|
171
171
|
yield this.dbPromise;
|
|
172
|
-
yield this.executeQuery(connection => connection.execute('INSERT INTO integration_credentials(id, credentials, crowdin_id) VALUES (?, ?, ?)', [
|
|
172
|
+
yield this.executeQuery((connection) => connection.execute('INSERT INTO integration_credentials(id, credentials, crowdin_id) VALUES (?, ?, ?)', [
|
|
173
173
|
id,
|
|
174
174
|
credentials,
|
|
175
175
|
crowdinId,
|
|
@@ -179,20 +179,20 @@ class MySQLStorage {
|
|
|
179
179
|
updateIntegrationCredentials(id, credentials) {
|
|
180
180
|
return __awaiter(this, void 0, void 0, function* () {
|
|
181
181
|
yield this.dbPromise;
|
|
182
|
-
yield this.executeQuery(connection => connection.execute('UPDATE integration_credentials SET credentials = ? WHERE id = ?', [credentials, id]));
|
|
182
|
+
yield this.executeQuery((connection) => connection.execute('UPDATE integration_credentials SET credentials = ? WHERE id = ?', [credentials, id]));
|
|
183
183
|
});
|
|
184
184
|
}
|
|
185
185
|
updateIntegrationConfig(id, config) {
|
|
186
186
|
return __awaiter(this, void 0, void 0, function* () {
|
|
187
187
|
yield this.dbPromise;
|
|
188
|
-
yield this.executeQuery(connection => connection.execute('UPDATE integration_credentials SET config = ? WHERE id = ?', [config, id]));
|
|
188
|
+
yield this.executeQuery((connection) => connection.execute('UPDATE integration_credentials SET config = ? WHERE id = ?', [config, id]));
|
|
189
189
|
});
|
|
190
190
|
}
|
|
191
191
|
getIntegrationCredentials(id) {
|
|
192
192
|
return __awaiter(this, void 0, void 0, function* () {
|
|
193
193
|
yield this.dbPromise;
|
|
194
194
|
return this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
|
|
195
|
-
const [rows
|
|
195
|
+
const [rows] = yield connection.execute('SELECT id, credentials, config, crowdin_id as "crowdinId" FROM integration_credentials WHERE id = ?', [id]);
|
|
196
196
|
return (rows || [])[0];
|
|
197
197
|
}));
|
|
198
198
|
});
|
|
@@ -201,7 +201,7 @@ class MySQLStorage {
|
|
|
201
201
|
return __awaiter(this, void 0, void 0, function* () {
|
|
202
202
|
yield this.dbPromise;
|
|
203
203
|
return this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
|
|
204
|
-
const [rows
|
|
204
|
+
const [rows] = yield connection.execute('SELECT id, credentials, config, crowdin_id as "crowdinId" FROM integration_credentials WHERE crowdin_id = ?', [crowdinId]);
|
|
205
205
|
return rows || [];
|
|
206
206
|
}));
|
|
207
207
|
});
|
|
@@ -227,13 +227,13 @@ class MySQLStorage {
|
|
|
227
227
|
saveMetadata(id, metadata) {
|
|
228
228
|
return __awaiter(this, void 0, void 0, function* () {
|
|
229
229
|
yield this.dbPromise;
|
|
230
|
-
yield this.executeQuery(connection => connection.execute('INSERT INTO app_metadata(id, data) VALUES (?, ?)', [id, JSON.stringify(metadata)]));
|
|
230
|
+
yield this.executeQuery((connection) => connection.execute('INSERT INTO app_metadata(id, data) VALUES (?, ?)', [id, JSON.stringify(metadata)]));
|
|
231
231
|
});
|
|
232
232
|
}
|
|
233
233
|
updateMetadata(id, metadata) {
|
|
234
234
|
return __awaiter(this, void 0, void 0, function* () {
|
|
235
235
|
yield this.dbPromise;
|
|
236
|
-
yield this.executeQuery(connection => connection.execute('UPDATE app_metadata SET data = ? WHERE id = ?', [JSON.stringify(metadata), id]));
|
|
236
|
+
yield this.executeQuery((connection) => connection.execute('UPDATE app_metadata SET data = ? WHERE id = ?', [JSON.stringify(metadata), id]));
|
|
237
237
|
});
|
|
238
238
|
}
|
|
239
239
|
getMetadata(id) {
|
|
@@ -250,14 +250,14 @@ class MySQLStorage {
|
|
|
250
250
|
deleteMetadata(id) {
|
|
251
251
|
return __awaiter(this, void 0, void 0, function* () {
|
|
252
252
|
yield this.dbPromise;
|
|
253
|
-
yield this.executeQuery(connection => connection.execute('DELETE FROM app_metadata where id = ?', [id]));
|
|
253
|
+
yield this.executeQuery((connection) => connection.execute('DELETE FROM app_metadata where id = ?', [id]));
|
|
254
254
|
});
|
|
255
255
|
}
|
|
256
256
|
getSyncSettingsByProvider(integrationId, provider) {
|
|
257
257
|
return __awaiter(this, void 0, void 0, function* () {
|
|
258
258
|
yield this.dbPromise;
|
|
259
259
|
return this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
|
|
260
|
-
const [rows
|
|
260
|
+
const [rows] = yield connection.execute('SELECT id, files, integration_id as "integrationId", crowdin_id as "crowdinId", type, provider FROM sync_settings WHERE integration_id = ? AND provider = ?', [integrationId, provider]);
|
|
261
261
|
return (rows || [])[0];
|
|
262
262
|
}));
|
|
263
263
|
});
|
|
@@ -266,7 +266,7 @@ class MySQLStorage {
|
|
|
266
266
|
return __awaiter(this, void 0, void 0, function* () {
|
|
267
267
|
yield this.dbPromise;
|
|
268
268
|
return this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
|
|
269
|
-
const [rows
|
|
269
|
+
const [rows] = yield connection.execute('SELECT id, files, integration_id as "integrationId", crowdin_id as "crowdinId", type, provider FROM sync_settings WHERE type = ?', [type]);
|
|
270
270
|
return rows || [];
|
|
271
271
|
}));
|
|
272
272
|
});
|
|
@@ -274,20 +274,20 @@ class MySQLStorage {
|
|
|
274
274
|
saveSyncSettings(files, integrationId, crowdinId, type, provider) {
|
|
275
275
|
return __awaiter(this, void 0, void 0, function* () {
|
|
276
276
|
yield this.dbPromise;
|
|
277
|
-
yield this.executeQuery(connection => connection.execute('INSERT INTO sync_settings(files, integration_id, crowdin_id, type, provider) VALUES (?, , ?, ?, ?)', [files, integrationId, crowdinId, type, provider]));
|
|
277
|
+
yield this.executeQuery((connection) => connection.execute('INSERT INTO sync_settings(files, integration_id, crowdin_id, type, provider) VALUES (?, , ?, ?, ?)', [files, integrationId, crowdinId, type, provider]));
|
|
278
278
|
});
|
|
279
279
|
}
|
|
280
280
|
updateSyncSettings(files, integrationId, crowdinId, type, provider) {
|
|
281
281
|
return __awaiter(this, void 0, void 0, function* () {
|
|
282
282
|
yield this.dbPromise;
|
|
283
|
-
yield this.executeQuery(connection => connection.execute('UPDATE sync_settings SET files = ? WHERE integration_id = ? AND crowdin_id = ? AND type = ? AND provider = ?', [files, integrationId, crowdinId, type, provider]));
|
|
283
|
+
yield this.executeQuery((connection) => connection.execute('UPDATE sync_settings SET files = ? WHERE integration_id = ? AND crowdin_id = ? AND type = ? AND provider = ?', [files, integrationId, crowdinId, type, provider]));
|
|
284
284
|
});
|
|
285
285
|
}
|
|
286
286
|
getSyncSettings(integrationId, crowdinId, type, provider) {
|
|
287
287
|
return __awaiter(this, void 0, void 0, function* () {
|
|
288
288
|
yield this.dbPromise;
|
|
289
289
|
return this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
|
|
290
|
-
const [rows
|
|
290
|
+
const [rows] = yield connection.execute('SELECT id, files, integration_id as "integrationId", crowdin_id as "crowdinId", type FROM sync_settings WHERE integration_id = ? AND crowdin_id = ? AND type = ? AND provider = ?', [integrationId, crowdinId, type, provider]);
|
|
291
291
|
return (rows || [])[0];
|
|
292
292
|
}));
|
|
293
293
|
});
|
package/out/storage/postgre.js
CHANGED
|
@@ -104,7 +104,7 @@ class PostgreStorage {
|
|
|
104
104
|
saveCrowdinCredentials(credentials) {
|
|
105
105
|
return __awaiter(this, void 0, void 0, function* () {
|
|
106
106
|
yield this.dbPromise;
|
|
107
|
-
yield this.executeQuery(client => client.query('INSERT INTO crowdin_credentials(id, app_secret, domain, user_id, organization_id, base_url, access_token, refresh_token, expire, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)', [
|
|
107
|
+
yield this.executeQuery((client) => client.query('INSERT INTO crowdin_credentials(id, app_secret, domain, user_id, organization_id, base_url, access_token, refresh_token, expire, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)', [
|
|
108
108
|
credentials.id,
|
|
109
109
|
credentials.appSecret,
|
|
110
110
|
credentials.domain,
|
|
@@ -121,7 +121,7 @@ class PostgreStorage {
|
|
|
121
121
|
updateCrowdinCredentials(credentials) {
|
|
122
122
|
return __awaiter(this, void 0, void 0, function* () {
|
|
123
123
|
yield this.dbPromise;
|
|
124
|
-
yield this.executeQuery(client => client.query('UPDATE crowdin_credentials SET app_secret = $1, domain = $2, user_id = $3, organization_id = $4, base_url = $5, access_token = $6, refresh_token = $7, expire = $8 WHERE id = $9', [
|
|
124
|
+
yield this.executeQuery((client) => client.query('UPDATE crowdin_credentials SET app_secret = $1, domain = $2, user_id = $3, organization_id = $4, base_url = $5, access_token = $6, refresh_token = $7, expire = $8 WHERE id = $9', [
|
|
125
125
|
credentials.appSecret,
|
|
126
126
|
credentials.domain,
|
|
127
127
|
credentials.userId,
|
|
@@ -165,7 +165,7 @@ class PostgreStorage {
|
|
|
165
165
|
saveIntegrationCredentials(id, credentials, crowdinId) {
|
|
166
166
|
return __awaiter(this, void 0, void 0, function* () {
|
|
167
167
|
yield this.dbPromise;
|
|
168
|
-
yield this.executeQuery(client => client.query('INSERT INTO integration_credentials(id, credentials, crowdin_id) VALUES ($1, $2, $3)', [
|
|
168
|
+
yield this.executeQuery((client) => client.query('INSERT INTO integration_credentials(id, credentials, crowdin_id) VALUES ($1, $2, $3)', [
|
|
169
169
|
id,
|
|
170
170
|
credentials,
|
|
171
171
|
crowdinId,
|
|
@@ -175,13 +175,13 @@ class PostgreStorage {
|
|
|
175
175
|
updateIntegrationCredentials(id, credentials) {
|
|
176
176
|
return __awaiter(this, void 0, void 0, function* () {
|
|
177
177
|
yield this.dbPromise;
|
|
178
|
-
yield this.executeQuery(client => client.query('UPDATE integration_credentials SET credentials = $1 WHERE id = $2', [credentials, id]));
|
|
178
|
+
yield this.executeQuery((client) => client.query('UPDATE integration_credentials SET credentials = $1 WHERE id = $2', [credentials, id]));
|
|
179
179
|
});
|
|
180
180
|
}
|
|
181
181
|
updateIntegrationConfig(id, config) {
|
|
182
182
|
return __awaiter(this, void 0, void 0, function* () {
|
|
183
183
|
yield this.dbPromise;
|
|
184
|
-
yield this.executeQuery(client => client.query('UPDATE integration_credentials SET config = $1 WHERE id = $2', [config, id]));
|
|
184
|
+
yield this.executeQuery((client) => client.query('UPDATE integration_credentials SET config = $1 WHERE id = $2', [config, id]));
|
|
185
185
|
});
|
|
186
186
|
}
|
|
187
187
|
getIntegrationCredentials(id) {
|
|
@@ -223,13 +223,13 @@ class PostgreStorage {
|
|
|
223
223
|
saveMetadata(id, metadata) {
|
|
224
224
|
return __awaiter(this, void 0, void 0, function* () {
|
|
225
225
|
yield this.dbPromise;
|
|
226
|
-
yield this.executeQuery(client => client.query('INSERT INTO app_metadata(id, data) VALUES ($1, $2)', [id, JSON.stringify(metadata)]));
|
|
226
|
+
yield this.executeQuery((client) => client.query('INSERT INTO app_metadata(id, data) VALUES ($1, $2)', [id, JSON.stringify(metadata)]));
|
|
227
227
|
});
|
|
228
228
|
}
|
|
229
229
|
updateMetadata(id, metadata) {
|
|
230
230
|
return __awaiter(this, void 0, void 0, function* () {
|
|
231
231
|
yield this.dbPromise;
|
|
232
|
-
yield this.executeQuery(client => client.query('UPDATE app_metadata SET data = $1 WHERE id = $2', [JSON.stringify(metadata), id]));
|
|
232
|
+
yield this.executeQuery((client) => client.query('UPDATE app_metadata SET data = $1 WHERE id = $2', [JSON.stringify(metadata), id]));
|
|
233
233
|
});
|
|
234
234
|
}
|
|
235
235
|
getMetadata(id) {
|
|
@@ -246,7 +246,7 @@ class PostgreStorage {
|
|
|
246
246
|
deleteMetadata(id) {
|
|
247
247
|
return __awaiter(this, void 0, void 0, function* () {
|
|
248
248
|
yield this.dbPromise;
|
|
249
|
-
yield this.executeQuery(client => client.query('DELETE FROM app_metadata where id = $1', [id]));
|
|
249
|
+
yield this.executeQuery((client) => client.query('DELETE FROM app_metadata where id = $1', [id]));
|
|
250
250
|
});
|
|
251
251
|
}
|
|
252
252
|
getSyncSettingsByProvider(integrationId, provider) {
|
|
@@ -270,13 +270,13 @@ class PostgreStorage {
|
|
|
270
270
|
saveSyncSettings(files, integrationId, crowdinId, type, provider) {
|
|
271
271
|
return __awaiter(this, void 0, void 0, function* () {
|
|
272
272
|
yield this.dbPromise;
|
|
273
|
-
yield this.executeQuery(client => client.query('INSERT INTO sync_settings(files, integration_id, crowdin_id, type, provider) VALUES ($1, $2, $3, $4, $5)', [files, integrationId, crowdinId, type, provider]));
|
|
273
|
+
yield this.executeQuery((client) => client.query('INSERT INTO sync_settings(files, integration_id, crowdin_id, type, provider) VALUES ($1, $2, $3, $4, $5)', [files, integrationId, crowdinId, type, provider]));
|
|
274
274
|
});
|
|
275
275
|
}
|
|
276
276
|
updateSyncSettings(files, integrationId, crowdinId, type, provider) {
|
|
277
277
|
return __awaiter(this, void 0, void 0, function* () {
|
|
278
278
|
yield this.dbPromise;
|
|
279
|
-
yield this.executeQuery(client => client.query('UPDATE sync_settings SET files = $1 WHERE integration_id = $2 AND crowdin_id = $3 AND type = $4 AND provider = $5', [files, integrationId, crowdinId, type, provider]));
|
|
279
|
+
yield this.executeQuery((client) => client.query('UPDATE sync_settings SET files = $1 WHERE integration_id = $2 AND crowdin_id = $3 AND type = $4 AND provider = $5', [files, integrationId, crowdinId, type, provider]));
|
|
280
280
|
});
|
|
281
281
|
}
|
|
282
282
|
getSyncSettings(integrationId, crowdinId, type, provider) {
|
package/out/storage/sqlite.js
CHANGED
|
@@ -28,7 +28,7 @@ class SQLiteStorage {
|
|
|
28
28
|
yield new Promise((res, rej) => {
|
|
29
29
|
var _a;
|
|
30
30
|
//@ts-ignore
|
|
31
|
-
(_a = this.db) === null || _a === void 0 ? void 0 : _a.run(query, params, err => {
|
|
31
|
+
(_a = this.db) === null || _a === void 0 ? void 0 : _a.run(query, params, (err) => {
|
|
32
32
|
if (err) {
|
|
33
33
|
rej(err);
|
|
34
34
|
}
|
|
@@ -45,7 +45,7 @@ class SQLiteStorage {
|
|
|
45
45
|
yield new Promise((res, rej) => {
|
|
46
46
|
var _a;
|
|
47
47
|
//@ts-ignore
|
|
48
|
-
(_a = this.db) === null || _a === void 0 ? void 0 : _a.run(query, params, err => {
|
|
48
|
+
(_a = this.db) === null || _a === void 0 ? void 0 : _a.run(query, params, (err) => {
|
|
49
49
|
if (err) {
|
|
50
50
|
rej(err);
|
|
51
51
|
}
|
|
@@ -118,7 +118,7 @@ class SQLiteStorage {
|
|
|
118
118
|
});
|
|
119
119
|
const sqlite = require('sqlite3');
|
|
120
120
|
//@ts-ignore
|
|
121
|
-
this.db = new sqlite.Database((0, path_1.join)(this.config.dbFolder, 'app.sqlite'), error => {
|
|
121
|
+
this.db = new sqlite.Database((0, path_1.join)(this.config.dbFolder, 'app.sqlite'), (error) => {
|
|
122
122
|
if (error) {
|
|
123
123
|
_connection_rej(error);
|
|
124
124
|
}
|
package/out/util/connection.js
CHANGED
|
@@ -22,26 +22,27 @@ const storage_1 = require("../storage");
|
|
|
22
22
|
function refreshToken(config, credentials) {
|
|
23
23
|
var _a, _b;
|
|
24
24
|
return __awaiter(this, void 0, void 0, function* () {
|
|
25
|
-
if (config.authenticationType === models_1.AuthenticationType.
|
|
26
|
-
const token = yield (0, crowdin_apps_functions_1.
|
|
25
|
+
if (config.authenticationType === models_1.AuthenticationType.CODE) {
|
|
26
|
+
const token = yield (0, crowdin_apps_functions_1.refreshOAuthToken)(config.clientId, config.clientSecret, (0, _1.decryptData)(config, credentials.refreshToken), (_a = config.crowdinUrls) === null || _a === void 0 ? void 0 : _a.accountUrl);
|
|
27
27
|
return {
|
|
28
28
|
accessToken: (0, _1.encryptData)(config, token.accessToken),
|
|
29
|
+
refreshToken: (0, _1.encryptData)(config, token.refreshToken),
|
|
29
30
|
expiresIn: token.expiresIn,
|
|
30
|
-
refreshToken: '',
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
|
-
const token = yield (0, crowdin_apps_functions_1.
|
|
33
|
+
const token = yield (0, crowdin_apps_functions_1.fetchAppToken)(config.identifier, credentials.appSecret, config.clientId, config.clientSecret, credentials.domain || '', credentials.userId, (_b = config.crowdinUrls) === null || _b === void 0 ? void 0 : _b.accountUrl);
|
|
34
34
|
return {
|
|
35
35
|
accessToken: (0, _1.encryptData)(config, token.accessToken),
|
|
36
|
-
refreshToken: (0, _1.encryptData)(config, token.refreshToken),
|
|
37
36
|
expiresIn: token.expiresIn,
|
|
37
|
+
refreshToken: '',
|
|
38
38
|
};
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
41
|
function prepareCrowdinClient(config, credentials) {
|
|
42
42
|
var _a, _b;
|
|
43
43
|
return __awaiter(this, void 0, void 0, function* () {
|
|
44
|
-
|
|
44
|
+
//2 min as an extra buffer
|
|
45
|
+
const isExpired = +credentials.expire - 120 < Date.now() / 1000;
|
|
45
46
|
const organization = credentials.type === models_1.AccountType.ENTERPRISE ? credentials.id : undefined;
|
|
46
47
|
if (!isExpired) {
|
|
47
48
|
const token = (0, _1.decryptData)(config, credentials.accessToken);
|
|
@@ -68,7 +69,7 @@ function prepareCrowdinClient(config, credentials) {
|
|
|
68
69
|
const token = (0, _1.decryptData)(config, credentials.accessToken);
|
|
69
70
|
return {
|
|
70
71
|
client: new crowdin_api_client_1.default({ token, organization, baseUrl: (_b = config.crowdinUrls) === null || _b === void 0 ? void 0 : _b.apiUrl }),
|
|
71
|
-
token
|
|
72
|
+
token,
|
|
72
73
|
};
|
|
73
74
|
});
|
|
74
75
|
}
|
|
@@ -117,14 +118,14 @@ function prepareIntegrationCredentials(config, integration, integrationCredentia
|
|
|
117
118
|
}
|
|
118
119
|
exports.prepareIntegrationCredentials = prepareIntegrationCredentials;
|
|
119
120
|
const subscriptionCache = {};
|
|
120
|
-
function addToCache(organization,
|
|
121
|
+
function addToCache(organization, appIdentifier, validUntil, type, cachingSeconds, subscribeLink) {
|
|
121
122
|
if (!cachingSeconds) {
|
|
122
123
|
return;
|
|
123
124
|
}
|
|
124
125
|
const orgCache = subscriptionCache[organization] || {};
|
|
125
126
|
const now = new Date();
|
|
126
127
|
now.setSeconds(now.getSeconds() + cachingSeconds);
|
|
127
|
-
orgCache[
|
|
128
|
+
orgCache[appIdentifier] = {
|
|
128
129
|
cacheValidUntil: now,
|
|
129
130
|
validUntil,
|
|
130
131
|
subscribeLink,
|
|
@@ -132,8 +133,8 @@ function addToCache(organization, appIdenfifier, validUntil, type, cachingSecond
|
|
|
132
133
|
};
|
|
133
134
|
subscriptionCache[organization] = orgCache;
|
|
134
135
|
}
|
|
135
|
-
function getFromCache(organization,
|
|
136
|
-
return (subscriptionCache[organization] || {})[
|
|
136
|
+
function getFromCache(organization, appIdentifier) {
|
|
137
|
+
return (subscriptionCache[organization] || {})[appIdentifier];
|
|
137
138
|
}
|
|
138
139
|
function clearCache(organization) {
|
|
139
140
|
delete subscriptionCache[organization];
|
package/out/util/cron.js
CHANGED
|
@@ -45,24 +45,24 @@ function runJob(config, integration, job) {
|
|
|
45
45
|
(0, _1.log)(`Starting cron job with expression [${job.expression}]`, config.logger);
|
|
46
46
|
const crowdinCredentialsList = yield (0, storage_1.getStorage)().getAllCrowdinCredentials();
|
|
47
47
|
yield Promise.all(crowdinCredentialsList.map((crowdinCredentials) => __awaiter(this, void 0, void 0, function* () {
|
|
48
|
-
const {
|
|
48
|
+
const { token } = yield (0, connection_1.prepareCrowdinClient)(config, crowdinCredentials);
|
|
49
49
|
const { expired } = yield (0, connection_1.checkSubscription)(config, token, crowdinCredentials.id, crowdinCredentials.type);
|
|
50
50
|
if (expired) {
|
|
51
51
|
(0, _1.log)(`Subscription expired. Skipping job [${job.expression}] for organization ${crowdinCredentials.id}`);
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
54
|
const integrationCredentialsList = yield (0, storage_1.getStorage)().getAllIntegrationCredentials(crowdinCredentials.id);
|
|
55
|
-
|
|
55
|
+
//executing in non-parallel way to properly prepare crowdin client (avoid expriration issues)
|
|
56
|
+
for (const integrationCredentials of integrationCredentialsList) {
|
|
57
|
+
const { client: crowdinClient } = yield (0, connection_1.prepareCrowdinClient)(config, crowdinCredentials);
|
|
56
58
|
const projectId = crowdinAppFunctions.getProjectId(integrationCredentials.id);
|
|
57
59
|
const apiCredentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
|
|
58
60
|
const rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, crowdinClient, projectId);
|
|
59
|
-
const intConfig = integrationCredentials.config
|
|
60
|
-
? JSON.parse(integrationCredentials.config)
|
|
61
|
-
: undefined;
|
|
61
|
+
const intConfig = integrationCredentials.config ? JSON.parse(integrationCredentials.config) : undefined;
|
|
62
62
|
(0, _1.log)(`Executing task for cron job with expression [${job.expression}] for project ${projectId}`, config.logger);
|
|
63
63
|
yield job.task(projectId, crowdinClient, apiCredentials, rootFolder, intConfig);
|
|
64
64
|
(0, _1.log)(`Task for cron job with expression [${job.expression}] for project ${projectId} completed`, config.logger);
|
|
65
|
-
}
|
|
65
|
+
}
|
|
66
66
|
})));
|
|
67
67
|
(0, _1.log)(`Cron job with expression [${job.expression}] completed`, config.logger);
|
|
68
68
|
});
|
|
@@ -76,7 +76,7 @@ function filesCron(config, integration, period) {
|
|
|
76
76
|
const files = JSON.parse(syncSettings.files);
|
|
77
77
|
const crowdinCredentials = yield (0, storage_1.getStorage)().getCrowdinCredentials(syncSettings.crowdinId);
|
|
78
78
|
const integrationCredentials = yield (0, storage_1.getStorage)().getIntegrationCredentials(syncSettings.integrationId);
|
|
79
|
-
if (!crowdinCredentials || !integrationCredentials
|
|
79
|
+
if (!crowdinCredentials || !integrationCredentials) {
|
|
80
80
|
return;
|
|
81
81
|
}
|
|
82
82
|
const intConfig = integrationCredentials.config
|
|
@@ -92,31 +92,44 @@ function filesCron(config, integration, period) {
|
|
|
92
92
|
(0, _1.log)(`Subscription expired. Skipping job [${period}] for organization ${crowdinCredentials.id}`);
|
|
93
93
|
return;
|
|
94
94
|
}
|
|
95
|
-
const apiCredentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
|
|
96
95
|
const rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, crowdinClient, projectId);
|
|
96
|
+
//split invocation into chunks to avoid expiration issues
|
|
97
|
+
const chunkSize = 10;
|
|
97
98
|
if (syncSettings.provider === 'crowdin') {
|
|
98
99
|
const crowdinFiles = files;
|
|
99
100
|
const onlyTranslated = intConfig.condition === SyncCondition.TRANSLATED;
|
|
100
101
|
const onlyApproved = intConfig.condition === SyncCondition.APPROVED;
|
|
101
102
|
const all = intConfig.condition === SyncCondition.ALL || intConfig.condition === undefined;
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
yield
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if (Object.keys(filteredFiles).length === 0) {
|
|
103
|
+
const filesToProcess = all
|
|
104
|
+
? crowdinFiles
|
|
105
|
+
: yield getOnlyTranslatedOrApprovedFiles(config, projectId, crowdinFiles, crowdinClient, onlyApproved, onlyTranslated);
|
|
106
|
+
(0, _1.log)(`Executing updateIntegration task for files cron job with period [${period}] for project ${projectId}.Files ${Object.keys(filesToProcess).length}`, config.logger);
|
|
107
|
+
if (!all) {
|
|
108
|
+
if (Object.keys(filesToProcess).length === 0) {
|
|
109
109
|
(0, _1.log)(`There is no ${onlyApproved ? 'approved' : 'translated'} file`, config.logger);
|
|
110
110
|
return;
|
|
111
111
|
}
|
|
112
|
-
|
|
112
|
+
}
|
|
113
|
+
const filesArr = Object.keys(filesToProcess);
|
|
114
|
+
for (let i = 0; i < filesArr.length; i += chunkSize) {
|
|
115
|
+
const chunk = filesArr.slice(i, i + chunkSize);
|
|
116
|
+
const filesChunk = {};
|
|
117
|
+
chunk.forEach((f) => (filesChunk[f] = filesToProcess[f]));
|
|
118
|
+
const apiCredentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
|
|
119
|
+
const { client } = yield (0, connection_1.prepareCrowdinClient)(config, crowdinCredentials);
|
|
120
|
+
yield integration.updateIntegration(projectId, client, apiCredentials, filesChunk, rootFolder, intConfig);
|
|
113
121
|
}
|
|
114
122
|
(0, _1.log)(`updateIntegration task for files cron job with period [${period}] for project ${projectId} completed`, config.logger);
|
|
115
123
|
}
|
|
116
124
|
else {
|
|
117
125
|
const intFiles = files;
|
|
118
|
-
(0, _1.log)(`Executing updateCrowdin task for files cron job with period [${period}] for project ${projectId}
|
|
119
|
-
|
|
126
|
+
(0, _1.log)(`Executing updateCrowdin task for files cron job with period [${period}] for project ${projectId}. Files ${intFiles.length}`, config.logger);
|
|
127
|
+
for (let i = 0; i < intFiles.length; i += chunkSize) {
|
|
128
|
+
const chunk = intFiles.slice(i, i + chunkSize);
|
|
129
|
+
const apiCredentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
|
|
130
|
+
const { client } = yield (0, connection_1.prepareCrowdinClient)(config, crowdinCredentials);
|
|
131
|
+
yield integration.updateCrowdin(projectId, client, apiCredentials, chunk, rootFolder, intConfig);
|
|
132
|
+
}
|
|
120
133
|
(0, _1.log)(`updateCrowdin task for files cron job with period [${period}] for project ${projectId} completed`, config.logger);
|
|
121
134
|
}
|
|
122
135
|
})));
|
|
@@ -133,18 +146,18 @@ function getOnlyTranslatedOrApprovedFiles(config, projectId, crowdinFiles, crowd
|
|
|
133
146
|
.getFileProgress(projectId, Number(fileId));
|
|
134
147
|
return {
|
|
135
148
|
id: fileId,
|
|
136
|
-
info: res.data.map(e => e.data),
|
|
149
|
+
info: res.data.map((e) => e.data),
|
|
137
150
|
};
|
|
138
151
|
})));
|
|
139
152
|
const filteredFiles = {};
|
|
140
|
-
Object.keys(crowdinFiles).forEach(fileId => {
|
|
141
|
-
const fileInfo = filesInfo.find(info => info.id === fileId);
|
|
153
|
+
Object.keys(crowdinFiles).forEach((fileId) => {
|
|
154
|
+
const fileInfo = filesInfo.find((info) => info.id === fileId);
|
|
142
155
|
if (!fileInfo) {
|
|
143
156
|
return;
|
|
144
157
|
}
|
|
145
158
|
const languages = crowdinFiles[fileId];
|
|
146
|
-
languages.forEach(language => {
|
|
147
|
-
const languageInfo = fileInfo.info.find(info => info.languageId === language);
|
|
159
|
+
languages.forEach((language) => {
|
|
160
|
+
const languageInfo = fileInfo.info.find((info) => info.languageId === language);
|
|
148
161
|
if (!languageInfo) {
|
|
149
162
|
return;
|
|
150
163
|
}
|
package/out/util/defaults.js
CHANGED
|
@@ -36,7 +36,7 @@ function getRootFolder(config, integration, client, projectId) {
|
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
38
|
const folder = integration.appFolderName || config.name;
|
|
39
|
-
const directories = (yield client.sourceFilesApi.withFetchAll().listProjectDirectories(projectId)).data.map(d => d.data);
|
|
39
|
+
const directories = (yield client.sourceFilesApi.withFetchAll().listProjectDirectories(projectId)).data.map((d) => d.data);
|
|
40
40
|
const { folder: rootFolder } = yield crowdinAppFunctions.getOrCreateFolder(directories, client, projectId, folder);
|
|
41
41
|
return rootFolder;
|
|
42
42
|
});
|
|
@@ -55,18 +55,18 @@ function applyDefaults(config, integration) {
|
|
|
55
55
|
allDirectories = (yield client.sourceFilesApi.withFetchAll().listProjectDirectories(projectId, {
|
|
56
56
|
directoryId: rootFolder.id,
|
|
57
57
|
recursion: 'true',
|
|
58
|
-
})).data.map(d => d.data);
|
|
58
|
+
})).data.map((d) => d.data);
|
|
59
59
|
}
|
|
60
60
|
else {
|
|
61
|
-
allDirectories = (yield client.sourceFilesApi.withFetchAll().listProjectDirectories(projectId)).data.map(d => d.data);
|
|
61
|
+
allDirectories = (yield client.sourceFilesApi.withFetchAll().listProjectDirectories(projectId)).data.map((d) => d.data);
|
|
62
62
|
}
|
|
63
|
-
const directoryIds = allDirectories.map(d => d.id);
|
|
64
|
-
let files = (yield client.sourceFilesApi.withFetchAll().listProjectFiles(projectId)).data.map(d => d.data);
|
|
65
|
-
files = files.filter(f => (rootFolder && f.directoryId === rootFolder.id) ||
|
|
63
|
+
const directoryIds = allDirectories.map((d) => d.id);
|
|
64
|
+
let files = (yield client.sourceFilesApi.withFetchAll().listProjectFiles(projectId)).data.map((d) => d.data);
|
|
65
|
+
files = files.filter((f) => (rootFolder && f.directoryId === rootFolder.id) ||
|
|
66
66
|
directoryIds.includes(f.directoryId) ||
|
|
67
67
|
(!rootFolder && !f.directoryId));
|
|
68
68
|
const res = [];
|
|
69
|
-
allDirectories.forEach(e => {
|
|
69
|
+
allDirectories.forEach((e) => {
|
|
70
70
|
const parentId = rootFolder && e.directoryId === rootFolder.id ? undefined : e.directoryId;
|
|
71
71
|
res.push({
|
|
72
72
|
id: e.id.toString(),
|
|
@@ -74,7 +74,7 @@ function applyDefaults(config, integration) {
|
|
|
74
74
|
name: e.name,
|
|
75
75
|
});
|
|
76
76
|
});
|
|
77
|
-
files.forEach(e => {
|
|
77
|
+
files.forEach((e) => {
|
|
78
78
|
const parentId = rootFolder && e.directoryId === rootFolder.id ? undefined : e.directoryId;
|
|
79
79
|
res.push({
|
|
80
80
|
id: e.id.toString(),
|
|
@@ -143,10 +143,10 @@
|
|
|
143
143
|
)
|
|
144
144
|
.then(checkResponse)
|
|
145
145
|
.then(reloadLocation)
|
|
146
|
-
.catch(e =>
|
|
147
|
-
.finally(() => {
|
|
146
|
+
.catch(e => {
|
|
148
147
|
loginButton.setAttribute('disabled', false);
|
|
149
148
|
loginButton.setAttribute('is-loading', false);
|
|
149
|
+
catchRejection(e, 'Credentials are not stored');
|
|
150
150
|
});
|
|
151
151
|
}
|
|
152
152
|
|
package/package.json
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crowdin/app-project-module",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"description": "Module that generates for you all common endpoints for serving standalone Crowdin App",
|
|
5
5
|
"main": "out/index.js",
|
|
6
6
|
"types": "out/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "tsc -p ./ && cp -R views out && cp -R static out && cp logo.png out",
|
|
9
9
|
"lint": "eslint --fix \"{src,tests}/**/*.{js,ts}\"",
|
|
10
|
+
"prettier": "prettier --config .prettierrc src/**/*.ts --write",
|
|
10
11
|
"lint-ci": "eslint \"{src,tests}/**/*.{js,ts}\"",
|
|
11
|
-
"test-coverage": "
|
|
12
|
-
"test": "
|
|
12
|
+
"test-coverage": "jest --config jestconfig.json --ci --reporters=jest-junit --reporters=default --coverage --coverageReporters=cobertura --coverageReporters=html",
|
|
13
|
+
"test": "jest --config jestconfig.json"
|
|
13
14
|
},
|
|
14
15
|
"dependencies": {
|
|
15
16
|
"@crowdin/crowdin-apps-functions": "~0.2.1",
|
|
@@ -27,6 +28,7 @@
|
|
|
27
28
|
"@types/crypto-js": "^4.0.0",
|
|
28
29
|
"@types/express": "4.17.13",
|
|
29
30
|
"@types/express-handlebars": "^5.3.1",
|
|
31
|
+
"@types/jest": "^29.2.5",
|
|
30
32
|
"@types/node": "^12.0.10",
|
|
31
33
|
"@types/node-cron": "^3.0.0",
|
|
32
34
|
"@typescript-eslint/eslint-plugin": "^2.3.1",
|
|
@@ -34,8 +36,10 @@
|
|
|
34
36
|
"eslint": "^6.4.0",
|
|
35
37
|
"eslint-config-prettier": "^6.3.0",
|
|
36
38
|
"eslint-plugin-prettier": "^3.1.1",
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
+
"jest": "^29.3.1",
|
|
40
|
+
"jest-junit": "^15.0.0",
|
|
41
|
+
"prettier": "^2.8.1",
|
|
42
|
+
"ts-jest": "^29.0.3",
|
|
39
43
|
"typescript": "^4.4.4"
|
|
40
44
|
},
|
|
41
45
|
"repository": {
|
|
@@ -48,6 +52,12 @@
|
|
|
48
52
|
"Applications",
|
|
49
53
|
"App"
|
|
50
54
|
],
|
|
55
|
+
"jest": {
|
|
56
|
+
"coverageReporters": [
|
|
57
|
+
"text",
|
|
58
|
+
"cobertura"
|
|
59
|
+
]
|
|
60
|
+
},
|
|
51
61
|
"license": "MIT",
|
|
52
62
|
"bugs": {
|
|
53
63
|
"url": "https://github.com/crowdin/app-project-module/issues"
|