@crowdin/app-project-module 0.28.10 → 0.29.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.
Files changed (40) hide show
  1. package/out/handlers/crowdin-file-progress.js +1 -1
  2. package/out/handlers/crowdin-update.js +7 -2
  3. package/out/handlers/crowdin-webhook.js +4 -3
  4. package/out/handlers/integration-update.js +5 -0
  5. package/out/handlers/integration-webhook.js +2 -1
  6. package/out/handlers/main.js +1 -0
  7. package/out/handlers/manifest.js +4 -0
  8. package/out/handlers/settings-save.js +11 -0
  9. package/out/handlers/settings.d.ts +4 -0
  10. package/out/handlers/settings.js +22 -0
  11. package/out/handlers/sync-settings-save.d.ts +2 -2
  12. package/out/handlers/sync-settings-save.js +8 -11
  13. package/out/handlers/sync-settings.js +1 -1
  14. package/out/index.js +18 -1
  15. package/out/middlewares/crowdin-client.js +5 -0
  16. package/out/models/index.d.ts +64 -3
  17. package/out/models/index.js +14 -1
  18. package/out/static/js/dependent.js +1 -2
  19. package/out/storage/index.d.ts +8 -5
  20. package/out/storage/mysql.d.ts +4 -1
  21. package/out/storage/mysql.js +35 -1
  22. package/out/storage/postgre.d.ts +4 -1
  23. package/out/storage/postgre.js +35 -1
  24. package/out/storage/sqlite.d.ts +4 -1
  25. package/out/storage/sqlite.js +33 -1
  26. package/out/util/api/api.d.ts +6 -0
  27. package/out/util/api/api.js +452 -0
  28. package/out/util/api/base.d.ts +7 -0
  29. package/out/util/api/base.js +8 -0
  30. package/out/util/api/components.d.ts +227 -0
  31. package/out/util/api/components.js +228 -0
  32. package/out/util/cron.d.ts +2 -1
  33. package/out/util/cron.js +76 -9
  34. package/out/util/defaults.js +26 -3
  35. package/out/util/file-snapshot.d.ts +7 -0
  36. package/out/util/file-snapshot.js +144 -0
  37. package/out/util/webhooks.d.ts +4 -3
  38. package/out/util/webhooks.js +29 -5
  39. package/out/views/main.handlebars +140 -8
  40. package/package.json +5 -1
