@crowdin/app-project-module 0.106.0 → 0.107.0-cf-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 (161) hide show
  1. package/out/app-test/integration/get-integration-files.js +0 -1
  2. package/out/app-test/integration/mocks/mock-axios.js +0 -1
  3. package/out/app-test/integration/update-crowdin.js +0 -1
  4. package/out/app-test/integration/update-integration.js +0 -1
  5. package/out/index.d.ts +1 -0
  6. package/out/index.js +30 -12
  7. package/out/middlewares/crowdin-client.d.ts +1 -1
  8. package/out/middlewares/integration-credentials.d.ts +1 -1
  9. package/out/middlewares/integration-credentials.js +4 -1
  10. package/out/middlewares/render-ui-module.d.ts +3 -3
  11. package/out/middlewares/render-ui-module.js +9 -13
  12. package/out/middlewares/ui-module.d.ts +1 -1
  13. package/out/middlewares/ui-module.js +10 -1
  14. package/out/modules/about.d.ts +2 -1
  15. package/out/modules/about.js +10 -3
  16. package/out/modules/ai-prompt-provider/handlers/compile.d.ts +1 -1
  17. package/out/modules/ai-prompt-provider/index.js +2 -2
  18. package/out/modules/ai-provider/handlers/chat-completions.d.ts +1 -1
  19. package/out/modules/ai-provider/handlers/chat-completions.js +0 -1
  20. package/out/modules/ai-provider/handlers/get-model-list.d.ts +1 -1
  21. package/out/modules/ai-provider/index.js +2 -2
  22. package/out/modules/ai-provider/types.d.ts +2 -2
  23. package/out/modules/ai-provider/util/index.js +0 -2
  24. package/out/modules/ai-request-processors/handler.d.ts +1 -1
  25. package/out/modules/ai-tools/handlers/tool-calls.d.ts +1 -1
  26. package/out/modules/ai-tools/index.js +1 -1
  27. package/out/modules/api/api.js +0 -1
  28. package/out/modules/auth-guard/handlers/verify.d.ts +1 -1
  29. package/out/modules/auth-guard/index.js +1 -1
  30. package/out/modules/automation-action/handlers/execute.d.ts +1 -1
  31. package/out/modules/automation-action/handlers/input-schema.d.ts +1 -1
  32. package/out/modules/automation-action/handlers/output-schema.d.ts +1 -1
  33. package/out/modules/automation-action/handlers/validate-settings.d.ts +1 -1
  34. package/out/modules/automation-action/index.js +1 -1
  35. package/out/modules/context-menu/index.js +2 -2
  36. package/out/modules/custom-mt/handlers/translate.d.ts +2 -2
  37. package/out/modules/custom-mt/handlers/translate.js +53 -4
  38. package/out/modules/custom-mt/index.js +6 -3
  39. package/out/modules/custom-mt/types.d.ts +14 -2
  40. package/out/modules/custom-spell-check/handlers/get-languages-list.d.ts +1 -1
  41. package/out/modules/custom-spell-check/handlers/spell-check.d.ts +1 -1
  42. package/out/modules/custom-spell-check/index.js +4 -4
  43. package/out/modules/editor-right-panel/index.js +1 -1
  44. package/out/modules/external-qa-check/handlers/validate.d.ts +1 -1
  45. package/out/modules/external-qa-check/index.js +2 -2
  46. package/out/modules/file-processing/handlers/custom-file-format.d.ts +7 -2
  47. package/out/modules/file-processing/handlers/custom-file-format.js +59 -19
  48. package/out/modules/file-processing/handlers/file-download.d.ts +1 -1
  49. package/out/modules/file-processing/handlers/file-download.js +5 -0
  50. package/out/modules/file-processing/handlers/pre-post-process.d.ts +1 -1
  51. package/out/modules/file-processing/handlers/pre-post-process.js +34 -14
  52. package/out/modules/file-processing/handlers/translations-alignment.d.ts +1 -1
  53. package/out/modules/file-processing/index.js +12 -2
  54. package/out/modules/file-processing/util/defaults.js +50 -6
  55. package/out/modules/file-processing/util/files.js +2 -1
  56. package/out/modules/form-data-display.d.ts +1 -1
  57. package/out/modules/form-data-save.d.ts +1 -1
  58. package/out/modules/install.d.ts +1 -1
  59. package/out/modules/integration/handlers/crowdin-file-progress.d.ts +1 -1
  60. package/out/modules/integration/handlers/crowdin-files.d.ts +1 -1
  61. package/out/modules/integration/handlers/crowdin-project.d.ts +1 -1
  62. package/out/modules/integration/handlers/crowdin-update.d.ts +1 -1
  63. package/out/modules/integration/handlers/crowdin-webhook.d.ts +1 -1
  64. package/out/modules/integration/handlers/integration-data.d.ts +1 -1
  65. package/out/modules/integration/handlers/integration-login.d.ts +1 -1
  66. package/out/modules/integration/handlers/integration-logout.d.ts +1 -1
  67. package/out/modules/integration/handlers/integration-update.d.ts +1 -1
  68. package/out/modules/integration/handlers/integration-webhook.d.ts +1 -1
  69. package/out/modules/integration/handlers/invite-users.d.ts +1 -1
  70. package/out/modules/integration/handlers/job-cancel.d.ts +1 -1
  71. package/out/modules/integration/handlers/job-info-deprecated.d.ts +1 -1
  72. package/out/modules/integration/handlers/job-info.d.ts +1 -1
  73. package/out/modules/integration/handlers/job-list.d.ts +1 -1
  74. package/out/modules/integration/handlers/main.d.ts +1 -1
  75. package/out/modules/integration/handlers/main.js +13 -1
  76. package/out/modules/integration/handlers/oauth-login.d.ts +1 -1
  77. package/out/modules/integration/handlers/oauth-login.js +10 -2
  78. package/out/modules/integration/handlers/oauth-polling.d.ts +1 -1
  79. package/out/modules/integration/handlers/oauth-url.d.ts +1 -1
  80. package/out/modules/integration/handlers/settings-save.d.ts +1 -1
  81. package/out/modules/integration/handlers/settings.d.ts +1 -1
  82. package/out/modules/integration/handlers/sync-settings-save.d.ts +1 -1
  83. package/out/modules/integration/handlers/sync-settings-save.js +0 -2
  84. package/out/modules/integration/handlers/sync-settings.d.ts +1 -1
  85. package/out/modules/integration/handlers/user-errors.d.ts +1 -1
  86. package/out/modules/integration/handlers/users.d.ts +1 -1
  87. package/out/modules/integration/index.js +12 -33
  88. package/out/modules/integration/util/cron.js +1 -10
  89. package/out/modules/integration/util/job.js +0 -4
  90. package/out/modules/integration/util/snapshot.js +1 -5
  91. package/out/modules/integration/util/webhooks.js +1 -8
  92. package/out/modules/manifest.js +15 -13
  93. package/out/modules/modal/index.js +2 -2
  94. package/out/modules/organization-menu/index.js +5 -4
  95. package/out/modules/organization-settings-menu/index.js +5 -4
  96. package/out/modules/profile-resources-menu/index.js +5 -4
  97. package/out/modules/profile-settings-menu/index.js +5 -4
  98. package/out/modules/project-menu/index.js +1 -1
  99. package/out/modules/project-menu-crowdsource/index.js +1 -1
  100. package/out/modules/project-reports/index.js +3 -2
  101. package/out/modules/project-tools/index.js +3 -2
  102. package/out/modules/status.d.ts +1 -1
  103. package/out/modules/status.js +12 -3
  104. package/out/modules/subscription-paid.d.ts +1 -1
  105. package/out/modules/uninstall.d.ts +1 -1
  106. package/out/modules/webhooks/handlers/webhook-handler.d.ts +1 -1
  107. package/out/modules/webhooks/handlers/webhook-handler.js +30 -15
  108. package/out/modules/webhooks/types.d.ts +7 -0
  109. package/out/modules/workflow-step-type/handlers/delete-step.d.ts +1 -1
  110. package/out/modules/workflow-step-type/handlers/step-settings-save.d.ts +1 -1
  111. package/out/modules/workflow-step-type/index.js +2 -2
  112. package/out/storage/d1.d.ts +107 -0
  113. package/out/storage/d1.js +829 -0
  114. package/out/storage/index.js +8 -2
  115. package/out/storage/mysql.js +0 -3
  116. package/out/storage/postgre.js +0 -1
  117. package/out/storage/sqlite.js +0 -3
  118. package/out/types.d.ts +41 -2
  119. package/out/util/axios.js +0 -1
  120. package/out/util/credentials-masker.d.ts +1 -1
  121. package/out/util/cron.d.ts +29 -0
  122. package/out/util/cron.js +87 -0
  123. package/out/util/index.d.ts +12 -1
  124. package/out/util/index.js +54 -6
  125. package/out/util/jsx-renderer.d.ts +6 -0
  126. package/out/util/jsx-renderer.js +13 -0
  127. package/out/util/logger.js +0 -4
  128. package/out/util/static-files.d.ts +19 -0
  129. package/out/util/static-files.js +87 -0
  130. package/out/views/AboutPage.d.ts +10 -0
  131. package/out/views/AboutPage.js +76 -0
  132. package/out/views/ErrorPage.d.ts +18 -0
  133. package/out/views/ErrorPage.js +56 -0
  134. package/out/views/FormPage.d.ts +14 -0
  135. package/out/views/FormPage.js +28 -0
  136. package/out/views/InstallPage.d.ts +10 -0
  137. package/out/views/InstallPage.js +22 -0
  138. package/out/views/LoginPage.d.ts +33 -0
  139. package/out/views/LoginPage.js +200 -0
  140. package/out/views/MainPage.d.ts +81 -0
  141. package/out/views/MainPage.js +1784 -0
  142. package/out/views/OAuthPage.d.ts +7 -0
  143. package/out/views/OAuthPage.js +17 -0
  144. package/out/views/SubscriptionPage.d.ts +7 -0
  145. package/out/views/SubscriptionPage.js +26 -0
  146. package/out/views/index.d.ts +13 -0
  147. package/out/views/index.js +25 -0
  148. package/out/views/layout/Head.d.ts +9 -0
  149. package/out/views/layout/Head.js +54 -0
  150. package/package.json +33 -18
  151. package/out/util/handlebars.d.ts +0 -1
  152. package/out/util/handlebars.js +0 -46
  153. package/out/views/about.handlebars +0 -102
  154. package/out/views/error.handlebars +0 -54
  155. package/out/views/form.handlebars +0 -31
  156. package/out/views/install.handlebars +0 -16
  157. package/out/views/login.handlebars +0 -332
  158. package/out/views/main.handlebars +0 -2042
  159. package/out/views/oauth.handlebars +0 -11
  160. package/out/views/partials/head.handlebars +0 -53
  161. package/out/views/subscription.handlebars +0 -26
