@crowdin/app-project-module 0.14.1 → 0.15.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.
@@ -13,6 +13,7 @@ exports.prepareCrowdinRequest = void 0;
13
13
  const crowdin_apps_functions_1 = require("@crowdin/crowdin-apps-functions");
14
14
  const storage_1 = require("../storage");
15
15
  const util_1 = require("../util");
16
+ const connection_1 = require("../util/connection");
16
17
  function getToken(req) {
17
18
  const tokenJwt = (req.query.tokenJwt || req.query.jwtToken);
18
19
  if (tokenJwt) {
@@ -24,61 +25,43 @@ function getToken(req) {
24
25
  }
25
26
  }
26
27
  }
27
- function prepareCrowdinRequest(jwtToken, config, optional = false) {
28
+ function prepareCrowdinRequest(jwtToken, config, optional = false, checkSubscriptionExpiration = true) {
28
29
  return __awaiter(this, void 0, void 0, function* () {
29
- let context;
30
- let client;
31
- try {
32
- (0, util_1.log)('Validating jwt token from incoming request', config.logger);
33
- const jwtPayload = yield (0, crowdin_apps_functions_1.validateJwtToken)(jwtToken, config.clientSecret);
34
- context = {
35
- jwtPayload,
36
- clientId: (0, crowdin_apps_functions_1.constructCrowdinIdFromJwtPayload)(jwtPayload),
37
- crowdinId: `${jwtPayload.domain || jwtPayload.context.organization_id}`,
38
- };
39
- }
40
- catch (e) {
41
- if (config.onError) {
42
- config.onError(e);
43
- }
44
- else {
45
- console.error(e);
46
- }
47
- throw new Error("Can't verify");
48
- }
49
- try {
50
- (0, util_1.log)('Loading crowdin credentials', config.logger);
51
- const credentials = yield (0, storage_1.getCrowdinCredentials)(context.crowdinId);
52
- if (!credentials) {
53
- if (optional) {
54
- return { context };
55
- }
56
- throw new Error("Can't find organization by id");
30
+ (0, util_1.log)('Validating jwt token from incoming request', config.logger);
31
+ const jwtPayload = yield (0, crowdin_apps_functions_1.validateJwtToken)(jwtToken, config.clientSecret);
32
+ const context = {
33
+ jwtPayload,
34
+ clientId: (0, crowdin_apps_functions_1.constructCrowdinIdFromJwtPayload)(jwtPayload),
35
+ crowdinId: `${jwtPayload.domain || jwtPayload.context.organization_id}`,
36
+ };
37
+ (0, util_1.log)('Loading crowdin credentials', config.logger);
38
+ const credentials = yield (0, storage_1.getCrowdinCredentials)(context.crowdinId);
39
+ if (!credentials) {
40
+ if (optional) {
41
+ return { context };
57
42
  }
58
- (0, util_1.log)('Building crowdin client instance', config.logger);
59
- client = yield (0, util_1.prepareCrowdinClient)(config, credentials);
43
+ throw new Error("Can't find organization by id");
60
44
  }
61
- catch (e) {
62
- if (config.onError) {
63
- config.onError(e);
64
- }
65
- else {
66
- console.error(e);
45
+ (0, util_1.log)('Building crowdin client instance', config.logger);
46
+ const { client, token } = yield (0, connection_1.prepareCrowdinClient)(config, credentials);
47
+ if (checkSubscriptionExpiration) {
48
+ const { expired, subscribeLink } = yield (0, connection_1.checkSubscription)(config, token, credentials.id, credentials.type);
49
+ if (expired) {
50
+ throw new util_1.CodeError(subscribeLink || '', 402);
67
51
  }
68
- throw new Error('Access denied');
69
52
  }
70
53
  return { context, client };
71
54
  });
72
55
  }
73
56
  exports.prepareCrowdinRequest = prepareCrowdinRequest;
74
- function handle(config, optional = false) {
57
+ function handle(config, optional = false, checkSubscriptionExpiration = true) {
75
58
  return (0, util_1.runAsyncWrapper)((req, res, next) => __awaiter(this, void 0, void 0, function* () {
76
59
  const tokenJwt = getToken(req);
77
60
  if (!tokenJwt) {
78
61
  return res.status(403).send({ error: 'Access denied' });
79
62
  }
80
63
  try {
81
- const data = yield prepareCrowdinRequest(tokenJwt, config, optional);
64
+ const data = yield prepareCrowdinRequest(tokenJwt, config, optional, checkSubscriptionExpiration);
82
65
  req.crowdinContext = data.context;
83
66
  if (data.client) {
84
67
  req.crowdinApiClient = data.client;
@@ -86,6 +69,15 @@ function handle(config, optional = false) {
86
69
  next();
87
70
  }
88
71
  catch (e) {
72
+ if (e instanceof util_1.CodeError) {
73
+ throw e;
74
+ }
75
+ if (config.onError) {
76
+ config.onError(e);
77
+ }
78
+ else {
79
+ console.error(e);
80
+ }
89
81
  const message = typeof e === 'string' ? e : e.message;
90
82
  return res.status(403).send({ error: message || 'Error' });
91
83
  }
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  const storage_1 = require("../storage");
13
13
  const util_1 = require("../util");
14
+ const connection_1 = require("../util/connection");
14
15
  function handle(config, integration, optional = false) {
15
16
  return (0, util_1.runAsyncWrapper)((req, res, next) => __awaiter(this, void 0, void 0, function* () {
16
17
  const clientId = req.crowdinContext.clientId;
@@ -26,7 +27,7 @@ function handle(config, integration, optional = false) {
26
27
  req.integrationSettings = JSON.parse(integrationCredentials.config);
27
28
  }
28
29
  try {
29
- req.integrationCredentials = yield (0, util_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
30
+ req.integrationCredentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
30
31
  }
31
32
  catch (e) {
32
33
  console.error(e);
@@ -0,0 +1,4 @@
1
+ /// <reference types="qs" />
2
+ import { Request, Response } from 'express';
3
+ import { Config } from '../models';
4
+ export default function handle(config: Config): (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;
@@ -0,0 +1,39 @@
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
+ const crowdin_apps_functions_1 = require("@crowdin/crowdin-apps-functions");
13
+ const storage_1 = require("../storage");
14
+ const util_1 = require("../util");
15
+ const connection_1 = require("../util/connection");
16
+ function handle(config) {
17
+ return (0, util_1.runAsyncWrapper)((req, res, next) => __awaiter(this, void 0, void 0, function* () {
18
+ const tokenJwt = req.query.tokenJwt;
19
+ if (!tokenJwt) {
20
+ return res.status(403).send({ error: 'Access denied' });
21
+ }
22
+ (0, util_1.log)('Validating jwt token from incoming request', config.logger);
23
+ const jwtPayload = yield (0, crowdin_apps_functions_1.validateJwtToken)(tokenJwt, config.clientSecret);
24
+ const id = `${jwtPayload.domain || jwtPayload.context.organization_id}`;
25
+ (0, util_1.log)('Loading crowdin credentials', config.logger);
26
+ const credentials = yield (0, storage_1.getCrowdinCredentials)(id);
27
+ if (!credentials) {
28
+ throw new Error("Can't find organization by id");
29
+ }
30
+ (0, util_1.log)('Building crowdin client instance', config.logger);
31
+ const { token } = yield (0, connection_1.prepareCrowdinClient)(config, credentials);
32
+ const { expired, subscribeLink } = yield (0, connection_1.checkSubscription)(config, token, credentials.id, credentials.type);
33
+ if (expired) {
34
+ return res.render('subscription', { subscribeLink });
35
+ }
36
+ next();
37
+ }), config.onError);
38
+ }
39
+ exports.default = handle;
@@ -106,6 +106,10 @@ export interface Config extends ImagePath {
106
106
  * Configuration to log everything that are happening in the app
107
107
  */
108
108
  logger?: Logger;
109
+ /**
110
+ * Configuration of app pricing
111
+ */
112
+ pricing?: Pricing;
109
113
  }
110
114
  export declare enum Scope {
111
115
  ALL_SCOPES = "all",
@@ -496,4 +500,11 @@ export interface Logger {
496
500
  enabled: boolean;
497
501
  log?: (message: string) => void;
498
502
  }
503
+ export interface Pricing {
504
+ planType: 'free' | 'recurring';
505
+ trial?: number;
506
+ trialCrowdin?: number;
507
+ trialEnterprise?: number;
508
+ cachingSeconds?: number;
509
+ }
499
510
  export {};
@@ -47,6 +47,13 @@ function catchRejection(e, message) {
47
47
  //session expired
48
48
  if (e.code && e.code === 401) {
49
49
  reloadLocation();
50
+ return;
51
+ }
52
+ //payment required
53
+ if (e.code && e.code === 402 && subscriptionModal) {
54
+ subscriptionLink = e.message || message;
55
+ subscriptionModal.open();
56
+ return;
50
57
  }
51
58
  showToast(e.message || message);
52
59
  }
@@ -0,0 +1,11 @@
1
+ import Crowdin from '@crowdin/crowdin-api-client';
2
+ import { AccountType, Config, CrowdinCredentials, IntegrationCredentials, IntegrationLogic } from '../models';
3
+ export declare function prepareCrowdinClient(config: Config, credentials: CrowdinCredentials): Promise<{
4
+ client: Crowdin;
5
+ token: string;
6
+ }>;
7
+ export declare function prepareIntegrationCredentials(config: Config, integration: IntegrationLogic, integrationCredentials: IntegrationCredentials): Promise<any>;
8
+ export declare function checkSubscription(config: Config, token: string, organization: string, accountType: AccountType): Promise<{
9
+ expired: boolean;
10
+ subscribeLink?: string;
11
+ }>;
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
22
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
23
+ return new (P || (P = Promise))(function (resolve, reject) {
24
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
25
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
26
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
27
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
28
+ });
29
+ };
30
+ var __importDefault = (this && this.__importDefault) || function (mod) {
31
+ return (mod && mod.__esModule) ? mod : { "default": mod };
32
+ };
33
+ Object.defineProperty(exports, "__esModule", { value: true });
34
+ exports.checkSubscription = exports.prepareIntegrationCredentials = exports.prepareCrowdinClient = void 0;
35
+ const crowdin_api_client_1 = __importDefault(require("@crowdin/crowdin-api-client"));
36
+ const crowdinAppFunctions = __importStar(require("@crowdin/crowdin-apps-functions"));
37
+ const axios_1 = __importDefault(require("axios"));
38
+ const _1 = require(".");
39
+ const models_1 = require("../models");
40
+ const storage_1 = require("../storage");
41
+ function prepareCrowdinClient(config, credentials) {
42
+ return __awaiter(this, void 0, void 0, function* () {
43
+ const isExpired = +credentials.expire < +new Date().getTime() / 1000;
44
+ let client;
45
+ let token;
46
+ const organization = credentials.type === models_1.AccountType.ENTERPRISE ? credentials.id : undefined;
47
+ if (!isExpired) {
48
+ const token = (0, _1.decryptData)(config.clientSecret, credentials.accessToken);
49
+ return {
50
+ client: new crowdin_api_client_1.default({ token, organization }),
51
+ token,
52
+ };
53
+ }
54
+ (0, _1.log)('Crowdin credentials have expired. Requesting a new credentials', config.logger);
55
+ const newCredentials = yield crowdinAppFunctions.refreshOAuthToken(config.clientId, config.clientSecret, (0, _1.decryptData)(config.clientSecret, credentials.refreshToken));
56
+ (0, _1.log)('Saving updated crowdin credentials in the database', config.logger);
57
+ yield (0, storage_1.updateCrowdinCredentials)({
58
+ id: credentials.id,
59
+ refreshToken: (0, _1.encryptData)(config.clientSecret, newCredentials.refreshToken),
60
+ accessToken: (0, _1.encryptData)(config.clientSecret, newCredentials.accessToken),
61
+ expire: (new Date().getTime() / 1000 + newCredentials.expiresIn).toString(),
62
+ type: credentials.type,
63
+ });
64
+ return {
65
+ client: new crowdin_api_client_1.default({ token: newCredentials.accessToken, organization }),
66
+ token: newCredentials.accessToken,
67
+ };
68
+ });
69
+ }
70
+ exports.prepareCrowdinClient = prepareCrowdinClient;
71
+ function prepareIntegrationCredentials(config, integration, integrationCredentials) {
72
+ var _a, _b, _c, _d, _e, _f, _g, _h;
73
+ return __awaiter(this, void 0, void 0, function* () {
74
+ const credentials = JSON.parse((0, _1.decryptData)(config.clientSecret, integrationCredentials.credentials));
75
+ if ((_a = integration.oauthLogin) === null || _a === void 0 ? void 0 : _a.refresh) {
76
+ (0, _1.log)('Checking if integration credentials need to be refreshed', config.logger);
77
+ const oauthLogin = integration.oauthLogin;
78
+ const { expireIn } = credentials;
79
+ //2 min as an extra buffer
80
+ const isExpired = expireIn + 120 < Date.now() / 1000;
81
+ if (isExpired) {
82
+ (0, _1.log)('Integration credentials have expired. Requesting a new credentials', config.logger);
83
+ let newCredentials;
84
+ if (oauthLogin.performRefreshTokenRequest) {
85
+ newCredentials = yield oauthLogin.performRefreshTokenRequest(credentials);
86
+ }
87
+ else {
88
+ const url = oauthLogin.refreshTokenUrl || oauthLogin.accessTokenUrl;
89
+ const request = {};
90
+ request[((_b = oauthLogin === null || oauthLogin === void 0 ? void 0 : oauthLogin.fieldsMapping) === null || _b === void 0 ? void 0 : _b.clientId) || 'client_id'] = oauthLogin === null || oauthLogin === void 0 ? void 0 : oauthLogin.clientId;
91
+ request[((_c = oauthLogin === null || oauthLogin === void 0 ? void 0 : oauthLogin.fieldsMapping) === null || _c === void 0 ? void 0 : _c.clientSecret) || 'client_secret'] = oauthLogin === null || oauthLogin === void 0 ? void 0 : oauthLogin.clientSecret;
92
+ request[((_d = oauthLogin === null || oauthLogin === void 0 ? void 0 : oauthLogin.fieldsMapping) === null || _d === void 0 ? void 0 : _d.refreshToken) || 'refresh_token'] = credentials.refreshToken;
93
+ if (oauthLogin === null || oauthLogin === void 0 ? void 0 : oauthLogin.extraRefreshTokenParameters) {
94
+ Object.entries(oauthLogin === null || oauthLogin === void 0 ? void 0 : oauthLogin.extraRefreshTokenParameters).forEach(([key, value]) => (request[key] = value));
95
+ }
96
+ newCredentials = (yield axios_1.default.post(url || '', request, {
97
+ headers: { Accept: 'application/json' },
98
+ })).data;
99
+ }
100
+ credentials.accessToken = newCredentials[((_e = oauthLogin === null || oauthLogin === void 0 ? void 0 : oauthLogin.fieldsMapping) === null || _e === void 0 ? void 0 : _e.accessToken) || 'access_token'];
101
+ credentials.expireIn =
102
+ Number(newCredentials[((_f = oauthLogin === null || oauthLogin === void 0 ? void 0 : oauthLogin.fieldsMapping) === null || _f === void 0 ? void 0 : _f.expiresIn) || 'expires_in']) + Date.now() / 1000;
103
+ if (newCredentials[((_g = oauthLogin === null || oauthLogin === void 0 ? void 0 : oauthLogin.fieldsMapping) === null || _g === void 0 ? void 0 : _g.refreshToken) || 'refresh_token']) {
104
+ credentials.refreshToken = newCredentials[((_h = oauthLogin === null || oauthLogin === void 0 ? void 0 : oauthLogin.fieldsMapping) === null || _h === void 0 ? void 0 : _h.refreshToken) || 'refresh_token'];
105
+ }
106
+ (0, _1.log)('Saving updated integration credentials in the database', config.logger);
107
+ yield (0, storage_1.updateIntegrationCredentials)(integrationCredentials.id, (0, _1.encryptData)(config.clientSecret, JSON.stringify(credentials)));
108
+ }
109
+ }
110
+ return credentials;
111
+ });
112
+ }
113
+ exports.prepareIntegrationCredentials = prepareIntegrationCredentials;
114
+ const subscriptionCache = {};
115
+ function addToCache(organization, validUntil, cachingSeconds, subscribeLink) {
116
+ if (!cachingSeconds) {
117
+ return;
118
+ }
119
+ const now = new Date();
120
+ now.setSeconds(now.getSeconds() + cachingSeconds);
121
+ subscriptionCache[organization] = {
122
+ cacheValidUntil: now,
123
+ validUntil,
124
+ subscribeLink,
125
+ };
126
+ }
127
+ function checkSubscription(config, token, organization, accountType) {
128
+ return __awaiter(this, void 0, void 0, function* () {
129
+ if (!config.pricing || config.pricing.planType === 'free') {
130
+ return { expired: false };
131
+ }
132
+ //default 2 weeks
133
+ const defaultSubscriptionPlan = 14;
134
+ let days;
135
+ if (organization) {
136
+ days = config.pricing.trialEnterprise || config.pricing.trial || defaultSubscriptionPlan;
137
+ }
138
+ else {
139
+ days = config.pricing.trialCrowdin || config.pricing.trial || defaultSubscriptionPlan;
140
+ }
141
+ (0, _1.log)(`Checking subscription plan. Subscriptino plan ${days} days`, config.logger);
142
+ if (subscriptionCache[organization]) {
143
+ const { cacheValidUntil, validUntil, subscribeLink } = subscriptionCache[organization];
144
+ if (cacheValidUntil.getTime() > Date.now()) {
145
+ (0, _1.log)(`Loaded data from cache. Subscription is vali until ${validUntil.toISOString()}`, config.logger);
146
+ const expired = new Date(validUntil).getTime() < Date.now();
147
+ (0, _1.log)(`expired ${expired}`, config.logger);
148
+ return { expired, subscribeLink };
149
+ }
150
+ }
151
+ try {
152
+ const appIdentifier = config.identifier;
153
+ const subscription = yield crowdinAppFunctions.getSubscription({
154
+ appIdentifier,
155
+ organization: accountType === models_1.AccountType.ENTERPRISE ? organization : undefined,
156
+ token,
157
+ });
158
+ (0, _1.log)(`Recieved subscription info. ${JSON.stringify(subscription)}`, config.logger);
159
+ const expired = new Date(subscription.expires).getTime() < Date.now();
160
+ (0, _1.log)(`expired ${expired}`, config.logger);
161
+ addToCache(organization, new Date(subscription.expires), config.pricing.cachingSeconds);
162
+ return { expired };
163
+ }
164
+ catch (e) {
165
+ if (e instanceof crowdinAppFunctions.PaymentRequiredError) {
166
+ const { initializedAt, subscribeLink } = e;
167
+ (0, _1.log)(`Recieved 402 payment error. initializedAt ${initializedAt}`, config.logger);
168
+ const date = new Date(initializedAt);
169
+ date.setDate(date.getDate() + days);
170
+ const expired = date.getTime() < Date.now();
171
+ (0, _1.log)(`expired ${expired}`, config.logger);
172
+ addToCache(organization, new Date(date), config.pricing.cachingSeconds, subscribeLink);
173
+ return { expired, subscribeLink };
174
+ }
175
+ if (config.onError) {
176
+ config.onError(e);
177
+ }
178
+ else {
179
+ console.error(e);
180
+ }
181
+ (0, _1.log)('Recieved http error from subscription request. Returning expired=true', config.logger);
182
+ return { expired: true };
183
+ }
184
+ });
185
+ }
186
+ exports.checkSubscription = checkSubscription;
@@ -0,0 +1,3 @@
1
+ import { Config, CronJob, IntegrationLogic } from '../models';
2
+ export declare function runJob(config: Config, integration: IntegrationLogic, job: CronJob): Promise<void>;
3
+ export declare function filesCron(config: Config, integration: IntegrationLogic, period: string): Promise<void>;
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
22
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
23
+ return new (P || (P = Promise))(function (resolve, reject) {
24
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
25
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
26
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
27
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
28
+ });
29
+ };
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ exports.filesCron = exports.runJob = void 0;
32
+ const crowdinAppFunctions = __importStar(require("@crowdin/crowdin-apps-functions"));
33
+ const _1 = require(".");
34
+ const storage_1 = require("../storage");
35
+ const connection_1 = require("./connection");
36
+ const defaults_1 = require("./defaults");
37
+ function runJob(config, integration, job) {
38
+ return __awaiter(this, void 0, void 0, function* () {
39
+ (0, _1.log)(`Starting cron job with expression [${job.expression}]`, config.logger);
40
+ const crowdinCredentialsList = yield (0, storage_1.getAllCrowdinCredentials)();
41
+ yield Promise.all(crowdinCredentialsList.map((crowdinCredentials) => __awaiter(this, void 0, void 0, function* () {
42
+ const { client: crowdinClient, token } = yield (0, connection_1.prepareCrowdinClient)(config, crowdinCredentials);
43
+ const { expired } = yield (0, connection_1.checkSubscription)(config, token, crowdinCredentials.id, crowdinCredentials.type);
44
+ if (expired) {
45
+ (0, _1.log)(`Subscription expired. Skipping job [${job.expression}] for organization ${crowdinCredentials.id}`);
46
+ return;
47
+ }
48
+ const integrationCredentialsList = yield (0, storage_1.getAllIntegrationCredentials)(crowdinCredentials.id);
49
+ yield Promise.all(integrationCredentialsList.map((integrationCredentials) => __awaiter(this, void 0, void 0, function* () {
50
+ const projectId = crowdinAppFunctions.getProjectId(integrationCredentials.id);
51
+ const apiCredentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
52
+ const rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, crowdinClient, projectId);
53
+ const intConfig = integrationCredentials.config
54
+ ? JSON.parse(integrationCredentials.config)
55
+ : undefined;
56
+ (0, _1.log)(`Executing task for cron job with expression [${job.expression}] for project ${projectId}`, config.logger);
57
+ yield job.task(projectId, crowdinClient, apiCredentials, rootFolder, intConfig);
58
+ (0, _1.log)(`Task for cron job with expression [${job.expression}] for project ${projectId} completed`, config.logger);
59
+ })));
60
+ })));
61
+ (0, _1.log)(`Cron job with expression [${job.expression}] completed`, config.logger);
62
+ });
63
+ }
64
+ exports.runJob = runJob;
65
+ function filesCron(config, integration, period) {
66
+ return __awaiter(this, void 0, void 0, function* () {
67
+ (0, _1.log)(`Starting files cron job with period [${period}]`, config.logger);
68
+ const syncSettingsList = yield (0, storage_1.getAllSyncSettingsByType)('schedule');
69
+ yield Promise.all(syncSettingsList.map((syncSettings) => __awaiter(this, void 0, void 0, function* () {
70
+ const files = JSON.parse(syncSettings.files);
71
+ const crowdinCredentials = yield (0, storage_1.getCrowdinCredentials)(syncSettings.crowdinId);
72
+ const integrationCredentials = yield (0, storage_1.getIntegrationCredentials)(syncSettings.integrationId);
73
+ if (crowdinCredentials && integrationCredentials) {
74
+ const intConfig = integrationCredentials.config
75
+ ? JSON.parse(integrationCredentials.config)
76
+ : { schedule: '0' };
77
+ if (period === intConfig.schedule) {
78
+ const projectId = crowdinAppFunctions.getProjectId(integrationCredentials.id);
79
+ const { client: crowdinClient, token } = yield (0, connection_1.prepareCrowdinClient)(config, crowdinCredentials);
80
+ const { expired } = yield (0, connection_1.checkSubscription)(config, token, crowdinCredentials.id, crowdinCredentials.type);
81
+ if (expired) {
82
+ (0, _1.log)(`Subscription expired. Skipping job [${period}] for organization ${crowdinCredentials.id}`);
83
+ return;
84
+ }
85
+ const apiCredentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
86
+ const rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, crowdinClient, projectId);
87
+ if (syncSettings.provider === 'crowdin') {
88
+ (0, _1.log)(`Executing updateIntegration task for files cron job with period [${period}] for project ${projectId} and request ${JSON.stringify(files, null, 2)}`, config.logger);
89
+ yield integration.updateIntegration(projectId, crowdinClient, apiCredentials, files, rootFolder, intConfig);
90
+ (0, _1.log)(`updateIntegration task for files cron job with period [${period}] for project ${projectId} completed`, config.logger);
91
+ }
92
+ else {
93
+ (0, _1.log)(`Executing updateCrowdin task for files cron job with period [${period}] for project ${projectId} and request ${JSON.stringify(files, null, 2)}`, config.logger);
94
+ yield integration.updateCrowdin(projectId, crowdinClient, apiCredentials, files, rootFolder, intConfig);
95
+ (0, _1.log)(`updateCrowdin task for files cron job with period [${period}] for project ${projectId} completed`, config.logger);
96
+ }
97
+ }
98
+ }
99
+ })));
100
+ (0, _1.log)(`Files cron job with period [${period}] completed`, config.logger);
101
+ });
102
+ }
103
+ exports.filesCron = filesCron;
@@ -0,0 +1,5 @@
1
+ import Crowdin, { SourceFilesModel } from '@crowdin/crowdin-api-client';
2
+ import { Config, IntegrationLogic } from '../models';
3
+ export declare function getRootFolder(config: Config, integration: IntegrationLogic, client: Crowdin, projectId: number): Promise<SourceFilesModel.Directory | undefined>;
4
+ export declare function getOauthRoute(integration: IntegrationLogic): string;
5
+ export declare function applyDefaults(config: Config, integration: IntegrationLogic): void;