@crowdin/app-project-module 0.107.0-cf-0 → 0.108.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 (151) hide show
  1. package/out/index.d.ts +0 -1
  2. package/out/index.js +12 -30
  3. package/out/middlewares/crowdin-client.d.ts +1 -1
  4. package/out/middlewares/integration-credentials.d.ts +1 -1
  5. package/out/middlewares/integration-credentials.js +1 -4
  6. package/out/middlewares/render-ui-module.d.ts +3 -3
  7. package/out/middlewares/render-ui-module.js +13 -9
  8. package/out/middlewares/ui-module.d.ts +1 -1
  9. package/out/middlewares/ui-module.js +1 -10
  10. package/out/modules/about.d.ts +1 -2
  11. package/out/modules/about.js +3 -10
  12. package/out/modules/ai-prompt-provider/handlers/compile.d.ts +1 -1
  13. package/out/modules/ai-prompt-provider/index.js +2 -2
  14. package/out/modules/ai-provider/handlers/chat-completions.d.ts +1 -1
  15. package/out/modules/ai-provider/handlers/get-model-list.d.ts +1 -1
  16. package/out/modules/ai-provider/index.js +2 -2
  17. package/out/modules/ai-provider/types.d.ts +2 -2
  18. package/out/modules/ai-request-processors/handler.d.ts +1 -1
  19. package/out/modules/ai-tools/handlers/tool-calls.d.ts +1 -1
  20. package/out/modules/ai-tools/index.js +1 -1
  21. package/out/modules/api/api.js +58 -7
  22. package/out/modules/api/base.d.ts +1 -0
  23. package/out/modules/api/base.js +1 -0
  24. package/out/modules/api/components.d.ts +251 -27
  25. package/out/modules/api/components.js +251 -27
  26. package/out/modules/auth-guard/handlers/verify.d.ts +1 -1
  27. package/out/modules/auth-guard/index.js +1 -1
  28. package/out/modules/automation-action/handlers/execute.d.ts +1 -1
  29. package/out/modules/automation-action/handlers/input-schema.d.ts +1 -1
  30. package/out/modules/automation-action/handlers/output-schema.d.ts +1 -1
  31. package/out/modules/automation-action/handlers/validate-settings.d.ts +1 -1
  32. package/out/modules/automation-action/index.js +1 -1
  33. package/out/modules/context-menu/index.js +2 -2
  34. package/out/modules/custom-mt/handlers/translate.d.ts +1 -1
  35. package/out/modules/custom-mt/handlers/translate.js +8 -17
  36. package/out/modules/custom-mt/index.js +3 -3
  37. package/out/modules/custom-mt/types.d.ts +1 -2
  38. package/out/modules/custom-spell-check/handlers/get-languages-list.d.ts +1 -1
  39. package/out/modules/custom-spell-check/handlers/spell-check.d.ts +1 -1
  40. package/out/modules/custom-spell-check/index.js +4 -4
  41. package/out/modules/editor-right-panel/index.js +1 -1
  42. package/out/modules/external-qa-check/handlers/validate.d.ts +1 -1
  43. package/out/modules/external-qa-check/index.js +2 -2
  44. package/out/modules/file-processing/handlers/custom-file-format.d.ts +2 -7
  45. package/out/modules/file-processing/handlers/custom-file-format.js +19 -59
  46. package/out/modules/file-processing/handlers/file-download.d.ts +1 -1
  47. package/out/modules/file-processing/handlers/file-download.js +0 -5
  48. package/out/modules/file-processing/handlers/pre-post-process.d.ts +1 -1
  49. package/out/modules/file-processing/handlers/pre-post-process.js +14 -34
  50. package/out/modules/file-processing/handlers/translations-alignment.d.ts +1 -1
  51. package/out/modules/file-processing/index.js +2 -12
  52. package/out/modules/file-processing/util/defaults.js +6 -50
  53. package/out/modules/file-processing/util/files.js +1 -2
  54. package/out/modules/form-data-display.d.ts +1 -1
  55. package/out/modules/form-data-save.d.ts +1 -1
  56. package/out/modules/install.d.ts +1 -1
  57. package/out/modules/integration/handlers/crowdin-file-progress.d.ts +1 -1
  58. package/out/modules/integration/handlers/crowdin-files.d.ts +1 -1
  59. package/out/modules/integration/handlers/crowdin-project.d.ts +1 -1
  60. package/out/modules/integration/handlers/crowdin-update.d.ts +1 -1
  61. package/out/modules/integration/handlers/crowdin-webhook.d.ts +1 -1
  62. package/out/modules/integration/handlers/integration-data.d.ts +1 -1
  63. package/out/modules/integration/handlers/integration-login.d.ts +1 -1
  64. package/out/modules/integration/handlers/integration-logout.d.ts +1 -1
  65. package/out/modules/integration/handlers/integration-update.d.ts +1 -1
  66. package/out/modules/integration/handlers/integration-webhook.d.ts +1 -1
  67. package/out/modules/integration/handlers/invite-users.d.ts +1 -1
  68. package/out/modules/integration/handlers/job-cancel.d.ts +1 -1
  69. package/out/modules/integration/handlers/job-info-deprecated.d.ts +1 -1
  70. package/out/modules/integration/handlers/job-info.d.ts +1 -1
  71. package/out/modules/integration/handlers/job-list.d.ts +1 -1
  72. package/out/modules/integration/handlers/main.d.ts +1 -1
  73. package/out/modules/integration/handlers/main.js +1 -13
  74. package/out/modules/integration/handlers/oauth-login.d.ts +1 -1
  75. package/out/modules/integration/handlers/oauth-login.js +2 -10
  76. package/out/modules/integration/handlers/oauth-polling.d.ts +1 -1
  77. package/out/modules/integration/handlers/oauth-url.d.ts +1 -1
  78. package/out/modules/integration/handlers/settings-save.d.ts +1 -1
  79. package/out/modules/integration/handlers/settings.d.ts +1 -1
  80. package/out/modules/integration/handlers/sync-settings-save.d.ts +1 -1
  81. package/out/modules/integration/handlers/sync-settings.d.ts +1 -1
  82. package/out/modules/integration/handlers/user-errors.d.ts +1 -1
  83. package/out/modules/integration/handlers/users.d.ts +1 -1
  84. package/out/modules/integration/index.js +33 -12
  85. package/out/modules/manifest.js +12 -12
  86. package/out/modules/modal/index.js +2 -2
  87. package/out/modules/organization-menu/index.js +4 -5
  88. package/out/modules/organization-settings-menu/index.js +4 -5
  89. package/out/modules/profile-resources-menu/index.js +4 -5
  90. package/out/modules/profile-settings-menu/index.js +4 -5
  91. package/out/modules/project-menu/index.js +1 -1
  92. package/out/modules/project-menu-crowdsource/index.js +1 -1
  93. package/out/modules/project-reports/index.js +2 -3
  94. package/out/modules/project-tools/index.js +2 -3
  95. package/out/modules/status.d.ts +1 -1
  96. package/out/modules/status.js +3 -12
  97. package/out/modules/subscription-paid.d.ts +1 -1
  98. package/out/modules/uninstall.d.ts +1 -1
  99. package/out/modules/webhooks/handlers/webhook-handler.d.ts +1 -1
  100. package/out/modules/webhooks/handlers/webhook-handler.js +15 -30
  101. package/out/modules/webhooks/types.d.ts +0 -7
  102. package/out/modules/workflow-step-type/handlers/delete-step.d.ts +1 -1
  103. package/out/modules/workflow-step-type/handlers/step-settings-save.d.ts +1 -1
  104. package/out/modules/workflow-step-type/index.js +2 -2
  105. package/out/modules/workflow-step-type/types.d.ts +1 -1
  106. package/out/storage/index.js +1 -8
  107. package/out/types.d.ts +4 -41
  108. package/out/util/connection.js +15 -4
  109. package/out/util/credentials-masker.d.ts +1 -1
  110. package/out/util/handlebars.d.ts +1 -0
  111. package/out/util/handlebars.js +46 -0
  112. package/out/util/index.d.ts +1 -11
  113. package/out/util/index.js +6 -50
  114. package/out/views/about.handlebars +102 -0
  115. package/out/views/error.handlebars +54 -0
  116. package/out/views/form.handlebars +31 -0
  117. package/out/views/install.handlebars +16 -0
  118. package/out/views/login.handlebars +332 -0
  119. package/out/views/main.handlebars +2042 -0
  120. package/out/views/oauth.handlebars +11 -0
  121. package/out/views/partials/head.handlebars +53 -0
  122. package/out/views/subscription.handlebars +26 -0
  123. package/package.json +12 -25
  124. package/out/storage/d1.d.ts +0 -107
  125. package/out/storage/d1.js +0 -829
  126. package/out/util/cron.d.ts +0 -29
  127. package/out/util/cron.js +0 -87
  128. package/out/util/jsx-renderer.d.ts +0 -6
  129. package/out/util/jsx-renderer.js +0 -13
  130. package/out/util/static-files.d.ts +0 -19
  131. package/out/util/static-files.js +0 -87
  132. package/out/views/AboutPage.d.ts +0 -10
  133. package/out/views/AboutPage.js +0 -76
  134. package/out/views/ErrorPage.d.ts +0 -18
  135. package/out/views/ErrorPage.js +0 -56
  136. package/out/views/FormPage.d.ts +0 -14
  137. package/out/views/FormPage.js +0 -28
  138. package/out/views/InstallPage.d.ts +0 -10
  139. package/out/views/InstallPage.js +0 -22
  140. package/out/views/LoginPage.d.ts +0 -33
  141. package/out/views/LoginPage.js +0 -200
  142. package/out/views/MainPage.d.ts +0 -81
  143. package/out/views/MainPage.js +0 -1784
  144. package/out/views/OAuthPage.d.ts +0 -7
  145. package/out/views/OAuthPage.js +0 -17
  146. package/out/views/SubscriptionPage.d.ts +0 -7
  147. package/out/views/SubscriptionPage.js +0 -26
  148. package/out/views/index.d.ts +0 -13
  149. package/out/views/index.js +0 -25
  150. package/out/views/layout/Head.d.ts +0 -9
  151. package/out/views/layout/Head.js +0 -54