@@ -62,7 +62,6 @@ const getIntegrationFilesTest = ({ appConfig, integrationTestConfig, }) => __awa
62
62
  yield (0, util_1.assert)(() => (0, globals_1.expect)(allFiles).toHaveLength(expectedTree.length), `Received files length: ${allFiles.length}, but expected tree length ${expectedTree.length}`);
63
63
  yield (0, util_1.assert)(() => (0, globals_1.expect)(allFiles).toEqual(globals_1.expect.arrayContaining(expectedTree.map((node) => globals_1.expect.objectContaining(node)))), 'Received files properties do not match to the expected properties');
64
64
  if (getIntegrationFiles === null || getIntegrationFiles === void 0 ? void 0 : getIntegrationFiles.extraChecks) {
65
- // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
66
65
  // @ts-ignore
67
66
  yield (0, util_1.assert)(() => getIntegrationFiles.extraChecks(), 'ExtraChecks for getIntegrationFiles() fails');
68
67
  }
@@ -10,7 +10,6 @@ const mock = Object.assign(Object.assign({}, mockOriginalAxios), { get: jest.fn(
10
10
  const storageId = file === null || file === void 0 ? void 0 : file.storageId;
11
11
  expect(storageId).not.toBeUndefined();
12
12
  return {
13
- // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
14
13
  // @ts-ignore
15
14
  data: index_1.mockStoragesById[storageId].data,
16
15
  };
@@ -134,7 +134,6 @@ const updateCrowdinTest = ({ appConfig, integrationTestConfig, }) => __awaiter(v
134
134
  yield (0, util_1.assert)(() => (0, globals_1.expect)(createdDirectories).toHaveLength(expectedDirectories.length), `Directories created: ${createdDirectories.length}, but expected: ${expectedDirectories.length}`);
135
135
  yield (0, util_1.assert)(() => (0, globals_1.expect)(createdDirectories).toEqual(globals_1.expect.arrayContaining(expectedDirectories.map((f) => globals_1.expect.objectContaining(f)))), 'The properties of the created directories do not match to the expected');
136
136
  if (updateCrowdin === null || updateCrowdin === void 0 ? void 0 : updateCrowdin.extraChecks) {
137
- // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
138
137
  // @ts-ignore
139
138
  yield (0, util_1.assert)(() => updateCrowdin.extraChecks({ request, result }), 'ExtraChecks for updateCrowdin() fails');
140
139
  }
@@ -75,7 +75,6 @@ const updateIntegrationTest = ({ appConfig, integrationTestConfig, }) => __await
75
75
  }
76
76
  if (updateIntegration === null || updateIntegration === void 0 ? void 0 : updateIntegration.extraChecks) {
77
77
  yield (0, util_1.assert)(
78
- // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
79
78
  // @ts-ignore
80
79
  () => updateIntegration.extraChecks({ request, result }), 'ExtraChecks for updateIntegration() fails');
81
80
  }
package/out/index.d.ts CHANGED
@@ -4,6 +4,7 @@ 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';
7
8
  export { express };
8
9
  export declare const metadataStore: CrowdinMetadataStore;
9
10
  export declare function createApp(clientConfig: ClientConfig): void;
package/out/index.js CHANGED
@@ -50,11 +50,12 @@ 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"));
53
55
  const types_1 = require("./types");
54
56
  const util_1 = require("./util");
55
57
  const form_schema_1 = require("./util/form-schema");
56
58
  const connection_1 = require("./util/connection");
57
- const handlebars_1 = require("./util/handlebars");
58
59
  const logger = __importStar(require("./util/logger"));
59
60
  const logger_1 = require("./util/logger");
60
61
  const terminus_express_1 = __importDefault(require("./util/terminus-express"));
@@ -63,6 +64,8 @@ const credentials_masker_1 = require("./util/credentials-masker");
63
64
  Object.defineProperty(exports, "getRequestCredentialsMasker", { enumerable: true, get: function () { return credentials_masker_1.getRequestCredentialsMasker; } });
64
65
  Object.defineProperty(exports, "postRequestCredentialsMasker", { enumerable: true, get: function () { return credentials_masker_1.postRequestCredentialsMasker; } });
65
66
  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");
66
69
  //apps
67
70
  const apiApp = __importStar(require("./modules/api"));
68
71
  const contextMenuApp = __importStar(require("./modules/context-menu"));
@@ -140,6 +143,27 @@ function addCrowdinEndpoints(app, clientConfig) {
140
143
  }
141
144
  storage.initialize(config);
142
145
  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
+ });
143
167
  app.use((req, res, next) => {
144
168
  if (config.webhooks && req.path === '/webhooks') {
145
169
  return terminus_express_1.default.raw({ type: '*/*', limit: '50mb' })(req, res, next);
@@ -153,11 +177,8 @@ function addCrowdinEndpoints(app, clientConfig) {
153
177
  app.use(logsFormatter.contextResolverMiddleware());
154
178
  app.use(logsFormatter.expressMiddleware());
155
179
  }
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));
180
+ app.use('/assets', (0, static_files_1.serveStatic)(config, config.assetsPath || 'static'));
181
+ app.use('/', (0, util_2.serveLogo)(config));
161
182
  app.get('/manifest.json', json_response_1.default, (0, manifest_1.default)(config));
162
183
  app.get('/', (0, about_1.default)(config));
163
184
  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)) {
@@ -192,7 +213,7 @@ function addCrowdinEndpoints(app, clientConfig) {
192
213
  contextMenuApp.register({ config, app });
193
214
  //other apps only work in authorized context
194
215
  if (!(0, util_1.isAuthorizedConfig)(config)) {
195
- return Object.assign({}, exports.metadataStore);
216
+ return Object.assign(Object.assign({}, exports.metadataStore), { cron: cron.getCron() });
196
217
  }
197
218
  app.post('/installed', (0, install_1.default)(config));
198
219
  app.post('/uninstall', (0, uninstall_1.default)(config));
@@ -225,7 +246,7 @@ function addCrowdinEndpoints(app, clientConfig) {
225
246
  automationAction.register({ config, app });
226
247
  authGuard.register({ config, app });
227
248
  addFormSchema({ config, app });
228
- return Object.assign(Object.assign({}, exports.metadataStore), { storage: storage.getStorage(), establishCrowdinConnection: (authRequest, moduleKey) => {
249
+ return Object.assign(Object.assign({}, exports.metadataStore), { storage: storage.getStorage(), cron: cron.getCron(), establishCrowdinConnection: (authRequest, moduleKey) => {
229
250
  let jwtToken = '';
230
251
  if (typeof authRequest === 'string') {
231
252
  jwtToken = authRequest;
@@ -279,9 +300,6 @@ function convertClientConfig(clientConfig) {
279
300
  const clientSecret = clientConfig.clientSecret || process.env.CROWDIN_CLIENT_SECRET;
280
301
  const port = clientConfig.port || process.env.PORT || 3000;
281
302
  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
- }
285
303
  if (clientConfig.authenticationType !== types_1.AuthenticationType.NONE) {
286
304
  if (!clientId && !clientSecret) {
287
305
  throw new Error('Missing [clientId, clientSecret] parameters');
@@ -291,7 +309,7 @@ function convertClientConfig(clientConfig) {
291
309
  clientConfig.api = Object.assign({ default: true }, clientConfig.api);
292
310
  }
293
311
  clientConfig.enableStatusPage = Object.assign({ database: true, filesystem: true }, (clientConfig.enableStatusPage || {}));
294
- return Object.assign(Object.assign({}, clientConfig), { baseUrl: baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl, clientId,
312
+ return Object.assign(Object.assign({}, clientConfig), { baseUrl: baseUrl ? (baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl) : undefined, clientId,
295
313
  clientSecret, awsConfig: {
296
314
  tmpBucketName,
297
315
  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: 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;
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;
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("../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;
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;
@@ -37,6 +37,7 @@ 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");
40
41
  function handle(config, integration, optional = false) {
41
42
  return (0, util_1.runAsyncWrapper)((req, res, next) => __awaiter(this, void 0, void 0, function* () {
42
43
  let clientId = req.crowdinContext.clientId;
@@ -89,7 +90,9 @@ function handle(config, integration, optional = false) {
89
90
  else {
90
91
  (0, logger_1.temporaryErrorDebug)('Access denied: integration-credentials', req);
91
92
  }
92
- return res.render('error', errorOptions);
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);
93
96
  }
94
97
  try {
95
98
  req.integrationCredentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
@@ -1,4 +1,4 @@
1
1
  /// <reference types="qs" />
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;
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;
@@ -8,29 +8,25 @@ 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
- };
14
11
  Object.defineProperty(exports, "__esModule", { value: true });
15
- const express_1 = __importDefault(require("express"));
16
12
  const util_1 = require("../util");
17
- function handle(moduleConfig) {
13
+ const static_files_1 = require("../util/static-files");
14
+ const views_1 = require("../views");
15
+ function handle(moduleConfig, config) {
18
16
  return (0, util_1.runAsyncWrapper)((req, res, next) => __awaiter(this, void 0, void 0, function* () {
19
17
  if (moduleConfig.formSchema) {
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`,
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`,
27
21
  formSchema: JSON.stringify(moduleConfig.formSchema),
28
22
  formUiSchema: moduleConfig.formUiSchema ? JSON.stringify(moduleConfig.formUiSchema) : '{}',
29
23
  formPatchDataUrl: moduleConfig.formPatchDataUrl,
30
24
  });
25
+ res.setHeader('Content-Type', 'text/html; charset=utf-8');
26
+ return res.send(html);
31
27
  }
32
28
  if (moduleConfig.uiPath) {
33
- return express_1.default.static(moduleConfig.uiPath)(req, res, next);
29
+ return (0, static_files_1.serveStatic)(config, moduleConfig.uiPath)(req, res, next);
34
30
  }
35
31
  throw new Error('uiPath or formSchema should be provided for module');
36
32
  }));
@@ -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: 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;
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;
@@ -16,8 +16,15 @@ 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");
19
20
  function handle({ config, allowUnauthorized = false, moduleType, }) {
20
21
  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
+ }
21
28
  if (allowUnauthorized) {
22
29
  next();
23
30
  return;
@@ -60,7 +67,9 @@ function handle({ config, allowUnauthorized = false, moduleType, }) {
60
67
  accountType: credentials.type,
61
68
  });
62
69
  if (expired) {
63
- return res.render('subscription', { subscribeLink });
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);
64
73
  }
65
74
  }
66
75
  next();
@@ -5,5 +5,6 @@ export declare function getAboutPageOptions(config: Config | UnauthorizedConfig)
5
5
  logo: string;
6
6
  manifest: string;
7
7
  storeLink: string;
8
+ showDebugLink: boolean;
8
9
  }>;
9
- export default function handle(config: Config | UnauthorizedConfig): (req: Request, res: Response, next: NextFunction) => Promise<void>;
10
+ export default function handle(config: Config | UnauthorizedConfig): (req: Request, res: Response, next: NextFunction) => Promise<Response<any, Record<string, any>> | undefined>;
@@ -16,6 +16,8 @@ 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");
19
21
  function getAboutPageOptions(config) {
20
22
  return __awaiter(this, void 0, void 0, function* () {
21
23
  let detailPage = '';
@@ -30,9 +32,10 @@ function getAboutPageOptions(config) {
30
32
  }
31
33
  return {
32
34
  name: config.name,
33
- logo: (0, util_1.getLogoUrl)(),
35
+ logo: (0, util_1.getLogoUrl)(config),
34
36
  manifest: config.baseUrl + '/manifest.json',
35
37
  storeLink: (config === null || config === void 0 ? void 0 : config.detailPage) || detailPage,
38
+ showDebugLink: process.env.SHOW_DEBUG_LINK === 'true',
36
39
  };
37
40
  });
38
41
  }
@@ -43,7 +46,9 @@ function handle(config) {
43
46
  const jwtToken = (0, crowdin_client_1.getToken)(req);
44
47
  if (!jwtToken) {
45
48
  const options = yield getAboutPageOptions(config);
46
- return res.render('about', options);
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);
47
52
  }
48
53
  else {
49
54
  next();
@@ -51,7 +56,9 @@ function handle(config) {
51
56
  }
52
57
  }
53
58
  const options = yield getAboutPageOptions(config);
54
- return res.render('about', options);
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);
55
62
  });
56
63
  }
57
64
  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: 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;
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;
@@ -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));
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));
25
25
  }
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); });
26
+ app.use('/logo/ai-prompt-provider', (0, util_1.serveLogo)(config, config.aiPromptProvider));
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: 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;
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;
@@ -57,7 +57,6 @@ function handle(aiProvider) {
57
57
  isStream,
58
58
  tools,
59
59
  toolChoice,
60
- /* eslint-disable @typescript-eslint/camelcase */
61
60
  sendEvent: ({ content, role, tool_calls }) => __awaiter(this, void 0, void 0, function* () {
62
61
  if (!isStream) {
63
62
  chunks.push({ content, role, tool_calls });
@@ -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: 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;
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;
@@ -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));
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));
20
20
  }
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); });
21
+ app.use('/logo/aiprovider', (0, util_1.serveLogo)(config, config.aiProvider));
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
  */
@@ -24,7 +24,6 @@ function normalizeContentParts(content) {
24
24
  ? content.map((part) => part.type === 'image'
25
25
  ? {
26
26
  type: 'image_url',
27
- // eslint-disable-next-line @typescript-eslint/camelcase
28
27
  image_url: {
29
28
  url: part.url,
30
29
  },
@@ -79,7 +78,6 @@ function mergeToolCalls(chunks) {
79
78
  }
80
79
  exports.mergeToolCalls = mergeToolCalls;
81
80
  function mergeChatCompletionChunks(chunks) {
82
- /* eslint-disable @typescript-eslint/camelcase */
83
81
  const tool_calls = mergeToolCalls(chunks);
84
82
  return [
85
83
  {
@@ -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: 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;
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;
@@ -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: 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;
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;
@@ -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));
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));
41
41
  }
42
42
  else {
43
43
  throw new Error(`The function name '${tool.function.name}' is not unique within aiTools and aiToolsWidget`);
@@ -164,7 +164,6 @@ function updateCrowdinContext(req, context) {
164
164
  if (context.clientId.includes('undefined')) {
165
165
  context.clientId = `${context.jwtPayload.domain || context.jwtPayload.context.organization_id}__${(_b = req.body) === null || _b === void 0 ? void 0 : _b.projectId}__${context.jwtPayload.sub}`;
166
166
  }
167
- // eslint-disable-next-line @typescript-eslint/camelcase
168
167
  context.jwtPayload.context.project_id = (_c = req.body) === null || _c === void 0 ? void 0 : _c.projectId;
169
168
  }
170
169
  return context;
@@ -2,4 +2,4 @@
2
2
  import { Response } from 'express';
3
3
  import { CrowdinClientRequest } from '../../../types';
4
4
  import { AuthGuardModule } from '../types';
5
- export default function verifyHandler(authGuardModules: AuthGuardModule[]): (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;
5
+ export default function verifyHandler(authGuardModules: AuthGuardModule[]): (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;
@@ -22,7 +22,7 @@ function register({ config, app }) {
22
22
  authGuardModules.forEach((module, index) => {
23
23
  if (module.settingsUiModule) {
24
24
  const moduleKey = module.key || `${config.identifier}-auth-guard-${index}`;
25
- app.use(`/auth-guard/${moduleKey}/settings`, (0, ui_module_1.default)({ config, moduleType: moduleKey }), (0, render_ui_module_1.default)(module.settingsUiModule));
25
+ app.use(`/auth-guard/${moduleKey}/settings`, (0, ui_module_1.default)({ config, moduleType: moduleKey }), (0, render_ui_module_1.default)(module.settingsUiModule, config));
26
26
  }
27
27
  });
28
28
  // Register verification endpoint
@@ -2,4 +2,4 @@
2
2
  import { Response } from 'express';
3
3
  import { CrowdinClientRequest } from '../../../types';
4
4
  import { AutomationActionModule } from '../types';
5
- export default function getExecuteHandler(automationAction: AutomationActionModule): (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;
5
+ export default function getExecuteHandler(automationAction: AutomationActionModule): (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;
@@ -2,4 +2,4 @@
2
2
  import { Response } from 'express';
3
3
  import { AutomationActionModule } from '../types';
4
4
  import { CrowdinClientRequest } from '../../../types';
5
- export default function getInputSchemaHandler(automationAction: AutomationActionModule): (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;
5
+ export default function getInputSchemaHandler(automationAction: AutomationActionModule): (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;
@@ -2,4 +2,4 @@
2
2
  import { Response } from 'express';
3
3
  import { AutomationActionModule } from '../types';
4
4
  import { CrowdinClientRequest } from '../../../types';
5
- export default function getOutputSchemaHandler(automationAction: AutomationActionModule): (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;
5
+ export default function getOutputSchemaHandler(automationAction: AutomationActionModule): (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;
@@ -2,4 +2,4 @@
2
2
  import { Response } from 'express';
3
3
  import { AutomationActionModule } from '../types';
4
4
  import { CrowdinClientRequest } from '../../../types';
5
- export default function getInputSchemaHandler(automationAction: AutomationActionModule): (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;
5
+ export default function getInputSchemaHandler(automationAction: AutomationActionModule): (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;
@@ -38,7 +38,7 @@ function register({ config, app }) {
38
38
  moduleKey: automationAction.key,
39
39
  }), (0, execute_1.default)(automationAction));
40
40
  if (automationAction.settingsUiModule) {
41
- app.use((0, util_1.getAutomationActionUrl)('/automation-action', automationAction), (0, ui_module_1.default)({ config, moduleType: automationAction.key }), (0, render_ui_module_1.default)(automationAction.settingsUiModule));
41
+ app.use((0, util_1.getAutomationActionUrl)('/automation-action', automationAction), (0, ui_module_1.default)({ config, moduleType: automationAction.key }), (0, render_ui_module_1.default)(automationAction.settingsUiModule, config));
42
42
  }
43
43
  }
44
44
  }
@@ -16,14 +16,14 @@ function register({ config, app }) {
16
16
  if (Array.isArray(config.contextMenu)) {
17
17
  config.contextMenu.forEach((contextMenu) => {
18
18
  if ((contextMenu === null || contextMenu === void 0 ? void 0 : contextMenu.uiPath) || (contextMenu === null || contextMenu === void 0 ? void 0 : contextMenu.formSchema)) {
19
- app.use(`/context-${contextMenu.key}`, (0, ui_module_1.default)({ config, allowUnauthorized, moduleType: contextMenu.key }), (0, render_ui_module_1.default)(contextMenu));
19
+ app.use(`/context-${contextMenu.key}`, (0, ui_module_1.default)({ config, allowUnauthorized, moduleType: contextMenu.key }), (0, render_ui_module_1.default)(contextMenu, config));
20
20
  }
21
21
  });
22
22
  }
23
23
  else {
24
24
  // backward compatibility will be removed after migration
25
25
  if (((_a = config.contextMenu) === null || _a === void 0 ? void 0 : _a.uiPath) || ((_b = config.contextMenu) === null || _b === void 0 ? void 0 : _b.formSchema)) {
26
- app.use('/context', (0, ui_module_1.default)({ config, allowUnauthorized, moduleType: config.contextMenu.key }), (0, render_ui_module_1.default)(config.contextMenu));
26
+ app.use('/context', (0, ui_module_1.default)({ config, allowUnauthorized, moduleType: config.contextMenu.key }), (0, render_ui_module_1.default)(config.contextMenu, config));
27
27
  }
28
28
  }
29
29
  }
@@ -1,5 +1,5 @@
1
1
  /// <reference types="qs" />
2
2
  import { Response } from 'express';
3
3
  import { CrowdinClientRequest } from '../../../types';
4
- import { CustomMTLogic } from '../types';
5
- export default function handle(config: CustomMTLogic): (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;
4
+ import { CustomMTHandleOptions } from '../types';
5
+ export default function handle({ baseUrl, folder, config, fileStore }: CustomMTHandleOptions): (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;