@crowdin/app-project-module 0.30.3 → 0.32.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 (82) hide show
  1. package/out/handlers/custom-mt/translate.d.ts +2 -2
  2. package/out/handlers/custom-mt/translate.js +8 -6
  3. package/out/handlers/file-processing/custom-file-format.d.ts +2 -2
  4. package/out/handlers/file-processing/custom-file-format.js +4 -4
  5. package/out/handlers/file-processing/file-download.d.ts +1 -1
  6. package/out/handlers/file-processing/file-download.js +3 -2
  7. package/out/handlers/file-processing/pre-post-process.d.ts +2 -2
  8. package/out/handlers/file-processing/pre-post-process.js +11 -3
  9. package/out/handlers/form-data-display.d.ts +1 -1
  10. package/out/handlers/form-data-save.d.ts +1 -1
  11. package/out/handlers/install.d.ts +1 -1
  12. package/out/handlers/install.js +5 -3
  13. package/out/handlers/integration/crowdin-file-progress.d.ts +2 -2
  14. package/out/handlers/integration/crowdin-file-progress.js +4 -4
  15. package/out/handlers/integration/crowdin-files.d.ts +1 -1
  16. package/out/handlers/integration/crowdin-files.js +4 -4
  17. package/out/handlers/integration/crowdin-project.d.ts +2 -2
  18. package/out/handlers/integration/crowdin-project.js +4 -4
  19. package/out/handlers/integration/crowdin-update.d.ts +1 -1
  20. package/out/handlers/integration/crowdin-update.js +4 -4
  21. package/out/handlers/integration/crowdin-webhook.d.ts +1 -1
  22. package/out/handlers/integration/crowdin-webhook.js +1 -1
  23. package/out/handlers/integration/integration-data.d.ts +2 -2
  24. package/out/handlers/integration/integration-data.js +4 -4
  25. package/out/handlers/integration/integration-login.d.ts +2 -2
  26. package/out/handlers/integration/integration-login.js +4 -4
  27. package/out/handlers/integration/integration-logout.d.ts +1 -1
  28. package/out/handlers/integration/integration-logout.js +4 -4
  29. package/out/handlers/integration/integration-update.d.ts +1 -1
  30. package/out/handlers/integration/integration-update.js +3 -3
  31. package/out/handlers/integration/integration-webhook.d.ts +1 -1
  32. package/out/handlers/integration/integration-webhook.js +1 -1
  33. package/out/handlers/integration/main.d.ts +1 -1
  34. package/out/handlers/integration/main.js +11 -3
  35. package/out/handlers/integration/oauth-login.d.ts +1 -1
  36. package/out/handlers/integration/oauth-login.js +6 -10
  37. package/out/handlers/integration/oauth-url.d.ts +2 -2
  38. package/out/handlers/integration/oauth-url.js +3 -3
  39. package/out/handlers/integration/settings-save.d.ts +1 -1
  40. package/out/handlers/integration/settings-save.js +2 -2
  41. package/out/handlers/integration/settings.d.ts +1 -2
  42. package/out/handlers/integration/settings.js +2 -2
  43. package/out/handlers/integration/sync-settings-save.d.ts +1 -1
  44. package/out/handlers/integration/sync-settings-save.js +1 -1
  45. package/out/handlers/integration/sync-settings.d.ts +1 -2
  46. package/out/handlers/integration/sync-settings.js +4 -4
  47. package/out/handlers/integration/synced-files.d.ts +1 -2
  48. package/out/handlers/integration/synced-files.js +4 -4
  49. package/out/handlers/manifest.js +9 -18
  50. package/out/handlers/subscription-paid.d.ts +1 -2
  51. package/out/handlers/subscription-paid.js +4 -3
  52. package/out/handlers/uninstall.d.ts +1 -1
  53. package/out/handlers/uninstall.js +7 -6
  54. package/out/index.d.ts +1 -1
  55. package/out/index.js +37 -32
  56. package/out/middlewares/crowdin-client.d.ts +4 -1
  57. package/out/middlewares/crowdin-client.js +26 -16
  58. package/out/middlewares/integration-credentials.d.ts +1 -1
  59. package/out/middlewares/integration-credentials.js +2 -2
  60. package/out/middlewares/render-ui-module.d.ts +2 -2
  61. package/out/middlewares/render-ui-module.js +2 -2
  62. package/out/middlewares/ui-module.d.ts +1 -1
  63. package/out/middlewares/ui-module.js +17 -6
  64. package/out/models/index.d.ts +27 -2
  65. package/out/models/index.js +13 -1
  66. package/out/storage/index.js +4 -4
  67. package/out/util/api/api.js +4 -4
  68. package/out/util/connection.d.ts +11 -2
  69. package/out/util/connection.js +17 -16
  70. package/out/util/cron.js +43 -25
  71. package/out/util/defaults.js +2 -1
  72. package/out/util/file-snapshot.d.ts +1 -1
  73. package/out/util/file-snapshot.js +4 -4
  74. package/out/util/index.d.ts +3 -6
  75. package/out/util/index.js +12 -42
  76. package/out/util/logger.d.ts +14 -0
  77. package/out/util/logger.js +71 -0
  78. package/out/util/synced-files.js +4 -4
  79. package/out/util/webhooks.d.ts +1 -1
  80. package/out/util/webhooks.js +6 -6
  81. package/out/views/partials/head.handlebars +28 -1
  82. package/package.json +1 -1
