@crowdin/app-project-module 0.22.2 → 0.22.4

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.
package/README.md CHANGED
@@ -93,7 +93,7 @@ const configuration = {
93
93
  integrationSearchListener: true, //turn on search listener and pass search string
94
94
  getIntegrationFiles: async (credentials, appSettings, parentId, search) => {
95
95
  //here you need to fetch files/objects from integration
96
- return [
96
+ const res = [
97
97
  {
98
98
  id: '12',
99
99
  name: 'File from integration',
@@ -122,6 +122,10 @@ const configuration = {
122
122
  nodeType: '2'
123
123
  },
124
124
  ];
125
+ return {
126
+ data: res,
127
+ message: 'Test',
128
+ };
125
129
  },
126
130
  updateCrowdin: async (projectId, client, credentials, request, rootFolder, appSettings) => {
127
131
  //here you need to get data from integration and upload it to Crowdin
@@ -149,6 +153,9 @@ const configuration = {
149
153
  fileContent,
150
154
  files.find((f) => f.name === 'integration.json'),
151
155
  );
156
+ return {
157
+ message: 'Some message',
158
+ };
152
159
  },
153
160
  updateIntegration: async (projectId, client, credentials, request, rootFolder, appSettings) => {
154
161
  //here should be logic to get translations from Crowdin and upload them to integration
@@ -443,6 +450,8 @@ configuration.projectIntegration.getConfiguration = (projectId, crowdinClient, i
443
450
  key: 'option',
444
451
  label: 'Select',
445
452
  type: 'select',
453
+ isSearchable: true, //allow to search for option(s), default is `false`
454
+ isMulti: true, //allow to select multiple options, default is `false`
446
455
  options: [
447
456
  {
448
457
  value: '12',
@@ -19,8 +19,12 @@ function handle(config, integration) {
19
19
  if (rootFolder) {
20
20
  (0, util_1.log)(`Upading crowdin files under folder ${rootFolder.id}`, config.logger);
21
21
  }
22
- yield integration.updateCrowdin(projectId, req.crowdinApiClient, req.integrationCredentials, req.body, rootFolder, req.integrationSettings);
23
- res.status(204).end();
22
+ const result = yield integration.updateCrowdin(projectId, req.crowdinApiClient, req.integrationCredentials, req.body, rootFolder, req.integrationSettings);
23
+ let message;
24
+ if ((0, util_1.isMessageResultType)(result)) {
25
+ message = result.message;
26
+ }
27
+ res.send({ message });
24
28
  }), config.onError);
25
29
  }
26
30
  exports.default = handle;
@@ -112,17 +112,17 @@ function handleParseFile(baseUrl, dataFolder, config, req, client, context, proj
112
112
  return Object.assign(Object.assign({}, string), { translations });
113
113
  });
114
114
  }
115
- const stringsJson = JSON.stringify(strings);
116
- if (Buffer.byteLength(stringsJson, 'utf8') < maxSize) {
115
+ const stringsNDJson = strings.map(s => JSON.stringify(s)).join('\n\r');
116
+ if (Buffer.byteLength(stringsNDJson, 'utf8') < maxSize) {
117
117
  response.strings = strings;
118
118
  }
119
119
  else {
120
120
  let url;
121
121
  if (config.storeFile) {
122
- url = yield config.storeFile(stringsJson);
122
+ url = yield config.storeFile(stringsNDJson);
123
123
  }
124
124
  else {
125
- const storedFile = yield storeFile(stringsJson, dataFolder);
125
+ const storedFile = yield storeFile(stringsNDJson, dataFolder);
126
126
  url = `${baseUrl}?file=${storedFile}`;
127
127
  }
128
128
  response.stringsUrl = url;
@@ -14,9 +14,18 @@ function handle(config, integration) {
14
14
  return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
15
15
  const { parent_id: parentId, search } = req.query;
16
16
  (0, util_1.log)('Recieved request to get integration data', config.logger);
17
- const files = yield integration.getIntegrationFiles(req.integrationCredentials, req.integrationSettings, parentId, search);
17
+ const result = yield integration.getIntegrationFiles(req.integrationCredentials, req.integrationSettings, parentId, search);
18
+ let message;
19
+ let files;
20
+ if ((0, util_1.isMessageResultType)(result)) {
21
+ files = result.data;
22
+ message = result.message;
23
+ }
24
+ else {
25
+ files = result;
26
+ }
18
27
  (0, util_1.log)(`Integration data response ${JSON.stringify(files, null, 2)}`, config.logger);
19
- res.send(files);
28
+ res.send({ data: files, message });
20
29
  }), config.onError);
21
30
  }
22
31
  exports.default = handle;
@@ -18,8 +18,12 @@ function handle(config, integration) {
18
18
  if (rootFolder) {
19
19
  (0, util_1.log)(`Upading integration data for crowding root folder ${rootFolder.id}`, config.logger);
20
20
  }
21
- yield integration.updateIntegration(req.crowdinContext.jwtPayload.context.project_id, req.crowdinApiClient, req.integrationCredentials, req.body, rootFolder, req.integrationSettings);
22
- res.status(204).end();
21
+ const result = yield integration.updateIntegration(req.crowdinContext.jwtPayload.context.project_id, req.crowdinApiClient, req.integrationCredentials, req.body, rootFolder, req.integrationSettings);
22
+ let message;
23
+ if ((0, util_1.isMessageResultType)(result)) {
24
+ message = result.message;
25
+ }
26
+ res.send({ message });
23
27
  }), config.onError);
