@crowdin/app-project-module 0.56.3 → 0.57.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.
@@ -5,9 +5,9 @@ export declare const crowdinFolders: {
5
5
  data: {
6
6
  id: number;
7
7
  path: string;
8
+ name: string;
8
9
  branchId?: number | undefined;
9
10
  directoryId?: number | undefined;
10
- name: string;
11
11
  title?: string | undefined;
12
12
  exportPattern?: string | undefined;
13
13
  priority?: SourceFilesModel.Priority | undefined;
@@ -29,8 +29,8 @@ export declare const crowdinFiles: {
29
29
  parserVersion?: number | undefined;
30
30
  importOptions?: SourceFilesModel.ImportOptions | undefined;
31
31
  exportOptions?: SourceFilesModel.GeneralExportOptions | SourceFilesModel.PropertyExportOptions | undefined;
32
- attachLabelIds?: number[] | undefined;
33
32
  excludedTargetLanguages?: string[] | undefined;
33
+ attachLabelIds?: number[] | undefined;
34
34
  };
35
35
  };
36
36
  };
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  const util_1 = require("../../../util");
13
13
  const logger_1 = require("../../../util/logger");
14
14
  const files_1 = require("../../integration/util/files");
15
+ const util_2 = require("../util");
15
16
  function handle(aiProvider) {
16
17
  return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
17
18
  try {
@@ -49,6 +50,9 @@ function handle(aiProvider) {
49
50
  if (req.logError) {
50
51
  req.logError(e);
51
52
  }
53
+ if ((0, util_2.isRateLimitError)(e)) {
54
+ res.status(429);
55
+ }
52
56
  res.send({ error: { message: (0, logger_1.getErrorMessage)(e) } });
53
57
  }
54
58
  }));
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.CONTEXT_WINDOW_LIMIT = void 0;
13
13
  const util_1 = require("../../../util");
14
14
  const logger_1 = require("../../../util/logger");
15
+ const util_2 = require("../util");
15
16
  exports.CONTEXT_WINDOW_LIMIT = 4096;
16
17
  function handle(aiProvider) {
17
18
  return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
@@ -35,6 +36,9 @@ function handle(aiProvider) {
35
36
  if (req.logError) {
36
37
  req.logError(e);
37
38
  }
39
+ if ((0, util_2.isRateLimitError)(e)) {
40
+ res.status(429);
41
+ }
38
42
  res.send({ error: { message: (0, logger_1.getErrorMessage)(e) } });
39
43
  }
40
44
  }));
