@crowdin/app-project-module 0.44.0 → 0.45.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.
Files changed (149) hide show
  1. package/out/index.d.ts +3 -3
  2. package/out/index.js +52 -59
  3. package/out/middlewares/crowdin-client.d.ts +1 -1
  4. package/out/middlewares/crowdin-client.js +3 -2
  5. package/out/middlewares/integration-credentials.d.ts +2 -2
  6. package/out/middlewares/render-ui-module.d.ts +2 -2
  7. package/out/middlewares/ui-module.d.ts +2 -2
  8. package/out/middlewares/ui-module.js +3 -3
  9. package/out/{util → modules}/api/api.d.ts +2 -1
  10. package/out/{util → modules}/api/api.js +22 -22
  11. package/out/modules/api/index.d.ts +6 -0
  12. package/out/modules/api/index.js +14 -0
  13. package/out/modules/api/types.d.ts +20 -0
  14. package/out/modules/api/types.js +11 -0
  15. package/out/modules/context-menu/index.d.ts +1 -1
  16. package/out/modules/context-menu/index.js +2 -2
  17. package/out/modules/context-menu/types.d.ts +27 -0
  18. package/out/modules/context-menu/types.js +18 -0
  19. package/out/modules/custom-mt/handlers/translate.d.ts +1 -1
  20. package/out/modules/custom-mt/index.d.ts +1 -1
  21. package/out/modules/custom-mt/types.d.ts +1 -1
  22. package/out/modules/custom-spell-check/handlers/get-languages-list.d.ts +1 -1
  23. package/out/modules/custom-spell-check/handlers/spell-check.d.ts +1 -1
  24. package/out/modules/custom-spell-check/index.d.ts +1 -1
  25. package/out/modules/custom-spell-check/index.js +2 -2
  26. package/out/modules/custom-spell-check/types.d.ts +1 -1
  27. package/out/modules/editor-right-panel/index.d.ts +1 -1
  28. package/out/modules/editor-right-panel/index.js +2 -2
  29. package/out/modules/editor-right-panel/types.d.ts +1 -1
  30. package/out/modules/editor-themes/index.d.ts +1 -1
  31. package/out/modules/editor-themes/types.d.ts +17 -0
  32. package/out/modules/editor-themes/types.js +2 -0
  33. package/out/modules/file-processing/handlers/custom-file-format.d.ts +1 -1
  34. package/out/modules/file-processing/handlers/custom-file-format.js +1 -1
  35. package/out/modules/file-processing/handlers/file-download.d.ts +2 -2
  36. package/out/modules/file-processing/handlers/pre-post-process.d.ts +1 -1
  37. package/out/modules/file-processing/handlers/pre-post-process.js +1 -1
  38. package/out/modules/file-processing/index.d.ts +1 -1
  39. package/out/modules/file-processing/index.js +1 -1
  40. package/out/modules/file-processing/types.d.ts +1 -1
  41. package/out/modules/file-processing/util/defaults.d.ts +3 -0
  42. package/out/modules/file-processing/util/defaults.js +30 -0
  43. package/out/modules/file-processing/util/files.d.ts +6 -0
  44. package/out/modules/file-processing/util/files.js +47 -0
  45. package/out/modules/form-data-display.d.ts +1 -1
  46. package/out/modules/form-data-save.d.ts +1 -1
  47. package/out/modules/install.d.ts +2 -2
  48. package/out/modules/install.js +3 -3
  49. package/out/modules/integration/handlers/crowdin-file-progress.d.ts +1 -1
  50. package/out/modules/integration/handlers/crowdin-files.d.ts +2 -2
  51. package/out/modules/integration/handlers/crowdin-files.js +1 -1
  52. package/out/modules/integration/handlers/crowdin-project.d.ts +1 -1
  53. package/out/modules/integration/handlers/crowdin-update.d.ts +2 -2
  54. package/out/modules/integration/handlers/crowdin-update.js +7 -7
  55. package/out/modules/integration/handlers/crowdin-webhook.d.ts +2 -2
  56. package/out/modules/integration/handlers/crowdin-webhook.js +16 -5
  57. package/out/modules/integration/handlers/integration-data.d.ts +1 -1
  58. package/out/modules/integration/handlers/integration-data.js +2 -2
  59. package/out/modules/integration/handlers/integration-login.d.ts +1 -1
  60. package/out/modules/integration/handlers/integration-logout.d.ts +2 -2
  61. package/out/modules/integration/handlers/integration-logout.js +11 -4
  62. package/out/modules/integration/handlers/integration-update.d.ts +2 -2
  63. package/out/modules/integration/handlers/integration-update.js +7 -6
  64. package/out/modules/integration/handlers/integration-webhook.d.ts +2 -2
  65. package/out/modules/integration/handlers/integration-webhook.js +7 -2
  66. package/out/modules/integration/handlers/job-cancel.d.ts +1 -1
  67. package/out/modules/integration/handlers/job-cancel.js +2 -2
  68. package/out/modules/integration/handlers/job-info.d.ts +1 -1
  69. package/out/modules/integration/handlers/job-info.js +2 -2
  70. package/out/modules/integration/handlers/main.d.ts +2 -2
  71. package/out/modules/integration/handlers/main.js +3 -3
  72. package/out/modules/integration/handlers/oauth-login.d.ts +2 -2
  73. package/out/modules/integration/handlers/oauth-login.js +1 -1
  74. package/out/modules/integration/handlers/oauth-url.d.ts +1 -1
  75. package/out/modules/integration/handlers/oauth-url.js +1 -1
  76. package/out/modules/integration/handlers/settings-save.d.ts +2 -2
  77. package/out/modules/integration/handlers/settings-save.js +25 -8
  78. package/out/modules/integration/handlers/settings.d.ts +1 -1
  79. package/out/modules/integration/handlers/subscription-info.d.ts +1 -1
  80. package/out/modules/integration/handlers/subscription-info.js +2 -2
  81. package/out/modules/integration/handlers/sync-settings-save.d.ts +2 -2
  82. package/out/modules/integration/handlers/sync-settings-save.js +15 -7
  83. package/out/modules/integration/handlers/sync-settings.d.ts +1 -1
  84. package/out/modules/integration/handlers/user-errors.d.ts +1 -1
  85. package/out/modules/integration/index.d.ts +1 -1
  86. package/out/modules/integration/index.js +15 -10
  87. package/out/modules/integration/types.d.ts +2 -13
  88. package/out/modules/integration/util/cron.d.ts +27 -0
  89. package/out/{util → modules/integration/util}/cron.js +92 -23
  90. package/out/{util → modules/integration/util}/defaults.d.ts +2 -6
  91. package/out/{util → modules/integration/util}/defaults.js +1 -46
  92. package/out/modules/integration/util/files.d.ts +5 -0
  93. package/out/{util → modules/integration/util}/files.js +9 -40
  94. package/out/{util → modules/integration/util}/job.d.ts +1 -1
  95. package/out/{util → modules/integration/util}/job.js +11 -11
  96. package/out/{util/file-snapshot.d.ts → modules/integration/util/snapshot.d.ts} +2 -4
  97. package/out/{util/file-snapshot.js → modules/integration/util/snapshot.js} +4 -63
  98. package/out/{models/job.d.ts → modules/integration/util/types.d.ts} +14 -0
  99. package/out/modules/integration/util/webhooks.d.ts +48 -0
  100. package/out/{util → modules/integration/util}/webhooks.js +92 -46
  101. package/out/modules/manifest.d.ts +1 -1
  102. package/out/modules/manifest.js +27 -66
  103. package/out/modules/modal/index.d.ts +1 -1
  104. package/out/modules/modal/index.js +2 -2
  105. package/out/modules/organization-menu/index.d.ts +1 -1
  106. package/out/modules/organization-menu/index.js +1 -2
  107. package/out/modules/profile-resources-menu/index.d.ts +1 -1
  108. package/out/modules/profile-resources-menu/index.js +1 -2
  109. package/out/modules/project-menu/index.d.ts +1 -1
  110. package/out/modules/project-menu/index.js +2 -2
  111. package/out/modules/project-menu-crowdsource/index.d.ts +1 -1
  112. package/out/modules/project-menu-crowdsource/index.js +2 -2
  113. package/out/modules/project-reports/index.d.ts +1 -1
  114. package/out/modules/project-reports/index.js +1 -2
  115. package/out/modules/project-tools/index.d.ts +1 -1
  116. package/out/modules/project-tools/index.js +1 -2
  117. package/out/modules/subscription-paid.d.ts +1 -1
  118. package/out/modules/subscription-paid.js +2 -2
  119. package/out/modules/uninstall.d.ts +2 -2
  120. package/out/modules/uninstall.js +6 -2
  121. package/out/storage/index.d.ts +3 -2
  122. package/out/storage/mysql.d.ts +3 -2
  123. package/out/storage/mysql.js +3 -3
  124. package/out/storage/postgre.d.ts +3 -2
  125. package/out/storage/postgre.js +3 -3
  126. package/out/storage/sqlite.d.ts +3 -2
  127. package/out/storage/sqlite.js +3 -3
  128. package/out/storage/types.d.ts +9 -0
  129. package/out/storage/types.js +2 -0
  130. package/out/{models/index.d.ts → types.d.ts} +16 -84
  131. package/out/{models/index.js → types.js} +1 -24
  132. package/out/util/connection.d.ts +1 -9
  133. package/out/util/connection.js +54 -150
  134. package/out/util/handlebars.d.ts +1 -0
  135. package/out/util/handlebars.js +34 -0
  136. package/out/util/index.d.ts +2 -3
  137. package/out/util/index.js +6 -6
  138. package/out/util/logger.d.ts +1 -1
  139. package/out/util/subscription.d.ts +9 -0
  140. package/out/util/subscription.js +111 -0
  141. package/package.json +1 -1
  142. package/out/util/cron.d.ts +0 -8
  143. package/out/util/files.d.ts +0 -10
  144. package/out/util/webhooks.d.ts +0 -29
  145. /package/out/{util → modules}/api/base.d.ts +0 -0
  146. /package/out/{util → modules}/api/base.js +0 -0
  147. /package/out/{util → modules}/api/components.d.ts +0 -0
  148. /package/out/{util → modules}/api/components.js +0 -0
  149. /package/out/{models/job.js → modules/integration/util/types.js} +0 -0
