@crowdin/app-project-module 0.51.1 → 0.51.3

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/out/index.js CHANGED
@@ -187,14 +187,11 @@ function addCrowdinEndpoints(app, clientConfig) {
187
187
  }
188
188
  exports.addCrowdinEndpoints = addCrowdinEndpoints;
189
189
  function addFormSchema({ app, config }) {
190
- if (Object.keys(config).some((moduleKey) => {
191
- var _a;
190
+ const shouldAddRoutes = Object.keys(config).some((moduleKey) => {
192
191
  const moduleConfig = config[moduleKey];
193
- if (typeof moduleConfig === 'object' && moduleConfig !== null) {
194
- return ('formSchema' in moduleConfig ||
195
- ('settingsUiModule' in moduleConfig && ((_a = moduleConfig.settingsUiModule) === null || _a === void 0 ? void 0 : _a.formSchema)));
196
- }
197
- })) {
192
+ return (0, util_1.hasFormSchema)(moduleConfig);
193
+ });
194
+ if (shouldAddRoutes) {
198
195
  app.get('/api/form-data', json_response_1.default, (0, crowdin_client_1.default)(config), (0, form_data_display_1.default)());
199
196
  app.post('/api/form-data', (0, crowdin_client_1.default)(config), (0, form_data_save_1.default)());
200
197
  }
@@ -60,6 +60,7 @@ function handle(config, optional = false, checkSubscriptionExpiration = true) {
60
60
  var _a;
61
61
  const jwtToken = getToken(req);
62
62
  if (!jwtToken) {
63
+ (0, logger_1.temporaryErrorDebug)('Access denied: crowdin-client', req);
63
64
  return res.status(403).send({ error: 'Access denied' });
64
65
  }
65
66
  try {
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  const storage_1 = require("../storage");
13
13
  const util_1 = require("../util");
14
14
  const connection_1 = require("../util/connection");
15
+ const logger_1 = require("../util/logger");
15
16
  function handle(config, integration, optional = false) {
16
17
  return (0, util_1.runAsyncWrapper)((req, res, next) => __awaiter(this, void 0, void 0, function* () {
17
18
  const clientId = req.crowdinContext.clientId;
@@ -22,6 +23,7 @@ function handle(config, integration, optional = false) {
22
23
  if (optional) {
23
24
  return next();
24
25
  }
26
+ (0, logger_1.temporaryErrorDebug)('Access denied: integration-credentials', req);
25
27
  return res.status(403).send({ error: 'Access denied' });
26
28
  }
27
29
  if (integrationConfig === null || integrationConfig === void 0 ? void 0 : integrationConfig.config) {
@@ -26,6 +26,7 @@ function handle(config, allowUnauthorized = false) {
26
26
  }
27
27
  const jwtToken = req.query.jwtToken;
28
28
  if (!jwtToken) {
29
+ (0, logger_1.temporaryErrorDebug)('Access denied: ui-module', req);
29
30
  return res.status(403).send({ error: 'Access denied' });
30
31
  }
31
32
  (0, logger_1.log)('Validating jwt token from incoming request');
@@ -18,11 +18,14 @@ function handle(aiProvider) {
18
18
  let choices;
19
19
  let message;
20
20
  let data;
21
+ const { crowdinApiClient: client, crowdinContext: context, body: { messages, model, action, responseFormat: { type: responseFormatType } = { type: undefined } }, } = req;
21
22
  const result = yield aiProvider.chatCompletions({
22
- messages: req.body.messages,
23
- model: req.body.model,
24
- client: req.crowdinApiClient,
25
- context: req.crowdinContext,
23
+ messages,
24
+ model,
25
+ action,
26
+ responseFormat: responseFormatType,
27
+ client,
28
+ context,
26
29
  req,
27
30
  });
28
31
  if ((0, files_1.isExtendedResultType)(result)) {
@@ -2,4 +2,5 @@
2
2
  import { Response } from 'express';
3
3
  import { CrowdinClientRequest } from '../../../types';
4
4
  import { AiProviderModule } from '../types';
5
+ export declare const CONTEXT_WINDOW_LIMIT = 4096;
5
6
  export default function handle(aiProvider: AiProviderModule): (req: CrowdinClientRequest | 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,15 +9,26 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.CONTEXT_WINDOW_LIMIT = void 0;
12
13
  const util_1 = require("../../../util");
13
14
  const logger_1 = require("../../../util/logger");
15
+ exports.CONTEXT_WINDOW_LIMIT = 4096;
14
16
  function handle(aiProvider) {
15
17
  return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
16
18
  try {
17
- const data = yield aiProvider.getModelsList({
19
+ const modelList = yield aiProvider.getModelsList({
18
20
  client: req.crowdinApiClient,
19
21
  context: req.crowdinContext,
20
22
  });
23
+ const data = modelList.map((model) => {
24
+ var _a, _b, _c;
25
+ return ({
26
+ id: model.id,
27
+ supportsJsonMode: (_a = model.supportsJsonMode) !== null && _a !== void 0 ? _a : false,
28
+ supportsFunctionCalling: (_b = model.supportsFunctionCalling) !== null && _b !== void 0 ? _b : false,
29
+ contextWindowLimit: (_c = model.contextWindowLimit) !== null && _c !== void 0 ? _c : exports.CONTEXT_WINDOW_LIMIT,
30
+ });
31
+ });
21
32
  res.send({ data });
22
33
  }
23
34
  catch (e) {
@@ -17,9 +17,11 @@ export interface AiProviderModule extends Environments {
17
17
  /**
18
18
  * processes a sequence of conversation messages and generates responses from the assistant
19
19
  */
20
- chatCompletions: ({ messages, model, client, context, req, }: {
20
+ chatCompletions: ({ messages, model, action, responseFormat, client, context, req, }: {
21
21
  messages: Message[];
22
22
  model: string;
23
+ action: string;
24
+ responseFormat: string;
23
25
  client: Crowdin;
24
26
  context: CrowdinContextInfo;
25
27
  req: CrowdinClientRequest;
@@ -34,6 +36,9 @@ export interface AiProviderModule extends Environments {
34
36
  }
35
37
  export interface SupportedModels {
36
38
  id: string;
39
+ supportsJsonMode?: boolean;
40
+ supportsFunctionCalling?: boolean;
41
+ contextWindowLimit?: number;
37
42
  }
38
43
  export interface Message {
39
44
  role?: string;
@@ -78,6 +78,7 @@ function handle(config, integration) {
78
78
  provider: types_1.Provider.CROWDIN,
79
79
  });
80
80
  if (!crowdinClient) {
81
+ (0, logger_1.temporaryErrorDebug)('Access denied: crowdin-webhooks', req);
81
82
  return res.status(403).send({ error: 'Access denied' });
82
83
  }
83
84
  if (!syncSettings) {
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  const util_1 = require("../../../util");
13
13
  const webhooks_1 = require("../util/webhooks");
14
14
  const types_1 = require("../types");
15
+ const logger_1 = require("../../../util/logger");
15
16
  function handle(config, integration) {
16
17
  return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
17
18
  var _a, _b;
@@ -25,6 +26,7 @@ function handle(config, integration) {
25
26
  provider: types_1.Provider.INTEGRATION,
26
27
  });
27
28
  if (!webhookData.crowdinClient) {
29
+ (0, logger_1.temporaryErrorDebug)('Access denied: integration-webhooks !webhookData.crowdinClient', req);
28
30
  return res.status(403).send({ error: 'Access denied' });
29
31
  }
30
32
  if (!webhookData.syncSettings) {
@@ -34,6 +36,7 @@ function handle(config, integration) {
34
36
  res.send({});
35
37
  }
36
38
  else {
39
+ (0, logger_1.temporaryErrorDebug)('Access denied: integration-webhooks !webhookUrlParam', req);
37
40
  return res.status(403).send({ error: 'Access denied' });
38
41
  }
39
42
  }));
@@ -18,6 +18,10 @@ const cron_1 = require("../util/cron");
18
18
  const snapshot_1 = require("../util/snapshot");
19
19
  const files_1 = require("../util/files");
20
20
  const job_1 = require("../util/job");
21
+ function checkAutoSyncSettings(integration, appSettings, provider) {
22
+ var _a;
23
+ return !!(!integration.webhooks && ((_a = integration.syncNewElements) === null || _a === void 0 ? void 0 : _a[provider]) && appSettings[`new-${provider}-files`]);
24
+ }
21
25
  function handle(config, integration) {
22
26
  return (0, util_1.runAsyncWrapper)((req, res) => __awaiter(this, void 0, void 0, function* () {
23
27
  const { files, provider, expandIntegrationFolders } = req.body;
@@ -29,7 +33,6 @@ function handle(config, integration) {
29
33
  payload: req.body,
30
34
  res,
31
35
  jobCallback: () => __awaiter(this, void 0, void 0, function* () {
32
- var _a;
33
36
  if (Array.isArray(expandIntegrationFolders) && expandIntegrationFolders.length) {
34
37
  const allFiles = (yield (0, files_1.expandFilesTree)(expandIntegrationFolders, req, integration)).map((node) => ({
35
38
  id: node.id,
@@ -56,7 +59,7 @@ function handle(config, integration) {
56
59
  });
57
60
  }
58
61
  const appSettings = req.integrationSettings || {};
59
- if (((_a = integration.syncNewElements) === null || _a === void 0 ? void 0 : _a[provider]) && appSettings[`new-${provider}-files`]) {
62
+ if (checkAutoSyncSettings(integration, appSettings, provider)) {
60
63
  yield (0, snapshot_1.createOrUpdateFileSnapshot)(config, integration, req, provider);
61
64
  }
62
65
  }),
@@ -10,3 +10,4 @@ export declare function decryptData(config: Config, data: string): string;
10
10
  export declare function executeWithRetry<T>(func: () => Promise<T>, numOfRetries?: number): Promise<T>;
11
11
  export declare function getLogoUrl(moduleConfig?: ImagePath, modulePath?: string): string;
12
12
  export declare function isAuthorizedConfig(config: Config | UnauthorizedConfig): config is Config;
13
+ export declare function hasFormSchema(moduleConfig: any): boolean;
package/out/util/index.js CHANGED
@@ -32,7 +32,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
32
32
  });
33
33
  };
34
34
  Object.defineProperty(exports, "__esModule", { value: true });
35
- exports.isAuthorizedConfig = exports.getLogoUrl = exports.executeWithRetry = exports.decryptData = exports.encryptData = exports.runAsyncWrapper = exports.CodeError = void 0;
35
+ exports.hasFormSchema = exports.isAuthorizedConfig = exports.getLogoUrl = 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
38
  const types_1 = require("../types");
@@ -118,3 +118,11 @@ function isAuthorizedConfig(config) {
118
118
  return !!config.clientId && !!config.clientSecret && config.authenticationType !== types_1.AuthenticationType.NONE;
119
119
  }
120
120
  exports.isAuthorizedConfig = isAuthorizedConfig;
121
+ function hasFormSchema(moduleConfig) {
122
+ var _a;
123
+ if (typeof moduleConfig === 'object' && moduleConfig !== null) {
124
+ return moduleConfig.formSchema || ((_a = moduleConfig.settingsUiModule) === null || _a === void 0 ? void 0 : _a.formSchema);
125
+ }
126
+ return false;
127
+ }
128
+ exports.hasFormSchema = hasFormSchema;
@@ -1,5 +1,7 @@
1
1
  import { AxiosError } from 'axios';
2
- import { Config, CrowdinContextInfo, UnauthorizedConfig } from '../types';
2
+ import { Config, CrowdinClientRequest, CrowdinContextInfo, UnauthorizedConfig } from '../types';
3
+ import { IntegrationRequest } from '../modules/integration/types';
4
+ import { Request } from 'express';
3
5
  export type LogFunction = (message: string) => void;
4
6
  export type LogErrorFunction = (error: any) => void;
5
7
  export type LogContext = {
@@ -34,4 +36,5 @@ export declare function handleUserError({ action, error, crowdinId, clientId, }:
34
36
  crowdinId: string;
35
37
  clientId?: string;
36
38
  }): Promise<void>;
39
+ export declare function temporaryErrorDebug(msg: string, req: Request | IntegrationRequest | CrowdinClientRequest): void;
37
40
  export {};
@@ -32,7 +32,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
32
32
  });
33
33
  };
34
34
  Object.defineProperty(exports, "__esModule", { value: true });
35
- exports.handleUserError = exports.AppModuleAggregateError = exports.AppModuleError = exports.getErrorMessage = exports.isAxiosError = exports.logError = exports.log = exports.withContextError = exports.withContext = exports.prepareContext = exports.initialize = void 0;
35
+ exports.temporaryErrorDebug = exports.handleUserError = exports.AppModuleAggregateError = exports.AppModuleError = exports.getErrorMessage = exports.isAxiosError = exports.logError = exports.log = exports.withContextError = exports.withContext = exports.prepareContext = exports.initialize = void 0;
36
36
  const logsFormatter = __importStar(require("@crowdin/logs-formatter"));
37
37
  const storage_1 = require("../storage");
38
38
  let logConfig;
@@ -274,3 +274,8 @@ function handleUserError({ action, error, crowdinId, clientId, }) {
274
274
  });
275
275
  }
276
276
  exports.handleUserError = handleUserError;
277
+ function temporaryErrorDebug(msg, req) {
278
+ // eslint-disable-next-line no-console
279
+ console.log(msg, req.headers, Object.assign({ originalUrl: req.originalUrl }, req.query));
280
+ }
281
+ exports.temporaryErrorDebug = temporaryErrorDebug;
@@ -721,6 +721,8 @@
721
721
  const settingsModal = document.getElementById('settings-modal');
722
722
  const settingsSaveBtn = document.getElementById('settings-save-btn');
723
723
  let config = JSON.parse('{{{config}}}');
724
+ const newCrowdinFiles = config?.['new-crowdin-files'];
725
+ const newIntegrationFiles = config?.['new-integration-files'];
724
726
 
725
727
  function triggerEvent(el, type) {
726
728
  const e = document.createEvent('HTMLEvents');
@@ -932,7 +934,7 @@
932
934
  {{#if syncNewElements.integration}}
933
935
  syncData = e.detail;
934
936
  const isFolder = await hasFolder(e.detail);
935
- if (isFolder) {
937
+ if (isFolder && !newIntegrationFiles) {
936
938
  openScheduleModal('integration');
937
939
  return;
938
940
  }
@@ -960,7 +962,7 @@
960
962
  {{#if syncNewElements.crowdin}}
961
963
  syncData = e.detail;
962
964
  const isFolder = await hasFolder(e.detail);
963
- if (isFolder) {
965
+ if (isFolder && !newCrowdinFiles) {
964
966
  openScheduleModal('crowdin');
965
967
  return;
966
968
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crowdin/app-project-module",
3
- "version": "0.51.1",
3
+ "version": "0.51.3",
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",