@crowdin/app-project-module 1.3.1 → 1.4.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/types.d.ts CHANGED
@@ -524,6 +524,10 @@ export interface ImagePath {
524
524
  * path to app logo (e.g. {@example join(__dirname, 'logo.png')})
525
525
  */
526
526
  imagePath?: string;
527
+ /**
528
+ * URL to app logo that can be used instead of hosting it in the app (e.g. 'https://example.com/logo.png')
529
+ */
530
+ imageUrl?: string;
527
531
  }
528
532
  export interface Logger {
529
533
  enabled: boolean;
@@ -14,7 +14,7 @@ export declare function getLogoUrl(config: Config | UnauthorizedConfig, moduleCo
14
14
  * Logo middleware with backwards compatibility
15
15
  * Serves both /logo.png (backwards-compatible) and actual file name
16
16
  * @param config - App configuration (required for Cloudflare Workers Assets support)
17
- * @param moduleConfig - Module configuration with imagePath (optional, falls back to config.imagePath)
17
+ * @param moduleConfig - Module configuration with imagePath or imageUrl (optional, falls back to config.imagePath)
18
18
  * @returns Express middleware
19
19
  */
20
20
  export declare function serveLogo(config: Config | UnauthorizedConfig, moduleConfig?: ImagePath): (req: Request, res: Response, next: Function) => Promise<void>;
package/out/util/index.js CHANGED
@@ -177,8 +177,30 @@ function executeWithRetry(func_1) {
177
177
  });
178
178
  }
179
179
  function getLogoUrl(config, moduleConfig, modulePath) {
180
+ if (moduleConfig) {
181
+ if (moduleConfig.imageUrl) {
182
+ if (modulePath) {
183
+ return `/logo${modulePath}/logo.png`;
184
+ }
185
+ return '/logo.png';
186
+ }
187
+ else if (moduleConfig.imagePath) {
188
+ const imagePath = moduleConfig.imagePath;
189
+ const fileName = basename(imagePath);
190
+ if (!modulePath) {
191
+ return `/${fileName}`;
192
+ }
193
+ return `/logo${modulePath}/${fileName}`;
194
+ }
195
+ }
196
+ if (config.imageUrl) {
197
+ if (modulePath) {
198
+ return `/logo${modulePath}/logo.png`;
199
+ }
200
+ return '/logo.png';
201
+ }
180
202
  // Extract file name from imagePath with fallback to config.imagePath
181
- const imagePath = (moduleConfig === null || moduleConfig === void 0 ? void 0 : moduleConfig.imagePath) || config.imagePath;
203
+ const imagePath = config.imagePath;
182
204
  const fileName = basename(imagePath);
183
205
  if (!modulePath) {
184
206
  return `/${fileName}`;
@@ -189,11 +211,42 @@ function getLogoUrl(config, moduleConfig, modulePath) {
189
211
  * Logo middleware with backwards compatibility
190
212
  * Serves both /logo.png (backwards-compatible) and actual file name
191
213
  * @param config - App configuration (required for Cloudflare Workers Assets support)
192
- * @param moduleConfig - Module configuration with imagePath (optional, falls back to config.imagePath)
214
+ * @param moduleConfig - Module configuration with imagePath or imageUrl (optional, falls back to config.imagePath)
193
215
  * @returns Express middleware
194
216
  */
195
217
  function serveLogo(config, moduleConfig) {
196
- const imagePath = (moduleConfig === null || moduleConfig === void 0 ? void 0 : moduleConfig.imagePath) || config.imagePath;
218
+ if (moduleConfig) {
219
+ if (moduleConfig.imageUrl) {
220
+ return (req, res, next) => __awaiter(this, void 0, void 0, function* () {
221
+ if (req.path === '/logo.png') {
222
+ res.redirect(moduleConfig.imageUrl);
223
+ return;
224
+ }
225
+ next();
226
+ });
227
+ }
228
+ else if (moduleConfig.imagePath) {
229
+ const fileHandler = (0, static_files_1.serveFile)(config, moduleConfig.imagePath);
230
+ const fileName = basename(moduleConfig.imagePath);
231
+ return (req, res, next) => __awaiter(this, void 0, void 0, function* () {
232
+ // Match exact paths: /logo.png (backwards-compatible) or /{actual-file-name}
233
+ if (req.path === '/logo.png' || req.path === `/${fileName}`) {
234
+ return fileHandler(req, res, next);
235
+ }
236
+ next();
237
+ });
238
+ }
239
+ }
240
+ if (config.imageUrl) {
241
+ return (req, res, next) => __awaiter(this, void 0, void 0, function* () {
242
+ if (req.path === '/logo.png') {
243
+ res.redirect(config.imageUrl);
244
+ return;
245
+ }
246
+ next();
247
+ });
248
+ }
249
+ const imagePath = config.imagePath;
197
250
  const fileName = basename(imagePath);
198
251
  const fileHandler = (0, static_files_1.serveFile)(config, imagePath);
199
252
  return (req, res, next) => __awaiter(this, void 0, void 0, function* () {
@@ -58,7 +58,8 @@ const AboutPage = ({ name, logo, manifest, storeLink, showDebugLink }) => (react
58
58
  react_1.default.createElement("div", { className: "mb-3" },
59
59
  react_1.default.createElement("label", { htmlFor: "manifest-url", className: "form-label" }, "Paste the following manifest URL when prompted during manual installation:"),
60
60
  react_1.default.createElement("div", { className: "input-group" },
61
- react_1.default.createElement("input", { type: "text", className: "form-control", id: "manifest-url", value: manifest, readOnly: true }))),
61
+ react_1.default.createElement("input", { type: "text", className: "form-control", id: "manifest-url", value: manifest, readOnly: true }),
62
+ react_1.default.createElement("button", { className: "btn btn-outline-secondary", type: "button", id: "copy-button" }, "Copy"))),
62
63
  storeLink && (react_1.default.createElement("div", null,
63
64
  "Read more about",
64
65
  ' ',
@@ -72,5 +73,16 @@ const AboutPage = ({ name, logo, manifest, storeLink, showDebugLink }) => (react
72
73
  ' ',
73
74
  react_1.default.createElement("a", { href: "/__debug", target: "_blank", title: "Open developer console in a new tab" }, "Developer Console"),
74
75
  ' ',
75
- "to inspect requests, debug issues, and monitor application behavior."))))))))));
76
+ "to inspect requests, debug issues, and monitor application behavior."))))))),
77
+ react_1.default.createElement("script", { dangerouslySetInnerHTML: {
78
+ __html: `
79
+ document.getElementById('copy-button').addEventListener('click', async function() {
80
+ var text = document.getElementById('manifest-url').value;
81
+ await navigator.clipboard.writeText(text);
82
+ var btn = document.getElementById('copy-button');
83
+ btn.textContent = 'Copied!';
84
+ setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
85
+ });
86
+ `.trim(),
87
+ } }))));
76
88
  exports.AboutPage = AboutPage;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crowdin/app-project-module",
3
- "version": "1.3.1",
3
+ "version": "1.4.0",
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",