@@ -12,54 +12,22 @@ 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
- exports.checkSubscription = exports.isAppFree = exports.clearCache = exports.prepareIntegrationCredentials = exports.prepareCrowdinClient = void 0;
15
+ exports.prepareIntegrationCredentials = exports.prepareCrowdinClient = void 0;
16
16
  const crowdin_api_client_1 = __importDefault(require("@crowdin/crowdin-api-client"));
17
17
  const crowdin_apps_functions_1 = require("@crowdin/crowdin-apps-functions");
18
18
  const axios_1 = __importDefault(require("axios"));
19
19
  const _1 = require(".");
20
- const models_1 = require("../models");
21
20
  const storage_1 = require("../storage");
21
+ const types_1 = require("../types");
22
22
  const axios_2 = require("./axios");
23
23
  const logger_1 = require("./logger");
24
24
  const axiosCustom = new axios_2.AxiosProvider().axios;
25
- function refreshToken(config, credentials) {
26
- var _a, _b;
27
- return __awaiter(this, void 0, void 0, function* () {
28
- if (config.authenticationType === models_1.AuthenticationType.CODE) {
29
- const token = yield (0, crowdin_apps_functions_1.refreshOAuthToken)({
30
- clientId: config.clientId,
31
- clientSecret: config.clientSecret,
32
- refreshToken: (0, _1.decryptData)(config, credentials.refreshToken),
33
- url: (_a = config.crowdinUrls) === null || _a === void 0 ? void 0 : _a.accountUrl,
34
- });
35
- return {
36
- accessToken: (0, _1.encryptData)(config, token.accessToken),
37
- refreshToken: (0, _1.encryptData)(config, token.refreshToken),
38
- expiresIn: token.expiresIn,
39
- };
40
- }
41
- const token = yield (0, crowdin_apps_functions_1.fetchAppToken)({
42
- appId: config.identifier,
43
- appSecret: credentials.appSecret,
44
- clientId: config.clientId,
45
- clientSecret: config.clientSecret,
46
- domain: credentials.domain || '',
47
- userId: credentials.userId,
48
- url: (_b = config.crowdinUrls) === null || _b === void 0 ? void 0 : _b.accountUrl,
49
- });
50
- return {
51
- accessToken: (0, _1.encryptData)(config, token.accessToken),
52
- expiresIn: token.expiresIn,
53
- refreshToken: '',
54
- };
55
- });
56
- }
57
25
  function prepareCrowdinClient({ config, credentials, autoRenew = false, context, }) {
58
26
  var _a, _b;
59
27
  return __awaiter(this, void 0, void 0, function* () {
60
28
  //2 min as an extra buffer
61
29
  const isExpired = +credentials.expire - 120 < Date.now() / 1000;
62
- const organization = credentials.type === models_1.AccountType.ENTERPRISE ? credentials.id : undefined;
30
+ const organization = credentials.type === types_1.AccountType.ENTERPRISE ? credentials.id : undefined;
63
31
  let token;
64
32
  let crowdinCreds;
65
33
  if (!isExpired) {
@@ -211,31 +179,6 @@ function prepareCrowdinClient({ config, credentials, autoRenew = false, context,
211
179
  });
212
180
  }
213
181
  exports.prepareCrowdinClient = prepareCrowdinClient;
214
- function refreshCrowdinCreds({ config, credentials }) {
215
- return __awaiter(this, void 0, void 0, function* () {
216
- (0, logger_1.log)('Crowdin credentials have expired. Requesting a new credentials');
217
- const newCredentials = yield refreshToken(config, credentials);
218
- (0, logger_1.log)('Saving updated crowdin credentials in the database');
219
- const newCrowdinCredentials = {
220
- id: credentials.id,
221
- appSecret: credentials.appSecret,
222
- domain: credentials.domain,
223
- userId: credentials.userId,
224
- organizationId: credentials.organizationId,
225
- baseUrl: credentials.baseUrl,
226
- refreshToken: newCredentials.refreshToken,
227
- accessToken: newCredentials.accessToken,
228
- expire: (new Date().getTime() / 1000 + newCredentials.expiresIn).toString(),
229
- type: credentials.type,
230
- };
231
- yield (0, storage_1.getStorage)().updateCrowdinCredentials(newCrowdinCredentials);
232
- const token = (0, _1.decryptData)(config, newCredentials.accessToken);
233
- return {
234
- credentials: newCrowdinCredentials,
235
- token,
236
- };
237
- });
238
- }
239
182
  function prepareIntegrationCredentials(config, integration, integrationCredentials) {
240
183
  var _a, _b, _c, _d, _e, _f, _g, _h;
241
184
  return __awaiter(this, void 0, void 0, function* () {
@@ -279,99 +222,60 @@ function prepareIntegrationCredentials(config, integration, integrationCredentia
279
222
  });
280
223
  }
281
224
  exports.prepareIntegrationCredentials = prepareIntegrationCredentials;
282
- const subscriptionCache = {};
283
- function addToCache(organization, appIdentifier, validUntil, type, cachingSeconds, subscribeLink) {
284
- if (!cachingSeconds) {
285
- return;
286
- }
287
- const orgCache = subscriptionCache[organization] || {};
288
- const now = new Date();
289
- now.setSeconds(now.getSeconds() + cachingSeconds);
290
- orgCache[appIdentifier] = {
291
- cacheValidUntil: now,
292
- validUntil,
293
- subscribeLink,
294
- type,
295
- };
296
- subscriptionCache[organization] = orgCache;
297
- }
298
- function getFromCache(organization, appIdentifier) {
299
- return (subscriptionCache[organization] || {})[appIdentifier];
300
- }
301
- function clearCache(organization) {
302
- delete subscriptionCache[organization];
303
- }
304
- exports.clearCache = clearCache;
305
- function isAppFree(config) {
306
- return !config.pricing || config.pricing.planType === 'free';
307
- }
308
- exports.isAppFree = isAppFree;
309
- function validateSubscription(date) {
310
- const expired = date.getTime() < Date.now();
311
- const daysLeft = Math.round((date.getTime() - Date.now()) / (1000 * 60 * 60 * 24));
312
- return { expired, daysLeft };
225
+ function refreshCrowdinCreds({ config, credentials }) {
226
+ return __awaiter(this, void 0, void 0, function* () {
227
+ (0, logger_1.log)('Crowdin credentials have expired. Requesting a new credentials');
228
+ const newCredentials = yield refreshToken(config, credentials);
229
+ (0, logger_1.log)('Saving updated crowdin credentials in the database');
230
+ const newCrowdinCredentials = {
231
+ id: credentials.id,
232
+ appSecret: credentials.appSecret,
233
+ domain: credentials.domain,
234
+ userId: credentials.userId,
235
+ organizationId: credentials.organizationId,
236
+ baseUrl: credentials.baseUrl,
237
+ refreshToken: newCredentials.refreshToken,
238
+ accessToken: newCredentials.accessToken,
239
+ expire: (new Date().getTime() / 1000 + newCredentials.expiresIn).toString(),
240
+ type: credentials.type,
241
+ };
242
+ yield (0, storage_1.getStorage)().updateCrowdinCredentials(newCrowdinCredentials);
243
+ const token = (0, _1.decryptData)(config, newCredentials.accessToken);
244
+ return {
245
+ credentials: newCrowdinCredentials,
246
+ token,
247
+ };
248
+ });
313
249
  }
314
- function checkSubscription({ config, token, organization, accountType, }) {
315
- var _a, _b, _c, _d, _e, _f, _g;
250
+ function refreshToken(config, credentials) {
251
+ var _a, _b;
316
252
  return __awaiter(this, void 0, void 0, function* () {
317
- if (isAppFree(config)) {
318
- return { expired: false };
319
- }
320
- (0, logger_1.log)('Checking subscription plan');
321
- const appIdentifier = config.identifier;
322
- const cacheEntry = getFromCache(organization, appIdentifier);
323
- if (cacheEntry) {
324
- const { cacheValidUntil, validUntil, subscribeLink, type } = cacheEntry;
325
- if (cacheValidUntil.getTime() > Date.now()) {
326
- (0, logger_1.log)(`Loaded data from cache. Subscription is valid until ${validUntil.toISOString()}`);
327
- const { expired, daysLeft } = validateSubscription(new Date(validUntil));
328
- (0, logger_1.log)(`expired ${expired}`);
329
- return { expired, subscribeLink, daysLeft, type };
330
- }
331
- }
332
- try {
333
- const subscription = yield (0, crowdin_apps_functions_1.getSubscription)({
334
- appIdentifier,
335
- organization: accountType === models_1.AccountType.ENTERPRISE ? organization : undefined,
336
- token,
337
- baseUrl: (_a = config.crowdinUrls) === null || _a === void 0 ? void 0 : _a.subscriptionUrl,
253
+ if (config.authenticationType === types_1.AuthenticationType.CODE) {
254
+ const token = yield (0, crowdin_apps_functions_1.refreshOAuthToken)({
255
+ clientId: config.clientId,
256
+ clientSecret: config.clientSecret,
257
+ refreshToken: (0, _1.decryptData)(config, credentials.refreshToken),
258
+ url: (_a = config.crowdinUrls) === null || _a === void 0 ? void 0 : _a.accountUrl,
338
259
  });
339
- (0, logger_1.log)(`Recieved subscription info. ${JSON.stringify(subscription)}`);
340
- const { expired, daysLeft } = validateSubscription(new Date(subscription.expires));
341
- (0, logger_1.log)(`expired ${expired}`);
342
- addToCache(organization, appIdentifier, new Date(subscription.expires), models_1.SubscriptionInfoType.SUBSCRIPTION, (_b = config.pricing) === null || _b === void 0 ? void 0 : _b.cachingSeconds);
343
- return { expired, daysLeft, type: models_1.SubscriptionInfoType.SUBSCRIPTION };
344
- }
345
- catch (e) {
346
- if (e instanceof crowdin_apps_functions_1.PaymentRequiredError) {
347
- const { initializedAt, subscribeLink } = e;
348
- (0, logger_1.log)(`Recieved 402 payment error. initializedAt ${initializedAt}`);
349
- //default 2 weeks
350
- const defaultSubscriptionPlan = 14;
351
- let days;
352
- if (accountType === models_1.AccountType.ENTERPRISE) {
353
- days = ((_c = config.pricing) === null || _c === void 0 ? void 0 : _c.trialEnterprise) || ((_d = config.pricing) === null || _d === void 0 ? void 0 : _d.trial) || defaultSubscriptionPlan;
354
- }
355
- else {
356
- days = ((_e = config.pricing) === null || _e === void 0 ? void 0 : _e.trialCrowdin) || ((_f = config.pricing) === null || _f === void 0 ? void 0 : _f.trial) || defaultSubscriptionPlan;
357
- }
358
- (0, logger_1.log)(`Subscriptino trial plan ${days} days`);
359
- const date = new Date(initializedAt);
360
- date.setDate(date.getDate() + days);
361
- const { expired, daysLeft } = validateSubscription(date);
362
- (0, logger_1.log)(`expired ${expired}`);
363
- addToCache(organization, appIdentifier, new Date(date), models_1.SubscriptionInfoType.TRIAL, (_g = config.pricing) === null || _g === void 0 ? void 0 : _g.cachingSeconds, subscribeLink);
364
- return { expired, subscribeLink, daysLeft, type: models_1.SubscriptionInfoType.TRIAL };
365
- }
366
- if (config.onError) {
367
- config.onError(e);
368
- }
369
- else {
370
- console.error(e);
371
- }
372
- (0, logger_1.log)('Recieved http error from subscription request. Returning expired=false');
373
- return { expired: false };
260
+ return {
261
+ accessToken: (0, _1.encryptData)(config, token.accessToken),
262
+ refreshToken: (0, _1.encryptData)(config, token.refreshToken),
263
+ expiresIn: token.expiresIn,
264
+ };
374
265
  }
266
+ const token = yield (0, crowdin_apps_functions_1.fetchAppToken)({
267
+ appId: config.identifier,
268
+ appSecret: credentials.appSecret,
269
+ clientId: config.clientId,
270
+ clientSecret: config.clientSecret,
271
+ domain: credentials.domain || '',
272
+ userId: credentials.userId,
273
+ url: (_b = config.crowdinUrls) === null || _b === void 0 ? void 0 : _b.accountUrl,
274
+ });
275
+ return {
276
+ accessToken: (0, _1.encryptData)(config, token.accessToken),
277
+ expiresIn: token.expiresIn,
278
+ refreshToken: '',
279
+ };
375
280
  });
376
281
  }
377
- exports.checkSubscription = checkSubscription;
@@ -0,0 +1 @@
1
+ export declare const engine: (path: string, options: object, callback: (e: any, rendered: string) => void) => void;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.engine = void 0;
7
+ const express_handlebars_1 = __importDefault(require("express-handlebars"));
8
+ exports.engine = (0, express_handlebars_1.default)({
9
+ layoutsDir: '',
10
+ defaultLayout: '',
11
+ helpers: {
12
+ ifeq: function (a, b, options) {
13
+ if (a === b) {
14
+ return options.fn(this);
15
+ }
16
+ return options.inverse(this);
17
+ },
18
+ checkLength: function (a, b, options) {
19
+ if (a.length > b) {
20
+ return options.fn(this);
21
+ }
22
+ return options.inverse(this);
23
+ },
24
+ in: function (a, b, options) {
25
+ if (a.toString().includes(b.toString())) {
26
+ return options.fn(this);
27
+ }
28
+ return options.inverse(this);
29
+ },
30
+ or: function (a, b, options) {
31
+ return a || b ? options.fn(this) : options.inverse(this);
32
+ },
33
+ },
34
+ });
@@ -1,6 +1,5 @@
1
1
  import { Request, Response } from 'express';
2
- import { Config, CrowdinClientRequest, ImagePath } from '../models';
3
- import { ExtendedResult } from '../modules/integration/types';
2
+ import { Config, CrowdinClientRequest, ImagePath, UnauthorizedConfig } from '../types';
4
3
  export declare class CodeError extends Error {
5
4
  code: number | undefined;
6
5
  constructor(message: string, code?: number);
@@ -9,5 +8,5 @@ export declare function runAsyncWrapper(callback: Function): (req: Request | Cro
9
8
  export declare function encryptData(config: Config, data: string): string;
10
9
  export declare function decryptData(config: Config, data: string): string;
11
10
  export declare function executeWithRetry<T>(func: () => Promise<T>, numOfRetries?: number): Promise<T>;
12
- export declare function isExtendedResultType<T>(data?: T | ExtendedResult<T>): data is ExtendedResult<T>;
13
11
  export declare function getLogoUrl(moduleConfig?: ImagePath, modulePath?: string): string;
12
+ export declare function isAuthorizedConfig(config: Config | UnauthorizedConfig): config is Config;
package/out/util/index.js CHANGED
@@ -32,9 +32,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
32
32
  });
33
33
  };
34
34
  Object.defineProperty(exports, "__esModule", { value: true });
35
- exports.getLogoUrl = exports.isExtendedResultType = exports.executeWithRetry = exports.decryptData = exports.encryptData = exports.runAsyncWrapper = exports.CodeError = void 0;
35
+ exports.isAuthorizedConfig = exports.getLogoUrl = exports.executeWithRetry = exports.decryptData = exports.encryptData = exports.runAsyncWrapper = exports.CodeError = void 0;
36
36
  const crypto = __importStar(require("crypto-js"));
37
37
  const storage_1 = require("../storage");
38
+ const types_1 = require("../types");
38
39
  const logger_1 = require("./logger");
39
40
  class CodeError extends Error {
40
41
  constructor(message, code) {
@@ -100,11 +101,6 @@ function executeWithRetry(func, numOfRetries = 2) {
100
101
  });
101
102
  }
102
103
  exports.executeWithRetry = executeWithRetry;
103
- function isExtendedResultType(data) {
104
- const dataTyped = data;
105
- return !!dataTyped && !Array.isArray(dataTyped);
106
- }
107
- exports.isExtendedResultType = isExtendedResultType;
108
104
  function getLogoUrl(moduleConfig, modulePath) {
109
105
  if (!moduleConfig && !modulePath) {
110
106
  return '/logo.png';
@@ -112,3 +108,7 @@ function getLogoUrl(moduleConfig, modulePath) {
112
108
  return `/logo${modulePath}/logo.png`;
113
109
  }
114
110
  exports.getLogoUrl = getLogoUrl;
111
+ function isAuthorizedConfig(config) {
112
+ return !!config.clientId && !!config.clientSecret && config.authenticationType !== types_1.AuthenticationType.NONE;
113
+ }
114
+ exports.isAuthorizedConfig = isAuthorizedConfig;
@@ -1,5 +1,5 @@
1
1
  import { AxiosError } from 'axios';
2
- import { Config, CrowdinContextInfo, UnauthorizedConfig } from '../models';
2
+ import { Config, CrowdinContextInfo, UnauthorizedConfig } from '../types';
3
3
  export type LogFunction = (message: string) => void;
4
4
  export type LogErrorFunction = (error: any) => void;
5
5
  export type LogContext = {
@@ -0,0 +1,9 @@
1
+ import { AccountType, Config, SubscriptionInfo, UnauthorizedConfig } from '../types';
2
+ export declare function isAppFree(config: Config | UnauthorizedConfig): boolean;
3
+ export declare function checkSubscription({ config, token, organization, accountType, }: {
4
+ config: Config;
5
+ token: string;
6
+ organization: string;
7
+ accountType: AccountType;
8
+ }): Promise<SubscriptionInfo>;
9
+ export declare function clearCache(organization: string): void;
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.clearCache = exports.checkSubscription = exports.isAppFree = void 0;
13
+ const crowdin_apps_functions_1 = require("@crowdin/crowdin-apps-functions");
14
+ const types_1 = require("../types");
15
+ const logger_1 = require("./logger");
16
+ const subscriptionCache = {};
17
+ function isAppFree(config) {
18
+ return !config.pricing || config.pricing.planType === 'free';
19
+ }
20
+ exports.isAppFree = isAppFree;
21
+ function checkSubscription({ config, token, organization, accountType, }) {
22
+ var _a, _b, _c, _d, _e, _f, _g;
23
+ return __awaiter(this, void 0, void 0, function* () {
24
+ if (isAppFree(config)) {
25
+ return { expired: false };
26
+ }
27
+ (0, logger_1.log)('Checking subscription plan');
28
+ const appIdentifier = config.identifier;
29
+ const cacheEntry = getFromCache(organization, appIdentifier);
30
+ if (cacheEntry) {
31
+ const { cacheValidUntil, validUntil, subscribeLink, type } = cacheEntry;
32
+ if (cacheValidUntil.getTime() > Date.now()) {
33
+ (0, logger_1.log)(`Loaded data from cache. Subscription is valid until ${validUntil.toISOString()}`);
34
+ const { expired, daysLeft } = validateSubscription(new Date(validUntil));
35
+ (0, logger_1.log)(`expired ${expired}`);
36
+ return { expired, subscribeLink, daysLeft, type };
37
+ }
38
+ }
39
+ try {
40
+ const subscription = yield (0, crowdin_apps_functions_1.getSubscription)({
41
+ appIdentifier,
42
+ organization: accountType === types_1.AccountType.ENTERPRISE ? organization : undefined,
43
+ token,
44
+ baseUrl: (_a = config.crowdinUrls) === null || _a === void 0 ? void 0 : _a.subscriptionUrl,
45
+ });
46
+ (0, logger_1.log)(`Recieved subscription info. ${JSON.stringify(subscription)}`);
47
+ const { expired, daysLeft } = validateSubscription(new Date(subscription.expires));
48
+ (0, logger_1.log)(`expired ${expired}`);
49
+ addToCache(organization, appIdentifier, new Date(subscription.expires), types_1.SubscriptionInfoType.SUBSCRIPTION, (_b = config.pricing) === null || _b === void 0 ? void 0 : _b.cachingSeconds);
50
+ return { expired, daysLeft, type: types_1.SubscriptionInfoType.SUBSCRIPTION };
51
+ }
52
+ catch (e) {
53
+ if (e instanceof crowdin_apps_functions_1.PaymentRequiredError) {
54
+ const { initializedAt, subscribeLink } = e;
55
+ (0, logger_1.log)(`Recieved 402 payment error. initializedAt ${initializedAt}`);
56
+ //default 2 weeks
57
+ const defaultSubscriptionPlan = 14;
58
+ let days;
59
+ if (accountType === types_1.AccountType.ENTERPRISE) {
60
+ days = ((_c = config.pricing) === null || _c === void 0 ? void 0 : _c.trialEnterprise) || ((_d = config.pricing) === null || _d === void 0 ? void 0 : _d.trial) || defaultSubscriptionPlan;
61
+ }
62
+ else {
63
+ days = ((_e = config.pricing) === null || _e === void 0 ? void 0 : _e.trialCrowdin) || ((_f = config.pricing) === null || _f === void 0 ? void 0 : _f.trial) || defaultSubscriptionPlan;
64
+ }
65
+ (0, logger_1.log)(`Subscriptino trial plan ${days} days`);
66
+ const date = new Date(initializedAt);
67
+ date.setDate(date.getDate() + days);
68
+ const { expired, daysLeft } = validateSubscription(date);
69
+ (0, logger_1.log)(`expired ${expired}`);
70
+ addToCache(organization, appIdentifier, new Date(date), types_1.SubscriptionInfoType.TRIAL, (_g = config.pricing) === null || _g === void 0 ? void 0 : _g.cachingSeconds, subscribeLink);
71
+ return { expired, subscribeLink, daysLeft, type: types_1.SubscriptionInfoType.TRIAL };
72
+ }
73
+ if (config.onError) {
74
+ config.onError(e);
75
+ }
76
+ else {
77
+ console.error(e);
78
+ }
79
+ (0, logger_1.log)('Recieved http error from subscription request. Returning expired=false');
80
+ return { expired: false };
81
+ }
82
+ });
83
+ }
84
+ exports.checkSubscription = checkSubscription;
85
+ function clearCache(organization) {
86
+ delete subscriptionCache[organization];
87
+ }
88
+ exports.clearCache = clearCache;
89
+ function addToCache(organization, appIdentifier, validUntil, type, cachingSeconds, subscribeLink) {
90
+ if (!cachingSeconds) {
91
+ return;
92
+ }
93
+ const orgCache = subscriptionCache[organization] || {};
94
+ const now = new Date();
95
+ now.setSeconds(now.getSeconds() + cachingSeconds);
96
+ orgCache[appIdentifier] = {
97
+ cacheValidUntil: now,
98
+ validUntil,
99
+ subscribeLink,
100
+ type,
101
+ };
102
+ subscriptionCache[organization] = orgCache;
103
+ }
104
+ function getFromCache(organization, appIdentifier) {
105
+ return (subscriptionCache[organization] || {})[appIdentifier];
106
+ }
107
+ function validateSubscription(date) {
108
+ const expired = date.getTime() < Date.now();
109
+ const daysLeft = Math.round((date.getTime() - Date.now()) / (1000 * 60 * 60 * 24));
110
+ return { expired, daysLeft };
111
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crowdin/app-project-module",
3
- "version": "0.44.0",
3
+ "version": "0.45.1",
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",
@@ -1,8 +0,0 @@
1
- import Crowdin from '@crowdin/crowdin-api-client';
2
- import { Config } from '../models';
3
- import { CronJob, IntegrationLogic, IntegrationRequest, Provider, UpdateIntegrationRequest } from '../modules/integration/types';
4
- export declare function runJob(config: Config, integration: IntegrationLogic, job: CronJob): Promise<void>;
5
- export declare function filesCron(config: Config, integration: IntegrationLogic, period: string): Promise<void>;
6
- export declare function skipFoldersFromIntegrationRequest(config: Config, integration: IntegrationLogic, projectId: number, crowdinFiles: UpdateIntegrationRequest, crowdinClient: Crowdin): Promise<UpdateIntegrationRequest>;
7
- export declare function createOrUpdateSyncSettings(config: Config, req: IntegrationRequest, files: any, provider: Provider, onlyCreate?: boolean): Promise<void>;
8
- export declare function removeFinishedJobs(): Promise<void>;
@@ -1,10 +0,0 @@
1
- /// <reference types="node" />
2
- import { IntegrationFile, IntegrationLogic, IntegrationRequest, SkipIntegrationNodes, TreeItem } from '../modules/integration/types';
3
- import { JobClient } from '../models/job';
4
- import { ProcessFileString } from '../modules/file-processing/types';
5
- export declare const MAX_BODY_SIZE: number;
6
- export declare function storeFile(fileContent: Buffer, folder: string): Promise<string>;
7
- export declare function getFileContent(url: string): Promise<Buffer>;
8
- export declare function getFileStrings(url: string): Promise<ProcessFileString[]>;
9
- export declare function skipFilesByRegex(files: TreeItem[] | undefined, skipIntegrationNodes?: SkipIntegrationNodes): TreeItem[];
10
- export declare function expandFilesTree(nodes: IntegrationFile[], req: IntegrationRequest, integration: IntegrationLogic, job?: JobClient): Promise<IntegrationFile[]>;
@@ -1,29 +0,0 @@
1
- import Crowdin from '@crowdin/crowdin-api-client';
2
- import { WebhooksModel } from '@crowdin/crowdin-api-client/out/webhooks';
3
- import { Config, CrowdinContextInfo } from '../models';
4
- import { AppSettings, IntegrationLogic, IntegrationSyncSettings, Provider, UpdateCrowdinWebhookPayloadsArgs, WebhookUrlParams } from '../modules/integration/types';
5
- export declare const HookEvents: any;
6
- export declare function encodedUrlParam(config: Config, integration: IntegrationLogic, crowdinContext: CrowdinContextInfo): string;
7
- export declare function decodedUrlParam(config: Config, data: string): WebhookUrlParams;
8
- export declare function makeCrowdinWebhookUrl(config: Config, integration: IntegrationLogic, crowdinContext: CrowdinContextInfo): string;
9
- export declare function registerWebhooks(config: Config, integration: IntegrationLogic, client: Crowdin, crowdinContext: CrowdinContextInfo, apiCredentials: any, appSettings: AppSettings): Promise<void>;
10
- export declare function unregisterWebhooks(config: Config, integration: IntegrationLogic, client: Crowdin, crowdinContext: CrowdinContextInfo, apiCredentials: any, appSettings: AppSettings): Promise<void>;
11
- export declare function getCrowdinProjectWebhook(config: Config, client: Crowdin, projectId: number, name: string): Promise<WebhooksModel.Webhook | undefined>;
12
- export declare function getAllCrowdinProjectWebhooks(config: Config, client: Crowdin, projectId: number): Promise<WebhooksModel.Webhook[]>;
13
- export declare function registerCrowdinWebhook(config: Config, url: string, client: Crowdin, crowdinContext: CrowdinContextInfo, events: WebhooksModel.Event[]): Promise<void>;
14
- export declare function updateCrowdinWebhooks(config: Config, client: Crowdin, projectId: number, webhook: WebhooksModel.Webhook, events: WebhooksModel.Event[], url: string): Promise<void>;
15
- export declare function unregisterCrowdinWebhooks(config: Config, client: Crowdin, projectId: number, webhook: WebhooksModel.Webhook): Promise<void>;
16
- export declare function unregisterAllCrowdinWebhooks(config: Config, integration: IntegrationLogic, crowdinId: string): Promise<void>;
17
- export declare function prepareWebhookData(config: Config, integration: IntegrationLogic, webhookUrlParam: string, provider: Provider): Promise<{
18
- projectId: number;
19
- crowdinClient: {
20
- client: Crowdin;
21
- token: string;
22
- };
23
- preparedIntegrationCredentials: any;
24
- rootFolder: import("@crowdin/crowdin-api-client").SourceFilesModel.Directory | undefined;
25
- appSettings: AppSettings;
26
- syncSettings: IntegrationSyncSettings | null;
27
- }>;
28
- export declare function updateCrowdinFromWebhookRequest(args: UpdateCrowdinWebhookPayloadsArgs): Promise<void>;
29
- export declare function listenQueueMessage(config: Config, integration: IntegrationLogic, queueUrl: string, queueName: string): Promise<void>;
File without changes
File without changes
File without changes
File without changes