@@ -11,9 +11,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.createOrUpdateFileSnapshot = exports.getIntegrationSnapshot = exports.getCrowdinSnapshot = exports.getAllNewFiles = exports.getFileDiff = void 0;
13
13
  const models_1 = require("../models");
14
- const index_1 = require("./index");
15
- const defaults_1 = require("./defaults");
16
14
  const storage_1 = require("../storage");
15
+ const defaults_1 = require("./defaults");
16
+ const index_1 = require("./index");
17
17
  function getFileDiff(currentFiles, savedFiles) {
18
18
  return currentFiles.filter((x) => !savedFiles.some((x2) => x2.id === x.id));
19
19
  }
@@ -138,11 +138,11 @@ function createOrUpdateFileSnapshot(config, integration, req, provider) {
138
138
  files = yield getIntegrationSnapshot(integration, req.integrationCredentials, req.integrationSettings);
139
139
  }
140
140
  if (existingSnapshot) {
141
- (0, index_1.log)(`Updating file snapshot for provider ${provider} ${JSON.stringify(files, null, 2)}`, config.logger);
141
+ req.logInfo(`Updating file snapshot for provider ${provider} ${JSON.stringify(files, null, 2)}`);
142
142
  yield (0, storage_1.getStorage)().updateFilesSnapshot(JSON.stringify(files), req.crowdinContext.clientId, req.crowdinContext.crowdinId, provider);
143
143
  }
144
144
  else {
145
- (0, index_1.log)(`Saving file snapshot for provider ${provider} ${JSON.stringify(files, null, 2)}`, config.logger);
145
+ req.logInfo(`Saving file snapshot for provider ${provider} ${JSON.stringify(files, null, 2)}`);
146
146
  yield (0, storage_1.getStorage)().saveFilesSnapshot(JSON.stringify(files), req.crowdinContext.clientId, req.crowdinContext.crowdinId, provider);
147
147
  }
148
148
  });
@@ -1,15 +1,12 @@
1
1
  import { Request, Response } from 'express';
2
- import { Config, ExtendedResult, Logger, ImagePath } from '../models';
2
+ import { Config, CrowdinClientRequest, ExtendedResult, ImagePath } from '../models';
3
3
  export declare class CodeError extends Error {
4
4
  code: number | undefined;
5
5
  constructor(message: string, code?: number);
6
6
  }
7
- export declare function log(message: string, logger?: Logger): void;
8
- export declare function getMessage(err: any): any;
9
- export declare function runAsyncWrapper(callback: Function, onError?: (e: any) => void): (req: Request, res: Response, next: Function) => void;
10
- export declare function logError(e: any, onError?: (e: any) => void): void;
7
+ export declare function runAsyncWrapper(callback: Function): (req: Request | CrowdinClientRequest, res: Response, next: Function) => void;
11
8
  export declare function encryptData(config: Config, data: string): string;
12
9
  export declare function decryptData(config: Config, data: string): string;
13
10
  export declare function executeWithRetry<T>(func: () => Promise<T>, numOfRetries?: number): Promise<T>;
14
11
  export declare function isExtendedResultType<T>(data?: T | ExtendedResult<T>): data is ExtendedResult<T>;
