@crowdin/app-project-module 0.98.0-cf-16 → 0.98.0-cf-18

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.
@@ -10,7 +10,15 @@ export declare function runAsyncWrapper(callback: Function): (req: Request | Cro
10
10
  export declare function encryptData(config: Config, data: string): string;
11
11
  export declare function decryptData(config: Config, data: string): string;
12
12
  export declare function executeWithRetry<T>(func: () => Promise<T>, numOfRetries?: number): Promise<T>;
13
- export declare function getLogoUrl(moduleConfig?: ImagePath, modulePath?: string): string;
13
+ export declare function getLogoUrl(config: Config | UnauthorizedConfig, moduleConfig?: ImagePath, modulePath?: string): string;
14
+ /**
15
+ * Logo middleware with backwards compatibility
16
+ * Serves both /logo.png (backwards-compatible) and actual file name
17
+ * @param config - App configuration (required for Cloudflare Workers Assets support)
18
+ * @param moduleConfig - Module configuration with imagePath (optional, falls back to config.imagePath)
19
+ * @returns Express middleware
20
+ */
21
+ export declare function serveLogo(config: Config | UnauthorizedConfig, moduleConfig?: ImagePath): (req: Request, res: Response, next: Function) => Promise<void>;
14
22
  export declare function isAuthorizedConfig(config: Config | UnauthorizedConfig): config is Config;
15
23
  export declare function isJson(string: string): boolean;
16
24
  export declare function getPreviousDate(days: number): Date;
package/out/util/index.js CHANGED
@@ -32,7 +32,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
32
32
  });
33
33
  };
34
34
  Object.defineProperty(exports, "__esModule", { value: true });
35
- exports.getFormattedDate = exports.validateEmail = exports.prepareFormDataMetadataId = exports.getPreviousDate = exports.isJson = exports.isAuthorizedConfig = exports.getLogoUrl = exports.executeWithRetry = exports.decryptData = exports.encryptData = exports.runAsyncWrapper = exports.extractBaseUrlFromRequest = exports.CodeError = exports.renderJSX = void 0;
35
+ exports.getFormattedDate = exports.validateEmail = exports.prepareFormDataMetadataId = exports.getPreviousDate = exports.isJson = exports.isAuthorizedConfig = exports.serveLogo = exports.getLogoUrl = exports.executeWithRetry = exports.decryptData = exports.encryptData = exports.runAsyncWrapper = exports.extractBaseUrlFromRequest = exports.CodeError = exports.renderJSX = void 0;
36
36
  const crypto = __importStar(require("crypto-js"));
37
37
  const storage_1 = require("../storage");
38
38
  const types_1 = require("../types");
@@ -40,8 +40,17 @@ const logger_1 = require("./logger");
40
40
  const crowdin_apps_functions_1 = require("@crowdin/crowdin-apps-functions");
41
41
  const jsx_renderer_1 = require("./jsx-renderer");
42
42
  const views_1 = require("../views");
43
+ const static_files_1 = require("./static-files");
43
44
  var jsx_renderer_2 = require("./jsx-renderer");
44
45
  Object.defineProperty(exports, "renderJSX", { enumerable: true, get: function () { return jsx_renderer_2.renderJSX; } });
46
+ /**
47
+ * Extract file name from path (works in both Node.js and Cloudflare Workers)
48
+ * Supports both Unix (/) and Windows (\) path separators
49
+ */
50
+ function basename(filePath) {
51
+ // Replace all backslashes with forward slashes, then get the last segment
52
+ return filePath.replace(/\\/g, '/').split('/').pop();
53
+ }
45
54
  class CodeError extends Error {
46
55
  constructor(message, code) {
47
56
  super(message);
@@ -120,13 +129,36 @@ function executeWithRetry(func, numOfRetries = 2) {
120
129
  });
121
130
  }
122
131
  exports.executeWithRetry = executeWithRetry;
