@crowdin/app-project-module 0.108.0 → 1.0.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.
- package/out/app-test/integration/get-integration-files.js +16 -4
- package/out/app-test/integration/types.d.ts +1 -1
- package/out/app-test/integration/update-crowdin.js +2 -2
- package/out/app-test/integration/update-integration.js +2 -2
- package/out/index.d.ts +2 -1
- package/out/index.js +73 -30
- package/out/middlewares/auto-credentials-masker.d.ts +4 -0
- package/out/middlewares/auto-credentials-masker.js +45 -0
- package/out/middlewares/crowdin-client.d.ts +1 -1
- package/out/middlewares/integration-credentials.d.ts +2 -2
- package/out/middlewares/integration-credentials.js +7 -4
- package/out/middlewares/render-ui-module.d.ts +3 -3
- package/out/middlewares/render-ui-module.js +10 -13
- package/out/middlewares/ui-module.d.ts +1 -1
- package/out/middlewares/ui-module.js +11 -1
- package/out/modules/about.d.ts +2 -1
- package/out/modules/about.js +10 -3
- package/out/modules/ai-prompt-provider/handlers/compile.d.ts +1 -1
- package/out/modules/ai-prompt-provider/handlers/compile.js +7 -1
- package/out/modules/ai-prompt-provider/index.js +2 -2
- package/out/modules/ai-prompt-provider/types.d.ts +7 -1
- package/out/modules/ai-provider/handlers/chat-completions.d.ts +1 -1
- package/out/modules/ai-provider/handlers/chat-completions.js +1 -1
- package/out/modules/ai-provider/handlers/get-model-list.d.ts +1 -1
- package/out/modules/ai-provider/index.js +2 -2
- package/out/modules/ai-provider/types.d.ts +4 -4
- package/out/modules/ai-request-processors/handler.d.ts +1 -1
- package/out/modules/ai-request-processors/handler.js +12 -2
- package/out/modules/ai-request-processors/types.d.ts +12 -2
- package/out/modules/ai-tools/handlers/tool-calls.d.ts +1 -1
- package/out/modules/ai-tools/handlers/tool-calls.js +1 -1
- package/out/modules/ai-tools/index.js +1 -1
- package/out/modules/ai-tools/types.d.ts +1 -1
- package/out/modules/auth-guard/handlers/verify.d.ts +1 -1
- package/out/modules/auth-guard/index.js +1 -1
- package/out/modules/automation-action/handlers/execute.d.ts +1 -1
- package/out/modules/automation-action/handlers/execute.js +1 -1
- package/out/modules/automation-action/handlers/input-schema.d.ts +1 -1
- package/out/modules/automation-action/handlers/output-schema.d.ts +1 -1
- package/out/modules/automation-action/handlers/validate-settings.d.ts +1 -1
- package/out/modules/automation-action/handlers/validate-settings.js +1 -1
- package/out/modules/automation-action/index.js +1 -1
- package/out/modules/automation-action/types.d.ts +4 -4
- package/out/modules/automation-action/util/index.js +2 -5
- package/out/modules/context-menu/index.js +2 -2
- package/out/modules/custom-mt/handlers/translate.d.ts +1 -1
- package/out/modules/custom-mt/handlers/translate.js +25 -9
- package/out/modules/custom-mt/index.js +3 -3
- package/out/modules/custom-mt/types.d.ts +10 -2
- package/out/modules/custom-spell-check/handlers/get-languages-list.d.ts +1 -1
- package/out/modules/custom-spell-check/handlers/spell-check.d.ts +1 -1
- package/out/modules/custom-spell-check/index.js +4 -4
- package/out/modules/editor-right-panel/index.js +1 -1
- package/out/modules/external-qa-check/handlers/validate.d.ts +1 -1
- package/out/modules/external-qa-check/index.js +2 -2
- package/out/modules/file-processing/handlers/custom-file-format.d.ts +7 -2
- package/out/modules/file-processing/handlers/custom-file-format.js +62 -22
- package/out/modules/file-processing/handlers/file-download.d.ts +1 -1
- package/out/modules/file-processing/handlers/file-download.js +5 -0
- package/out/modules/file-processing/handlers/pre-post-process.d.ts +1 -1
- package/out/modules/file-processing/handlers/pre-post-process.js +41 -15
- package/out/modules/file-processing/handlers/translations-alignment.d.ts +1 -1
- package/out/modules/file-processing/handlers/translations-alignment.js +10 -4
- package/out/modules/file-processing/index.js +12 -2
- package/out/modules/file-processing/types.d.ts +36 -5
- package/out/modules/file-processing/util/defaults.js +50 -6
- package/out/modules/file-processing/util/files.js +2 -1
- package/out/modules/form-data-display.d.ts +1 -1
- package/out/modules/form-data-save.d.ts +1 -1
- package/out/modules/install.d.ts +1 -1
- package/out/modules/integration/handlers/crowdin-file-progress.d.ts +1 -1
- package/out/modules/integration/handlers/crowdin-file-progress.js +5 -1
- package/out/modules/integration/handlers/crowdin-files-target-languages.d.ts +5 -0
- package/out/modules/integration/handlers/crowdin-files-target-languages.js +103 -0
- package/out/modules/integration/handlers/crowdin-files.d.ts +1 -1
- package/out/modules/integration/handlers/crowdin-files.js +7 -1
- package/out/modules/integration/handlers/crowdin-project.d.ts +1 -1
- package/out/modules/integration/handlers/crowdin-update.d.ts +1 -1
- package/out/modules/integration/handlers/crowdin-update.js +59 -18
- package/out/modules/integration/handlers/crowdin-webhook.d.ts +1 -1
- package/out/modules/integration/handlers/crowdin-webhook.js +15 -8
- package/out/modules/integration/handlers/integration-data.d.ts +1 -1
- package/out/modules/integration/handlers/integration-data.js +13 -6
- package/out/modules/integration/handlers/integration-login.d.ts +1 -1
- package/out/modules/integration/handlers/integration-logout.d.ts +1 -1
- package/out/modules/integration/handlers/integration-logout.js +8 -3
- package/out/modules/integration/handlers/integration-update.d.ts +1 -1
- package/out/modules/integration/handlers/integration-update.js +44 -6
- package/out/modules/integration/handlers/integration-webhook.d.ts +1 -1
- package/out/modules/integration/handlers/invite-users.d.ts +1 -1
- package/out/modules/integration/handlers/job-cancel.d.ts +1 -1
- package/out/modules/integration/handlers/job-info-deprecated.d.ts +1 -1
- package/out/modules/integration/handlers/job-info-deprecated.js +3 -2
- package/out/modules/integration/handlers/job-info.d.ts +1 -1
- package/out/modules/integration/handlers/job-list.d.ts +1 -1
- package/out/modules/integration/handlers/main.d.ts +1 -1
- package/out/modules/integration/handlers/main.js +32 -2
- package/out/modules/integration/handlers/oauth-login.d.ts +1 -1
- package/out/modules/integration/handlers/oauth-login.js +28 -6
- package/out/modules/integration/handlers/oauth-polling.d.ts +1 -1
- package/out/modules/integration/handlers/oauth-url.d.ts +1 -1
- package/out/modules/integration/handlers/settings-save.d.ts +1 -1
- package/out/modules/integration/handlers/settings-save.js +9 -9
- package/out/modules/integration/handlers/settings.d.ts +1 -1
- package/out/modules/integration/handlers/sync-settings-save.d.ts +1 -1
- package/out/modules/integration/handlers/sync-settings-save.js +5 -9
- package/out/modules/integration/handlers/sync-settings.d.ts +1 -1
- package/out/modules/integration/handlers/user-errors.d.ts +1 -1
- package/out/modules/integration/handlers/users.d.ts +1 -1
- package/out/modules/integration/index.js +19 -33
- package/out/modules/integration/types.d.ts +133 -29
- package/out/modules/integration/types.js +1 -0
- package/out/modules/integration/util/cron.d.ts +2 -2
- package/out/modules/integration/util/cron.js +40 -24
- package/out/modules/integration/util/defaults.d.ts +4 -0
- package/out/modules/integration/util/defaults.js +175 -15
- package/out/modules/integration/util/files.d.ts +2 -1
- package/out/modules/integration/util/files.js +19 -8
- package/out/modules/integration/util/job.js +4 -3
- package/out/modules/integration/util/snapshot.js +19 -3
- package/out/modules/integration/util/types.d.ts +1 -0
- package/out/modules/integration/util/types.js +1 -0
- package/out/modules/integration/util/webhooks.d.ts +8 -8
- package/out/modules/integration/util/webhooks.js +34 -17
- package/out/modules/manifest.js +12 -12
- package/out/modules/modal/index.js +2 -2
- package/out/modules/organization-menu/index.js +5 -4
- package/out/modules/organization-settings-menu/index.js +5 -4
- package/out/modules/profile-resources-menu/index.js +5 -4
- package/out/modules/profile-settings-menu/index.js +5 -4
- package/out/modules/project-menu/index.js +1 -1
- package/out/modules/project-menu-crowdsource/index.js +1 -1
- package/out/modules/project-reports/index.js +3 -2
- package/out/modules/project-tools/index.js +3 -2
- package/out/modules/status.d.ts +1 -1
- package/out/modules/status.js +12 -3
- package/out/modules/subscription-paid.d.ts +1 -1
- package/out/modules/uninstall.d.ts +1 -1
- package/out/modules/uninstall.js +1 -1
- package/out/modules/webhooks/handlers/webhook-handler.d.ts +2 -2
- package/out/modules/webhooks/handlers/webhook-handler.js +33 -22
- package/out/modules/webhooks/types.d.ts +7 -0
- package/out/modules/workflow-step-type/handlers/delete-step.d.ts +1 -1
- package/out/modules/workflow-step-type/handlers/step-settings-save.d.ts +1 -1
- package/out/modules/workflow-step-type/index.js +2 -2
- package/out/modules/workflow-step-type/util/index.js +3 -6
- package/out/static/js/dependent.js +16 -7
- package/out/static/ui/error.bundle.js +474 -0
- package/out/static/ui/error.bundle.js.map +1 -0
- package/out/static/ui/install.bundle.js +459 -0
- package/out/static/ui/install.bundle.js.map +1 -0
- package/out/static/ui/login.bundle.js +630 -0
- package/out/static/ui/login.bundle.js.map +1 -0
- package/out/static/ui/main.bundle.js +2109 -0
- package/out/static/ui/main.bundle.js.map +1 -0
- package/out/static/ui/oauth.bundle.js +467 -0
- package/out/static/ui/oauth.bundle.js.map +1 -0
- package/out/storage/d1.d.ts +107 -0
- package/out/storage/d1.js +831 -0
- package/out/storage/index.js +8 -1
- package/out/storage/mysql.js +22 -19
- package/out/storage/postgre.d.ts +0 -1
- package/out/storage/postgre.js +20 -30
- package/out/storage/sqlite.d.ts +2 -5
- package/out/storage/sqlite.js +29 -69
- package/out/types.d.ts +78 -18
- package/out/util/connection.js +1 -1
- package/out/util/credentials-masker.d.ts +3 -3
- package/out/util/credentials-masker.js +14 -20
- package/out/util/cron.d.ts +29 -0
- package/out/util/cron.js +87 -0
- package/out/util/index.d.ts +14 -1
- package/out/util/index.js +121 -10
- package/out/util/jsx-renderer.d.ts +14 -0
- package/out/util/jsx-renderer.js +35 -0
- package/out/util/logger.d.ts +1 -0
- package/out/util/logger.js +2 -2
- package/out/util/static-files.d.ts +19 -0
- package/out/util/static-files.js +87 -0
- package/out/util/subscription.js +1 -1
- package/out/views/AboutPage.d.ts +10 -0
- package/out/views/AboutPage.js +76 -0
- package/out/views/FormPage.d.ts +14 -0
- package/out/views/FormPage.js +28 -0
- package/out/views/SubscriptionPage.d.ts +7 -0
- package/out/views/SubscriptionPage.js +26 -0
- package/out/views/index.d.ts +8 -0
- package/out/views/index.js +15 -0
- package/out/views/layout/Head.d.ts +9 -0
- package/out/views/layout/Head.js +54 -0
- package/package.json +43 -41
- package/out/util/handlebars.d.ts +0 -1
- package/out/util/handlebars.js +0 -46
- package/out/views/about.handlebars +0 -102
- package/out/views/error.handlebars +0 -54
- package/out/views/form.handlebars +0 -31
- package/out/views/install.handlebars +0 -16
- package/out/views/login.handlebars +0 -332
- package/out/views/main.handlebars +0 -2042
- package/out/views/oauth.handlebars +0 -11
- package/out/views/partials/head.handlebars +0 -53
- package/out/views/subscription.handlebars +0 -26
|
@@ -8,16 +8,12 @@ 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
|
-
exports.
|
|
16
|
-
const lodash_get_1 = __importDefault(require("lodash.get"));
|
|
17
|
-
const index_1 = require("./index");
|
|
18
|
-
const index_2 = require("../index");
|
|
19
|
-
const crowdin_client_1 = require("../middlewares/crowdin-client");
|
|
12
|
+
exports.postRequestCredentialsMasker = exports.maskKey = exports.getRequestCredentialsMasker = void 0;
|
|
20
13
|
const crowdin_apps_functions_1 = require("@crowdin/crowdin-apps-functions");
|
|
14
|
+
const index_1 = require("../index");
|
|
15
|
+
const crowdin_client_1 = require("../middlewares/crowdin-client");
|
|
16
|
+
const index_2 = require("./index");
|
|
21
17
|
function maskKey(key) {
|
|
22
18
|
const maskWith = '*';
|
|
23
19
|
const unmaskedCharsAtEnd = 3;
|
|
@@ -29,18 +25,16 @@ function getMaskableFieldsKeys(moduleConfig) {
|
|
|
29
25
|
if (!moduleConfig.formUiSchema) {
|
|
30
26
|
return [];
|
|
31
27
|
}
|
|
32
|
-
return Object.keys(moduleConfig.formUiSchema).filter((fieldKey) => {
|
|
33
|
-
return (0, lodash_get_1.default)(moduleConfig, `formUiSchema[${fieldKey}]['ui:widget']`) === 'password';
|
|
34
|
-
});
|
|
28
|
+
return Object.keys(moduleConfig.formUiSchema).filter((fieldKey) => { var _a, _b; return ((_b = (_a = moduleConfig === null || moduleConfig === void 0 ? void 0 : moduleConfig.formUiSchema) === null || _a === void 0 ? void 0 : _a[fieldKey]) === null || _b === void 0 ? void 0 : _b['ui:widget']) === 'password'; });
|
|
35
29
|
}
|
|
36
30
|
function getRequestCredentialsMasker({ moduleConfig, dataPath = 'formData', }) {
|
|
37
31
|
return function (req, res, next) {
|
|
38
|
-
|
|
39
|
-
if (!moduleConfig || !moduleConfig.formSchema || !moduleConfig.formUiSchema) {
|
|
32
|
+
if (req.__credentialsMaskerApplied) {
|
|
40
33
|
return next();
|
|
41
34
|
}
|
|
42
|
-
|
|
43
|
-
|
|
35
|
+
req.__credentialsMaskerApplied = true;
|
|
36
|
+
// we can't find "password" fields without ui schema
|
|
37
|
+
if (!moduleConfig || !moduleConfig.formSchema || !moduleConfig.formUiSchema) {
|
|
44
38
|
return next();
|
|
45
39
|
}
|
|
46
40
|
const maskableFieldsKeys = getMaskableFieldsKeys(moduleConfig);
|
|
@@ -69,13 +63,13 @@ function getRequestCredentialsMasker({ moduleConfig, dataPath = 'formData', }) {
|
|
|
69
63
|
}
|
|
70
64
|
exports.getRequestCredentialsMasker = getRequestCredentialsMasker;
|
|
71
65
|
function postRequestCredentialsMasker(moduleConfig, credentialsExtractor) {
|
|
72
|
-
return (0,
|
|
66
|
+
return (0, index_2.runAsyncWrapper)((req, res, next) => __awaiter(this, void 0, void 0, function* () {
|
|
73
67
|
var _a;
|
|
74
|
-
if (
|
|
68
|
+
if (req.__credentialsMaskerApplied) {
|
|
75
69
|
return next();
|
|
76
70
|
}
|
|
77
|
-
|
|
78
|
-
if (!moduleConfig.
|
|
71
|
+
req.__credentialsMaskerApplied = true;
|
|
72
|
+
if (!moduleConfig || !moduleConfig.formSchema || !moduleConfig.formUiSchema) {
|
|
79
73
|
return next();
|
|
80
74
|
}
|
|
81
75
|
const fieldsKeysInRequest = Object.keys(((_a = req.body) === null || _a === void 0 ? void 0 : _a.data) || []);
|
|
@@ -88,7 +82,7 @@ function postRequestCredentialsMasker(moduleConfig, credentialsExtractor) {
|
|
|
88
82
|
const jwtToken = (0, crowdin_client_1.getToken)(req) || '';
|
|
89
83
|
const jwtPayload = yield (0, crowdin_apps_functions_1.validateJwtToken)(jwtToken, process.env.CROWDIN_CLIENT_SECRET || '');
|
|
90
84
|
const crowdinId = `${jwtPayload.context.organization_id}`;
|
|
91
|
-
unmaskedFields = yield
|
|
85
|
+
unmaskedFields = yield index_1.metadataStore.getMetadata(`form-data-${crowdinId}`);
|
|
92
86
|
}
|
|
93
87
|
unmaskedFields = unmaskedFields || {};
|
|
94
88
|
const maskableFieldsKeys = getMaskableFieldsKeys(moduleConfig);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Config, UnauthorizedConfig } from '../types';
|
|
2
|
+
export interface Cron {
|
|
3
|
+
/**
|
|
4
|
+
* Schedule a task to run on a cron expression
|
|
5
|
+
* @param expression - Cron expression (e.g., '0 * * * *' for hourly)
|
|
6
|
+
* @param task - Async task to execute
|
|
7
|
+
*/
|
|
8
|
+
schedule(expression: string, task: () => Promise<void>): void;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Default Node.js cron handler that uses node-cron
|
|
12
|
+
*/
|
|
13
|
+
export declare class NodeCron implements Cron {
|
|
14
|
+
private cron;
|
|
15
|
+
private pendingSchedules;
|
|
16
|
+
private initialized;
|
|
17
|
+
constructor();
|
|
18
|
+
schedule(expression: string, task: () => Promise<void>): void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Initialize the cron instance
|
|
22
|
+
* @param config - Client configuration
|
|
23
|
+
*/
|
|
24
|
+
export declare function initialize(config: Config | UnauthorizedConfig): void;
|
|
25
|
+
/**
|
|
26
|
+
* Get the initialized cron instance
|
|
27
|
+
* @returns The cron instance
|
|
28
|
+
*/
|
|
29
|
+
export declare function getCron(): Cron;
|
package/out/util/cron.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.getCron = exports.initialize = exports.NodeCron = void 0;
|
|
27
|
+
const logger_1 = require("./logger");
|
|
28
|
+
/**
|
|
29
|
+
* Default Node.js cron handler that uses node-cron
|
|
30
|
+
*/
|
|
31
|
+
class NodeCron {
|
|
32
|
+
constructor() {
|
|
33
|
+
this.pendingSchedules = [];
|
|
34
|
+
this.initialized = false;
|
|
35
|
+
// Dynamically import node-cron
|
|
36
|
+
Promise.resolve().then(() => __importStar(require('node-cron'))).then((nodeCron) => {
|
|
37
|
+
this.cron = nodeCron.default || nodeCron;
|
|
38
|
+
this.initialized = true;
|
|
39
|
+
// Schedule all pending tasks
|
|
40
|
+
this.pendingSchedules.forEach(({ expression, task }) => {
|
|
41
|
+
this.cron.schedule(expression, task);
|
|
42
|
+
});
|
|
43
|
+
this.pendingSchedules = [];
|
|
44
|
+
})
|
|
45
|
+
.catch((error) => {
|
|
46
|
+
console.error('Failed to load node-cron:', error);
|
|
47
|
+
throw new Error('node-cron is required for the default cron. Please install it or provide a custom cron in config.');
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
schedule(expression, task) {
|
|
51
|
+
if (this.initialized && this.cron) {
|
|
52
|
+
this.cron.schedule(expression, task);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
// Queue the task until node-cron is loaded
|
|
56
|
+
this.pendingSchedules.push({ expression, task });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.NodeCron = NodeCron;
|
|
61
|
+
let cron;
|
|
62
|
+
/**
|
|
63
|
+
* Initialize the cron instance
|
|
64
|
+
* @param config - Client configuration
|
|
65
|
+
*/
|
|
66
|
+
function initialize(config) {
|
|
67
|
+
if (config.cron) {
|
|
68
|
+
(0, logger_1.log)('Using custom cron implementation');
|
|
69
|
+
cron = config.cron;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
(0, logger_1.log)('Using default NodeCron implementation');
|
|
73
|
+
cron = new NodeCron();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
exports.initialize = initialize;
|
|
77
|
+
/**
|
|
78
|
+
* Get the initialized cron instance
|
|
79
|
+
* @returns The cron instance
|
|
80
|
+
*/
|
|
81
|
+
function getCron() {
|
|
82
|
+
if (!cron) {
|
|
83
|
+
throw new Error('Cron not initialized');
|
|
84
|
+
}
|
|
85
|
+
return cron;
|
|
86
|
+
}
|
|
87
|
+
exports.getCron = getCron;
|
package/out/util/index.d.ts
CHANGED
|
@@ -4,14 +4,24 @@ export declare class CodeError extends Error {
|
|
|
4
4
|
code: number | undefined;
|
|
5
5
|
constructor(message: string, code?: number);
|
|
6
6
|
}
|
|
7
|
+
export declare function extractBaseUrlFromRequest(req: Request): string;
|
|
7
8
|
export declare function runAsyncWrapper(callback: Function): (req: Request | CrowdinClientRequest, res: Response, next: Function) => void;
|
|
8
9
|
export declare function encryptData(config: Config, data: string): string;
|
|
9
10
|
export declare function decryptData(config: Config, data: string): string;
|
|
10
11
|
export declare function executeWithRetry<T>(func: () => Promise<T>, numOfRetries?: number): Promise<T>;
|
|
11
|
-
export declare function getLogoUrl(moduleConfig?: ImagePath, modulePath?: string): string;
|
|
12
|
+
export declare function getLogoUrl(config: Config | UnauthorizedConfig, moduleConfig?: ImagePath, modulePath?: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Logo middleware with backwards compatibility
|
|
15
|
+
* Serves both /logo.png (backwards-compatible) and actual file name
|
|
16
|
+
* @param config - App configuration (required for Cloudflare Workers Assets support)
|
|
17
|
+
* @param moduleConfig - Module configuration with imagePath (optional, falls back to config.imagePath)
|
|
18
|
+
* @returns Express middleware
|
|
19
|
+
*/
|
|
20
|
+
export declare function serveLogo(config: Config | UnauthorizedConfig, moduleConfig?: ImagePath): (req: Request, res: Response, next: Function) => Promise<void>;
|
|
12
21
|
export declare function isAuthorizedConfig(config: Config | UnauthorizedConfig): config is Config;
|
|
13
22
|
export declare function isJson(string: string): boolean;
|
|
14
23
|
export declare function isDefined(value: any): boolean;
|
|
24
|
+
export declare function isString(value: any): value is string;
|
|
15
25
|
export declare function getPreviousDate(days: number): Date;
|
|
16
26
|
export declare function prepareFormDataMetadataId(req: CrowdinClientRequest, config: Config): Promise<string>;
|
|
17
27
|
export declare function validateEmail(email: string | number): boolean;
|
|
@@ -19,3 +29,6 @@ export declare function getFormattedDate({ date, userTimezone }: {
|
|
|
19
29
|
date: Date | number;
|
|
20
30
|
userTimezone: string | undefined;
|
|
21
31
|
}): string;
|
|
32
|
+
export declare function kebabCase(str?: string): string;
|
|
33
|
+
export declare function snakeCase(str?: string): string;
|
|
34
|
+
export declare function uniqBy<T>(array: any, key: keyof T): T[];
|
package/out/util/index.js
CHANGED
|
@@ -32,12 +32,22 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
32
32
|
});
|
|
33
33
|
};
|
|
34
34
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
-
exports.getFormattedDate = exports.validateEmail = exports.prepareFormDataMetadataId = exports.getPreviousDate = exports.isDefined = exports.isJson = exports.isAuthorizedConfig = exports.getLogoUrl = exports.executeWithRetry = exports.decryptData = exports.encryptData = exports.runAsyncWrapper = exports.CodeError = void 0;
|
|
36
|
-
const
|
|
35
|
+
exports.uniqBy = exports.snakeCase = exports.kebabCase = exports.getFormattedDate = exports.validateEmail = exports.prepareFormDataMetadataId = exports.getPreviousDate = exports.isString = exports.isDefined = exports.isJson = exports.isAuthorizedConfig = exports.serveLogo = exports.getLogoUrl = exports.executeWithRetry = exports.decryptData = exports.encryptData = exports.runAsyncWrapper = exports.extractBaseUrlFromRequest = exports.CodeError = void 0;
|
|
36
|
+
const crowdin_apps_functions_1 = require("@crowdin/crowdin-apps-functions");
|
|
37
|
+
const crypto = __importStar(require("crypto"));
|
|
37
38
|
const storage_1 = require("../storage");
|
|
38
39
|
const types_1 = require("../types");
|
|
40
|
+
const jsx_renderer_1 = require("./jsx-renderer");
|
|
39
41
|
const logger_1 = require("./logger");
|
|
40
|
-
const
|
|
42
|
+
const static_files_1 = require("./static-files");
|
|
43
|
+
/**
|
|
44
|
+
* Extract file name from path (works in both Node.js and Cloudflare Workers)
|
|
45
|
+
* Supports both Unix (/) and Windows (\) path separators
|
|
46
|
+
*/
|
|
47
|
+
function basename(filePath) {
|
|
48
|
+
// Replace all backslashes with forward slashes, then get the last segment
|
|
49
|
+
return filePath.replace(/\\/g, '/').split('/').pop();
|
|
50
|
+
}
|
|
41
51
|
class CodeError extends Error {
|
|
42
52
|
constructor(message, code) {
|
|
43
53
|
super(message);
|
|
@@ -45,6 +55,12 @@ class CodeError extends Error {
|
|
|
45
55
|
}
|
|
46
56
|
}
|
|
47
57
|
exports.CodeError = CodeError;
|
|
58
|
+
function extractBaseUrlFromRequest(req) {
|
|
59
|
+
const protocol = req.protocol;
|
|
60
|
+
const host = req.get('host');
|
|
61
|
+
return `${protocol}://${host}`;
|
|
62
|
+
}
|
|
63
|
+
exports.extractBaseUrlFromRequest = extractBaseUrlFromRequest;
|
|
48
64
|
function isCrowdinClientRequest(req) {
|
|
49
65
|
return req.crowdinContext;
|
|
50
66
|
}
|
|
@@ -61,7 +77,9 @@ function handleError(err, req, res) {
|
|
|
61
77
|
if (!res.headersSent) {
|
|
62
78
|
const errorMessage = { message: (0, logger_1.getErrorMessage)(err), code };
|
|
63
79
|
if ('integrationCredentials' in req) {
|
|
64
|
-
|
|
80
|
+
const html = (0, jsx_renderer_1.renderJSXOnClient)({ name: 'error', props: errorMessage });
|
|
81
|
+
res.setHeader('Content-Type', 'text/html; charset=utf-8');
|
|
82
|
+
res.send(html);
|
|
65
83
|
}
|
|
66
84
|
else {
|
|
67
85
|
res.status(code).send({ error: errorMessage });
|
|
@@ -84,11 +102,38 @@ function runAsyncWrapper(callback) {
|
|
|
84
102
|
}
|
|
85
103
|
exports.runAsyncWrapper = runAsyncWrapper;
|
|
86
104
|
function encryptData(config, data) {
|
|
87
|
-
|
|
105
|
+
const secret = config.cryptoSecret || config.clientSecret;
|
|
106
|
+
const salt = crypto.randomBytes(8);
|
|
107
|
+
const password = Buffer.concat([Buffer.from(secret, 'binary'), salt]);
|
|
108
|
+
const hash = [];
|
|
109
|
+
let digest = password;
|
|
110
|
+
for (let i = 0; i < 3; i++) {
|
|
111
|
+
hash[i] = crypto.createHash('md5').update(digest).digest();
|
|
112
|
+
digest = Buffer.concat([hash[i], password]);
|
|
113
|
+
}
|
|
114
|
+
const keyDerivation = Buffer.concat(hash);
|
|
115
|
+
const key = keyDerivation.subarray(0, 32);
|
|
116
|
+
const iv = keyDerivation.subarray(32);
|
|
117
|
+
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
|
|
118
|
+
return Buffer.concat([Buffer.from('Salted__', 'utf8'), salt, cipher.update(data), cipher.final()]).toString('base64');
|
|
88
119
|
}
|
|
89
120
|
exports.encryptData = encryptData;
|
|
90
121
|
function decryptData(config, data) {
|
|
91
|
-
|
|
122
|
+
const secret = config.cryptoSecret || config.clientSecret;
|
|
123
|
+
const cypher = Buffer.from(data, 'base64');
|
|
124
|
+
const salt = cypher.subarray(8, 16);
|
|
125
|
+
const password = Buffer.concat([Buffer.from(secret, 'binary'), salt]);
|
|
126
|
+
const md5Hashes = [];
|
|
127
|
+
let digest = password;
|
|
128
|
+
for (let i = 0; i < 3; i++) {
|
|
129
|
+
md5Hashes[i] = crypto.createHash('md5').update(digest).digest();
|
|
130
|
+
digest = Buffer.concat([md5Hashes[i], password]);
|
|
131
|
+
}
|
|
132
|
+
const key = Buffer.concat([md5Hashes[0], md5Hashes[1]]);
|
|
133
|
+
const iv = md5Hashes[2];
|
|
134
|
+
const contents = cypher.subarray(16);
|
|
135
|
+
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
|
|
136
|
+
return decipher.update(contents, undefined, 'utf-8') + decipher.final('utf-8');
|
|
92
137
|
}
|
|
93
138
|
exports.decryptData = decryptData;
|
|
94
139
|
function executeWithRetry(func, numOfRetries = 2) {
|
|
@@ -108,13 +153,36 @@ function executeWithRetry(func, numOfRetries = 2) {
|
|
|
108
153
|
});
|
|
109
154
|
}
|
|
110
155
|
exports.executeWithRetry = executeWithRetry;
|
|
111
|
-
function getLogoUrl(moduleConfig, modulePath) {
|
|
112
|
-
|
|
113
|
-
|
|
156
|
+
function getLogoUrl(config, moduleConfig, modulePath) {
|
|
157
|
+
// Extract file name from imagePath with fallback to config.imagePath
|
|
158
|
+
const imagePath = (moduleConfig === null || moduleConfig === void 0 ? void 0 : moduleConfig.imagePath) || config.imagePath;
|
|
159
|
+
const fileName = basename(imagePath);
|
|
160
|
+
if (!modulePath) {
|
|
161
|
+
return `/${fileName}`;
|
|
114
162
|
}
|
|
115
|
-
return `/logo${modulePath}
|
|
163
|
+
return `/logo${modulePath}/${fileName}`;
|
|
116
164
|
}
|
|
117
165
|
exports.getLogoUrl = getLogoUrl;
|
|
166
|
+
/**
|
|
167
|
+
* Logo middleware with backwards compatibility
|
|
168
|
+
* Serves both /logo.png (backwards-compatible) and actual file name
|
|
169
|
+
* @param config - App configuration (required for Cloudflare Workers Assets support)
|
|
170
|
+
* @param moduleConfig - Module configuration with imagePath (optional, falls back to config.imagePath)
|
|
171
|
+
* @returns Express middleware
|
|
172
|
+
*/
|
|
173
|
+
function serveLogo(config, moduleConfig) {
|
|
174
|
+
const imagePath = (moduleConfig === null || moduleConfig === void 0 ? void 0 : moduleConfig.imagePath) || config.imagePath;
|
|
175
|
+
const fileName = basename(imagePath);
|
|
176
|
+
const fileHandler = (0, static_files_1.serveFile)(config, imagePath);
|
|
177
|
+
return (req, res, next) => __awaiter(this, void 0, void 0, function* () {
|
|
178
|
+
// Match exact paths: /logo.png (backwards-compatible) or /{actual-file-name}
|
|
179
|
+
if (req.path === '/logo.png' || req.path === `/${fileName}`) {
|
|
180
|
+
return fileHandler(req, res, next);
|
|
181
|
+
}
|
|
182
|
+
next();
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
exports.serveLogo = serveLogo;
|
|
118
186
|
function isAuthorizedConfig(config) {
|
|
119
187
|
return !!config.clientId && !!config.clientSecret && config.authenticationType !== types_1.AuthenticationType.NONE;
|
|
120
188
|
}
|
|
@@ -133,6 +201,10 @@ function isDefined(value) {
|
|
|
133
201
|
return value !== undefined && value !== null;
|
|
134
202
|
}
|
|
135
203
|
exports.isDefined = isDefined;
|
|
204
|
+
function isString(value) {
|
|
205
|
+
return typeof value === 'string' || value instanceof String;
|
|
206
|
+
}
|
|
207
|
+
exports.isString = isString;
|
|
136
208
|
function getPreviousDate(days) {
|
|
137
209
|
const date = new Date();
|
|
138
210
|
date.setDate(date.getDate() - days);
|
|
@@ -182,3 +254,42 @@ function getFormattedDate({ date, userTimezone }) {
|
|
|
182
254
|
}).format(date);
|
|
183
255
|
}
|
|
184
256
|
exports.getFormattedDate = getFormattedDate;
|
|
257
|
+
function kebabCase(str) {
|
|
258
|
+
if (!str) {
|
|
259
|
+
return '';
|
|
260
|
+
}
|
|
261
|
+
return (str
|
|
262
|
+
// Insert dash between lowercase & uppercase
|
|
263
|
+
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
264
|
+
// Insert dash between letters & numbers
|
|
265
|
+
.replace(/([a-zA-Z])([0-9])/g, '$1-$2')
|
|
266
|
+
.replace(/([0-9])([a-zA-Z])/g, '$1-$2')
|
|
267
|
+
// Replace spaces & underscores with dash
|
|
268
|
+
.replace(/[\s_]+/g, '-')
|
|
269
|
+
// Normalize multiple dashes
|
|
270
|
+
.replace(/-+/g, '-')
|
|
271
|
+
// Lowercase everything
|
|
272
|
+
.toLowerCase());
|
|
273
|
+
}
|
|
274
|
+
exports.kebabCase = kebabCase;
|
|
275
|
+
function snakeCase(str) {
|
|
276
|
+
return kebabCase(str).replace(/-/g, '_');
|
|
277
|
+
}
|
|
278
|
+
exports.snakeCase = snakeCase;
|
|
279
|
+
function uniqBy(array, key) {
|
|
280
|
+
if (!Array.isArray(array)) {
|
|
281
|
+
return [];
|
|
282
|
+
}
|
|
283
|
+
const seen = new Set();
|
|
284
|
+
return array.filter((item) => {
|
|
285
|
+
const k = item[key];
|
|
286
|
+
if (seen.has(k)) {
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
seen.add(k);
|
|
291
|
+
return true;
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
exports.uniqBy = uniqBy;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { FC } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Renders a React component to HTML string
|
|
4
|
+
* Uses React Server-Side Rendering (renderToStaticMarkup)
|
|
5
|
+
*/
|
|
6
|
+
export declare function renderJSXOnServer<P = any>(Component: FC<P>, props: P): string;
|
|
7
|
+
/**
|
|
8
|
+
* Renders a React component to HTML string to be hydrated on client side
|
|
9
|
+
*/
|
|
10
|
+
export declare function renderJSXOnClient({ name, props, withHead, }: {
|
|
11
|
+
name: string;
|
|
12
|
+
props: any;
|
|
13
|
+
withHead?: boolean;
|
|
14
|
+
}): string;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.renderJSXOnClient = exports.renderJSXOnServer = void 0;
|
|
4
|
+
const server_1 = require("react-dom/server");
|
|
5
|
+
const views_1 = require("../views");
|
|
6
|
+
/**
|
|
7
|
+
* Renders a React component to HTML string
|
|
8
|
+
* Uses React Server-Side Rendering (renderToStaticMarkup)
|
|
9
|
+
*/
|
|
10
|
+
function renderJSXOnServer(Component, props) {
|
|
11
|
+
const element = Component(props);
|
|
12
|
+
return '<!DOCTYPE html>' + (0, server_1.renderToStaticMarkup)(element);
|
|
13
|
+
}
|
|
14
|
+
exports.renderJSXOnServer = renderJSXOnServer;
|
|
15
|
+
/**
|
|
16
|
+
* Renders a React component to HTML string to be hydrated on client side
|
|
17
|
+
*/
|
|
18
|
+
function renderJSXOnClient({ name, props, withHead = true, }) {
|
|
19
|
+
const head = withHead ? (0, server_1.renderToStaticMarkup)((0, views_1.Head)(props)) : '';
|
|
20
|
+
return `
|
|
21
|
+
<!DOCTYPE html>
|
|
22
|
+
<html>
|
|
23
|
+
${head}
|
|
24
|
+
<body>
|
|
25
|
+
<div id="root"></div>
|
|
26
|
+
<script>
|
|
27
|
+
// Make props available to client JS
|
|
28
|
+
window.__PAGE_PROPS__ = ${JSON.stringify(props).replace(/</g, '\\u003c')};
|
|
29
|
+
</script>
|
|
30
|
+
<script type="module" src="/assets/ui/${name}.bundle.js"></script>
|
|
31
|
+
</body>
|
|
32
|
+
</html>
|
|
33
|
+
`;
|
|
34
|
+
}
|
|
35
|
+
exports.renderJSXOnClient = renderJSXOnClient;
|
package/out/util/logger.d.ts
CHANGED
|
@@ -32,6 +32,7 @@ export declare class AppUserModuleError extends AppModuleError {
|
|
|
32
32
|
}
|
|
33
33
|
export declare class AppModuleAggregateError extends Error {
|
|
34
34
|
errors: Error[] | AppModuleError[] | AppUserModuleError[];
|
|
35
|
+
isPartialSuccess?: boolean;
|
|
35
36
|
constructor(errors: Error[] | AppModuleError[] | AppUserModuleError[], message: string);
|
|
36
37
|
}
|
|
37
38
|
export declare function handleUserError({ action, error, crowdinId, clientId, }: {
|
package/out/util/logger.js
CHANGED
|
@@ -62,7 +62,7 @@ function log(message, context) {
|
|
|
62
62
|
var _a, _b, _c;
|
|
63
63
|
if (logConfig === null || logConfig === void 0 ? void 0 : logConfig.enabled) {
|
|
64
64
|
if (logConfig.log) {
|
|
65
|
-
logConfig.log(message, context);
|
|
65
|
+
logConfig.log({ message, context });
|
|
66
66
|
}
|
|
67
67
|
else {
|
|
68
68
|
let prefix = `[${new Date().toISOString()}]`;
|
|
@@ -96,7 +96,7 @@ exports.log = log;
|
|
|
96
96
|
function logError(e, context) {
|
|
97
97
|
var _a, _b, _c;
|
|
98
98
|
if (onError) {
|
|
99
|
-
onError(e, context);
|
|
99
|
+
onError({ error: e, context });
|
|
100
100
|
}
|
|
101
101
|
else {
|
|
102
102
|
if (context) {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static Files Abstraction Layer
|
|
3
|
+
* Dual compatibility: Node.js (Express) + Cloudflare Workers (Assets Fetcher)
|
|
4
|
+
*/
|
|
5
|
+
/// <reference types="serve-static" />
|
|
6
|
+
import express, { Request, Response } from 'express';
|
|
7
|
+
import { Config, UnauthorizedConfig } from '../types';
|
|
8
|
+
/**
|
|
9
|
+
* Serve static directory with dual compatibility
|
|
10
|
+
* @param config - App configuration
|
|
11
|
+
* @param staticPath - Path to static directory
|
|
12
|
+
*/
|
|
13
|
+
export declare function serveStatic(config: Config | UnauthorizedConfig, staticPath: string): ((req: Request, res: Response, next: Function) => Promise<void>) | import("serve-static").RequestHandler<express.Response<any, Record<string, any>>>;
|
|
14
|
+
/**
|
|
15
|
+
* Serve single file (e.g., logo.png, icons/star.svg) with dual compatibility
|
|
16
|
+
* @param config - App configuration
|
|
17
|
+
* @param filePath - Path to file
|
|
18
|
+
*/
|
|
19
|
+
export declare function serveFile(config: Config | UnauthorizedConfig, filePath: string): (req: Request, res: Response, next: Function) => Promise<void>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Static Files Abstraction Layer
|
|
4
|
+
* Dual compatibility: Node.js (Express) + Cloudflare Workers (Assets Fetcher)
|
|
5
|
+
*/
|
|
6
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
7
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
8
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
9
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
10
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
11
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
12
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
16
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
17
|
+
};
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.serveFile = exports.serveStatic = void 0;
|
|
20
|
+
const express_1 = __importDefault(require("express"));
|
|
21
|
+
const path_1 = __importDefault(require("path"));
|
|
22
|
+
/**
|
|
23
|
+
* Proxy Workers Assets response to Express response
|
|
24
|
+
*/
|
|
25
|
+
function proxyAssetsResponse(fetcher, assetPath, baseUrl, req, res, next) {
|
|
26
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
27
|
+
try {
|
|
28
|
+
if (assetPath === '/') {
|
|
29
|
+
return next();
|
|
30
|
+
}
|
|
31
|
+
const assetUrl = new URL(assetPath, baseUrl);
|
|
32
|
+
const response = yield fetcher.fetch(assetUrl.toString());
|
|
33
|
+
if (!response.ok) {
|
|
34
|
+
return next();
|
|
35
|
+
}
|
|
36
|
+
const body = yield response.arrayBuffer();
|
|
37
|
+
const contentType = response.headers.get('content-type');
|
|
38
|
+
if (contentType) {
|
|
39
|
+
res.setHeader('Content-Type', contentType);
|
|
40
|
+
}
|
|
41
|
+
res.send(Buffer.from(body));
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
next(err);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Serve static directory with dual compatibility
|
|
50
|
+
* @param config - App configuration
|
|
51
|
+
* @param staticPath - Path to static directory
|
|
52
|
+
*/
|
|
53
|
+
function serveStatic(config, staticPath) {
|
|
54
|
+
var _a;
|
|
55
|
+
if ((_a = config.assetsConfig) === null || _a === void 0 ? void 0 : _a.fetcher) {
|
|
56
|
+
const assetsFetcher = config.assetsConfig.fetcher;
|
|
57
|
+
return (req, res, next) => __awaiter(this, void 0, void 0, function* () {
|
|
58
|
+
const assetPath = `/${staticPath}/${req.path}`.replace(/\/+/g, '/');
|
|
59
|
+
yield proxyAssetsResponse(assetsFetcher, assetPath, config.baseUrl, req, res, next);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
const rootDir = path_1.default.dirname(__dirname);
|
|
63
|
+
const absolutePath = path_1.default.isAbsolute(staticPath) ? staticPath : path_1.default.join(rootDir, staticPath);
|
|
64
|
+
return express_1.default.static(absolutePath);
|
|
65
|
+
}
|
|
66
|
+
exports.serveStatic = serveStatic;
|
|
67
|
+
/**
|
|
68
|
+
* Serve single file (e.g., logo.png, icons/star.svg) with dual compatibility
|
|
69
|
+
* @param config - App configuration
|
|
70
|
+
* @param filePath - Path to file
|
|
71
|
+
*/
|
|
72
|
+
function serveFile(config, filePath) {
|
|
73
|
+
return (req, res, next) => __awaiter(this, void 0, void 0, function* () {
|
|
74
|
+
var _a;
|
|
75
|
+
if ((_a = config.assetsConfig) === null || _a === void 0 ? void 0 : _a.fetcher) {
|
|
76
|
+
const assetsFetcher = config.assetsConfig.fetcher;
|
|
77
|
+
const assetPath = filePath.startsWith('/') ? filePath : `/${filePath}`;
|
|
78
|
+
yield proxyAssetsResponse(assetsFetcher, assetPath, config.baseUrl, req, res, next);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
const rootDir = path_1.default.dirname(__dirname);
|
|
82
|
+
const absolutePath = path_1.default.isAbsolute(filePath) ? filePath : path_1.default.join(rootDir, filePath);
|
|
83
|
+
res.sendFile(absolutePath);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
exports.serveFile = serveFile;
|
package/out/util/subscription.js
CHANGED
|
@@ -71,7 +71,7 @@ function checkSubscription({ config, token, organization, accountType, }) {
|
|
|
71
71
|
return { expired, subscribeLink, daysLeft, type: types_1.SubscriptionInfoType.TRIAL };
|
|
72
72
|
}
|
|
73
73
|
if (config.onError) {
|
|
74
|
-
config.onError(e);
|
|
74
|
+
config.onError({ error: e });
|
|
75
75
|
}
|
|
76
76
|
else {
|
|
77
77
|
console.error(e);
|