@@ -12,7 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  const util_1 = require("../util");
13
13
  function handle(config, integration) {
14
14
  return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
15
- const fileId = Number(req.params.fileId);
15
+ const fileId = Number(req.params.fileId || req.body.fileId);
16
16
  (0, util_1.log)(`Loading translation progress for file ${fileId}`, config.logger);
17
17
  if (integration.getFileProgress) {
18
18
  const progress = yield integration.getFileProgress(req.crowdinContext.jwtPayload.context.project_id, req.crowdinApiClient, fileId);
@@ -13,13 +13,18 @@ const util_1 = require("../util");
13
13
  const defaults_1 = require("../util/defaults");
14
14
  function handle(config, integration) {
15
15
  return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
16
- const projectId = req.crowdinContext.jwtPayload.context.project_id;
17
- const uploadTranslations = req.query.uploadTranslations === 'true';
16
+ var _a, _b;
17
+ const projectId = req.crowdinContext.jwtPayload.context.project_id || (req === null || req === void 0 ? void 0 : req.body.projectId);
18
+ const uploadTranslations = req.query.uploadTranslations === 'true' || ((_a = req.body) === null || _a === void 0 ? void 0 : _a.uploadTranslations);
18
19
  (0, util_1.log)(`Updating crowdin project ${projectId}`, config.logger);
19
20
  const rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, req.crowdinApiClient, projectId);
20
21
  if (rootFolder) {
21
22
  (0, util_1.log)(`Updating crowdin files under folder ${rootFolder.id}`, config.logger);
22
23
  }
24
+ // A request via API has a different structure
25
+ if (((_b = config.api) === null || _b === void 0 ? void 0 : _b.default) && req.body.files) {
26
+ req.body = req.body.files;
27
+ }
23
28
  const result = yield integration.updateCrowdin(projectId, req.crowdinApiClient, req.integrationCredentials, req.body, rootFolder, req.integrationSettings, uploadTranslations);
24
29
  let message;
25
30
  if ((0, util_1.isExtendedResultType)(result)) {
@@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
+ const models_1 = require("../models");
12
13
  const util_1 = require("../util");
13
14
  const webhooks_1 = require("../util/webhooks");
14
15
  function handle(config, integration) {
@@ -18,7 +19,7 @@ function handle(config, integration) {
18
19
  const webhookUrlParam = req.query[urlParam];
19
20
  let filesToSync;
20
21
  if (webhookUrlParam) {
21
- const { projectId, crowdinClient, preparedIntegrationCredentials, rootFolder, appSettings, syncSettings } = yield (0, webhooks_1.prepareWebhookData)(config, integration, webhookUrlParam, 'crowdin');
22
+ const { projectId, crowdinClient, preparedIntegrationCredentials, rootFolder, appSettings, syncSettings, newFiles, } = yield (0, webhooks_1.prepareWebhookData)(config, integration, webhookUrlParam, models_1.Provider.CROWDIN);
22
23
  if (!crowdinClient) {
23
24
  return res.status(403).send({ error: 'Access denied' });
24
25
  }
@@ -26,12 +27,12 @@ function handle(config, integration) {
26
27
  return res.status(200).send({ message: 'Sync is not configured' });
27
28
  }
28
29
  if ((_b = integration.webhooks) === null || _b === void 0 ? void 0 : _b.crowdinWebhookInterceptor) {
29
- filesToSync = yield integration.webhooks.crowdinWebhookInterceptor(projectId, crowdinClient.client, rootFolder, appSettings, syncSettings, req.body);
30
+ filesToSync = yield integration.webhooks.crowdinWebhookInterceptor(projectId, crowdinClient.client, rootFolder, appSettings, syncSettings, req.body, newFiles);
30
31
  }
31
32
  else {
32
33
  filesToSync = (0, webhooks_1.filterSyncFiles)(req.body.events, JSON.parse(syncSettings.files));
33
34
  }
34
- const result = yield integration.updateIntegration(projectId, crowdinClient.client, preparedIntegrationCredentials, filesToSync, rootFolder, appSettings);
35
+ const result = yield integration.updateIntegration(projectId, crowdinClient.client, preparedIntegrationCredentials, Object.assign(Object.assign({}, filesToSync), newFiles), rootFolder, appSettings);
35
36
  let message;
36
37
  if ((0, util_1.isExtendedResultType)(result)) {
37
38
  message = result.message;
@@ -13,11 +13,16 @@ const util_1 = require("../util");
13
13
  const defaults_1 = require("../util/defaults");
14
14
  function handle(config, integration) {
15
15
  return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
16
+ var _a;
16
17
  (0, util_1.log)('Updating integration data', config.logger);
17
18
  const rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, req.crowdinApiClient, req.crowdinContext.jwtPayload.context.project_id);
18
19
  if (rootFolder) {
19
20
  (0, util_1.log)(`Updating integration data for crowding root folder ${rootFolder.id}`, config.logger);
20
21
  }
22
+ // A request via API has a different structure
23
+ if (((_a = config.api) === null || _a === void 0 ? void 0 : _a.default) && req.body.files) {
24
+ req.body = req.body.files;
25
+ }
21
26
  const result = yield integration.updateIntegration(req.crowdinContext.jwtPayload.context.project_id, req.crowdinApiClient, req.integrationCredentials, req.body, rootFolder, req.integrationSettings);
22
27
  let message;
23
28
  if ((0, util_1.isExtendedResultType)(result)) {
@@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
+ const models_1 = require("../models");
12
13
  const util_1 = require("../util");
13
14
  const webhooks_1 = require("../util/webhooks");
14
15
  function handle(config, integration) {
@@ -17,7 +18,7 @@ function handle(config, integration) {
17
18
  const urlParam = (_a = integration.webhooks) === null || _a === void 0 ? void 0 : _a.urlParam;
18
19
  const webhookUrlParam = req.query[urlParam];
19
20
  if (((_b = integration.webhooks) === null || _b === void 0 ? void 0 : _b.integrationWebhookInterceptor) && webhookUrlParam) {
20
- const webhookData = yield (0, webhooks_1.prepareWebhookData)(config, integration, webhookUrlParam, 'integration');
21
+ const webhookData = yield (0, webhooks_1.prepareWebhookData)(config, integration, webhookUrlParam, models_1.Provider.INTEGRATION);
21
22
  if (!webhookData.crowdinClient) {
22
23
  return res.status(403).send({ error: 'Access denied' });
23
24
  }
@@ -44,6 +44,7 @@ function handle(config, integration) {
44
44
  (0, util_1.log)(`Adding configuration fields ${JSON.stringify(configurationFields, null, 2)}`, config.logger);
45
45
  }
46
46
  options.infoModal = integration.infoModal;
47
+ options.syncNewElements = integration.syncNewElements;
47
48
  options.withCronSync = integration.withCronSync;
48
49
  options.webhooks = integration.webhooks
49
50
  ? {
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const models_1 = require("../models");
4
4
  const connection_1 = require("../util/connection");
5
5
  const util_1 = require("../util");
6
+ const api_1 = require("../util/api/api");
6
7
  function handle(config) {
7
8
  const modules = {};
8
9
  if (config.projectIntegration) {
@@ -182,6 +183,9 @@ function handle(config) {
182
183
  },
183
184
  ];
184
185
  }
186
+ if (config.api) {
187
+ modules['api'] = (0, api_1.getApiManifest)(config, config.api);
188
+ }
185
189
  const events = {
186
190
  installed: '/installed',
187
191
  uninstall: '/uninstall',
@@ -9,9 +9,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
+ const models_1 = require("../models");
12
13
  const storage_1 = require("../storage");
13
14
  const util_1 = require("../util");
14
15
  const webhooks_1 = require("../util/webhooks");
16
+ const file_snapshot_1 = require("../util/file-snapshot");
17
+ const cron_1 = require("../util/cron");
15
18
  function handle(config, integration) {
16
19
  return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
17
20
  const appSettings = req.body.config;
@@ -20,6 +23,14 @@ function handle(config, integration) {
20
23
  if (integration.webhooks) {
21
24
  yield (0, webhooks_1.registerWebhooks)(config, integration, req.crowdinApiClient, req.crowdinContext, req.integrationCredentials, appSettings);
22
25
  }
26
+ if (appSettings['new-crowdin-files']) {
27
+ yield (0, cron_1.createOrUpdateSyncSettings)(config, req, {}, models_1.Provider.CROWDIN, true);
28
+ (0, file_snapshot_1.createOrUpdateFileSnapshot)(config, integration, req, models_1.Provider.CROWDIN);
29
+ }
30
+ if (appSettings['new-integration-files']) {
31
+ yield (0, cron_1.createOrUpdateSyncSettings)(config, req, [], models_1.Provider.INTEGRATION, true);
32
+ (0, file_snapshot_1.createOrUpdateFileSnapshot)(config, integration, req, models_1.Provider.INTEGRATION);
33
+ }
23
34
  res.status(204).end();
24
35
  }), config.onError);
25
36
  }
@@ -0,0 +1,4 @@
1
+ /// <reference types="qs" />
2
+ import { Response } from 'express';
3
+ import { Config } from '../models';
4
+ export default function handle(config: Config): (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,22 @@
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 util_1 = require("../util");
13
+ function handle(config) {
14
+ return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
15
+ let settings = {};
16
+ if (req.integrationSettings) {
17
+ settings = req.integrationSettings;
18
+ }
19
+ res.send(settings);
20
+ }), config.onError);
21
+ }
22
+ exports.default = handle;
@@ -1,4 +1,4 @@
1
1
  /// <reference types="qs" />
2
2
  import { Response } from 'express';
3
- import { Config } from '../models';
4
- export default function handle(config: Config): (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;
3
+ import { Config, IntegrationLogic } from '../models';
4
+ export default function handle(config: Config, integration: IntegrationLogic): (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;
@@ -9,19 +9,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- const storage_1 = require("../storage");
13
12
  const util_1 = require("../util");
14
- function handle(config) {
13
+ const file_snapshot_1 = require("../util/file-snapshot");
14
+ const cron_1 = require("../util/cron");
15
+ function handle(config, integration) {
15
16
  return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
16
- const { files, type, provider } = req.body;
17
- const existingSettings = yield (0, storage_1.getStorage)().getSyncSettings(req.crowdinContext.clientId, req.crowdinContext.crowdinId, type, provider);
18
- if (existingSettings) {
19
- (0, util_1.log)(`Updating sync settings for type ${type} and provider ${provider} ${JSON.stringify(files, null, 2)}`, config.logger);
20
- yield (0, storage_1.getStorage)().updateSyncSettings(JSON.stringify(files), req.crowdinContext.clientId, req.crowdinContext.crowdinId, type, provider);
21
- }
22
- else {
23
- (0, util_1.log)(`Saving sync settings for type ${type} and provider ${provider} ${JSON.stringify(files, null, 2)}`, config.logger);
24
- yield (0, storage_1.getStorage)().saveSyncSettings(JSON.stringify(files), req.crowdinContext.clientId, req.crowdinContext.crowdinId, type, provider);
17
+ var _a;
18
+ const { files, provider } = req.body;
19
+ yield (0, cron_1.createOrUpdateSyncSettings)(config, req, files, provider);
20
+ if ((_a = integration.syncNewElements) === null || _a === void 0 ? void 0 : _a[provider]) {
21
+ yield (0, file_snapshot_1.createOrUpdateFileSnapshot)(config, integration, req, provider);
25
22
  }
26
23
  res.status(204).end();
27
24
  }), config.onError);
@@ -14,7 +14,7 @@ const util_1 = require("../util");
14
14
  function handle(config) {
15
15
  return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
16
16
  let files = {};
17
- const provider = req.params.provider;
17
+ const provider = req.params.provider || req.body.provider;
18
18
  (0, util_1.log)(`Loading sync settings for provider ${provider}`, config.logger);
19
19
  const syncSettings = yield (0, storage_1.getStorage)().getSyncSettingsByProvider(req.crowdinContext.clientId, provider);
20
20
  if (syncSettings) {
package/out/index.js CHANGED
@@ -79,6 +79,7 @@ const connection_1 = require("./util/connection");
79
79
  const cron_1 = require("./util/cron");
80
80
  const defaults_1 = require("./util/defaults");
81
81
  const webhooks_1 = require("./util/webhooks");
82
+ const api_1 = require("./util/api/api");
82
83
  var models_2 = require("./models");
83
84
  Object.defineProperty(exports, "Scope", { enumerable: true, get: function () { return models_2.Scope; } });
84
85
  function addCrowdinEndpoints(app, clientConfig) {
@@ -142,7 +143,7 @@ function addCrowdinEndpoints(app, clientConfig) {
142
143
  app.post('/api/crowdin/update', json_response_1.default, (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, integrationLogic), (0, crowdin_update_1.default)(config, integrationLogic));
143
144
  app.post('/api/integration/update', json_response_1.default, (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, integrationLogic), (0, integration_update_1.default)(config, integrationLogic));
144
145
  app.get('/api/sync-settings/:provider', json_response_1.default, (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, integrationLogic), (0, sync_settings_1.default)(config));
145
- app.post('/api/sync-settings', json_response_1.default, (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, integrationLogic), (0, sync_settings_save_1.default)(config));
146
+ app.post('/api/sync-settings', json_response_1.default, (0, crowdin_client_1.default)(config), (0, integration_credentials_1.default)(config, integrationLogic), (0, sync_settings_save_1.default)(config, integrationLogic));
146
147
  if (integrationLogic.oauthLogin) {
147
148
  app.get((0, defaults_1.getOauthRoute)(integrationLogic), (0, oauth_login_1.default)(config, integrationLogic));
148
149
  app.post('/api/oauth-url', json_response_1.default, (0, crowdin_client_1.default)(config, false, false), (0, oauth_url_1.default)(config, integrationLogic));
@@ -228,6 +229,12 @@ function addCrowdinEndpoints(app, clientConfig) {
228
229
  if (((_f = config.contextMenu) === null || _f === void 0 ? void 0 : _f.uiPath) || ((_g = config.contextMenu) === null || _g === void 0 ? void 0 : _g.formSchema)) {
229
230
  app.use('/context', (0, ui_module_1.default)(config, config.contextMenu.allowUnauthorized), (0, render_ui_module_1.default)(config, config.contextMenu));
230
231
  }
232
+ if (config.api) {
233
+ if (config.api.default) {
234
+ (0, api_1.addDefaultApiEndpoints)(app, config);
235
+ }
236
+ (0, api_1.addSwagerApiDocumentation)(app, config);
237
+ }
231
238
  if (Object.keys(config).some((moduleKey) => {
232
239
  const moduleConfig = config[moduleKey];
233
240
  return typeof moduleConfig === 'object' && moduleConfig.hasOwnProperty('formSchema');
@@ -254,6 +261,16 @@ function addCrowdinEndpoints(app, clientConfig) {
254
261
  }
255
262
  }),
256
263
  establishCrowdinConnection: (jwtToken) => (0, crowdin_client_1.prepareCrowdinRequest)(jwtToken, config),
264
+ encryptCrowdinConnection: (data) => (0, util_1.encryptData)(config, JSON.stringify(data)),
265
+ dencryptCrowdinConnection: (hash) => __awaiter(this, void 0, void 0, function* () {
266
+ const { crowdinId, extra } = JSON.parse((0, util_1.decryptData)(config, hash));
267
+ const creds = yield storage.getStorage().getCrowdinCredentials(crowdinId);
268
+ if (!creds) {
269
+ throw new Error('Failed to find Crowdin credentials');
270
+ }
271
+ const { client } = yield (0, connection_1.prepareCrowdinClient)(config, creds);
272
+ return { client, extra };
273
+ }),
257
274
  };
258
275
  }
259
276
  exports.addCrowdinEndpoints = addCrowdinEndpoints;
@@ -14,6 +14,7 @@ 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
16
  const connection_1 = require("../util/connection");
17
+ const api_1 = require("../util/api/api");
17
18
  function prepareCrowdinRequest(jwtToken, config, optional = false, checkSubscriptionExpiration = true) {
18
19
  return __awaiter(this, void 0, void 0, function* () {
19
20
  (0, util_1.log)('Validating jwt token from incoming request', config.logger);
@@ -46,12 +47,16 @@ function prepareCrowdinRequest(jwtToken, config, optional = false, checkSubscrip
46
47
  exports.prepareCrowdinRequest = prepareCrowdinRequest;
47
48
  function handle(config, optional = false, checkSubscriptionExpiration = true) {
48
49
  return (0, util_1.runAsyncWrapper)((req, res, next) => __awaiter(this, void 0, void 0, function* () {
50
+ var _a;
49
51
  const jwtToken = getToken(req);
50
52
  if (!jwtToken) {
51
53
  return res.status(403).send({ error: 'Access denied' });
52
54
  }
53
55
  try {
54
56
  const data = yield prepareCrowdinRequest(jwtToken, config, optional, checkSubscriptionExpiration);
57
+ if ((_a = config.api) === null || _a === void 0 ? void 0 : _a.default) {
58
+ data.context = (0, api_1.updateCrowdinContext)(req, data.context);
59
+ }
55
60
  req.crowdinContext = data.context;
56
61
  if (data.client) {
57
62
  req.crowdinApiClient = data.client;
@@ -104,6 +104,10 @@ export interface ClientConfig extends ImagePath {
104
104
  * reports module
105
105
  */
106
106
  projectReports?: UiModule & ImagePath;
107
+ /**
108
+ * API module
109
+ */
110
+ api?: ApiModule;
107
111
  /**
108
112
  * context menu module
109
113
  */
@@ -235,6 +239,13 @@ export interface IntegrationLogic {
235
239
  * background jobs that will be executed for each crowdin project and user
236
240
  */
237
241
  cronJobs?: CronJob[];
242
+ /**
243
+ * Enable new file sync when syncing via cron or webhook
244
+ */
245
+ syncNewElements?: {
246
+ crowdin: boolean;
247
+ integration: boolean;
248
+ };
238
249
  withCronSync?: {
239
250
  crowdin: boolean;
240
251
  integration: boolean;
@@ -745,13 +756,32 @@ export interface CrowdinAppUtilities {
745
756
  context: CrowdinContextInfo;
746
757
  client?: Crowdin;
747
758
  }>;
759
+ encryptCrowdinConnection: (data: {
760
+ crowdinId: string;
761
+ extra: Record<string, any>;
762
+ }) => string;
763
+ dencryptCrowdinConnection: (hash: string) => Promise<{
764
+ client: Crowdin;
765
+ extra: Record<string, any>;
766
+ }>;
767
+ }
768
+ export declare enum Provider {
769
+ CROWDIN = "crowdin",
770
+ INTEGRATION = "integration"
748
771
  }
749
772
  export interface IntegrationSyncSettings {
750
773
  id: number;
751
774
  files?: any;
752
775
  integrationId: string;
753
776
  crowdinId: string;
754
- provider: 'integration' | 'crowdin';
777
+ provider: Provider;
778
+ }
779
+ export interface IntegrationFilesSnapshot {
780
+ id: number;
781
+ files?: any;
782
+ integrationId: string;
783
+ crowdinId: string;
784
+ provider: Provider;
755
785
  }
756
786
  export interface ImagePath {
757
787
  /**
@@ -759,6 +789,26 @@ export interface ImagePath {
759
789
  */
760
790
  imagePath?: string;
761
791
  }
792
+ export declare enum RequestMethods {
793
+ GET = "GET",
794
+ POST = "POST",
795
+ PUT = "PUT",
796
+ PATCH = "PATCH",
797
+ DELETE = "DELETE"
798
+ }
799
+ export interface ApiEndpoints {
800
+ key: string;
801
+ name: string;
802
+ url: string;
803
+ method: RequestMethods;
804
+ description?: string;
805
+ documentationUrl?: string;
806
+ }
807
+ export interface ApiModule {
808
+ default?: boolean;
809
+ endpoints?: ApiEndpoints[];
810
+ docFile?: string;
811
+ }
762
812
  export interface Logger {
763
813
  enabled: boolean;
764
814
  log?: (message: string) => void;
@@ -777,8 +827,8 @@ export interface Webhooks {
777
827
  urlParam?: string;
778
828
  crowdinWebhooks?: (client: Crowdin, projectId: number, available: boolean, config?: any) => Promise<void>;
779
829
  integrationWebhooks?: (apiCredentials: any, urlParam: string, available: boolean, config?: any, syncSettings?: any) => Promise<void>;
780
- crowdinWebhookInterceptor?: (projectId: number, client: Crowdin, appRootFolder?: SourceFilesModel.Directory, config?: any, syncSettings?: any, webhookRequest?: any) => Promise<UpdateIntegrationRequest>;
781
- integrationWebhookInterceptor?: (projectId: number, client: Crowdin, apiCredentials: any, appRootFolder?: SourceFilesModel.Directory, config?: any, syncSettings?: any, webhookRequest?: any) => Promise<IntegrationFile[]>;
830
+ crowdinWebhookInterceptor?: (projectId: number, client: Crowdin, appRootFolder?: SourceFilesModel.Directory, config?: any, syncSettings?: any, webhookRequest?: any, newFiles?: TreeItem[] | UpdateIntegrationRequest) => Promise<UpdateIntegrationRequest>;
831
+ integrationWebhookInterceptor?: (projectId: number, client: Crowdin, apiCredentials: any, appRootFolder?: SourceFilesModel.Directory, config?: any, syncSettings?: any, webhookRequest?: any, newFiles?: TreeItem[] | UpdateIntegrationRequest) => Promise<IntegrationFile[]>;
782
832
  queueUrl: string;
783
833
  }
784
834
  export declare enum SyncCondition {
@@ -802,4 +852,15 @@ export type WebhookUrlParams = {
802
852
  crowdinId: string;
803
853
  clientId: string;
804
854
  };
855
+ export interface GetAllNewFilesArgs {
856
+ config: Config;
857
+ integration: IntegrationLogic;
858
+ crowdinApiClient: Crowdin;
859
+ crowdinId: string;
860
+ integrationCredentials: any;
861
+ integrationId: string;
862
+ projectId: number;
863
+ integrationSettings: any;
864
+ syncSettings: IntegrationSyncSettings;
865
+ }
805
866
  export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SyncType = exports.SyncCondition = exports.ContextOptionsTypes = exports.ContextOptionsLocations = exports.EditorPanelsMode = exports.ProcessFileJobType = exports.SubscriptionInfoType = exports.AccountType = exports.Scope = exports.AuthenticationType = void 0;
3
+ exports.SyncType = exports.SyncCondition = exports.RequestMethods = exports.Provider = exports.ContextOptionsTypes = exports.ContextOptionsLocations = exports.EditorPanelsMode = exports.ProcessFileJobType = exports.SubscriptionInfoType = exports.AccountType = exports.Scope = exports.AuthenticationType = void 0;
4
4
  var AuthenticationType;
5
5
  (function (AuthenticationType) {
6
6
  AuthenticationType["CODE"] = "authorization_code";
@@ -66,6 +66,19 @@ var ContextOptionsTypes;
66
66
  ContextOptionsTypes["NEW_TAB"] = "new_tab";
67
67
  ContextOptionsTypes["REDIRECT"] = "redirect";
68
68
  })(ContextOptionsTypes = exports.ContextOptionsTypes || (exports.ContextOptionsTypes = {}));
69
+ var Provider;
70
+ (function (Provider) {
71
+ Provider["CROWDIN"] = "crowdin";
72
+ Provider["INTEGRATION"] = "integration";
73
+ })(Provider = exports.Provider || (exports.Provider = {}));
74
+ var RequestMethods;
75
+ (function (RequestMethods) {
76
+ RequestMethods["GET"] = "GET";
77
+ RequestMethods["POST"] = "POST";
78
+ RequestMethods["PUT"] = "PUT";
79
+ RequestMethods["PATCH"] = "PATCH";
80
+ RequestMethods["DELETE"] = "DELETE";
81
+ })(RequestMethods = exports.RequestMethods || (exports.RequestMethods = {}));
69
82
  var SyncCondition;
70
83
  (function (SyncCondition) {
71
84
  SyncCondition[SyncCondition["ALL"] = 0] = "ALL";
@@ -3,8 +3,7 @@ document.addEventListener('DOMContentLoaded', () => {
3
3
 
4
4
  if (fields.length > 0) {
5
5
  fields.forEach((field) => {
6
- const conditionString = field.dataset['dependency'].replace(/'/g, '"');
7
- const conditions = JSON.parse(conditionString);
6
+ const conditions = JSON.parse( field.dataset['dependency']);
8
7
  action(field, conditions);
9
8
 
10
9
  const success = check(conditions);
@@ -1,4 +1,4 @@
1
- import { Config, CrowdinCredentials, IntegrationCredentials, IntegrationSyncSettings } from '../models';
1
+ import { Config, CrowdinCredentials, IntegrationCredentials, IntegrationFilesSnapshot, IntegrationSyncSettings, Provider } from '../models';
2
2
  export interface Storage {
3
3
  migrate(): Promise<void>;
4
4
  saveCrowdinCredentials(credentials: CrowdinCredentials): Promise<void>;
@@ -17,11 +17,14 @@ export interface Storage {
17
17
  updateMetadata(id: string, metadata: any): Promise<void>;
18
18
  getMetadata(id: string): Promise<any | undefined>;
19
19
  deleteMetadata(id: string): Promise<void>;
20
- getSyncSettingsByProvider(integrationId: string, provider: string): Promise<IntegrationSyncSettings | undefined>;
20
+ getSyncSettingsByProvider(integrationId: string, provider: Provider): Promise<IntegrationSyncSettings | undefined>;
21
21
  getAllSyncSettingsByType(type: string): Promise<IntegrationSyncSettings[]>;
22
- saveSyncSettings(files: any, integrationId: string, crowdinId: string, type: string, provider: string): Promise<void>;
23
- updateSyncSettings(files: any, integrationId: string, crowdinId: string, type: string, provider: string): Promise<void>;
24
- getSyncSettings(integrationId: string, crowdinId: string, type: string, provider: string): Promise<IntegrationSyncSettings | undefined>;
22
+ saveSyncSettings(files: any, integrationId: string, crowdinId: string, type: string, provider: Provider): Promise<void>;
23
+ updateSyncSettings(files: any, integrationId: string, crowdinId: string, type: string, provider: Provider): Promise<void>;
24
+ getSyncSettings(integrationId: string, crowdinId: string, type: string, provider: Provider): Promise<IntegrationSyncSettings | undefined>;
25
+ saveFilesSnapshot(files: any, integrationId: string, crowdinId: string, provider: Provider): Promise<void>;
26
+ updateFilesSnapshot(files: any, integrationId: string, crowdinId: string, provider: Provider): Promise<void>;
27
+ getFilesSnapshot(integrationId: string, crowdinId: string, provider: Provider): Promise<IntegrationFilesSnapshot | undefined>;
25
28
  }
26
29
  export declare function initialize(config: Config): Promise<void>;
27
30
  export declare function getStorage(): Storage;
@@ -1,5 +1,5 @@
1
1
  import { Storage } from '.';
2
- import { CrowdinCredentials, IntegrationCredentials, IntegrationSyncSettings } from '../models';
2
+ import { CrowdinCredentials, IntegrationCredentials, IntegrationFilesSnapshot, IntegrationSyncSettings } from '../models';
3
3
  export interface MySQLStorageConfig {
4
4
  uri?: string;
5
5
  host?: string;
@@ -39,4 +39,7 @@ export declare class MySQLStorage implements Storage {
39
39
  saveSyncSettings(files: any, integrationId: string, crowdinId: string, type: string, provider: string): Promise<void>;
40
40
  updateSyncSettings(files: any, integrationId: string, crowdinId: string, type: string, provider: string): Promise<void>;
41
41
  getSyncSettings(integrationId: string, crowdinId: string, type: string, provider: string): Promise<IntegrationSyncSettings | undefined>;
42
+ saveFilesSnapshot(files: any, integrationId: string, crowdinId: string, provider: string): Promise<void>;
43
+ updateFilesSnapshot(files: any, integrationId: string, crowdinId: string, provider: string): Promise<void>;
44
+ getFilesSnapshot(integrationId: string, crowdinId: string, provider: string): Promise<IntegrationFilesSnapshot | undefined>;
42
45
  }
@@ -103,6 +103,16 @@ class MySQLStorage {
103
103
  data text
104
104
  )
105
105
  `);
106
+ yield connection.execute(`
107
+ create table if not exists files_snapshot
108
+ (
109
+ id int auto_increment primary key,
110
+ files text,
111
+ integration_id varchar(255) not null,
112
+ crowdin_id varchar(255) not null,
113
+ provider varchar(255) not null
114
+ )
115
+ `);
106
116
  });
107
117
  }
108
118
  saveCrowdinCredentials(credentials) {
@@ -163,6 +173,7 @@ class MySQLStorage {
163
173
  yield connection.execute('DELETE FROM crowdin_credentials where id = ?', [id]);
164
174
  yield connection.execute('DELETE FROM integration_credentials where crowdin_id = ?', [id]);
165
175
  yield connection.execute('DELETE FROM sync_settings WHERE crowdin_id = ?', [id]);
176
+ yield connection.execute('DELETE FROM files_snapshot WHERE crowdin_id = ?', [id]);
166
177
  }));
167
178
  });
168
179
  }
@@ -212,6 +223,7 @@ class MySQLStorage {
212
223
  yield this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
213
224
  yield connection.execute('DELETE FROM integration_credentials where id = ?', [id]);
214
225
  yield connection.execute('DELETE FROM sync_settings where integration_id = ?', [id]);
226
+ yield connection.execute('DELETE FROM files_snapshot where integration_id = ?', [id]);
215
227
  }));
216
228
  });
217
229
  }
@@ -221,6 +233,7 @@ class MySQLStorage {
221
233
  yield this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
222
234
  yield connection.execute('DELETE FROM integration_credentials where crowdin_id = ?', [crowdinId]);
223
235
  yield connection.execute('DELETE FROM sync_settings where crowdin_id = ?', [crowdinId]);
236
+ yield connection.execute('DELETE FROM files_snapshot where crowdin_id = ?', [crowdinId]);
224
237
  }));
225
238
  });
226
239
  }
@@ -287,7 +300,28 @@ class MySQLStorage {
287
300
  return __awaiter(this, void 0, void 0, function* () {
288
301
  yield this.dbPromise;
289
302
  return this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
290
- const [rows] = yield connection.execute('SELECT id, files, integration_id as "integrationId", crowdin_id as "crowdinId", type FROM sync_settings WHERE integration_id = ? AND crowdin_id = ? AND type = ? AND provider = ?', [integrationId, crowdinId, type, provider]);
303
+ const [rows] = yield connection.execute('SELECT id, files, integration_id as "integrationId", crowdin_id as "crowdinId", type, provider FROM sync_settings WHERE integration_id = ? AND crowdin_id = ? AND type = ? AND provider = ?', [integrationId, crowdinId, type, provider]);
304
+ return (rows || [])[0];
305
+ }));
306
+ });
307
+ }
308
+ saveFilesSnapshot(files, integrationId, crowdinId, provider) {
309
+ return __awaiter(this, void 0, void 0, function* () {
310
+ yield this.dbPromise;
311
+ yield this.executeQuery((connection) => connection.execute('INSERT INTO files_snapshot(files, integration_id, crowdin_id, provider) VALUES (?, ?, ?, ?)', [files, integrationId, crowdinId, provider]));
312
+ });
313
+ }
314
+ updateFilesSnapshot(files, integrationId, crowdinId, provider) {
315
+ return __awaiter(this, void 0, void 0, function* () {
316
+ yield this.dbPromise;
317
+ yield this.executeQuery((connection) => connection.execute('UPDATE files_snapshot SET files = ? WHERE integration_id = ? AND crowdin_id = ? AND provider = ?', [files, integrationId, crowdinId, provider]));
318
+ });
319
+ }
320
+ getFilesSnapshot(integrationId, crowdinId, provider) {
321
+ return __awaiter(this, void 0, void 0, function* () {
322
+ yield this.dbPromise;
323
+ return this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
324
+ const [rows] = yield connection.execute('SELECT id, files, integration_id as "integrationId", crowdin_id as "crowdinId" FROM files_snapshot WHERE integration_id = ? AND crowdin_id = ? AND provider = ?', [integrationId, crowdinId, provider]);
291
325
  return (rows || [])[0];
292
326
  }));
293
327
  });
@@ -1,6 +1,6 @@
1
1
  import { Client } from 'pg';
2
2
  import { Storage } from '.';
3
- import { CrowdinCredentials, IntegrationCredentials, IntegrationSyncSettings } from '../models';
3
+ import { CrowdinCredentials, IntegrationCredentials, IntegrationFilesSnapshot, IntegrationSyncSettings } from '../models';
4
4
  export interface PostgreStorageConfig {
5
5
  host?: string;
6
6
  connectionString?: string;
@@ -43,4 +43,7 @@ export declare class PostgreStorage implements Storage {
43
43
  saveSyncSettings(files: any, integrationId: string, crowdinId: string, type: string, provider: string): Promise<void>;
44
44
  updateSyncSettings(files: any, integrationId: string, crowdinId: string, type: string, provider: string): Promise<void>;
45
45
  getSyncSettings(integrationId: string, crowdinId: string, type: string, provider: string): Promise<IntegrationSyncSettings | undefined>;
46
+ saveFilesSnapshot(files: any, integrationId: string, crowdinId: string, provider: string): Promise<void>;
47
+ updateFilesSnapshot(files: any, integrationId: string, crowdinId: string, provider: string): Promise<void>;
48
+ getFilesSnapshot(integrationId: string, crowdinId: string, provider: string): Promise<IntegrationFilesSnapshot | undefined>;
46
49
  }