@crowdin/app-project-module 0.63.0 → 0.64.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.
@@ -31,7 +31,7 @@ function handle() {
31
31
  hour12: false,
32
32
  timeZone: userTimezone,
33
33
  }).format(date);
34
- return Object.assign(Object.assign({}, userError), { createdAt: formattedDate });
34
+ return Object.assign(Object.assign({}, userError), { formattedDate });
35
35
  });
36
36
  req.logInfo(`Returning ${userErrors === null || userErrors === void 0 ? void 0 : userErrors.length} user errors`);
37
37
  res.send(userErrors);
@@ -67,7 +67,7 @@ function runAsJob({ integrationId, crowdinId, type, title, payload, res, project
67
67
  },
68
68
  type: jobType,
69
69
  fetchTranslation: ({ fileId, languageId }) => __awaiter(this, void 0, void 0, function* () {
70
- const translationCache = yield storage.getTranslationCache({
70
+ const translationCache = yield storage.getFileTranslationCacheByLanguage({
71
71
  integrationId,
72
72
  crowdinId,
73
73
  fileId,
@@ -89,20 +89,28 @@ function runAsJob({ integrationId, crowdinId, type, title, payload, res, project
89
89
  }
90
90
  return translation;
91
91
  }),
92
- translationUploaded: ({ fileId, languageId, etag }) => __awaiter(this, void 0, void 0, function* () {
93
- const translationCache = yield storage.getTranslationCache({
92
+ // translationUploaded: async ({ fileId, languageId, etag }) => {
93
+ translationUploaded: ({ fileId, translationParams }) => __awaiter(this, void 0, void 0, function* () {
94
+ const translationCache = (yield storage.getFileTranslationCache({
94
95
  integrationId,
95
96
  crowdinId,
96
97
  fileId,
97
- languageId,
98
- });
99
- (0, logger_1.log)(`Saving etag translation for file ${fileId} in language ${languageId}`);
100
- if (!translationCache) {
101
- yield storage.saveTranslationCache({ integrationId, crowdinId, fileId, languageId, etag });
102
- }
103
- else {
104
- yield storage.updateTranslationCache({ integrationId, crowdinId, fileId, languageId, etag });
98
+ })) || [];
99
+ const cacheMap = new Map(translationCache.map((cache) => [cache.languageId, cache]));
100
+ const updates = [];
101
+ const inserts = [];
102
+ for (const { languageId, etag } of translationParams) {
103
+ const cache = cacheMap.get(languageId);
104
+ if (cache) {
105
+ (0, logger_1.log)(`Updating etag translation for file ${fileId} in language ${languageId}`);
106
+ updates.push(storage.updateTranslationCache({ integrationId, crowdinId, fileId, languageId, etag }));
107
+ }
108
+ else {
109
+ (0, logger_1.log)(`Saving new etag translation for file ${fileId} in language ${languageId}`);
110
+ inserts.push(storage.saveTranslationCache({ integrationId, crowdinId, fileId, languageId, etag }));
111
+ }
105
112
  }
113
+ yield Promise.all([...updates, ...inserts]);
106
114
  }),
107
115
  };
108
116
  try {
@@ -67,10 +67,12 @@ export interface GetAllNewFilesArgs {
67
67
  integrationSettings: any;
68
68
  syncSettings: IntegrationSyncSettings;
69
69
  }
70
- export type SaveUploadedFileTranslation = ({ fileId, languageId, etag, }: {
70
+ export type SaveUploadedFileTranslation = ({ fileId, translationParams, }: {
71
71
  fileId: number;
72
- languageId: string;
73
- etag: string;
72
+ translationParams: {
73
+ languageId: string;
74
+ etag: string;
75
+ }[];
74
76
  }) => Promise<void>;
75
77
  export type FetchTranslation = ({ fileId, languageId, }: {
76
78
  fileId: number;
@@ -83,5 +85,6 @@ export interface TranslationCache {
83
85
  languageId: string;
84
86
  etag?: string;
85
87
  }
86
- export type GetTranslationCacheParams = Pick<TranslationCache, 'integrationId' | 'crowdinId' | 'fileId' | 'languageId'>;
88
+ export type GetFileTranslationCache = Pick<TranslationCache, 'integrationId' | 'crowdinId' | 'fileId'>;
89
+ export type GetFileTranslationCacheByLanguageParams = Pick<TranslationCache, 'integrationId' | 'crowdinId' | 'fileId' | 'languageId'>;
87
90
  export type UpdateTranslationCacheParams = Pick<TranslationCache, 'integrationId' | 'crowdinId' | 'fileId' | 'languageId' | 'etag'>;
@@ -1,6 +1,6 @@
1
1
  import { IntegrationConfig, IntegrationCredentials, IntegrationFilesSnapshot, IntegrationSyncSettings, IntegrationWebhooks, Provider } from '../modules/integration/types';
2
2
  import { Config, CrowdinCredentials, UnauthorizedConfig } from '../types';
3
- import { CreateJobParams, GetActiveJobsParams, GetJobParams, GetTranslationCacheParams, Job, TranslationCache, UpdateJobParams, UpdateTranslationCacheParams } from '../modules/integration/util/types';
3
+ import { CreateJobParams, GetActiveJobsParams, GetJobParams, GetFileTranslationCacheByLanguageParams, Job, TranslationCache, UpdateJobParams, UpdateTranslationCacheParams, GetFileTranslationCache } from '../modules/integration/util/types';
4
4
  import { UserErrors } from './types';
5
5
  export interface Storage {
6
6
  migrate(): Promise<void>;
@@ -44,7 +44,8 @@ export interface Storage {
44
44
  getActiveJobs(params: GetActiveJobsParams): Promise<Job[] | undefined>;
45
45
  deleteFinishedJobs(): Promise<void>;
46
46
  saveTranslationCache(params: TranslationCache): Promise<void>;
47
- getTranslationCache(params: GetTranslationCacheParams): Promise<TranslationCache | undefined>;
47
+ getFileTranslationCache(params: GetFileTranslationCache): Promise<TranslationCache[] | undefined>;
48
+ getFileTranslationCacheByLanguage(params: GetFileTranslationCacheByLanguageParams): Promise<TranslationCache | undefined>;
48
49
  updateTranslationCache(params: UpdateTranslationCacheParams): Promise<void>;
49
50
  }
50
51
  export declare function initialize(config: Config | UnauthorizedConfig): Promise<void>;
@@ -1,6 +1,6 @@
1
1
  import { Storage } from '.';
2
2
  import { CrowdinCredentials } from '../types';
3
- import { CreateJobParams, GetActiveJobsParams, GetJobParams, GetTranslationCacheParams, Job, TranslationCache, UpdateJobParams, UpdateTranslationCacheParams } from '../modules/integration/util/types';
3
+ import { CreateJobParams, GetActiveJobsParams, GetJobParams, GetFileTranslationCacheByLanguageParams, Job, TranslationCache, UpdateJobParams, UpdateTranslationCacheParams, GetFileTranslationCache } from '../modules/integration/util/types';
4
4
  import { IntegrationConfig, IntegrationCredentials, IntegrationFilesSnapshot, IntegrationSyncSettings, IntegrationWebhooks } from '../modules/integration/types';
5
5
  import { UserErrors } from './types';
6
6
  export interface MySQLStorageConfig {
@@ -61,6 +61,7 @@ export declare class MySQLStorage implements Storage {
61
61
  getActiveJobs({ integrationId, crowdinId }: GetActiveJobsParams): Promise<Job[] | undefined>;
62
62
  deleteFinishedJobs(): Promise<void>;
63
63
  saveTranslationCache({ integrationId, crowdinId, fileId, languageId, etag, }: TranslationCache): Promise<void>;
64
- getTranslationCache({ integrationId, crowdinId, fileId, languageId, }: GetTranslationCacheParams): Promise<TranslationCache | undefined>;
64
+ getFileTranslationCache({ integrationId, crowdinId, fileId, }: GetFileTranslationCache): Promise<TranslationCache[] | undefined>;
65
+ getFileTranslationCacheByLanguage({ integrationId, crowdinId, fileId, languageId, }: GetFileTranslationCacheByLanguageParams): Promise<TranslationCache | undefined>;
65
66
  updateTranslationCache({ integrationId, crowdinId, fileId, languageId, etag, }: UpdateTranslationCacheParams): Promise<void>;
66
67
  }
@@ -598,7 +598,20 @@ class MySQLStorage {
598
598
  `, [integrationId, crowdinId, fileId, languageId, etag]));
599
599
  });
600
600
  }
601
- getTranslationCache({ integrationId, crowdinId, fileId, languageId, }) {
601
+ getFileTranslationCache({ integrationId, crowdinId, fileId, }) {
602
+ return __awaiter(this, void 0, void 0, function* () {
603
+ yield this.dbPromise;
604
+ return this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
605
+ const [rows] = yield connection.execute(`
606
+ SELECT integration_id as integrationId, crowdin_id as crowdinId, file_id as fileId, language_id as languageId, etag
607
+ FROM translation_file_cache
608
+ WHERE integration_id = ? AND crowdin_id = ? AND file_id = ?
609
+ `, [integrationId, crowdinId, fileId]);
610
+ return rows || [];
611
+ }));
612
+ });
613
+ }
614
+ getFileTranslationCacheByLanguage({ integrationId, crowdinId, fileId, languageId, }) {
602
615
  return __awaiter(this, void 0, void 0, function* () {
603
616
  yield this.dbPromise;
604
617
  return this.executeQuery((connection) => __awaiter(this, void 0, void 0, function* () {
@@ -2,7 +2,7 @@ import { Client } from 'pg';
2
2
  import { Storage } from '.';
3
3
  import { CrowdinCredentials } from '../types';
4
4
  import { IntegrationConfig, IntegrationCredentials, IntegrationFilesSnapshot, IntegrationSyncSettings, IntegrationWebhooks } from '../modules/integration/types';
5
- import { CreateJobParams, GetActiveJobsParams, GetJobParams, GetTranslationCacheParams, Job, TranslationCache, UpdateJobParams, UpdateTranslationCacheParams } from '../modules/integration/util/types';
5
+ import { CreateJobParams, GetActiveJobsParams, GetJobParams, GetFileTranslationCacheByLanguageParams, Job, TranslationCache, UpdateJobParams, UpdateTranslationCacheParams, GetFileTranslationCache } from '../modules/integration/util/types';
6
6
  import { UserErrors } from './types';
7
7
  export interface PostgreStorageConfig {
8
8
  host?: string;
@@ -67,6 +67,7 @@ export declare class PostgreStorage implements Storage {
67
67
  getActiveJobs({ integrationId, crowdinId }: GetActiveJobsParams): Promise<Job[] | undefined>;
68
68
  deleteFinishedJobs(): Promise<void>;
69
69
  saveTranslationCache({ integrationId, crowdinId, fileId, languageId, etag, }: TranslationCache): Promise<void>;
70
- getTranslationCache({ integrationId, crowdinId, fileId, languageId, }: GetTranslationCacheParams): Promise<TranslationCache | undefined>;
70
+ getFileTranslationCache({ integrationId, crowdinId, fileId, }: GetFileTranslationCache): Promise<TranslationCache[] | undefined>;
71
+ getFileTranslationCacheByLanguage({ integrationId, crowdinId, fileId, languageId, }: GetFileTranslationCacheByLanguageParams): Promise<TranslationCache | undefined>;
71
72
  updateTranslationCache({ integrationId, crowdinId, fileId, languageId, etag, }: UpdateTranslationCacheParams): Promise<void>;
72
73
  }
@@ -51,7 +51,7 @@ class PostgreStorage {
51
51
  yield this.executeQuery(this.addTables);
52
52
  this._res && this._res();
53
53
  // TODO: temporary code
54
- yield this.executeQuery(this.alterTables);
54
+ yield this.executeQuery((client) => this.alterTables(client));
55
55
  }
56
56
  catch (e) {
57
57
  console.error(e);
@@ -619,7 +619,20 @@ class PostgreStorage {
619
619
  `, [integrationId, crowdinId, fileId, languageId, etag]));
620
620
  });
621
621
  }
622
- getTranslationCache({ integrationId, crowdinId, fileId, languageId, }) {
622
+ getFileTranslationCache({ integrationId, crowdinId, fileId, }) {
623
+ return __awaiter(this, void 0, void 0, function* () {
624
+ yield this.dbPromise;
625
+ return this.executeQuery((client) => __awaiter(this, void 0, void 0, function* () {
626
+ const res = yield client.query(`
627
+ SELECT integration_id as integrationId, crowdin_id as crowdinId, file_id as fileId, language_id as languageId, etag
628
+ FROM translation_file_cache
629
+ WHERE integration_id = $1 AND crowdin_id = $2 AND file_id = $3
630
+ `, [integrationId, crowdinId, fileId]);
631
+ return (res === null || res === void 0 ? void 0 : res.rows) || [];
632
+ }));
633
+ });
634
+ }
635
+ getFileTranslationCacheByLanguage({ integrationId, crowdinId, fileId, languageId, }) {
623
636
  return __awaiter(this, void 0, void 0, function* () {
624
637
  yield this.dbPromise;
625
638
  return this.executeQuery((client) => __awaiter(this, void 0, void 0, function* () {
@@ -1,7 +1,7 @@
1
1
  import { Storage } from '.';
2
2
  import { CrowdinCredentials } from '../types';
3
3
  import { IntegrationConfig, IntegrationCredentials, IntegrationFilesSnapshot, IntegrationSyncSettings, IntegrationWebhooks } from '../modules/integration/types';
4
- import { CreateJobParams, GetActiveJobsParams, GetJobParams, GetTranslationCacheParams, Job, TranslationCache, UpdateJobParams, UpdateTranslationCacheParams } from '../modules/integration/util/types';
4
+ import { CreateJobParams, GetActiveJobsParams, GetJobParams, GetFileTranslationCacheByLanguageParams, Job, TranslationCache, UpdateJobParams, UpdateTranslationCacheParams, GetFileTranslationCache } from '../modules/integration/util/types';
5
5
  import { UserErrors } from './types';
6
6
  export interface SQLiteStorageConfig {
7
7
  dbFolder: string;
@@ -62,6 +62,7 @@ export declare class SQLiteStorage implements Storage {
62
62
  getActiveJobs({ integrationId, crowdinId }: GetActiveJobsParams): Promise<Job[] | undefined>;
63
63
  deleteFinishedJobs(): Promise<void>;
64
64
  saveTranslationCache({ integrationId, crowdinId, fileId, languageId, etag }: TranslationCache): Promise<void>;
65
- getTranslationCache({ integrationId, crowdinId, fileId, languageId, }: GetTranslationCacheParams): Promise<TranslationCache | undefined>;
65
+ getFileTranslationCache({ integrationId, crowdinId, fileId, }: GetFileTranslationCache): Promise<TranslationCache[] | undefined>;
66
+ getFileTranslationCacheByLanguage({ integrationId, crowdinId, fileId, languageId, }: GetFileTranslationCacheByLanguageParams): Promise<TranslationCache | undefined>;
66
67
  updateTranslationCache({ integrationId, crowdinId, fileId, languageId, etag, }: UpdateTranslationCacheParams): Promise<void>;
67
68
  }
@@ -594,7 +594,16 @@ class SQLiteStorage {
594
594
  VALUES (?, ?, ?, ?, ?)
595
595
  `, [integrationId, crowdinId, fileId, languageId, etag]);
596
596
  }
597
- getTranslationCache({ integrationId, crowdinId, fileId, languageId, }) {
597
+ getFileTranslationCache({ integrationId, crowdinId, fileId, }) {
598
+ return __awaiter(this, void 0, void 0, function* () {
599
+ return this.each(`
600
+ SELECT integration_id as integrationId, crowdin_id as crowdinId, file_id as fileId, language_id as languageId, etag
601
+ FROM translation_file_cache
602
+ WHERE integration_id = ? AND crowdin_id = ? AND file_id = ?
603
+ `, [integrationId, crowdinId, fileId]);
604
+ });
605
+ }
606
+ getFileTranslationCacheByLanguage({ integrationId, crowdinId, fileId, languageId, }) {
598
607
  return __awaiter(this, void 0, void 0, function* () {
599
608
  const row = yield this.get(`
600
609
  SELECT integration_id as integrationId, crowdin_id as crowdinId, file_id as fileId, language_id as languageId, etag
@@ -13,7 +13,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.postRequestCredentialsMasker = exports.getRequestCredentialsMasker = void 0;
16
- const lodash_1 = __importDefault(require("lodash"));
16
+ const lodash_get_1 = __importDefault(require("lodash.get"));
17
17
  const index_1 = require("./index");
18
18
  const index_2 = require("../index");
19
19
  const crowdin_client_1 = require("../middlewares/crowdin-client");
@@ -29,7 +29,7 @@ function getMaskableFieldsKeys(moduleConfig) {
29
29
  return [];
30
30
  }
31
31
  return Object.keys(moduleConfig.formUiSchema).filter((fieldKey) => {
32
- return lodash_1.default.get(moduleConfig, `formUiSchema[${fieldKey}]['ui:widget']`) === 'password';
32
+ return (0, lodash_get_1.default)(moduleConfig, `formUiSchema[${fieldKey}]['ui:widget']`) === 'password';
33
33
  });
34
34
  }
35
35
  function postRequestCredentialsMasker(moduleConfig, credentialsExtractor) {
@@ -1143,6 +1143,10 @@
1143
1143
  modal.innerHTML = getUserErrorDetail(item);
1144
1144
  };
1145
1145
 
1146
+ const formatDate = (field, index, item) => {
1147
+ return item.formattedDate;
1148
+ }
1149
+
1146
1150
  table.setTableConfig && table.setTableConfig({
1147
1151
  defaultSortingColumn: "createdAt",
1148
1152
  defaultSortingDir: "desc",
@@ -1152,6 +1156,7 @@
1152
1156
  name: "Date",
1153
1157
  isSortable: true,
1154
1158
  clickFn: clickRow,
1159
+ formatFn: formatDate,
1155
1160
  },
1156
1161
  {
1157
1162
  field: "action",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crowdin/app-project-module",
3
- "version": "0.63.0",
3
+ "version": "0.64.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",
@@ -27,6 +27,7 @@
27
27
  "crypto-js": "^4.2.0",
28
28
  "express": "4.19.2",
29
29
  "express-handlebars": "^5.3.5",
30
+ "lodash.get": "^4.4.2",
30
31
  "lodash.uniqby": "^4.7.0",
31
32
  "mysql2": "^3.10.2",
32
33
  "node-cron": "^3.0.3",
@@ -58,6 +59,7 @@
58
59
  "@types/express-handlebars": "^5.3.1",
59
60
  "@types/jest": "^29.5.12",
60
61
  "@types/lodash.uniqby": "^4.7.9",
62
+ "@types/lodash.get": "^4.4.9",
61
63
  "@types/node": "^16.18.101",
62
64
  "@types/node-cron": "^3.0.11",
63
65
  "@types/pg": "^8.11.6",