package/out/index.d.ts CHANGED
@@ -4,7 +4,6 @@ import express from './util/terminus-express';
4
4
  import { getRequestCredentialsMasker, postRequestCredentialsMasker, maskKey } from './util/credentials-masker';
5
5
  export { getRequestCredentialsMasker, postRequestCredentialsMasker, maskKey };
6
6
  export { ProjectPermissions, Scope, UserPermissions } from './types';
7
- export { Cron } from './util/cron';
8
7
  export { express };
9
8
  export declare const metadataStore: CrowdinMetadataStore;
10
9
  export declare function createApp(clientConfig: ClientConfig): void;
package/out/index.js CHANGED
@@ -50,12 +50,11 @@ const subscription_paid_1 = __importDefault(require("./modules/subscription-paid
50
50
  const uninstall_1 = __importDefault(require("./modules/uninstall"));
51
51
  const status_1 = __importDefault(require("./modules/status"));
52
52
  const storage = __importStar(require("./storage"));
53
- const d1_1 = require("./storage/d1");
54
- const cron = __importStar(require("./util/cron"));
55
53
  const types_1 = require("./types");
56
54
  const util_1 = require("./util");
57
55
  const form_schema_1 = require("./util/form-schema");
58
56
  const connection_1 = require("./util/connection");
57
+ const handlebars_1 = require("./util/handlebars");
59
58
  const logger = __importStar(require("./util/logger"));
60
59
  const logger_1 = require("./util/logger");
61
60
  const terminus_express_1 = __importDefault(require("./util/terminus-express"));
@@ -64,8 +63,6 @@ const credentials_masker_1 = require("./util/credentials-masker");
64
63
  Object.defineProperty(exports, "getRequestCredentialsMasker", { enumerable: true, get: function () { return credentials_masker_1.getRequestCredentialsMasker; } });
65
64
  Object.defineProperty(exports, "postRequestCredentialsMasker", { enumerable: true, get: function () { return credentials_masker_1.postRequestCredentialsMasker; } });
66
65
  Object.defineProperty(exports, "maskKey", { enumerable: true, get: function () { return credentials_masker_1.maskKey; } });
67
- const static_files_1 = require("./util/static-files");
68
- const util_2 = require("./util");
69
66
  //apps
70
67
  const apiApp = __importStar(require("./modules/api"));
71
68
  const contextMenuApp = __importStar(require("./modules/context-menu"));
@@ -143,27 +140,6 @@ function addCrowdinEndpoints(app, clientConfig) {
143
140
  }
144
141
  storage.initialize(config);
145
142
  logger.initialize(config);
146
- cron.initialize(config);
147
- // Middleware to ensure D1 migration before handling requests
148
- app.use((req, res, next) => __awaiter(this, void 0, void 0, function* () {
149
- try {
150
- const storageInstance = storage.getStorage();
151
- if (storageInstance instanceof d1_1.D1Storage) {
152
- yield storageInstance.ensureMigrated();
153
- }
154
- next();
155
- }
156
- catch (error) {
157
- next(error);
158
- }
159
- }));
160
- // Middleware to detect and cache baseUrl from request if not provided
161
- app.use((req, res, next) => {
162
- if (!config.baseUrl) {
163
- config.baseUrl = (0, util_1.extractBaseUrlFromRequest)(req);
164
- }
165
- next();
166
- });
167
143
  app.use((req, res, next) => {
168
144
  if (config.webhooks && req.path === '/webhooks') {
169
145
  return terminus_express_1.default.raw({ type: '*/*', limit: '50mb' })(req, res, next);
@@ -177,8 +153,11 @@ function addCrowdinEndpoints(app, clientConfig) {
177
153
  app.use(logsFormatter.contextResolverMiddleware());
178
154
  app.use(logsFormatter.expressMiddleware());
179
155
  }
180
- app.use('/assets', (0, static_files_1.serveStatic)(config, config.assetsPath || 'static'));
181
- app.use('/', (0, util_2.serveLogo)(config));
156
+ app.use('/assets', terminus_express_1.default.static((0, path_1.join)(__dirname, 'static')));
157
+ app.set('views', (0, path_1.join)(__dirname, 'views'));
158
+ app.engine('handlebars', handlebars_1.engine);
159
+ app.set('view engine', 'handlebars');
160
+ app.get((0, util_1.getLogoUrl)(), (req, res) => res.sendFile(config.imagePath));
182
161
  app.get('/manifest.json', json_response_1.default, (0, manifest_1.default)(config));
183
162
  app.get('/', (0, about_1.default)(config));
184
163
  if (((_a = config === null || config === void 0 ? void 0 : config.enableStatusPage) === null || _a === void 0 ? void 0 : _a.database) || ((_b = config === null || config === void 0 ? void 0 : config.enableStatusPage) === null || _b === void 0 ? void 0 : _b.filesystem)) {
@@ -213,7 +192,7 @@ function addCrowdinEndpoints(app, clientConfig) {
213
192
  contextMenuApp.register({ config, app });
214
193
  //other apps only work in authorized context
215
194
  if (!(0, util_1.isAuthorizedConfig)(config)) {
216
- return Object.assign(Object.assign({}, exports.metadataStore), { cron: cron.getCron() });
195
+ return Object.assign({}, exports.metadataStore);
217
196
  }
218
197
  app.post('/installed', (0, install_1.default)(config));
219
198
  app.post('/uninstall', (0, uninstall_1.default)(config));
@@ -246,7 +225,7 @@ function addCrowdinEndpoints(app, clientConfig) {
246
225
  automationAction.register({ config, app });
247
226
  authGuard.register({ config, app });
248
227
  addFormSchema({ config, app });
249
- return Object.assign(Object.assign({}, exports.metadataStore), { storage: storage.getStorage(), cron: cron.getCron(), establishCrowdinConnection: (authRequest, moduleKey) => {
228
+ return Object.assign(Object.assign({}, exports.metadataStore), { storage: storage.getStorage(), establishCrowdinConnection: (authRequest, moduleKey) => {
250
229
  let jwtToken = '';
251
230
  if (typeof authRequest === 'string') {
252
231
  jwtToken = authRequest;
@@ -300,6 +279,9 @@ function convertClientConfig(clientConfig) {
300
279
  const clientSecret = clientConfig.clientSecret || process.env.CROWDIN_CLIENT_SECRET;
301
280
  const port = clientConfig.port || process.env.PORT || 3000;
302
281
  const { region = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION, tmpBucketName = process.env.AWS_TMP_BUCKET_NAME, } = clientConfig.awsConfig || {};
282
+ if (!baseUrl) {
283
+ throw new Error('Missing baseUrl parameter');
284
+ }
303
285
  if (clientConfig.authenticationType !== types_1.AuthenticationType.NONE) {
304
286
  if (!clientId && !clientSecret) {
305
287
  throw new Error('Missing [clientId, clientSecret] parameters');
@@ -309,7 +291,7 @@ function convertClientConfig(clientConfig) {
309
291
  clientConfig.api = Object.assign({ default: true }, clientConfig.api);
310
292
  }
311
293
  clientConfig.enableStatusPage = Object.assign({ database: true, filesystem: true }, (clientConfig.enableStatusPage || {}));
312
- return Object.assign(Object.assign({}, clientConfig), { baseUrl: baseUrl ? (baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl) : undefined, clientId,
294
+ return Object.assign(Object.assign({}, clientConfig), { baseUrl: baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl, clientId,
313
295
  clientSecret, awsConfig: {
314
296
  tmpBucketName,
315
297
  region,
@@ -21,5 +21,5 @@ export default function handle({ config, optional, checkSubscriptionExpiration,
21
21
  optional: boolean;
22
22
  checkSubscriptionExpiration: boolean;
23
23
  moduleKey?: string[] | string | undefined;
24
- }): (req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>> | CrowdinClientRequest, res: Response<any, Record<string, any>>, next: Function) => void;
24
+ }): (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;
25
25
  export declare function getToken(req: CrowdinClientRequest): string | undefined;
@@ -2,4 +2,4 @@
2
2
  import { Response } from 'express';
3
3
  import { Config } from '../types';
4
4
  import { IntegrationLogic } from '../modules/integration/types';
5
- export default function handle(config: Config, integration: IntegrationLogic, optional?: boolean): (req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>> | import("../types").CrowdinClientRequest, res: Response<any, Record<string, any>>, next: Function) => void;
5
+ export default function handle(config: Config, integration: IntegrationLogic, optional?: boolean): (req: import("../types").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;
@@ -37,7 +37,6 @@ const util_1 = require("../util");
37
37
  const connection_1 = require("../util/connection");
38
38
  const logger_1 = require("../util/logger");
39
39
  const crowdinAppFunctions = __importStar(require("@crowdin/crowdin-apps-functions"));
40
- const views_1 = require("../views");
41
40
  function handle(config, integration, optional = false) {
42
41
  return (0, util_1.runAsyncWrapper)((req, res, next) => __awaiter(this, void 0, void 0, function* () {
43
42
  let clientId = req.crowdinContext.clientId;
@@ -90,9 +89,7 @@ function handle(config, integration, optional = false) {
90
89
  else {
91
90
  (0, logger_1.temporaryErrorDebug)('Access denied: integration-credentials', req);
92
91
  }
93
- const html = (0, util_1.renderJSX)(views_1.ErrorPage, errorOptions);
94
- res.setHeader('Content-Type', 'text/html; charset=utf-8');
95
- return res.send(html);
92
+ return res.render('error', errorOptions);
96
93
  }
97
94
  try {
98
95
  req.integrationCredentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
@@ -1,4 +1,4 @@
1
1
  /// <reference types="qs" />
2
- import { Request, Response } from 'express';
3
- import { UiModule, Config, UnauthorizedConfig } from '../types';
4
- export default function handle(moduleConfig: UiModule, config: Config | UnauthorizedConfig): (req: Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>> | import("../types").CrowdinClientRequest, res: Response<any, Record<string, any>>, next: Function) => void;
2
+ import express from 'express';
3
+ import { UiModule } from '../types';
4
+ export default function handle(moduleConfig: UiModule): (req: import("../types").CrowdinClientRequest | express.Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: express.Response<any, Record<string, any>>, next: Function) => void;
@@ -8,25 +8,29 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
11
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
+ const express_1 = __importDefault(require("express"));
12
16
  const util_1 = require("../util");
13
- const static_files_1 = require("../util/static-files");
14
- const views_1 = require("../views");
15
- function handle(moduleConfig, config) {
17
+ function handle(moduleConfig) {
16
18
  return (0, util_1.runAsyncWrapper)((req, res, next) => __awaiter(this, void 0, void 0, function* () {
17
19
  if (moduleConfig.formSchema) {
18
- const html = (0, util_1.renderJSX)(views_1.FormPage, {
19
- formGetDataUrl: moduleConfig.formGetDataUrl || `/api/${moduleConfig.key}/form-data`,
20
- formPostDataUrl: moduleConfig.formPostDataUrl || `/api/${moduleConfig.key}/form-data`,
20
+ return res.render('form', {
21
+ formGetDataUrl: moduleConfig.formGetDataUrl
22
+ ? moduleConfig.formGetDataUrl
23
+ : `/api/${moduleConfig.key}/form-data`,
24
+ formPostDataUrl: moduleConfig.formPostDataUrl
25
+ ? moduleConfig.formPostDataUrl
26
+ : `/api/${moduleConfig.key}/form-data`,
21
27
  formSchema: JSON.stringify(moduleConfig.formSchema),
22
28
  formUiSchema: moduleConfig.formUiSchema ? JSON.stringify(moduleConfig.formUiSchema) : '{}',
23
29
  formPatchDataUrl: moduleConfig.formPatchDataUrl,
24
30
  });
25
- res.setHeader('Content-Type', 'text/html; charset=utf-8');
26
- return res.send(html);
27
31
  }
28
32
  if (moduleConfig.uiPath) {
29
- return (0, static_files_1.serveStatic)(config, moduleConfig.uiPath)(req, res, next);
33
+ return express_1.default.static(moduleConfig.uiPath)(req, res, next);
30
34
  }
31
35
  throw new Error('uiPath or formSchema should be provided for module');
32
36
  }));
@@ -5,4 +5,4 @@ export default function handle({ config, allowUnauthorized, moduleType, }: {
5
5
  config: Config | UnauthorizedConfig;
6
6
  allowUnauthorized?: boolean;
7
7
  moduleType?: string | undefined;
8
- }): (req: Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>> | import("../types").CrowdinClientRequest, res: Response<any, Record<string, any>>, next: Function) => void;
8
+ }): (req: import("../types").CrowdinClientRequest | Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: Function) => void;
@@ -16,15 +16,8 @@ const util_1 = require("../util");
16
16
  const connection_1 = require("../util/connection");
17
17
  const logger_1 = require("../util/logger");
18
18
  const subscription_1 = require("../util/subscription");
19
- const views_1 = require("../views");
20
19
  function handle({ config, allowUnauthorized = false, moduleType, }) {
21
20
  return (0, util_1.runAsyncWrapper)((req, res, next) => __awaiter(this, void 0, void 0, function* () {
22
- // Allow access to non-HTML files
23
- const isHtmlFile = /\.html?$/i.test(req.path);
24
- if (!isHtmlFile) {
25
- next();
26
- return;
27
- }
28
21
  if (allowUnauthorized) {
29
22
  next();
30
23
  return;
@@ -67,9 +60,7 @@ function handle({ config, allowUnauthorized = false, moduleType, }) {
67
60
  accountType: credentials.type,
68
61
  });
69
62
  if (expired) {
70
- const html = (0, util_1.renderJSX)(views_1.SubscriptionPage, { subscribeLink });
71
- res.setHeader('Content-Type', 'text/html; charset=utf-8');
72
- return res.send(html);
63
+ return res.render('subscription', { subscribeLink });
73
64
  }
74
65
  }
75
66
  next();
@@ -5,6 +5,5 @@ export declare function getAboutPageOptions(config: Config | UnauthorizedConfig)
5
5
  logo: string;
6
6
  manifest: string;
7
7
  storeLink: string;
8
- showDebugLink: boolean;
9
8
  }>;
10
- export default function handle(config: Config | UnauthorizedConfig): (req: Request, res: Response, next: NextFunction) => Promise<Response<any, Record<string, any>> | undefined>;
9
+ export default function handle(config: Config | UnauthorizedConfig): (req: Request, res: Response, next: NextFunction) => Promise<void>;
@@ -16,8 +16,6 @@ exports.getAboutPageOptions = void 0;
16
16
  const axios_1 = __importDefault(require("axios"));
17
17
  const util_1 = require("../util");
18
18
  const crowdin_client_1 = require("../middlewares/crowdin-client");
19
- const jsx_renderer_1 = require("../util/jsx-renderer");
20
- const views_1 = require("../views");
21
19
  function getAboutPageOptions(config) {
22
20
  return __awaiter(this, void 0, void 0, function* () {
23
21
  let detailPage = '';
@@ -32,10 +30,9 @@ function getAboutPageOptions(config) {
32
30
  }
33
31
  return {
34
32
  name: config.name,
35
- logo: (0, util_1.getLogoUrl)(config),
33
+ logo: (0, util_1.getLogoUrl)(),
36
34
  manifest: config.baseUrl + '/manifest.json',
37
35
  storeLink: (config === null || config === void 0 ? void 0 : config.detailPage) || detailPage,
38
- showDebugLink: process.env.SHOW_DEBUG_LINK === 'true',
39
36
  };
40
37
  });
41
38
  }
@@ -46,9 +43,7 @@ function handle(config) {
46
43
  const jwtToken = (0, crowdin_client_1.getToken)(req);
47
44
  if (!jwtToken) {
48
45
  const options = yield getAboutPageOptions(config);
49
- const html = (0, jsx_renderer_1.renderJSX)(views_1.AboutPage, options);
50
- res.setHeader('Content-Type', 'text/html; charset=utf-8');
51
- return res.send(html);
46
+ return res.render('about', options);
52
47
  }
53
48
  else {
54
49
  next();
@@ -56,9 +51,7 @@ function handle(config) {
56
51
  }
57
52
  }
58
53
  const options = yield getAboutPageOptions(config);
59
- const html = (0, jsx_renderer_1.renderJSX)(views_1.AboutPage, options);
60
- res.setHeader('Content-Type', 'text/html; charset=utf-8');
61
- return res.send(html);
54
+ return res.render('about', options);
62
55
  });
63
56
  }
64
57
  exports.default = handle;
@@ -2,4 +2,4 @@
2
2
  import { Response } from 'express';
3
3
  import { CrowdinClientRequest } from '../../../types';
4
4
  import { AiPromptProviderModule } from '../types';
5
- export default function handle(aiPromptProvider: AiPromptProviderModule): (req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>> | CrowdinClientRequest, res: Response<any, Record<string, any>>, next: Function) => void;
5
+ export default function handle(aiPromptProvider: AiPromptProviderModule): (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;
@@ -21,8 +21,8 @@ function register({ config, app }) {
21
21
  moduleKey: config.aiPromptProvider.key,
22
22
  }), (0, compile_1.default)(config.aiPromptProvider));
23
23
  if (config.aiPromptProvider.formSchema || config.aiPromptProvider.uiPath) {
24
- app.use('/prompt-provider/settings', (0, ui_module_1.default)({ config, allowUnauthorized: true, moduleType: config.aiPromptProvider.key }), (0, render_ui_module_1.default)(config.aiPromptProvider, config));
24
+ app.use('/prompt-provider/settings', (0, ui_module_1.default)({ config, allowUnauthorized: true, moduleType: config.aiPromptProvider.key }), (0, render_ui_module_1.default)(config.aiPromptProvider));
25
25
  }
26
- app.use('/logo/ai-prompt-provider', (0, util_1.serveLogo)(config, config.aiPromptProvider));
26
+ app.get((0, util_1.getLogoUrl)(config.aiPromptProvider, '/ai-prompt-provider'), (req, res) => { var _a; return res.sendFile(((_a = config.aiPromptProvider) === null || _a === void 0 ? void 0 : _a.imagePath) || config.imagePath); });
27
27
  }
28
28
  exports.register = register;
@@ -2,4 +2,4 @@
2
2
  import { Response } from 'express';
3
3
  import { CrowdinClientRequest } from '../../../types';
4
4
  import { AiProviderModule } from '../types';
5
- export default function handle(aiProvider: AiProviderModule): (req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>> | CrowdinClientRequest, res: Response<any, Record<string, any>>, next: Function) => void;
5
+ 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;
@@ -3,4 +3,4 @@ import { Response } from 'express';
3
3
  import { CrowdinClientRequest } from '../../../types';
4
4
  import { AiProviderModule } from '../types';
5
5
  export declare const CONTEXT_WINDOW_LIMIT = 4096;
6
- export default function handle(aiProvider: AiProviderModule): (req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>> | CrowdinClientRequest, res: Response<any, Record<string, any>>, next: Function) => void;
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;
@@ -16,9 +16,9 @@ function register({ config, app }) {
16
16
  return;
17
17
  }
18
18
  if (config.aiProvider.settingsUiModule) {
19
- app.use('/settings', (0, ui_module_1.default)({ config, allowUnauthorized: true, moduleType: config.aiProvider.key }), (0, render_ui_module_1.default)(config.aiProvider.settingsUiModule, config));
19
+ app.use('/settings', (0, ui_module_1.default)({ config, allowUnauthorized: true, moduleType: config.aiProvider.key }), (0, render_ui_module_1.default)(config.aiProvider.settingsUiModule));
20
20
  }
21
- app.use('/logo/aiprovider', (0, util_1.serveLogo)(config, config.aiProvider));
21
+ app.get((0, util_1.getLogoUrl)(config.aiProvider, '/aiprovider'), (req, res) => { var _a; return res.sendFile(((_a = config.aiProvider) === null || _a === void 0 ? void 0 : _a.imagePath) || config.imagePath); });
22
22
  app.get('/ai-provider/models', json_response_1.default, (0, crowdin_client_1.default)({
23
23
  config,
24
24
  optional: false,
@@ -5,11 +5,11 @@ export interface AiProviderModule extends Environments, ModuleKey {
5
5
  /**
6
6
  * module name
7
7
  */
8
- name?: string;
8
+ name: string;
9
9
  /**
10
10
  * module description
11
11
  */
12
- description?: string;
12
+ description: string;
13
13
  /**
14
14
  * Settings UI module
15
15
  */
@@ -2,4 +2,4 @@
2
2
  import { Response } from 'express';
3
3
  import { CrowdinClientRequest } from '../../types';
4
4
  import { AiRequestProcessorModule, AiStreamProcessorModule } from './types';
5
- export default function handle(module: AiRequestProcessorModule | AiStreamProcessorModule, canHandleStream?: boolean): (req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>> | CrowdinClientRequest, res: Response<any, Record<string, any>>, next: Function) => void;
5
+ export default function handle(module: AiRequestProcessorModule | AiStreamProcessorModule, canHandleStream?: boolean): (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;
@@ -2,4 +2,4 @@
2
2
  import { Response } from 'express';
3
3
  import { CrowdinClientRequest } from '../../../types';
4
4
  import { AiTool } from '../types';
5
- export default function handle(aiTool: AiTool): (req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>> | CrowdinClientRequest, res: Response<any, Record<string, any>>, next: Function) => void;
5
+ export default function handle(aiTool: AiTool): (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;
@@ -37,7 +37,7 @@ function registerAiToolWidgets({ config, app }) {
37
37
  const tools = Array.isArray(config.aiToolsWidget) ? config.aiToolsWidget : [config.aiToolsWidget];
38
38
  for (const tool of tools) {
39
39
  if ((0, util_1.isUniqueFunctionName)(tool)) {
40
- app.use((0, util_1.getAiToolWidgetUrl)(tool), (0, ui_module_1.default)({ config, moduleType: tool.key }), (0, render_ui_module_1.default)(tool, config));
40
+ app.use((0, util_1.getAiToolWidgetUrl)(tool), (0, ui_module_1.default)({ config, moduleType: tool.key }), (0, render_ui_module_1.default)(tool));
41
41
  }
42
42
  else {
43
43
  throw new Error(`The function name '${tool.function.name}' is not unique within aiTools and aiToolsWidget`);
@@ -256,9 +256,14 @@ function addDefaultApiEndpoints(app, config) {
256
256
  * content:
257
257
  * application/json:
258
258
  * schema:
259
+ * type: object
259
260
  * properties:
260
261
  * data:
261
262
  * $ref: '#/components/schemas/IntegrationFiles'
263
+ * message:
264
+ * type: string
265
+ * nullable: true
266
+ * description: 'Optional message (e.g., error info)'
262
267
  *
263
268
  */
264
269
  app.get('/integration-files', api_call_1.default, json_response_1.default, (0, crowdin_client_1.default)({
@@ -330,30 +335,36 @@ function addDefaultApiEndpoints(app, config) {
330
335
  * tags:
331
336
  * - 'Jobs'
332
337
  * summary: 'List Jobs'
338
+ * description: 'Retrieve a paginated list of all jobs for the current integration'
333
339
  * operationId: job.list
334
340
  * parameters:
335
341
  * - $ref: '#/components/parameters/ProjectId'
336
342
  * - name: limit
337
343
  * in: query
338
344
  * required: false
339
- * description: 'Number of jobs to return'
345
+ * description: 'Maximum number of jobs to return'
340
346
  * schema:
341
347
  * type: integer
348
+ * default: 25
349
+ * minimum: 1
350
+ * maximum: 100
342
351
  * example: 25
343
352
  * - name: offset
344
353
  * in: query
345
354
  * required: false
346
- * description: 'Number of jobs to skip'
355
+ * description: 'Number of jobs to skip for pagination'
347
356
  * schema:
348
357
  * type: integer
358
+ * default: 0
359
+ * minimum: 0
349
360
  * example: 0
350
361
  * responses:
351
362
  * 200:
352
- * description: 'Job information retrieved successfully'
363
+ * description: 'List of jobs retrieved successfully'
353
364
  * content:
354
365
  * application/json:
355
366
  * schema:
356
- * $ref: '#/components/schemas/JobResponse'
367
+ * $ref: '#/components/schemas/JobListResponse'
357
368
  */
358
369
  app.get('/all-jobs', api_call_1.default, json_response_1.default, (0, crowdin_client_1.default)({
359
370
  config,
@@ -368,12 +379,14 @@ function addDefaultApiEndpoints(app, config) {
368
379
  * tags:
369
380
  * - 'Jobs'
370
381
  * summary: 'Get Job Info'
382
+ * description: 'Retrieve detailed information about a specific job including progress, status, and timing data'
371
383
  * operationId: job.info
372
384
  * parameters:
373
385
  * - $ref: '#/components/parameters/ProjectId'
374
386
  * - name: jobId
375
387
  * in: query
376
388
  * required: true
389
+ * description: 'Unique identifier of the job. Get via [List Jobs](#operation/job.list)'
377
390
  * schema:
378
391
  * type: string
379
392
  * example: 067da473-fc0b-43e3-b0a2-09d26af130c1
@@ -383,7 +396,19 @@ function addDefaultApiEndpoints(app, config) {
383
396
  * content:
384
397
  * application/json:
385
398
  * schema:
386
- * $ref: '#/components/schemas/JobResponse'
399
+ * $ref: '#/components/schemas/JobInfoResponse'
400
+ * 400:
401
+ * description: 'Bad Request - jobId parameter is missing'
402
+ * content:
403
+ * application/json:
404
+ * schema:
405
+ * $ref: '#/components/schemas/ErrorResponse'
406
+ * 404:
407
+ * description: 'Job not found'
408
+ * content:
409
+ * application/json:
410
+ * schema:
411
+ * $ref: '#/components/schemas/ErrorResponse'
387
412
  */
388
413
  app.get('/job-info', api_call_1.default, json_response_1.default, (0, crowdin_client_1.default)({
389
414
  config,
@@ -429,18 +454,32 @@ function addDefaultApiEndpoints(app, config) {
429
454
  * tags:
430
455
  * - 'Jobs'
431
456
  * summary: 'Cancel Job'
457
+ * description: 'Cancel a running job. Only jobs with status "created" or "inProgress" can be canceled'
432
458
  * operationId: job.cancel
433
459
  * parameters:
434
460
  * - $ref: '#/components/parameters/ProjectId'
435
461
  * - name: jobId
436
462
  * in: query
437
463
  * required: true
464
+ * description: 'Unique identifier of the job to cancel. Get via [List Jobs](#operation/job.list)'
438
465
  * schema:
439
466
  * type: string
440
467
  * example: 067da473-fc0b-43e3-b0a2-09d26af130c1
441
468
  * responses:
442
469
  * 204:
443
470
  * description: 'Job canceled successfully'
471
+ * 400:
472
+ * description: 'Bad Request - jobId parameter is missing'
473
+ * content:
474
+ * application/json:
475
+ * schema:
476
+ * $ref: '#/components/schemas/ErrorResponse'
477
+ * 404:
478
+ * description: 'Job not found'
479
+ * content:
480
+ * application/json:
481
+ * schema:
482
+ * $ref: '#/components/schemas/ErrorResponse'
444
483
  */
445
484
  app.delete('/jobs', api_call_1.default, json_response_1.default, (0, crowdin_client_1.default)({
446
485
  config,
@@ -460,7 +499,7 @@ function addDefaultApiEndpoints(app, config) {
460
499
  * - $ref: '#/components/parameters/ProjectId'
461
500
  * responses:
462
501
  * 200:
463
- * description: 'File translation progress'
502
+ * description: 'Application Settings'
464
503
  * content:
465
504
  * application/json:
466
505
  * schema:
@@ -468,7 +507,7 @@ function addDefaultApiEndpoints(app, config) {
468
507
  * data:
469
508
  * $ref: '#/components/schemas/SettingsResponse'
470
509
  */
471
- app.get('/settings', api_call_1.default, (0, crowdin_client_1.default)({
510
+ app.get('/settings', api_call_1.default, json_response_1.default, (0, crowdin_client_1.default)({
472
511
  config,
473
512
  optional: false,
474
513
  checkSubscriptionExpiration: true,
@@ -510,6 +549,7 @@ function addDefaultApiEndpoints(app, config) {
510
549
  * - name: provider
511
550
  * in: query
512
551
  * required: true
552
+ * description: 'Data source: "crowdin" for Crowdin file-language pairs, "integration" for integration files with sync schedule'
513
553
  * schema:
514
554
  * type: string
515
555
  * enum:
@@ -638,6 +678,17 @@ function addSwagerApiDocumentation(app, config) {
638
678
  servers: [
639
679
  {
640
680
  url: `{protocol}//{host}/api/v2/applications/${config.identifier}/api`,
681
+ variables: {
682
+ protocol: {
683
+ default: 'https',
684
+ enum: ['https', 'http'],
685
+ description: 'Protocol (https for production)',
686
+ },
687
+ host: {
688
+ default: 'crowdin.com',
689
+ description: 'Crowdin host (crowdin.com or {organization}.crowdin.com for Enterprise)',
690
+ },
691
+ },
641
692
  },
642
693
  ],
643
694
  },
@@ -4,4 +4,5 @@
4
4
  * - name: 'Files'
5
5
  * - name: 'Settings'
6
6
  * - name: 'Login'
7
+ * - name: 'Jobs'
7
8
  */
@@ -5,4 +5,5 @@
5
5
  * - name: 'Files'
6
6
  * - name: 'Settings'
7
7
  * - name: 'Login'
8
+ * - name: 'Jobs'
8
9
  */