@crowdin/app-project-module 0.16.1 → 0.16.3
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 +36 -0
- package/out/handlers/manifest.js +22 -8
- package/out/handlers/subscription-info.js +3 -2
- package/out/models/index.d.ts +15 -1
- package/out/models/index.js +6 -1
- package/out/util/connection.js +20 -18
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -519,6 +519,42 @@ const configuration = {
|
|
|
519
519
|
crowdinModule.createApp(configuration);
|
|
520
520
|
```
|
|
521
521
|
|
|
522
|
+
Also custom file format module can support strings export.
|
|
523
|
+
|
|
524
|
+
```javascript
|
|
525
|
+
const crowdinModule = require('@crowdin/app-project-module');
|
|
526
|
+
const convert = require('xml-js');
|
|
527
|
+
|
|
528
|
+
const configuration = {
|
|
529
|
+
baseUrl: 'https://123.ngrok.io',
|
|
530
|
+
clientId: 'clientId',
|
|
531
|
+
clientSecret: 'clientSecret',
|
|
532
|
+
name: 'Sample App',
|
|
533
|
+
identifier: 'sample-app',
|
|
534
|
+
description: 'Sample App description',
|
|
535
|
+
dbFolder: __dirname,
|
|
536
|
+
imagePath: __dirname + '/' + 'logo.png',
|
|
537
|
+
customFileFormat: {
|
|
538
|
+
type: 'type-xyz',
|
|
539
|
+
stringsExport: true,
|
|
540
|
+
extensions: [
|
|
541
|
+
'.resx'
|
|
542
|
+
],
|
|
543
|
+
parseFile: async (file, req, client, context, projectId) => {
|
|
544
|
+
//parse logic
|
|
545
|
+
return { strings: [] };
|
|
546
|
+
},
|
|
547
|
+
buildFile: async (file, req, strings, client, context, projectId) => {
|
|
548
|
+
const isStringsExport = !!req.file.path;
|
|
549
|
+
//export logic
|
|
550
|
+
return { contentFile: {} }
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
|
|
555
|
+
crowdinModule.createApp(configuration);
|
|
556
|
+
```
|
|
557
|
+
|
|
522
558
|
### Custom MT
|
|
523
559
|
|
|
524
560
|
Example of [custom mt module](https://support.crowdin.com/crowdin-apps-modules/#custom-mt-machine-translation-module).
|
package/out/handlers/manifest.js
CHANGED
|
@@ -15,14 +15,28 @@ function handle(config) {
|
|
|
15
15
|
];
|
|
16
16
|
}
|
|
17
17
|
if (config.customFileFormat) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
if (config.customFileFormat.stringsExport) {
|
|
19
|
+
modules['custom-file-format'] = [
|
|
20
|
+
{
|
|
21
|
+
key: config.identifier + '-ff',
|
|
22
|
+
type: config.customFileFormat.type,
|
|
23
|
+
stringsExport: true,
|
|
24
|
+
extensions: config.customFileFormat.extensions,
|
|
25
|
+
url: '/process',
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
modules['custom-file-format'] = [
|
|
31
|
+
{
|
|
32
|
+
key: config.identifier + '-ff',
|
|
33
|
+
type: config.customFileFormat.type,
|
|
34
|
+
multilingual: !!config.customFileFormat.multilingual,
|
|
35
|
+
signaturePatterns: config.customFileFormat.signaturePatterns,
|
|
36
|
+
url: '/process',
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
}
|
|
26
40
|
}
|
|
27
41
|
if (config.customMT) {
|
|
28
42
|
modules['custom-mt'] = [
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const models_1 = require("../models");
|
|
3
4
|
function handle(config) {
|
|
4
5
|
return (req, res) => {
|
|
5
6
|
var _a;
|
|
6
7
|
const subscriptionInfo = req.subscriptionInfo;
|
|
7
|
-
let showInfo =
|
|
8
|
-
if ((_a = config.pricing) === null || _a === void 0 ? void 0 : _a.infoDisplayDaysThreshold) {
|
|
8
|
+
let showInfo = (subscriptionInfo === null || subscriptionInfo === void 0 ? void 0 : subscriptionInfo.type) === models_1.SubscriptionInfoType.TRIAL;
|
|
9
|
+
if (showInfo && ((_a = config.pricing) === null || _a === void 0 ? void 0 : _a.infoDisplayDaysThreshold)) {
|
|
9
10
|
showInfo = config.pricing.infoDisplayDaysThreshold >= ((subscriptionInfo === null || subscriptionInfo === void 0 ? void 0 : subscriptionInfo.daysLeft) || 0);
|
|
10
11
|
}
|
|
11
12
|
res.send(Object.assign(Object.assign({}, (subscriptionInfo || {})), { showInfo }));
|
package/out/models/index.d.ts
CHANGED
|
@@ -340,10 +340,15 @@ export interface CrowdinContextInfo {
|
|
|
340
340
|
crowdinId: string;
|
|
341
341
|
clientId: string;
|
|
342
342
|
}
|
|
343
|
+
export declare enum SubscriptionInfoType {
|
|
344
|
+
TRIAL = "trial",
|
|
345
|
+
SUBSCRIPTION = "subscription"
|
|
346
|
+
}
|
|
343
347
|
export interface SubscriptionInfo {
|
|
344
348
|
expired: boolean;
|
|
345
349
|
subscribeLink?: string;
|
|
346
350
|
daysLeft?: number;
|
|
351
|
+
type?: SubscriptionInfoType;
|
|
347
352
|
}
|
|
348
353
|
export interface IntegrationCredentials {
|
|
349
354
|
id: string;
|
|
@@ -385,6 +390,14 @@ export interface CustomFileFormatLogic {
|
|
|
385
390
|
* Flag to automatically upload translations
|
|
386
391
|
*/
|
|
387
392
|
autoUploadTranslations?: boolean;
|
|
393
|
+
/**
|
|
394
|
+
* Enable strings export
|
|
395
|
+
*/
|
|
396
|
+
stringsExport?: boolean;
|
|
397
|
+
/**
|
|
398
|
+
* File extensions (used for strings export)
|
|
399
|
+
*/
|
|
400
|
+
extensions?: string[];
|
|
388
401
|
/**
|
|
389
402
|
* Used for initial source file upload, source file update, and translation upload
|
|
390
403
|
*/
|
|
@@ -392,7 +405,7 @@ export interface CustomFileFormatLogic {
|
|
|
392
405
|
/**
|
|
393
406
|
* Used for translation download
|
|
394
407
|
*/
|
|
395
|
-
buildFile: (fileContent: string | object, req: Omit<ProcessFileRequest, 'jobType'
|
|
408
|
+
buildFile: (fileContent: string | object, req: Omit<ProcessFileRequest, 'jobType'>, strings: ProcessFileString[], client: Crowdin, context: CrowdinContextInfo, projectId: number) => Promise<BuildFileResponse>;
|
|
396
409
|
}
|
|
397
410
|
export interface SignaturePatterns {
|
|
398
411
|
fileName?: string;
|
|
@@ -409,6 +422,7 @@ export interface ProcessFileRequest {
|
|
|
409
422
|
export interface ProcessFileRecord {
|
|
410
423
|
content?: string;
|
|
411
424
|
contentUrl?: string;
|
|
425
|
+
path?: string;
|
|
412
426
|
}
|
|
413
427
|
export declare enum ProcessFileJobType {
|
|
414
428
|
PARSE_FILE = "parse-file",
|
package/out/models/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EditorPanelsMode = exports.ProcessFileJobType = exports.AccountType = exports.Scope = void 0;
|
|
3
|
+
exports.EditorPanelsMode = exports.ProcessFileJobType = exports.SubscriptionInfoType = exports.AccountType = exports.Scope = void 0;
|
|
4
4
|
var Scope;
|
|
5
5
|
(function (Scope) {
|
|
6
6
|
Scope["ALL_SCOPES"] = "all";
|
|
@@ -22,6 +22,11 @@ var AccountType;
|
|
|
22
22
|
AccountType["NORMAL"] = "normal";
|
|
23
23
|
AccountType["ENTERPRISE"] = "enterprise";
|
|
24
24
|
})(AccountType = exports.AccountType || (exports.AccountType = {}));
|
|
25
|
+
var SubscriptionInfoType;
|
|
26
|
+
(function (SubscriptionInfoType) {
|
|
27
|
+
SubscriptionInfoType["TRIAL"] = "trial";
|
|
28
|
+
SubscriptionInfoType["SUBSCRIPTION"] = "subscription";
|
|
29
|
+
})(SubscriptionInfoType = exports.SubscriptionInfoType || (exports.SubscriptionInfoType = {}));
|
|
25
30
|
var ProcessFileJobType;
|
|
26
31
|
(function (ProcessFileJobType) {
|
|
27
32
|
ProcessFileJobType["PARSE_FILE"] = "parse-file";
|
package/out/util/connection.js
CHANGED
|
@@ -112,7 +112,7 @@ function prepareIntegrationCredentials(config, integration, integrationCredentia
|
|
|
112
112
|
}
|
|
113
113
|
exports.prepareIntegrationCredentials = prepareIntegrationCredentials;
|
|
114
114
|
const subscriptionCache = {};
|
|
115
|
-
function addToCache(organization, appIdenfifier, validUntil, cachingSeconds, subscribeLink) {
|
|
115
|
+
function addToCache(organization, appIdenfifier, validUntil, type, cachingSeconds, subscribeLink) {
|
|
116
116
|
if (!cachingSeconds) {
|
|
117
117
|
return;
|
|
118
118
|
}
|
|
@@ -123,6 +123,7 @@ function addToCache(organization, appIdenfifier, validUntil, cachingSeconds, sub
|
|
|
123
123
|
cacheValidUntil: now,
|
|
124
124
|
validUntil,
|
|
125
125
|
subscribeLink,
|
|
126
|
+
type,
|
|
126
127
|
};
|
|
127
128
|
subscriptionCache[organization] = orgCache;
|
|
128
129
|
}
|
|
@@ -148,25 +149,16 @@ function checkSubscription(config, token, organization, accountType) {
|
|
|
148
149
|
if (isAppFree(config)) {
|
|
149
150
|
return { expired: false };
|
|
150
151
|
}
|
|
151
|
-
|
|
152
|
-
const defaultSubscriptionPlan = 14;
|
|
153
|
-
let days;
|
|
154
|
-
if (organization) {
|
|
155
|
-
days = ((_a = config.pricing) === null || _a === void 0 ? void 0 : _a.trialEnterprise) || ((_b = config.pricing) === null || _b === void 0 ? void 0 : _b.trial) || defaultSubscriptionPlan;
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
days = ((_c = config.pricing) === null || _c === void 0 ? void 0 : _c.trialCrowdin) || ((_d = config.pricing) === null || _d === void 0 ? void 0 : _d.trial) || defaultSubscriptionPlan;
|
|
159
|
-
}
|
|
160
|
-
(0, _1.log)(`Checking subscription plan. Subscriptino plan ${days} days`, config.logger);
|
|
152
|
+
(0, _1.log)('Checking subscription plan', config.logger);
|
|
161
153
|
const appIdentifier = config.identifier;
|
|
162
154
|
const cacheEntry = getFromCache(organization, appIdentifier);
|
|
163
155
|
if (cacheEntry) {
|
|
164
|
-
const { cacheValidUntil, validUntil, subscribeLink } = cacheEntry;
|
|
156
|
+
const { cacheValidUntil, validUntil, subscribeLink, type } = cacheEntry;
|
|
165
157
|
if (cacheValidUntil.getTime() > Date.now()) {
|
|
166
|
-
(0, _1.log)(`Loaded data from cache. Subscription is
|
|
158
|
+
(0, _1.log)(`Loaded data from cache. Subscription is valid until ${validUntil.toISOString()}`, config.logger);
|
|
167
159
|
const { expired, daysLeft } = validateSubscription(new Date(validUntil));
|
|
168
160
|
(0, _1.log)(`expired ${expired}`, config.logger);
|
|
169
|
-
return { expired, subscribeLink, daysLeft };
|
|
161
|
+
return { expired, subscribeLink, daysLeft, type };
|
|
170
162
|
}
|
|
171
163
|
}
|
|
172
164
|
try {
|
|
@@ -178,19 +170,29 @@ function checkSubscription(config, token, organization, accountType) {
|
|
|
178
170
|
(0, _1.log)(`Recieved subscription info. ${JSON.stringify(subscription)}`, config.logger);
|
|
179
171
|
const { expired, daysLeft } = validateSubscription(new Date(subscription.expires));
|
|
180
172
|
(0, _1.log)(`expired ${expired}`, config.logger);
|
|
181
|
-
addToCache(organization, appIdentifier, new Date(subscription.expires), (
|
|
182
|
-
return { expired, daysLeft };
|
|
173
|
+
addToCache(organization, appIdentifier, new Date(subscription.expires), models_1.SubscriptionInfoType.SUBSCRIPTION, (_a = config.pricing) === null || _a === void 0 ? void 0 : _a.cachingSeconds);
|
|
174
|
+
return { expired, daysLeft, type: models_1.SubscriptionInfoType.SUBSCRIPTION };
|
|
183
175
|
}
|
|
184
176
|
catch (e) {
|
|
185
177
|
if (e instanceof crowdinAppFunctions.PaymentRequiredError) {
|
|
186
178
|
const { initializedAt, subscribeLink } = e;
|
|
187
179
|
(0, _1.log)(`Recieved 402 payment error. initializedAt ${initializedAt}`, config.logger);
|
|
180
|
+
//default 2 weeks
|
|
181
|
+
const defaultSubscriptionPlan = 14;
|
|
182
|
+
let days;
|
|
183
|
+
if (organization) {
|
|
184
|
+
days = ((_b = config.pricing) === null || _b === void 0 ? void 0 : _b.trialEnterprise) || ((_c = config.pricing) === null || _c === void 0 ? void 0 : _c.trial) || defaultSubscriptionPlan;
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
days = ((_d = config.pricing) === null || _d === void 0 ? void 0 : _d.trialCrowdin) || ((_e = config.pricing) === null || _e === void 0 ? void 0 : _e.trial) || defaultSubscriptionPlan;
|
|
188
|
+
}
|
|
189
|
+
(0, _1.log)(`Subscriptino trial plan ${days} days`, config.logger);
|
|
188
190
|
const date = new Date(initializedAt);
|
|
189
191
|
date.setDate(date.getDate() + days);
|
|
190
192
|
const { expired, daysLeft } = validateSubscription(date);
|
|
191
193
|
(0, _1.log)(`expired ${expired}`, config.logger);
|
|
192
|
-
addToCache(organization, appIdentifier, new Date(date), (_f = config.pricing) === null || _f === void 0 ? void 0 : _f.cachingSeconds, subscribeLink);
|
|
193
|
-
return { expired, subscribeLink, daysLeft };
|
|
194
|
+
addToCache(organization, appIdentifier, new Date(date), models_1.SubscriptionInfoType.TRIAL, (_f = config.pricing) === null || _f === void 0 ? void 0 : _f.cachingSeconds, subscribeLink);
|
|
195
|
+
return { expired, subscribeLink, daysLeft, type: models_1.SubscriptionInfoType.TRIAL };
|
|
194
196
|
}
|
|
195
197
|
if (config.onError) {
|
|
196
198
|
config.onError(e);
|
package/package.json
CHANGED