@@ -0,0 +1,11 @@
1
+ import { AppModuleAggregateError } from '../../../util/logger';
2
+ interface RateLimitErrorOptions {
3
+ error?: Error;
4
+ message?: string;
5
+ }
6
+ export declare function isRateLimitError(e: any): boolean;
7
+ export declare class RateLimitError extends AppModuleAggregateError {
8
+ readonly status = 429;
9
+ constructor({ error, message }?: RateLimitErrorOptions);
10
+ }
11
+ export {};
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RateLimitError = exports.isRateLimitError = void 0;
4
+ const logger_1 = require("../../../util/logger");
5
+ const HTTP_RATE_LIMIT = 429;
6
+ function isRateLimitError(e) {
7
+ if (!e || typeof e !== 'object') {
8
+ return false;
9
+ }
10
+ return ('status' in e && e.status === HTTP_RATE_LIMIT) || ('code' in e && e.code === HTTP_RATE_LIMIT);
11
+ }
12
+ exports.isRateLimitError = isRateLimitError;
13
+ class RateLimitError extends logger_1.AppModuleAggregateError {
14
+ constructor({ error, message } = {}) {
15
+ const newMessage = message || 'Rate limit reached';
16
+ super([error || new Error(newMessage)], newMessage);
17
+ this.status = HTTP_RATE_LIMIT;
18
+ this.name = 'RateLimitError';
19
+ }
20
+ }
21
+ exports.RateLimitError = RateLimitError;
@@ -24,6 +24,7 @@ function handle(config) {
24
24
  appSecret: event.appSecret,
25
25
  domain: event.domain,
26
26
  userId: event.userId,
27
+ agentId: event.agentId,
27
28
  organizationId: event.organizationId,
28
29
  baseUrl: event.baseUrl,
29
30
  accessToken: token.accessToken,
@@ -45,7 +46,7 @@ function handle(config) {
45
46
  }
46
47
  exports.default = handle;
47
48
  function fetchToken(config, event) {
48
- var _a, _b;
49
+ var _a, _b, _c;
49
50
  return __awaiter(this, void 0, void 0, function* () {
50
51
  if (config.authenticationType === types_1.AuthenticationType.CODE) {
51
52
  const token = yield (0, crowdin_apps_functions_1.generateOAuthToken)({
@@ -60,6 +61,23 @@ function fetchToken(config, event) {
60
61
  expiresIn: token.expiresIn,
61
62
  };
62
63
  }
64
+ if (config.authenticationType === types_1.AuthenticationType.AGENT) {
65
+ const token = yield (0, crowdin_apps_functions_1.fetchAgentToken)({
66
+ appId: config.identifier,
67
+ appSecret: event.appSecret,
68
+ clientId: config.clientId,
69
+ clientSecret: config.clientSecret,
70
+ domain: event.domain || '',
71
+ userId: event.userId,
72
+ agentId: event.agentId,
73
+ url: (_b = config.crowdinUrls) === null || _b === void 0 ? void 0 : _b.accountUrl,
74
+ });
75
+ return {
76
+ accessToken: (0, util_1.encryptData)(config, token.accessToken),
77
+ expiresIn: token.expiresIn,
78
+ refreshToken: '',
79
+ };
80
+ }
63
81
  const token = yield (0, crowdin_apps_functions_1.fetchAppToken)({
64
82
  appId: config.identifier,
65
83
  appSecret: event.appSecret,
@@ -67,7 +85,7 @@ function fetchToken(config, event) {
67
85
  clientSecret: config.clientSecret,
68
86
  domain: event.domain || '',
69
87
  userId: event.userId,
70
- url: (_b = config.crowdinUrls) === null || _b === void 0 ? void 0 : _b.accountUrl,
88
+ url: (_c = config.crowdinUrls) === null || _c === void 0 ? void 0 : _c.accountUrl,
71
89
  });
72
90
  return {
73
91
  accessToken: (0, util_1.encryptData)(config, token.accessToken),
@@ -87,6 +87,8 @@ function filesCron({ config, integration, period, }) {
87
87
  const syncSettingsList = yield (0, storage_1.getStorage)().getAllSyncSettingsByType('schedule');
88
88
  for (const syncSettings of syncSettingsList) {
89
89
  let projectData;
90
+ let crowdinClient;
91
+ let token;
90
92
  let files = JSON.parse(syncSettings.files);
91
93
  let newFiles = [];
92
94
  const crowdinCredentials = yield (0, storage_1.getStorage)().getCrowdinCredentials(syncSettings.crowdinId);
@@ -116,12 +118,20 @@ function filesCron({ config, integration, period, }) {
116
118
  },
117
119
  },
118
120
  };
119
- const { client: crowdinClient, token } = yield (0, connection_1.prepareCrowdinClient)({
120
- config,
121
- credentials: crowdinCredentials,
122
- autoRenew: true,
123
- context,
124
- });
121
+ try {
122
+ const preparedCrowdinClient = yield (0, connection_1.prepareCrowdinClient)({
123
+ config,
124
+ credentials: crowdinCredentials,
125
+ autoRenew: true,
126
+ context,
127
+ });
128
+ token = preparedCrowdinClient.token;
129
+ crowdinClient = preparedCrowdinClient.client;
130
+ }
131
+ catch (e) {
132
+ (0, logger_1.logError)(e);
133
+ continue;
134
+ }
125
135
  const { expired } = yield (0, subscription_1.checkSubscription)({
126
136
  config,
127
137
  token,
@@ -195,6 +205,9 @@ function filesCron({ config, integration, period, }) {
195
205
  onlyApproved,
196
206
  onlyTranslated,
197
207
  });
208
+ if (Object.keys(filesToProcess).length < 0) {
209
+ continue;
210
+ }
198
211
  (0, logger_1.log)(`Executing updateIntegration task for files cron job with period [${period}] for project ${projectId}.Files ${Object.keys(filesToProcess).length}`);
199
212
  if (!all) {
200
213
  if (Object.keys(filesToProcess).length === 0) {
@@ -245,6 +258,9 @@ function filesCron({ config, integration, period, }) {
245
258
  // eslint-disable-next-line @typescript-eslint/camelcase
246
259
  node_type: file.nodeType || file.node_type }, (file.type ? { type: file.type } : {}))));
247
260
  const intFiles = allIntFiles.filter((file) => 'type' in file);
261
+ if (intFiles.length < 0) {
262
+ continue;
263
+ }
248
264
  (0, logger_1.log)(`Executing updateCrowdin task for files cron job with period [${period}] for project ${projectId}. Files ${intFiles.length}`);
249
265
  const apiCredentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
250
266
  try {
@@ -215,10 +215,10 @@ function handle(config) {
215
215
  events['subscription_paid'] = '/subscription-paid';
216
216
  }
217
217
  return (_req, res) => {
218
- const manifest = Object.assign(Object.assign({ identifier: config.identifier, name: config.name, logo: (0, util_1.getLogoUrl)(), baseUrl: config.baseUrl, authentication: {
218
+ const manifest = Object.assign(Object.assign(Object.assign(Object.assign({ identifier: config.identifier, name: config.name, logo: (0, util_1.getLogoUrl)(), baseUrl: config.baseUrl, authentication: {
219
219
  type: config.authenticationType || types_1.AuthenticationType.APP,
220
220
  clientId: config.clientId,
221
- }, events, scopes: config.scopes ? config.scopes : [types_1.Scope.PROJECTS] }, (config.defaultPermissions && { default_permissions: config.defaultPermissions })), { modules });
221
+ } }, (config.agent && { agent: config.agent })), { events, scopes: config.scopes ? config.scopes : [types_1.Scope.PROJECTS] }), (config.defaultPermissions && { default_permissions: config.defaultPermissions })), { modules });
222
222
  res.send(manifest);
223
223
  };
224
224
  }