@crowdin/app-project-module 0.28.0-9 → 0.28.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/out/handlers/{custom-file-format/process.js → file-processing/custom-file-format.js} +8 -23
- package/out/handlers/file-processing/file-download.d.ts +4 -0
- package/out/handlers/{custom-file-format/download.js → file-processing/file-download.js} +3 -2
- package/out/handlers/file-processing/pre-post-process.d.ts +4 -0
- package/out/handlers/file-processing/pre-post-process.js +99 -0
- package/out/handlers/manifest.js +63 -0
- package/out/index.d.ts +3 -3
- package/out/index.js +43 -24
- package/out/models/index.d.ts +85 -18
- package/out/models/index.js +20 -1
- package/out/static/js/form.js +9 -9
- package/out/storage/index.js +4 -7
- package/out/util/defaults.d.ts +3 -2
- package/out/util/defaults.js +16 -3
- package/out/util/files.d.ts +3 -0
- package/out/util/files.js +43 -0
- package/out/views/form.handlebars +2 -0
- package/package.json +1 -1
- package/out/handlers/custom-file-format/download.d.ts +0 -4
- /package/out/handlers/{custom-file-format/process.d.ts → file-processing/custom-file-format.d.ts} +0 -0
package/out/handlers/{custom-file-format/process.js → file-processing/custom-file-format.js}
RENAMED
|
@@ -12,12 +12,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
const axios_1 = __importDefault(require("axios"));
|
|
16
15
|
const fs_1 = __importDefault(require("fs"));
|
|
17
16
|
const path_1 = __importDefault(require("path"));
|
|
18
17
|
const models_1 = require("../../models");
|
|
19
18
|
const util_1 = require("../../util");
|
|
20
|
-
const
|
|
19
|
+
const files_1 = require("../../util/files");
|
|
21
20
|
function handle(baseConfig, baseUrl, folder, config) {
|
|
22
21
|
if (!fs_1.default.existsSync(path_1.default.join(folder, 'custom-file-format'))) {
|
|
23
22
|
fs_1.default.mkdirSync(path_1.default.join(folder, 'custom-file-format'), { recursive: true });
|
|
@@ -38,7 +37,7 @@ function handle(baseConfig, baseUrl, folder, config) {
|
|
|
38
37
|
file = Buffer.from(body.file.content, 'base64').toString();
|
|
39
38
|
}
|
|
40
39
|
else if (body.file.contentUrl) {
|
|
41
|
-
file =
|
|
40
|
+
file = yield (0, files_1.getFileContent)(body.file.contentUrl);
|
|
42
41
|
}
|
|
43
42
|
let response = {};
|
|
44
43
|
let error;
|
|
@@ -71,10 +70,7 @@ function handleBuildFile(baseUrl, dataFolder, config, req, client, context, proj
|
|
|
71
70
|
strings = req.strings;
|
|
72
71
|
}
|
|
73
72
|
else {
|
|
74
|
-
|
|
75
|
-
const response = (yield axios_1.default.get(req.stringsUrl)).data;
|
|
76
|
-
const jsonRows = response.split(/\n|\n\r/).filter(Boolean);
|
|
77
|
-
strings = jsonRows.map((jsonStringRow) => JSON.parse(jsonStringRow));
|
|
73
|
+
strings = yield (0, files_1.getFileContent)(req.stringsUrl, true);
|
|
78
74
|
}
|
|
79
75
|
let res;
|
|
80
76
|
if ((req.file.id || !file) && config.exportStrings) {
|
|
@@ -87,7 +83,7 @@ function handleBuildFile(baseUrl, dataFolder, config, req, client, context, proj
|
|
|
87
83
|
return { response };
|
|
88
84
|
}
|
|
89
85
|
const contentFileEncoded = Buffer.from(res.contentFile).toString('base64');
|
|
90
|
-
if (Buffer.byteLength(contentFileEncoded, 'utf8') < MAX_BODY_SIZE) {
|
|
86
|
+
if (Buffer.byteLength(contentFileEncoded, 'utf8') < files_1.MAX_BODY_SIZE) {
|
|
91
87
|
response.content = contentFileEncoded;
|
|
92
88
|
}
|
|
93
89
|
else {
|
|
@@ -96,7 +92,7 @@ function handleBuildFile(baseUrl, dataFolder, config, req, client, context, proj
|
|
|
96
92
|
url = yield config.storeFile(res.contentFile);
|
|
97
93
|
}
|
|
98
94
|
else {
|
|
99
|
-
const storedFile = yield storeFile(res.contentFile, dataFolder);
|
|
95
|
+
const storedFile = yield (0, files_1.storeFile)(res.contentFile, path_1.default.join(dataFolder, 'custom-file-format'));
|
|
100
96
|
url = `${baseUrl}?file=${storedFile}`;
|
|
101
97
|
}
|
|
102
98
|
response.contentUrl = url;
|
|
@@ -111,7 +107,7 @@ function handleParseFile(baseUrl, dataFolder, config, req, client, context, proj
|
|
|
111
107
|
return { response };
|
|
112
108
|
}
|
|
113
109
|
const res = yield config.parseFile(file, req, client, context, projectId);
|
|
114
|
-
let maxSize = MAX_BODY_SIZE;
|
|
110
|
+
let maxSize = files_1.MAX_BODY_SIZE;
|
|
115
111
|
if (res.strings && res.previewFile) {
|
|
116
112
|
maxSize = maxSize / 2;
|
|
117
113
|
}
|
|
@@ -126,7 +122,7 @@ function handleParseFile(baseUrl, dataFolder, config, req, client, context, proj
|
|
|
126
122
|
url = yield config.storeFile(res.previewFile);
|
|
127
123
|
}
|
|
128
124
|
else {
|
|
129
|
-
const storedFile = yield storeFile(res.previewFile, dataFolder);
|
|
125
|
+
const storedFile = yield (0, files_1.storeFile)(res.previewFile, path_1.default.join(dataFolder, 'custom-file-format'));
|
|
130
126
|
url = `${baseUrl}?file=${storedFile}`;
|
|
131
127
|
}
|
|
132
128
|
response.previewUrl = url;
|
|
@@ -153,7 +149,7 @@ function handleParseFile(baseUrl, dataFolder, config, req, client, context, proj
|
|
|
153
149
|
url = yield config.storeFile(stringsNDJson);
|
|
154
150
|
}
|
|
155
151
|
else {
|
|
156
|
-
const storedFile = yield storeFile(stringsNDJson, dataFolder);
|
|
152
|
+
const storedFile = yield (0, files_1.storeFile)(stringsNDJson, path_1.default.join(dataFolder, 'custom-file-format'));
|
|
157
153
|
url = `${baseUrl}?file=${storedFile}`;
|
|
158
154
|
}
|
|
159
155
|
response.stringsUrl = url;
|
|
@@ -162,14 +158,3 @@ function handleParseFile(baseUrl, dataFolder, config, req, client, context, proj
|
|
|
162
158
|
return { response, error: res.error };
|
|
163
159
|
});
|
|
164
160
|
}
|
|
165
|
-
function storeFile(fileContent, folder) {
|
|
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) => {
|
|
168
|
-
if (err) {
|
|
169
|
-
rej(err);
|
|
170
|
-
}
|
|
171
|
-
else {
|
|
172
|
-
res(fileName);
|
|
173
|
-
}
|
|
174
|
-
}));
|
|
175
|
-
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/// <reference types="qs" />
|
|
2
|
+
import { Request, Response } from 'express';
|
|
3
|
+
import { Config, FileProcessLogic } from '../../models';
|
|
4
|
+
export default function handle(config: Config, processingConfig: FileProcessLogic, folderName: string): (req: Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: Function) => void;
|
|
@@ -15,9 +15,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
const fs_1 = __importDefault(require("fs"));
|
|
16
16
|
const path_1 = __importDefault(require("path"));
|
|
17
17
|
const util_1 = require("../../util");
|
|
18
|
-
function handle(config,
|
|
18
|
+
function handle(config, processingConfig, folderName) {
|
|
19
|
+
const folder = processingConfig.filesFolder || config.dbFolder;
|
|
19
20
|
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
20
|
-
const filePath = path_1.default.join(folder,
|
|
21
|
+
const filePath = path_1.default.join(folder, folderName, req.query.file);
|
|
21
22
|
(0, util_1.log)(`Downloading file ${filePath}`, config.logger);
|
|
22
23
|
res.download(filePath, function (err) {
|
|
23
24
|
if (err) {
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/// <reference types="qs" />
|
|
2
|
+
import { Response } from 'express';
|
|
3
|
+
import { Config, FileImportExportLogic } from '../../models';
|
|
4
|
+
export default function handle(baseConfig: Config, config: FileImportExportLogic, folderName: string): (req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: Function) => void;
|
|
@@ -0,0 +1,99 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const fs_1 = __importDefault(require("fs"));
|
|
16
|
+
const path_1 = __importDefault(require("path"));
|
|
17
|
+
const models_1 = require("../../models");
|
|
18
|
+
const util_1 = require("../../util");
|
|
19
|
+
const files_1 = require("../../util/files");
|
|
20
|
+
function handle(baseConfig, config, folderName) {
|
|
21
|
+
const folderPath = config.filesFolder || baseConfig.dbFolder;
|
|
22
|
+
if (!fs_1.default.existsSync(path_1.default.join(folderPath, folderName))) {
|
|
23
|
+
fs_1.default.mkdirSync(path_1.default.join(folderPath, folderName), { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
26
|
+
const response = {};
|
|
27
|
+
const baseFilesUrl = `${baseConfig.baseUrl}/file/download/${folderName}`;
|
|
28
|
+
const body = req.body;
|
|
29
|
+
let processingError;
|
|
30
|
+
let fileContent;
|
|
31
|
+
if (body.stringsUrl) {
|
|
32
|
+
fileContent = yield (0, files_1.getFileContent)(body.stringsUrl, true);
|
|
33
|
+
}
|
|
34
|
+
else if (body.strings) {
|
|
35
|
+
fileContent = body.strings;
|
|
36
|
+
}
|
|
37
|
+
else if (body.file.contentUrl) {
|
|
38
|
+
fileContent = yield (0, files_1.getFileContent)(body.file.contentUrl);
|
|
39
|
+
}
|
|
40
|
+
else if (body.file.content) {
|
|
41
|
+
fileContent = Buffer.from(body.file.content, 'base64').toString();
|
|
42
|
+
}
|
|
43
|
+
const fileProcessResult = yield config.fileProcess(body, fileContent, req.crowdinApiClient, req.crowdinContext, req.crowdinContext.jwtPayload.context.project_id);
|
|
44
|
+
switch (body.jobType) {
|
|
45
|
+
case models_1.ProcessFileJobType.PRE_IMPORT:
|
|
46
|
+
case models_1.ProcessFileJobType.POST_EXPORT:
|
|
47
|
+
const { contentFile, base64EncodedContent, fileName, fileType, error: contentFileError, } = fileProcessResult;
|
|
48
|
+
if (contentFile) {
|
|
49
|
+
const contentFileEncoded = base64EncodedContent || Buffer.from(contentFile).toString('base64');
|
|
50
|
+
if (Buffer.byteLength(contentFileEncoded, 'utf8') < files_1.MAX_BODY_SIZE) {
|
|
51
|
+
response.content = contentFileEncoded;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
let url;
|
|
55
|
+
if (config.storeFile) {
|
|
56
|
+
url = yield config.storeFile(contentFile);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
const storedFile = yield (0, files_1.storeFile)(contentFile, path_1.default.join(folderPath, folderName));
|
|
60
|
+
url = `${baseFilesUrl}?file=${storedFile}`;
|
|
61
|
+
}
|
|
62
|
+
response.contentUrl = url;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (fileName) {
|
|
66
|
+
response.fileName = fileName;
|
|
67
|
+
}
|
|
68
|
+
if (fileType) {
|
|
69
|
+
response.fileType = fileType;
|
|
70
|
+
}
|
|
71
|
+
processingError = contentFileError;
|
|
72
|
+
break;
|
|
73
|
+
case models_1.ProcessFileJobType.POST_IMPORT:
|
|
74
|
+
case models_1.ProcessFileJobType.PRE_EXPORT:
|
|
75
|
+
const { strings, error: stringsFileError } = fileProcessResult;
|
|
76
|
+
if (strings) {
|
|
77
|
+
const stringsNDJson = strings.map((s) => JSON.stringify(s)).join('\n\r');
|
|
78
|
+
if (Buffer.byteLength(stringsNDJson, 'utf8') < files_1.MAX_BODY_SIZE) {
|
|
79
|
+
response.strings = strings;
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
let url;
|
|
83
|
+
if (config.storeFile) {
|
|
84
|
+
url = yield config.storeFile(stringsNDJson);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
const storedFile = yield (0, files_1.storeFile)(stringsNDJson, path_1.default.join(folderPath, folderName));
|
|
88
|
+
url = `${baseFilesUrl}?file=${storedFile}`;
|
|
89
|
+
}
|
|
90
|
+
response.stringsUrl = url;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
processingError = stringsFileError;
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
res.send({ data: response, error: processingError ? { message: processingError } : undefined });
|
|
97
|
+
}), baseConfig.onError);
|
|
98
|
+
}
|
|
99
|
+
exports.default = handle;
|
package/out/handlers/manifest.js
CHANGED
|
@@ -31,6 +31,42 @@ function handle(config) {
|
|
|
31
31
|
},
|
|
32
32
|
];
|
|
33
33
|
}
|
|
34
|
+
if (config.filePreImport) {
|
|
35
|
+
modules['file-pre-import'] = [
|
|
36
|
+
{
|
|
37
|
+
key: config.identifier + '-pri',
|
|
38
|
+
signaturePatterns: config.filePreImport.signaturePatterns,
|
|
39
|
+
url: '/pre-import',
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
}
|
|
43
|
+
if (config.filePostImport) {
|
|
44
|
+
modules['file-post-import'] = [
|
|
45
|
+
{
|
|
46
|
+
key: config.identifier + '-poi',
|
|
47
|
+
signaturePatterns: config.filePostImport.signaturePatterns,
|
|
48
|
+
url: '/post-import',
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
}
|
|
52
|
+
if (config.filePreExport) {
|
|
53
|
+
modules['file-pre-export'] = [
|
|
54
|
+
{
|
|
55
|
+
key: config.identifier + '-pre',
|
|
56
|
+
signaturePatterns: config.filePreExport.signaturePatterns,
|
|
57
|
+
url: '/pre-export',
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
}
|
|
61
|
+
if (config.filePostExport) {
|
|
62
|
+
modules['file-post-export'] = [
|
|
63
|
+
{
|
|
64
|
+
key: config.identifier + '-poe',
|
|
65
|
+
signaturePatterns: config.filePostExport.signaturePatterns,
|
|
66
|
+
url: '/post-export',
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
}
|
|
34
70
|
if (config.customMT) {
|
|
35
71
|
modules['custom-mt'] = [
|
|
36
72
|
{
|
|
@@ -116,6 +152,33 @@ function handle(config) {
|
|
|
116
152
|
},
|
|
117
153
|
];
|
|
118
154
|
}
|
|
155
|
+
if (config.modal) {
|
|
156
|
+
modules['modal'] = [
|
|
157
|
+
{
|
|
158
|
+
key: config.identifier + '-modal',
|
|
159
|
+
name: config.name,
|
|
160
|
+
url: config.modal.url,
|
|
161
|
+
environments: config.modal.environments,
|
|
162
|
+
},
|
|
163
|
+
];
|
|
164
|
+
}
|
|
165
|
+
if (config.contextMenu) {
|
|
166
|
+
modules['context-menu'] = [
|
|
167
|
+
{
|
|
168
|
+
key: config.identifier + '-context-menu',
|
|
169
|
+
name: config.name,
|
|
170
|
+
description: config.description,
|
|
171
|
+
options: Object.assign(Object.assign({ location: config.contextMenu.location, type: config.contextMenu.type }, (config.contextMenu.module
|
|
172
|
+
? {
|
|
173
|
+
module: {
|
|
174
|
+
[config.contextMenu.module]: modules[config.contextMenu.module][0].key,
|
|
175
|
+
},
|
|
176
|
+
}
|
|
177
|
+
: {})), { url: config.contextMenu.url }),
|
|
178
|
+
environments: config.contextMenu.environments,
|
|
179
|
+
},
|
|
180
|
+
];
|
|
181
|
+
}
|
|
119
182
|
const events = {
|
|
120
183
|
installed: '/installed',
|
|
121
184
|
uninstall: '/uninstall',
|
package/out/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Express } from 'express';
|
|
2
|
-
import { Config, CrowdinAppUtilities } from './models';
|
|
2
|
+
import { ClientConfig, Config, CrowdinAppUtilities } from './models';
|
|
3
3
|
export { Scope } from './models';
|
|
4
|
-
export declare function addCrowdinEndpoints(app: Express,
|
|
5
|
-
export declare function createApp(
|
|
4
|
+
export declare function addCrowdinEndpoints(app: Express, clientConfig: Config | ClientConfig): CrowdinAppUtilities;
|
|
5
|
+
export declare function createApp(clientConfig: ClientConfig): void;
|
package/out/index.js
CHANGED
|
@@ -45,22 +45,23 @@ const crowdin_files_1 = __importDefault(require("./handlers/crowdin-files"));
|
|
|
45
45
|
const crowdin_project_1 = __importDefault(require("./handlers/crowdin-project"));
|
|
46
46
|
const crowdin_update_1 = __importDefault(require("./handlers/crowdin-update"));
|
|
47
47
|
const crowdin_webhook_1 = __importDefault(require("./handlers/crowdin-webhook"));
|
|
48
|
-
const integration_webhook_1 = __importDefault(require("./handlers/integration-webhook"));
|
|
49
|
-
const download_1 = __importDefault(require("./handlers/custom-file-format/download"));
|
|
50
|
-
const process_1 = __importDefault(require("./handlers/custom-file-format/process"));
|
|
51
48
|
const translate_1 = __importDefault(require("./handlers/custom-mt/translate"));
|
|
49
|
+
const custom_file_format_1 = __importDefault(require("./handlers/file-processing/custom-file-format"));
|
|
50
|
+
const file_download_1 = __importDefault(require("./handlers/file-processing/file-download"));
|
|
51
|
+
const pre_post_process_1 = __importDefault(require("./handlers/file-processing/pre-post-process"));
|
|
52
|
+
const form_data_display_1 = __importDefault(require("./handlers/form-data-display"));
|
|
53
|
+
const form_data_save_1 = __importDefault(require("./handlers/form-data-save"));
|
|
52
54
|
const install_1 = __importDefault(require("./handlers/install"));
|
|
53
55
|
const integration_data_1 = __importDefault(require("./handlers/integration-data"));
|
|
54
56
|
const integration_login_1 = __importDefault(require("./handlers/integration-login"));
|
|
55
57
|
const integration_logout_1 = __importDefault(require("./handlers/integration-logout"));
|
|
56
58
|
const integration_update_1 = __importDefault(require("./handlers/integration-update"));
|
|
59
|
+
const integration_webhook_1 = __importDefault(require("./handlers/integration-webhook"));
|
|
57
60
|
const main_1 = __importDefault(require("./handlers/main"));
|
|
58
61
|
const manifest_1 = __importDefault(require("./handlers/manifest"));
|
|
59
62
|
const oauth_login_1 = __importDefault(require("./handlers/oauth-login"));
|
|
60
63
|
const oauth_url_1 = __importDefault(require("./handlers/oauth-url"));
|
|
61
64
|
const settings_save_1 = __importDefault(require("./handlers/settings-save"));
|
|
62
|
-
const form_data_display_1 = __importDefault(require("./handlers/form-data-display"));
|
|
63
|
-
const form_data_save_1 = __importDefault(require("./handlers/form-data-save"));
|
|
64
65
|
const subscription_info_1 = __importDefault(require("./handlers/subscription-info"));
|
|
65
66
|
const subscription_paid_1 = __importDefault(require("./handlers/subscription-paid"));
|
|
66
67
|
const sync_settings_1 = __importDefault(require("./handlers/sync-settings"));
|
|
@@ -69,22 +70,23 @@ const uninstall_1 = __importDefault(require("./handlers/uninstall"));
|
|
|
69
70
|
const crowdin_client_1 = __importStar(require("./middlewares/crowdin-client"));
|
|
70
71
|
const integration_credentials_1 = __importDefault(require("./middlewares/integration-credentials"));
|
|
71
72
|
const json_response_1 = __importDefault(require("./middlewares/json-response"));
|
|
72
|
-
const ui_module_1 = __importDefault(require("./middlewares/ui-module"));
|
|
73
73
|
const render_ui_module_1 = __importDefault(require("./middlewares/render-ui-module"));
|
|
74
|
+
const ui_module_1 = __importDefault(require("./middlewares/ui-module"));
|
|
75
|
+
const models_1 = require("./models");
|
|
74
76
|
const storage = __importStar(require("./storage"));
|
|
75
77
|
const util_1 = require("./util");
|
|
76
78
|
const connection_1 = require("./util/connection");
|
|
77
79
|
const cron_1 = require("./util/cron");
|
|
78
80
|
const defaults_1 = require("./util/defaults");
|
|
79
81
|
const webhooks_1 = require("./util/webhooks");
|
|
80
|
-
var
|
|
81
|
-
Object.defineProperty(exports, "Scope", { enumerable: true, get: function () { return
|
|
82
|
-
function addCrowdinEndpoints(app,
|
|
82
|
+
var models_2 = require("./models");
|
|
83
|
+
Object.defineProperty(exports, "Scope", { enumerable: true, get: function () { return models_2.Scope; } });
|
|
84
|
+
function addCrowdinEndpoints(app, clientConfig) {
|
|
83
85
|
var _a, _b, _c;
|
|
84
|
-
|
|
85
|
-
|
|
86
|
+
const config = (0, defaults_1.convertClientConfig)(clientConfig);
|
|
87
|
+
if (!config.disableGlobalErrorHandling) {
|
|
88
|
+
handleUncaughtErrors(config);
|
|
86
89
|
}
|
|
87
|
-
const config = Object.assign(Object.assign({}, plainConfig), { baseUrl: plainConfig.baseUrl.endsWith('/') ? plainConfig.baseUrl.slice(0, -1) : plainConfig.baseUrl });
|
|
88
90
|
storage.initialize(config);
|
|
89
91
|
app.use(express_1.default.json({ limit: '50mb' }));
|
|
90
92
|
app.use('/assets', express_1.default.static((0, path_1.join)(__dirname, 'static')));
|
|
@@ -117,7 +119,7 @@ function addCrowdinEndpoints(app, plainConfig) {
|
|
|
117
119
|
},
|
|
118
120
|
}));
|
|
119
121
|
app.set('view engine', 'handlebars');
|
|
120
|
-
app.get('/logo.png', (req, res) => res.sendFile(config.imagePath
|
|
122
|
+
app.get('/logo.png', (req, res) => res.sendFile(config.imagePath));
|
|
121
123
|
app.post('/installed', (0, install_1.default)(config));
|
|
122
124
|
app.post('/uninstall', (0, uninstall_1.default)(config));
|
|
123
125
|
app.get('/manifest.json', json_response_1.default, (0, manifest_1.default)(config));
|
|
@@ -126,8 +128,8 @@ function addCrowdinEndpoints(app, plainConfig) {
|
|
|
126
128
|
}
|
|
127
129
|
const integrationLogic = config.projectIntegration;
|
|
128
130
|
if (integrationLogic) {
|
|
129
|
-
(0, defaults_1.
|
|
130
|
-
app.get('/logo/integration/logo.png', (req, res) => res.sendFile(integrationLogic.imagePath || config.imagePath
|
|
131
|
+
(0, defaults_1.applyIntegrationModuleDefaults)(config, integrationLogic);
|
|
132
|
+
app.get('/logo/integration/logo.png', (req, res) => res.sendFile(integrationLogic.imagePath || config.imagePath));
|
|
131
133
|
app.get('/', (0, crowdin_client_1.default)(config, true, false), (0, integration_credentials_1.default)(config, integrationLogic, true), (0, main_1.default)(config, integrationLogic));
|
|
132
134
|
app.get('/api/subscription-info', json_response_1.default, (0, crowdin_client_1.default)(config), (0, subscription_info_1.default)(config));
|
|
133
135
|
app.post('/api/settings', (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, integrationLogic), (0, settings_save_1.default)(config, integrationLogic));
|
|
@@ -172,19 +174,35 @@ function addCrowdinEndpoints(app, plainConfig) {
|
|
|
172
174
|
}
|
|
173
175
|
}
|
|
174
176
|
if (config.customFileFormat) {
|
|
175
|
-
app.post('/process', (0, crowdin_client_1.default)(config), (0,
|
|
176
|
-
app.get('/file/download', (0,
|
|
177
|
+
app.post('/process', (0, crowdin_client_1.default)(config), (0, custom_file_format_1.default)(config, config.baseUrl, config.customFileFormat.filesFolder || config.dbFolder, config.customFileFormat));
|
|
178
|
+
app.get('/file/download', (0, file_download_1.default)(config, config.customFileFormat, 'custom-file-format'));
|
|
179
|
+
}
|
|
180
|
+
if (config.filePreImport) {
|
|
181
|
+
app.post('/pre-import', (0, crowdin_client_1.default)(config), (0, pre_post_process_1.default)(config, config.filePreImport, models_1.ProcessFileJobType.PRE_IMPORT));
|
|
182
|
+
app.get(`/file/download/${models_1.ProcessFileJobType.PRE_IMPORT}`, (0, file_download_1.default)(config, config.filePreImport, models_1.ProcessFileJobType.PRE_IMPORT));
|
|
183
|
+
}
|
|
184
|
+
if (config.filePostImport) {
|
|
185
|
+
app.post('/post-import', (0, crowdin_client_1.default)(config), (0, pre_post_process_1.default)(config, config.filePostImport, models_1.ProcessFileJobType.POST_IMPORT));
|
|
186
|
+
app.get(`/file/download/${models_1.ProcessFileJobType.POST_IMPORT}`, (0, file_download_1.default)(config, config.filePostImport, models_1.ProcessFileJobType.POST_IMPORT));
|
|
187
|
+
}
|
|
188
|
+
if (config.filePreExport) {
|
|
189
|
+
app.post('/pre-export', (0, crowdin_client_1.default)(config), (0, pre_post_process_1.default)(config, config.filePreExport, models_1.ProcessFileJobType.PRE_EXPORT));
|
|
190
|
+
app.get(`/file/download/${models_1.ProcessFileJobType.PRE_EXPORT}`, (0, file_download_1.default)(config, config.filePreExport, models_1.ProcessFileJobType.PRE_EXPORT));
|
|
191
|
+
}
|
|
192
|
+
if (config.filePostExport) {
|
|
193
|
+
app.post('/post-export', (0, crowdin_client_1.default)(config), (0, pre_post_process_1.default)(config, config.filePostExport, models_1.ProcessFileJobType.POST_EXPORT));
|
|
194
|
+
app.get(`/file/download/${models_1.ProcessFileJobType.POST_EXPORT}`, (0, file_download_1.default)(config, config.filePostExport, models_1.ProcessFileJobType.POST_EXPORT));
|
|
177
195
|
}
|
|
178
196
|
if (config.customMT) {
|
|
179
|
-
app.get('/logo/mt/logo.png', (req, res) => { var _a; return res.sendFile(((_a = config.customMT) === null || _a === void 0 ? void 0 : _a.imagePath) || config.imagePath
|
|
197
|
+
app.get('/logo/mt/logo.png', (req, res) => { var _a; return res.sendFile(((_a = config.customMT) === null || _a === void 0 ? void 0 : _a.imagePath) || config.imagePath); });
|
|
180
198
|
app.post('/translate', (0, crowdin_client_1.default)(config), (0, translate_1.default)(config, config.customMT));
|
|
181
199
|
}
|
|
182
200
|
if (config.profileResourcesMenu) {
|
|
183
|
-
app.get('/logo/resources/logo.png', (req, res) => { var _a; return res.sendFile(((_a = config.profileResourcesMenu) === null || _a === void 0 ? void 0 : _a.imagePath) || config.imagePath
|
|
201
|
+
app.get('/logo/resources/logo.png', (req, res) => { var _a; return res.sendFile(((_a = config.profileResourcesMenu) === null || _a === void 0 ? void 0 : _a.imagePath) || config.imagePath); });
|
|
184
202
|
app.use('/resources', (0, ui_module_1.default)(config, config.profileResourcesMenu.allowUnauthorized), (0, render_ui_module_1.default)(config, config.profileResourcesMenu));
|
|
185
203
|
}
|
|
186
204
|
if (config.organizationMenu) {
|
|
187
|
-
app.get('/logo/resources/logo.png', (req, res) => { var _a; return res.sendFile(((_a = config.organizationMenu) === null || _a === void 0 ? void 0 : _a.imagePath) || config.imagePath
|
|
205
|
+
app.get('/logo/resources/logo.png', (req, res) => { var _a; return res.sendFile(((_a = config.organizationMenu) === null || _a === void 0 ? void 0 : _a.imagePath) || config.imagePath); });
|
|
188
206
|
app.use('/resources', (0, ui_module_1.default)(config, config.organizationMenu.allowUnauthorized), (0, render_ui_module_1.default)(config, config.organizationMenu));
|
|
189
207
|
}
|
|
190
208
|
if (config.editorRightPanel) {
|
|
@@ -197,11 +215,11 @@ function addCrowdinEndpoints(app, plainConfig) {
|
|
|
197
215
|
app.use('/project-menu-crowdsource', (0, ui_module_1.default)(config, config.projectMenuCrowdsource.allowUnauthorized), (0, render_ui_module_1.default)(config, config.projectMenuCrowdsource));
|
|
198
216
|
}
|
|
199
217
|
if (config.projectTools) {
|
|
200
|
-
app.get('/logo/tools/logo.png', (req, res) => { var _a; return res.sendFile(((_a = config.projectTools) === null || _a === void 0 ? void 0 : _a.imagePath) || config.imagePath
|
|
218
|
+
app.get('/logo/tools/logo.png', (req, res) => { var _a; return res.sendFile(((_a = config.projectTools) === null || _a === void 0 ? void 0 : _a.imagePath) || config.imagePath); });
|
|
201
219
|
app.use('/tools', (0, ui_module_1.default)(config, config.projectTools.allowUnauthorized), (0, render_ui_module_1.default)(config, config.projectTools));
|
|
202
220
|
}
|
|
203
221
|
if (config.projectReports) {
|
|
204
|
-
app.get('/logo/reports/logo.png', (req, res) => { var _a; return res.sendFile(((_a = config.projectReports) === null || _a === void 0 ? void 0 : _a.imagePath) || config.imagePath
|
|
222
|
+
app.get('/logo/reports/logo.png', (req, res) => { var _a; return res.sendFile(((_a = config.projectReports) === null || _a === void 0 ? void 0 : _a.imagePath) || config.imagePath); });
|
|
205
223
|
app.use('/reports', (0, ui_module_1.default)(config, config.projectReports.allowUnauthorized), (0, render_ui_module_1.default)(config, config.projectReports));
|
|
206
224
|
}
|
|
207
225
|
if (Object.keys(config).some((moduleKey) => {
|
|
@@ -233,11 +251,12 @@ function addCrowdinEndpoints(app, plainConfig) {
|
|
|
233
251
|
};
|
|
234
252
|
}
|
|
235
253
|
exports.addCrowdinEndpoints = addCrowdinEndpoints;
|
|
236
|
-
function createApp(
|
|
254
|
+
function createApp(clientConfig) {
|
|
237
255
|
const app = (0, express_1.default)();
|
|
256
|
+
const config = (0, defaults_1.convertClientConfig)(clientConfig);
|
|
238
257
|
addCrowdinEndpoints(app, config);
|
|
239
258
|
/* eslint no-console: "off" */
|
|
240
|
-
app.listen(config.port
|
|
259
|
+
app.listen(config.port, () => console.log(`App started on port ${config.port}`));
|
|
241
260
|
}
|
|
242
261
|
exports.createApp = createApp;
|
|
243
262
|
function handleUncaughtErrors(config) {
|
package/out/models/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { JwtPayload, VerifyOptions } from '@crowdin/crowdin-apps-functions';
|
|
|
3
3
|
import { Request } from 'express';
|
|
4
4
|
import { MySQLStorageConfig } from '../storage/mysql';
|
|
5
5
|
import { PostgreStorageConfig } from '../storage/postgre';
|
|
6
|
-
export interface
|
|
6
|
+
export interface ClientConfig extends ImagePath {
|
|
7
7
|
/**
|
|
8
8
|
* Authentication Crowdin App type: "authorization_code", "crowdin_app". Default: "crowdin_app"
|
|
9
9
|
*/
|
|
@@ -11,11 +11,11 @@ export interface Config extends ImagePath {
|
|
|
11
11
|
/**
|
|
12
12
|
* client id that we received when registering the app
|
|
13
13
|
*/
|
|
14
|
-
clientId
|
|
14
|
+
clientId?: string;
|
|
15
15
|
/**
|
|
16
16
|
* client secret that we received when registering the app
|
|
17
17
|
*/
|
|
18
|
-
clientSecret
|
|
18
|
+
clientSecret?: string;
|
|
19
19
|
/**
|
|
20
20
|
* Secret to encrypt/decrypt credentials (by default @clientSecret will be used)
|
|
21
21
|
*/
|
|
@@ -27,7 +27,7 @@ export interface Config extends ImagePath {
|
|
|
27
27
|
/**
|
|
28
28
|
* https url where an app is reachable from the internet (e.g. the one that ngrok generates for us)
|
|
29
29
|
*/
|
|
30
|
-
baseUrl
|
|
30
|
+
baseUrl?: string;
|
|
31
31
|
/**
|
|
32
32
|
* define custom Crowdin urls (e.g. to work against local Crowdin server)
|
|
33
33
|
*/
|
|
@@ -104,6 +104,14 @@ export interface Config extends ImagePath {
|
|
|
104
104
|
* reports module
|
|
105
105
|
*/
|
|
106
106
|
projectReports?: UiModule & ImagePath;
|
|
107
|
+
/**
|
|
108
|
+
* context menu module
|
|
109
|
+
*/
|
|
110
|
+
contextMenu?: ContextModule & ModuleContent & Environments;
|
|
111
|
+
/**
|
|
112
|
+
* modal module
|
|
113
|
+
*/
|
|
114
|
+
modal?: ModuleContent & Environments;
|
|
107
115
|
/**
|
|
108
116
|
* Uninstall hook for cleanup logic
|
|
109
117
|
*/
|
|
@@ -127,7 +135,19 @@ export interface Config extends ImagePath {
|
|
|
127
135
|
* Configuration of app pricing
|
|
128
136
|
*/
|
|
129
137
|
pricing?: Pricing;
|
|
138
|
+
filePreImport?: FilePreImportLogic;
|
|
139
|
+
filePostImport?: FilePostImportLogic;
|
|
140
|
+
filePreExport?: FilePreExportLogic;
|
|
141
|
+
filePostExport?: FilePostExportLogic;
|
|
130
142
|
}
|
|
143
|
+
export type Config = ClientConfig & {
|
|
144
|
+
baseUrl: string;
|
|
145
|
+
clientId: string;
|
|
146
|
+
clientSecret: string;
|
|
147
|
+
port: number;
|
|
148
|
+
dbFolder: string;
|
|
149
|
+
imagePath: string;
|
|
150
|
+
};
|
|
131
151
|
export declare enum AuthenticationType {
|
|
132
152
|
CODE = "authorization_code",
|
|
133
153
|
APP = "crowdin_app"
|
|
@@ -484,23 +504,29 @@ export interface CronJob {
|
|
|
484
504
|
task: (projectId: number, client: Crowdin, apiCredentials: any, appRootFolder?: SourceFilesModel.Directory, config?: any) => Promise<void>;
|
|
485
505
|
expression: string;
|
|
486
506
|
}
|
|
487
|
-
export interface
|
|
488
|
-
/**
|
|
489
|
-
* The type parameter value for a custom file format. Used for a custom format file upload via API.
|
|
490
|
-
*/
|
|
491
|
-
type: string;
|
|
507
|
+
export interface FileProcessLogic {
|
|
492
508
|
/**
|
|
493
509
|
* Folder where larger file will be temporary stored (default "{@link dbFolder}/custom-file-format")
|
|
494
510
|
*/
|
|
495
511
|
filesFolder?: string;
|
|
496
|
-
/**
|
|
497
|
-
* This parameter is used to combine the content of multiple languages into one request when uploading and downloading translations in your Crowdin project.
|
|
498
|
-
*/
|
|
499
|
-
multilingual?: boolean;
|
|
500
512
|
/**
|
|
501
513
|
* Contains fileName and/or fileContent regular expressions used to detect file type when uploading a new source file via UI (or via API without specified type parameter). If the file matches regular expressions, it's labeled as a custom format file.
|
|
502
514
|
*/
|
|
503
515
|
signaturePatterns?: SignaturePatterns;
|
|
516
|
+
/**
|
|
517
|
+
* Override to store huge responses (by default they will be stored in fs)
|
|
518
|
+
*/
|
|
519
|
+
storeFile?: (content: string) => Promise<string>;
|
|
520
|
+
}
|
|
521
|
+
export interface CustomFileFormatLogic extends FileProcessLogic {
|
|
522
|
+
/**
|
|
523
|
+
* The type parameter value for a custom file format. Used for a custom format file upload via API.
|
|
524
|
+
*/
|
|
525
|
+
type: string;
|
|
526
|
+
/**
|
|
527
|
+
* This parameter is used to combine the content of multiple languages into one request when uploading and downloading translations in your Crowdin project.
|
|
528
|
+
*/
|
|
529
|
+
multilingual?: boolean;
|
|
504
530
|
/**
|
|
505
531
|
* Flag to automatically upload translations
|
|
506
532
|
*/
|
|
@@ -533,10 +559,19 @@ export interface CustomFileFormatLogic {
|
|
|
533
559
|
* Used for strings export
|
|
534
560
|
*/
|
|
535
561
|
exportStrings?: (req: Omit<ProcessFileRequest, 'jobType'>, strings: ProcessFileString[], client: Crowdin, context: CrowdinContextInfo, projectId: number) => Promise<BuildFileResponse>;
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
562
|
+
}
|
|
563
|
+
export type FileImportExportLogic = FilePreImportLogic | FilePostImportLogic | FilePreExportLogic | FilePostExportLogic;
|
|
564
|
+
export interface FilePreImportLogic extends FileProcessLogic {
|
|
565
|
+
fileProcess: (req: ProcessFileRequest, content: string, client: Crowdin, context: CrowdinContextInfo, projectId: number) => Promise<BuildFileResponse>;
|
|
566
|
+
}
|
|
567
|
+
export interface FilePostImportLogic extends FileProcessLogic {
|
|
568
|
+
fileProcess: (req: ProcessFileRequest, content: string, client: Crowdin, context: CrowdinContextInfo, projectId: number) => Promise<ParseFileResponse>;
|
|
569
|
+
}
|
|
570
|
+
export interface FilePreExportLogic extends FileProcessLogic {
|
|
571
|
+
fileProcess: (req: ProcessFileRequest, content: string, client: Crowdin, context: CrowdinContextInfo, projectId: number) => Promise<ParseFileResponse>;
|
|
572
|
+
}
|
|
573
|
+
export interface FilePostExportLogic extends FileProcessLogic {
|
|
574
|
+
fileProcess: (req: ProcessFileRequest, content: string, client: Crowdin, context: CrowdinContextInfo, projectId: number) => Promise<BuildFileResponse>;
|
|
540
575
|
}
|
|
541
576
|
export interface SignaturePatterns {
|
|
542
577
|
fileName?: string;
|
|
@@ -559,7 +594,11 @@ export interface ProcessFileRecord {
|
|
|
559
594
|
}
|
|
560
595
|
export declare enum ProcessFileJobType {
|
|
561
596
|
PARSE_FILE = "parse-file",
|
|
562
|
-
BUILD_FILE = "build-file"
|
|
597
|
+
BUILD_FILE = "build-file",
|
|
598
|
+
PRE_IMPORT = "pre-import-file",
|
|
599
|
+
POST_IMPORT = "post-import-file",
|
|
600
|
+
PRE_EXPORT = "pre-export-file",
|
|
601
|
+
POST_EXPORT = "post-export-file"
|
|
563
602
|
}
|
|
564
603
|
export interface ParseFileResponse {
|
|
565
604
|
previewFile?: string;
|
|
@@ -568,7 +607,10 @@ export interface ParseFileResponse {
|
|
|
568
607
|
}
|
|
569
608
|
export interface BuildFileResponse {
|
|
570
609
|
contentFile: string;
|
|
610
|
+
base64EncodedContent?: string;
|
|
571
611
|
error?: string;
|
|
612
|
+
fileName?: string;
|
|
613
|
+
fileType?: string;
|
|
572
614
|
}
|
|
573
615
|
export interface ProcessFileString {
|
|
574
616
|
previewId?: number;
|
|
@@ -582,6 +624,7 @@ export interface ProcessFileString {
|
|
|
582
624
|
labels?: string[];
|
|
583
625
|
text: string | SourceStringsModel.PluralText;
|
|
584
626
|
translations?: StringTranslations;
|
|
627
|
+
uniqId?: string;
|
|
585
628
|
}
|
|
586
629
|
export interface StringTranslations {
|
|
587
630
|
[language: string]: {
|
|
@@ -640,6 +683,30 @@ export declare enum EditorPanelsMode {
|
|
|
640
683
|
TRANSLATE = "TRANSLATE",
|
|
641
684
|
PROOFREAD = "proofread"
|
|
642
685
|
}
|
|
686
|
+
interface ModuleContent {
|
|
687
|
+
/**
|
|
688
|
+
* relative URL to the content page of the module
|
|
689
|
+
*/
|
|
690
|
+
url?: string;
|
|
691
|
+
}
|
|
692
|
+
export interface ContextModule {
|
|
693
|
+
location: ContextOptionsLocations;
|
|
694
|
+
type: ContextOptionsTypes;
|
|
695
|
+
module: string;
|
|
696
|
+
}
|
|
697
|
+
export declare enum ContextOptionsLocations {
|
|
698
|
+
TM = "tm",
|
|
699
|
+
GLOSSARY = "glossary",
|
|
700
|
+
LANGUAGE = "language",
|
|
701
|
+
SCREENSHOT = "screenshot",
|
|
702
|
+
SOURCE_FILE = "source_file",
|
|
703
|
+
TRANSLATED_FILE = "translated_file"
|
|
704
|
+
}
|
|
705
|
+
export declare enum ContextOptionsTypes {
|
|
706
|
+
MODAL = "modal",
|
|
707
|
+
NEW_TAB = "new_tab",
|
|
708
|
+
REDIRECT = "redirect"
|
|
709
|
+
}
|
|
643
710
|
export interface CrowdinAppUtilities {
|
|
644
711
|
saveMetadata: (id: string, metadata: any) => Promise<void>;
|
|
645
712
|
getMetadata: (id: string) => Promise<any | undefined>;
|