123
- function getLogoUrl(moduleConfig, modulePath) {
124
- if (!moduleConfig && !modulePath) {
125
- return '/logo.png';
132
+ function getLogoUrl(config, moduleConfig, modulePath) {
133
+ // Extract file name from imagePath with fallback to config.imagePath
134
+ const imagePath = (moduleConfig === null || moduleConfig === void 0 ? void 0 : moduleConfig.imagePath) || config.imagePath;
135
+ const fileName = basename(imagePath);
136
+ if (!modulePath) {
137
+ return `/${fileName}`;
126
138
  }
127
- return `/logo${modulePath}/logo.png`;
139
+ return `/logo${modulePath}/${fileName}`;
128
140
  }
129
141
  exports.getLogoUrl = getLogoUrl;
142
+ /**
143
+ * Logo middleware with backwards compatibility
144
+ * Serves both /logo.png (backwards-compatible) and actual file name
145
+ * @param config - App configuration (required for Cloudflare Workers Assets support)
146
+ * @param moduleConfig - Module configuration with imagePath (optional, falls back to config.imagePath)
147
+ * @returns Express middleware
148
+ */
149
+ function serveLogo(config, moduleConfig) {
150
+ const imagePath = (moduleConfig === null || moduleConfig === void 0 ? void 0 : moduleConfig.imagePath) || config.imagePath;
151
+ const fileName = basename(imagePath);
152
+ const fileHandler = (0, static_files_1.serveFile)(config, imagePath);
153
+ return (req, res, next) => __awaiter(this, void 0, void 0, function* () {
154
+ // Match exact paths: /logo.png (backwards-compatible) or /{actual-file-name}
155
+ if (req.path === '/logo.png' || req.path === `/${fileName}`) {
156
+ return fileHandler(req, res, next);
157
+ }
158
+ next();
159
+ });
160
+ }
161
+ exports.serveLogo = serveLogo;
130
162
  function isAuthorizedConfig(config) {
131
163
  return !!config.clientId && !!config.clientSecret && config.authenticationType !== types_1.AuthenticationType.NONE;
132
164
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crowdin/app-project-module",
3
- "version": "0.98.0-cf-16",
3
+ "version": "0.98.0-cf-18",
4
4
  "description": "Module that generates for you all common endpoints for serving standalone Crowdin App",
5
5
  "main": "out/index.js",
6
6
  "types": "out/index.d.ts",
@@ -19,8 +19,6 @@
19
19
  "out/**/*"
20
20
  ],
21
21
  "dependencies": {
22
- "@aws-sdk/client-s3": "^3.758.0",
23
- "@aws-sdk/s3-request-presigner": "^3.758.0",
24
22
  "@crowdin/crowdin-apps-functions": "^0.12.0",
25
23
  "@crowdin/logs-formatter": "^2.1.8",
26
24
  "@godaddy/terminus": "^4.12.1",
@@ -43,7 +41,21 @@
43
41
  "swagger-jsdoc": "^6.2.8",
44
42
  "uuid": "^8.3.2"
45
43
  },
44
+ "peerDependencies": {
45
+ "@aws-sdk/client-s3": "^3.758.0",
46
+ "@aws-sdk/s3-request-presigner": "^3.758.0"
47
+ },
48
+ "peerDependenciesMeta": {
49
+ "@aws-sdk/client-s3": {
50
+ "optional": true
51
+ },
52
+ "@aws-sdk/s3-request-presigner": {
53
+ "optional": true
54
+ }
55
+ },
46
56
  "devDependencies": {
57
+ "@aws-sdk/client-s3": "^3.758.0",
58
+ "@aws-sdk/s3-request-presigner": "^3.758.0",
47
59
  "@babel/preset-react": "^7.26.3",
48
60
  "@cloudflare/workers-types": "^4.20251117.0",
49
61
  "@emotion/react": "^11.14.0",