15
- export declare function getLogoUrl(config: Config, moduleConfig?: ImagePath, modulePath?: string): string;
12
+ export declare function getLogoUrl(moduleConfig?: ImagePath, modulePath?: string): string;
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.logError = exports.runAsyncWrapper = exports.getMessage = exports.log = exports.CodeError = void 0;
35
+ exports.getLogoUrl = exports.isExtendedResultType = 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 logger_1 = require("./logger");
38
39
  class CodeError extends Error {
39
40
  constructor(message, code) {
40
41
  super(message);
@@ -42,39 +43,12 @@ class CodeError extends Error {
42
43
  }
43
44
  }
44
45
  exports.CodeError = CodeError;
45
- function log(message, logger) {
46
- if (logger === null || logger === void 0 ? void 0 : logger.enabled) {
47
- if (logger.log) {
48
- logger.log(message);
49
- }
50
- else {
51
- const timestamp = new Date().toISOString();
52
- // eslint-disable-next-line no-console
53
- console.log(`[${timestamp}] ${message}`);
54
- }
55
- }
56
- }
57
- exports.log = log;
58
46
  function isCrowdinClientRequest(req) {
59
47
  return req.crowdinContext;
60
48
  }
61
- function getMessage(err) {
62
- let message;
63
- if (typeof err === 'string') {
64
- message = err;
65
- }
66
- else if (err.message) {
67
- message = err.message;
68
- }
69
- else {
70
- message = JSON.stringify(err);
71
- }
72
- return message;
73
- }
74
- exports.getMessage = getMessage;
75
49
  function handleError(err, req, res) {
76
50
  return __awaiter(this, void 0, void 0, function* () {
77
- const code = err.code ? err.code : 500;
51
+ const code = err.code && typeof err.code === 'number' ? err.code : 500;
78
52
  if (code === 401 && isCrowdinClientRequest(req)) {
79
53
  yield (0, storage_1.getStorage)().deleteIntegrationCredentials(req.crowdinContext.clientId);
80
54
  }
@@ -82,27 +56,23 @@ function handleError(err, req, res) {
82
56
  res.redirect('/');
83
57
  return;
84
58
  }
85
- res.status(code).send({ message: getMessage(err), code });
59
+ res.status(code).send({ message: (0, logger_1.getErrorMessage)(err), code });
86
60
  });
87
61
  }
88
- function runAsyncWrapper(callback, onError) {
62
+ function runAsyncWrapper(callback) {
89
63
  return (req, res, next) => {
90
64
  callback(req, res, next).catch((e) => {
91
- logError(e, onError);
65
+ if (isCrowdinClientRequest(req)) {
66
+ req.logError(e);
67
+ }
68
+ else {
69
+ (0, logger_1.logError)(e);
70
+ }
92
71
  handleError(e, req, res);
93
72
  });
94
73
  };
95
74
  }
96
75
  exports.runAsyncWrapper = runAsyncWrapper;
97
- function logError(e, onError) {
98
- if (onError) {
99
- onError(e);
100
- }
101
- else {
102
- console.error(e);
103
- }
104
- }
105
- exports.logError = logError;
106
76
  function encryptData(config, data) {
107
77
  return crypto.AES.encrypt(data, config.cryptoSecret || config.clientSecret).toString();
108
78
  }
@@ -133,7 +103,7 @@ function isExtendedResultType(data) {
133
103
  return !!dataTyped && !Array.isArray(dataTyped);
134
104
  }
135
105
  exports.isExtendedResultType = isExtendedResultType;
136
- function getLogoUrl(config, moduleConfig, modulePath) {
106
+ function getLogoUrl(moduleConfig, modulePath) {
137
107
  if (!moduleConfig && !modulePath) {
138
108
  return '/logo.png';
139
109
  }
@@ -0,0 +1,14 @@
1
+ import { Config } from '../models';
2
+ export type LogFunction = (message: string) => void;
3
+ export type LogErrorFunction = (error: any) => void;
4
+ export type LogContext = {
5
+ userId: string;
6
+ orgId: string;
7
+ projectId: number;
8
+ };
9
+ export declare function initialize(config: Config): void;
10
+ export declare function withContext(context: LogContext): LogFunction;
11
+ export declare function withContextError(context: LogContext): LogFunction;
12
+ export declare function log(message: string, context?: LogContext): void;
13
+ export declare function logError(e: any, context?: LogContext): void;
14
+ export declare function getErrorMessage(err: any): any;
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getErrorMessage = exports.logError = exports.log = exports.withContextError = exports.withContext = exports.initialize = void 0;
4
+ let logConfig;
5
+ let onError;
6
+ function initialize(config) {
7
+ logConfig = config.logger;
8
+ onError = config.onError;
9
+ }
10
+ exports.initialize = initialize;
11
+ function withContext(context) {
12
+ return (message) => log(message, context);
13
+ }
14
+ exports.withContext = withContext;
15
+ function withContextError(context) {
16
+ return (e) => logError(e, context);
17
+ }
18
+ exports.withContextError = withContextError;
19
+ function log(message, context) {
20
+ if (logConfig === null || logConfig === void 0 ? void 0 : logConfig.enabled) {
21
+ if (logConfig.log) {
22
+ logConfig.log(message);
23
+ }
24
+ else {
25
+ let prefix = `[${new Date().toISOString()}]`;
26
+ if (context) {
27
+ prefix += ` Context [${JSON.stringify(context)}]`;
28
+ }
29
+ // eslint-disable-next-line no-console
30
+ console.log(`${prefix} ${message}`);
31
+ }
32
+ }
33
+ }
34
+ exports.log = log;
35
+ function logError(e, context) {
36
+ if (onError) {
37
+ onError(e, context);
38
+ }
39
+ else {
40
+ let message = `[${new Date().toISOString()}] Error.`;
41
+ if (context) {
42
+ message += ` Context ${JSON.stringify(context)}`;
43
+ }
44
+ if (isAxiosError(e)) {
45
+ const request = e.config ? { url: e.config.url, method: e.config.method, data: e.config.data } : {};
46
+ const response = e.response ? { data: e.response.data, status: e.response.status } : {};
47
+ console.error(`${message} Axios error. Request ${JSON.stringify(request)}. Response ${JSON.stringify(response)}. Message ${e.message}`);
48
+ }
49
+ else {
50
+ console.error(message, e);
51
+ }
52
+ }
53
+ }
54
+ exports.logError = logError;
55
+ function isAxiosError(e) {
56
+ return !!e.isAxiosError;
57
+ }
58
+ function getErrorMessage(err) {
59
+ let message;
60
+ if (typeof err === 'string') {
61
+ message = err;
62
+ }
63
+ else if (err.message) {
64
+ message = err.message;
65
+ }
66
+ else {
67
+ message = 'Internal Server Error';
68
+ }
69
+ return message;
70
+ }
71
+ exports.getErrorMessage = getErrorMessage;
@@ -11,19 +11,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.createOrUpdateSyncedFiles = void 0;
13
13
  const storage_1 = require("../storage");
14
- const index_1 = require("./index");
14
+ const logger_1 = require("./logger");
15
15
  function createOrUpdateSyncedFiles(args) {
16
16
  return __awaiter(this, void 0, void 0, function* () {
17
- const { config, req } = args;
17
+ const { req } = args;
18
18
  let fileIds = args.fileIds;
19
19
  const existingFiles = yield (0, storage_1.getStorage)().getSyncedFiles(req.crowdinContext.clientId, req.crowdinContext.crowdinId);
20
20
  if (existingFiles) {
21
21
  fileIds = [...new Set([...JSON.parse(existingFiles.fileIds), ...fileIds])];
22
- (0, index_1.log)(`Updating synced files ${JSON.stringify(fileIds, null, 2)}`, config.logger);
22
+ (0, logger_1.log)(`Updating synced files ${JSON.stringify(fileIds, null, 2)}`);
23
23
  yield (0, storage_1.getStorage)().updateSyncedFiles(JSON.stringify(fileIds), req.crowdinContext.clientId, req.crowdinContext.crowdinId);
24
24
  }
25
25
  else {
26
- (0, index_1.log)(`Saving synced files ${JSON.stringify(fileIds, null, 2)}`, config.logger);
26
+ (0, logger_1.log)(`Saving synced files ${JSON.stringify(fileIds, null, 2)}`);
27
27
  yield (0, storage_1.getStorage)().saveSyncedFiles(JSON.stringify(fileIds), req.crowdinContext.clientId, req.crowdinContext.crowdinId);
28
28
  }
29
29
  });
@@ -1,6 +1,6 @@
1
1
  import Crowdin from '@crowdin/crowdin-api-client';
2
- import { Config, CrowdinContextInfo, IntegrationLogic, IntegrationSyncSettings, Payload, Provider, TreeItem, UpdateCrowdinWebhookPayloadsArgs, UpdateIntegrationRequest, WebhookUrlParams } from '../models';
3
2
  import { WebhooksModel } from '@crowdin/crowdin-api-client/out/webhooks';
3
+ import { Config, CrowdinContextInfo, IntegrationLogic, IntegrationSyncSettings, Payload, Provider, TreeItem, UpdateCrowdinWebhookPayloadsArgs, UpdateIntegrationRequest, WebhookUrlParams } from '../models';
4
4
  export declare function encodedUrlParam(config: Config, integration: IntegrationLogic, crowdinContext: CrowdinContextInfo): string;
5
5
  export declare function decodedUrlParam(config: Config, data: string): WebhookUrlParams;
6
6
  export declare function makeCrowdinWebhookUrl(config: Config, integration: IntegrationLogic, crowdinContext: CrowdinContextInfo): string;
@@ -39,12 +39,12 @@ exports.listenQueueMessage = exports.updateCrowdinFromWebhookRequest = exports.p
39
39
  const crowdinAppFunctions = __importStar(require("@crowdin/crowdin-apps-functions"));
40
40
  const amqplib_1 = __importDefault(require("amqplib"));
41
41
  const models_1 = require("../models");
42
- const index_1 = require("./index");
43
- const connection_1 = require("./connection");
44
42
  const storage_1 = require("../storage");
43
+ const connection_1 = require("./connection");
45
44
  const defaults_1 = require("./defaults");
46
- const util_1 = require("../util");
47
45
  const file_snapshot_1 = require("./file-snapshot");
46
+ const index_1 = require("./index");
47
+ const logger_1 = require("./logger");
48
48
  const HookEvents = {
49
49
  ALL: ['file.translated', 'file.approved'],
50
50
  TRANSLATED: ['file.translated'],
@@ -200,7 +200,7 @@ function unregisterAllCrowdinWebhooks(config, integration, crowdinId) {
200
200
  if (crowdinCredentials) {
201
201
  const credentials = yield (0, storage_1.getStorage)().getAllIntegrationCredentials(crowdinId);
202
202
  const projectIds = credentials.map((c) => crowdinAppFunctions.getProjectId(c.id));
203
- const crowdinClient = yield (0, connection_1.prepareCrowdinClient)(config, crowdinCredentials);
203
+ const crowdinClient = yield (0, connection_1.prepareCrowdinClient)({ config, credentials: crowdinCredentials });
204
204
  yield Promise.all(projectIds.map((projectId) => __awaiter(this, void 0, void 0, function* () {
205
205
  const webhooks = yield getAllCrowdinProjectWebhooks(config, crowdinClient.client, projectId);
206
206
  yield Promise.all(webhooks.map((hook) => __awaiter(this, void 0, void 0, function* () { return yield unregisterCrowdinWebhooks(config, crowdinClient.client, projectId, hook); })));
@@ -236,7 +236,7 @@ function prepareWebhookData(config, integration, webhookUrlParam, provider) {
236
236
  let newFiles = [];
237
237
  const { projectId, crowdinId, clientId } = decodedUrlParam(config, webhookUrlParam);
238
238
  const crowdinCredentials = yield (0, storage_1.getStorage)().getCrowdinCredentials(crowdinId);
239
- const crowdinClient = yield (0, connection_1.prepareCrowdinClient)(config, crowdinCredentials);
239
+ const crowdinClient = yield (0, connection_1.prepareCrowdinClient)({ config, credentials: crowdinCredentials });
240
240
  const integrationCredentials = yield (0, storage_1.getStorage)().getIntegrationCredentials(clientId);
241
241
  const preparedIntegrationCredentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
242
242
  if (integrationCredentials === null || integrationCredentials === void 0 ? void 0 : integrationCredentials.config) {
@@ -338,7 +338,7 @@ function consumer(channel, config, integration) {
338
338
  yield updateCrowdinFromWebhookRequest({ integration, webhookData, req: data });
339
339
  }
340
340
  catch (e) {
341
- (0, util_1.logError)(e, config.onError);
341
+ (0, logger_1.logError)(e);
342
342
  }
343
343
  channel.ack(msg);
344
344
  });
@@ -18,4 +18,31 @@
18
18
  margin-left: 10px;
19
19
  }
20
20
  </style>
21
- </head>
21
+ {{#if sentryData}}
22
+ <script
23
+ src="https://browser.sentry-cdn.com/7.60.0/bundle.replay.min.js"
24
+ integrity="sha384-N+VZps2PwFdv9LugkPA8nw+SMI1mGJG7IDe49jaxZlWDDJhHQ+SHakMpwhLQLAka"
25
+ crossorigin="anonymous"
26
+ ></script>
27
+ <script>
28
+ Sentry.init({
29
+ dsn: "{{sentryData.dsn}}",
30
+ environment: "frontend",
31
+ replaysSessionSampleRate: 0,
32
+ replaysOnErrorSampleRate: 1.0,
33
+ integrations: [new Sentry.Replay()],
34
+ });
35
+
36
+ Sentry.configureScope(function(scope) {
37
+ scope.setTag("identifier", "{{sentryData.appIdentifier}}");
38
+
39
+ AP.getContext(contextData => {
40
+ const { user_id, ...rest } = contextData;
41
+
42
+ user_id && scope.setUser({ id: user_id });
43
+ scope.setTags(rest);
44
+ });
45
+ });
46
+ </script>
47
+ {{/if}}
48
+ </head>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crowdin/app-project-module",
3
- "version": "0.30.3",
3
+ "version": "0.32.0",
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",