24
28
  }
25
29
  exports.default = handle;
@@ -172,15 +172,15 @@ export interface IntegrationLogic {
172
172
  /**
173
173
  * function to get data from integration
174
174
  */
175
- getIntegrationFiles: (apiCredentials: any, config?: any, parentId?: any, search?: any) => Promise<TreeItem[]>;
175
+ getIntegrationFiles: (apiCredentials: any, config?: any, parentId?: any, search?: any) => Promise<TreeItem[] | MessageResult<TreeItem[]>>;
176
176
  /**
177
177
  * function to update crowdin files (e.g. pull integration data to crowdin source files)
178
178
  */
179
- updateCrowdin: (projectId: number, client: Crowdin, apiCredentials: any, request: IntegrationFile[], appRootFolder?: SourceFilesModel.Directory, config?: any) => Promise<void>;
179
+ updateCrowdin: (projectId: number, client: Crowdin, apiCredentials: any, request: IntegrationFile[], appRootFolder?: SourceFilesModel.Directory, config?: any) => Promise<void | MessageResult<void>>;
180
180
  /**
181
181
  * function to update integration content (e.g. load crowdin translations and push them to integration service)
182
182
  */
183
- updateIntegration: (projectId: number, client: Crowdin, apiCredentials: any, request: UpdateIntegrationRequest, appRootFolder?: SourceFilesModel.Directory, config?: any) => Promise<void>;
183
+ updateIntegration: (projectId: number, client: Crowdin, apiCredentials: any, request: UpdateIntegrationRequest, appRootFolder?: SourceFilesModel.Directory, config?: any) => Promise<void | MessageResult<void>>;
184
184
  /**
185
185
  * function to define configuration(settings) modal for you app (by default app will not have any custom settings)
186
186
  */
@@ -379,6 +379,10 @@ export interface FormField {
379
379
  value: string;
380
380
  }[];
381
381
  }
382
+ export interface MessageResult<T> {
383
+ data?: T;
384
+ message?: string;
385
+ }
382
386
  export declare type TreeItem = File | Folder;
383
387
  export interface File {
384
388
  id: string;
@@ -69,6 +69,9 @@ function checkResponse(response) {
69
69
  if (![200, 201, 304].includes(response.status)) {
70
70
  reject(res);
71
71
  } else {
72
+ if (res.message) {
73
+ showToast(res.message);
74
+ }
72
75
  resolve(res);
73
76
  }
74
77
  })
@@ -1,5 +1,5 @@
1
1
  import { Request, Response } from 'express';
2
- import { Config, Logger } from '../models';
2
+ import { Config, Logger, MessageResult } from '../models';
3
3
  export declare class CodeError extends Error {
4
4
  code: number | undefined;
5
5
  constructor(message: string, code?: number);
@@ -10,3 +10,4 @@ export declare function runAsyncWrapper(callback: Function, onError?: (e: any) =
10
10
  export declare function encryptData(config: Config, data: string): string;
11
11
  export declare function decryptData(config: Config, data: string): string;
12
12
  export declare function executeWithRetry<T>(func: () => Promise<T>, numOfRetries?: number): Promise<T>;
13
+ export declare function isMessageResultType<T>(data?: T | MessageResult<T>): data is MessageResult<T>;
package/out/util/index.js CHANGED
@@ -28,7 +28,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
28
28
  });
29
29
  };
30
30
  Object.defineProperty(exports, "__esModule", { value: true });
31
- exports.executeWithRetry = exports.decryptData = exports.encryptData = exports.runAsyncWrapper = exports.getMessage = exports.log = exports.CodeError = void 0;
31
+ exports.isMessageResultType = exports.executeWithRetry = exports.decryptData = exports.encryptData = exports.runAsyncWrapper = exports.getMessage = exports.log = exports.CodeError = void 0;
32
32
  const crypto = __importStar(require("crypto-js"));
33
33
  const storage_1 = require("../storage");
34
34
  class CodeError extends Error {
@@ -120,3 +120,8 @@ function executeWithRetry(func, numOfRetries = 2) {
120
120
  });
121
121
  }
122
122
  exports.executeWithRetry = executeWithRetry;
123
+ function isMessageResultType(data) {
124
+ const dataTyped = data;
125
+ return !!(dataTyped === null || dataTyped === void 0 ? void 0 : dataTyped.data) || !!(dataTyped === null || dataTyped === void 0 ? void 0 : dataTyped.message);
126
+ }
127
+ exports.isMessageResultType = isMessageResultType;
@@ -222,7 +222,8 @@
222
222
  .then(restParams => fetch(`api/integration/data${restParams}&parent_id=${parentId}&search=${search}`))
223
223
  .then(checkResponse)
224
224
  .then((res) => {
225
- const tree = res.map(e => {
225
+ const files = res.data;
226
+ const tree = files.map(e => {
226
227
  const item = {
227
228
  parent_id: e.parentId ? e.parentId : '0',
228
229
  name: e.name,
@@ -243,7 +244,7 @@
243
244
  appComponent.pushIntegrationFilesData(tree);
244
245
  }
245
246
  if (search) {
246
- const openIds = res.filter(e => !e.type).map(e => e.id);
247
+ const openIds = files.filter(e => !e.type).map(e => e.id);
247
248
  appComponent.setIntegrationOpenedFolders(openIds);
248
249
  }
249
250
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crowdin/app-project-module",
3
- "version": "0.22.2",
3
+ "version": "0.22.4",
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",