anote-server-libs 0.11.6 → 0.11.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anote-server-libs",
3
- "version": "0.11.6",
3
+ "version": "0.11.8",
4
4
  "description": "Helpers for express-TS servers",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",
package/services/utils.js CHANGED
@@ -12,9 +12,8 @@ exports.sendSelfPostableMessage = sendSelfPostableMessage;
12
12
  exports.fpEuros = fpEuros;
13
13
  exports.digitize = digitize;
14
14
  exports.readEmailTemplates = readEmailTemplates;
15
- exports.replacePlaceholders = replacePlaceholders;
16
15
  exports.getHtmlReplaced = getHtmlReplaced;
17
- exports.getEmailTitle = getEmailTitle;
16
+ exports.getEmailOneSimpleValue = getEmailOneSimpleValue;
18
17
  const fs = require("fs");
19
18
  function atob(str) {
20
19
  return Buffer.from(str, 'base64').toString('binary');
@@ -250,27 +249,17 @@ function getHtml(template, translationKeyValue) {
250
249
  });
251
250
  return template;
252
251
  }
253
- function getHtmlReplaced(config, templates, key, lang, defaultTemplateTranslations = {}, projectSpecificTranslations = {}, envSpecificTranslations, extraData, newPage) {
254
- const asTranslationMap = (value) => value && typeof value === 'object' ? value : {};
255
- const defaultTranslations = defaultTemplateTranslations?.[lang] || defaultTemplateTranslations?.[0] || {};
256
- const projectSpecificTrans = {
257
- ...asTranslationMap(projectSpecificTranslations?.[config.app.product]?.[lang] || projectSpecificTranslations?.[config.app.name]?.[0]),
258
- ...asTranslationMap(projectSpecificTranslations?.[config.app.product]?.[key]?.[lang] || projectSpecificTranslations?.[config.app.name]?.[key]?.[0])
259
- };
260
- const envSpecificTrans = {
261
- ...asTranslationMap(envSpecificTranslations?.[config.app.name]?.[lang] || envSpecificTranslations?.[config.app.name]?.[0]),
262
- ...asTranslationMap(envSpecificTranslations?.[config.app.name]?.[key]?.[lang] || envSpecificTranslations?.[config.app.name]?.[key]?.[0])
263
- };
264
- extraData = Object.fromEntries(Object.entries(extraData || {}).map(([k, v]) => [k, `{{${v}}}`]));
265
- const translationKeyValue = {
266
- ...defaultTranslations,
267
- ...projectSpecificTrans,
268
- ...envSpecificTrans,
269
- ...extraData,
270
- domain: config.frontend,
271
- ...config.app.emailConfig
252
+ function getHtmlReplaced(config, templates, key, lang, translations, data = {}, dynamicData = {}, newPage) {
253
+ const { product, name } = config.app;
254
+ const merged = {
255
+ ...(translations.common[lang] ?? translations.common[0] ?? {}),
256
+ ...(translations.byProduct[product]?.[lang] ?? translations.byProduct[product]?.[0] ?? {}),
257
+ ...(translations.byEnv[name]?.[lang] ?? translations.byEnv[name]?.[0] ?? {}),
258
+ ...(data[name] ?? {}),
259
+ ...dynamicData,
260
+ domain: config.frontend
272
261
  };
273
- let html = getHtml(templates[key], translationKeyValue);
262
+ let html = getHtml(templates[key], merged);
274
263
  if (newPage) {
275
264
  html = html.replace('</head>', `<style>
276
265
  @media print {
@@ -285,10 +274,15 @@ function getHtmlReplaced(config, templates, key, lang, defaultTemplateTranslatio
285
274
  }
286
275
  return html;
287
276
  }
288
- function getEmailTitle(config, key, lang, defaultTitles = {}, projectSpecificTitles = {}, envSpecificTitles = {}, extraData = {}) {
277
+ function getEmailOneSimpleValue(config, key, lang, translations, data = {}, dynamicData = {}) {
278
+ const { product, name } = config.app;
279
+ const merged = {
280
+ ...(translations.common[lang] ?? translations.common[0] ?? {}),
281
+ ...(translations.byProduct[product]?.[lang] ?? translations.byProduct[product]?.[0] ?? {}),
282
+ ...(translations.byEnv[name]?.[lang] ?? translations.byEnv[name]?.[0] ?? {}),
283
+ ...(data[name] ?? {}),
284
+ ...dynamicData
285
+ };
289
286
  const pattern = new RegExp('{{\\s*([a-zA-Z._0-9]+)\\s*}}', 'g');
290
- const title = envSpecificTitles?.[config.app.name]?.[lang]?.[key]
291
- || projectSpecificTitles?.[config.app.product]?.[lang]?.[key]
292
- || defaultTitles?.[lang]?.[key];
293
- return title?.replace(pattern, (_, placeholderKey) => extraData?.[placeholderKey] || config.app.emailConfig?.[placeholderKey] || placeholderKey);
287
+ return merged[key]?.replace(pattern, (_, placeholderKey) => String(dynamicData[placeholderKey] ?? placeholderKey));
294
288
  }
package/services/utils.ts CHANGED
@@ -3,6 +3,8 @@ import {NextFunction, Request, Response} from 'express';
3
3
  import {Logger} from 'winston';
4
4
  import {BaseModelRepository} from '../models/repository/BaseModelRepository';
5
5
 
6
+ interface MinimalConfiguration {frontend: string, app: {product: string, name: string}}
7
+
6
8
  export function atob(str: string): string {
7
9
  return Buffer.from(str, 'base64').toString('binary');
8
10
  }
@@ -193,7 +195,7 @@ function loadEmailTemplates(path: string): Record<string, string> | undefined {
193
195
  return loadedEmailTemplates;
194
196
  }
195
197
 
196
- export function readEmailTemplates(path: string, config: Record<string, any>): {[id: string]: string} | undefined {
198
+ export function readEmailTemplates(path: string, config: MinimalConfiguration): {[id: string]: string} | undefined {
197
199
  const {product, name} = config.app;
198
200
  if(!product || !name) return loadEmailTemplates(path);
199
201
  const mainPath = path + '/' + product;
@@ -203,7 +205,7 @@ export function readEmailTemplates(path: string, config: Record<string, any>): {
203
205
  return {...defaultTemplates, ...overrideTemplates};
204
206
  }
205
207
 
206
- export function replacePlaceholders(data: Record<string, any>, keys: string[], depth: number): any {
208
+ function replacePlaceholders(data: Record<string, any>, keys: string[], depth: number): any {
207
209
  if(!keys || depth >= keys.length) return undefined;
208
210
  if(depth === keys.length - 1) return (data || {})[keys[depth]];
209
211
  return replacePlaceholders((data || {})[keys[depth]], keys, depth + 1);
@@ -229,36 +231,25 @@ function getHtml(template: string, translationKeyValue: Record<string, any>): st
229
231
  return template;
230
232
  }
231
233
 
232
- export function getHtmlReplaced(config: {frontend: string, app: {product: string, name: string, emailConfig: Record<string, string>}},
233
- templates: Record<string, string>,
234
- key: string, lang: number,
235
- defaultTemplateTranslations: Record<number, Record<string | number, string>> = {},
236
- projectSpecificTranslations: Record<string, Record<string | number, Record<string | number, string>>> = {},
237
- envSpecificTranslations?: Record<string, Record<string | number, Record<string | number, string>>>,
238
- extraData?: Record<string, any>,
234
+ export function getHtmlReplaced(config: MinimalConfiguration, templates: Record<string, string>, key: string, lang: number,
235
+ translations: {
236
+ common: Record<number, Record<string, string>>,
237
+ byProduct: Record<string, Record<number, Record<string, string>>>,
238
+ byEnv: Record<string, Record<number, Record<string, string>>>
239
+ },
240
+ data: Record<string, Record<string, string | number>> = {},
241
+ dynamicData: Record<string, string | number> = {},
239
242
  newPage?: boolean): string {
240
- const asTranslationMap = (value: unknown): Record<string | number, string> =>
241
- value && typeof value === 'object' ? value as Record<string | number, string> : {};
242
- const defaultTranslations = defaultTemplateTranslations?.[lang] || defaultTemplateTranslations?.[0] || {};
243
- const projectSpecificTrans = {
244
- ...asTranslationMap(projectSpecificTranslations?.[config.app.product]?.[lang] || projectSpecificTranslations?.[config.app.name]?.[0]),
245
- ...asTranslationMap(projectSpecificTranslations?.[config.app.product]?.[key]?.[lang] || projectSpecificTranslations?.[config.app.name]?.[key]?.[0])
246
- };
247
- const envSpecificTrans = {
248
- ...asTranslationMap(envSpecificTranslations?.[config.app.name]?.[lang] || envSpecificTranslations?.[config.app.name]?.[0]),
249
- ...asTranslationMap(envSpecificTranslations?.[config.app.name]?.[key]?.[lang] || envSpecificTranslations?.[config.app.name]?.[key]?.[0])
250
- };
251
- // Add {{}} around all extraData values so that they will be auto translated in the template if needed
252
- extraData = Object.fromEntries(Object.entries(extraData || {}).map(([k, v]) => [k, `{{${v}}}`]));
253
- const translationKeyValue = {
254
- ...defaultTranslations,
255
- ...projectSpecificTrans,
256
- ...envSpecificTrans,
257
- ...extraData,
258
- domain: config.frontend,
259
- ...config.app.emailConfig
243
+ const {product, name} = config.app;
244
+ const merged = {
245
+ ...(translations.common[lang] ?? translations.common[0] ?? {}),
246
+ ...(translations.byProduct[product]?.[lang] ?? translations.byProduct[product]?.[0] ?? {}),
247
+ ...(translations.byEnv[name]?.[lang] ?? translations.byEnv[name]?.[0] ?? {}),
248
+ ...(data[name] ?? {}),
249
+ ...dynamicData,
250
+ domain: config.frontend
260
251
  };
261
- let html = getHtml(templates[key], translationKeyValue);
252
+ let html = getHtml(templates[key], merged);
262
253
  if(newPage) {
263
254
  html = html.replace('</head>', `<style>
264
255
  @media print {
@@ -274,15 +265,24 @@ export function getHtmlReplaced(config: {frontend: string, app: {product: string
274
265
  return html;
275
266
  }
276
267
 
277
- export function getEmailTitle(config: {frontend: string, app: {product: string, name: string, emailConfig: Record<string, any>}},
278
- key: string, lang: number,
279
- defaultTitles: Record<number, Record<string | number, string>> = {},
280
- projectSpecificTitles: Record<string, Record<number, Record<string | number, string>>> = {},
281
- envSpecificTitles: Record<string, Record<number, Record<string | number, string>>> = {},
282
- extraData: Record<string, string> = {}): string | undefined {
268
+ export function getEmailOneSimpleValue(config: MinimalConfiguration, key: string, lang: number,
269
+ translations: {
270
+ common: Record<number, Record<string, string>>,
271
+ byProduct: Record<string, Record<number, Record<string, string>>>,
272
+ byEnv: Record<string, Record<number, Record<string, string>>>
273
+ },
274
+ data: Record<string, Record<string, string | number>> = {},
275
+ dynamicData: Record<string, string | number> = {}): string | undefined {
276
+ const {product, name} = config.app;
277
+ const merged: Record<string, string | number> = {
278
+ ...(translations.common[lang] ?? translations.common[0] ?? {}),
279
+ ...(translations.byProduct[product]?.[lang] ?? translations.byProduct[product]?.[0] ?? {}),
280
+ ...(translations.byEnv[name]?.[lang] ?? translations.byEnv[name]?.[0] ?? {}),
281
+ ...(data[name] ?? {}),
282
+ ...dynamicData
283
+ };
283
284
  const pattern = new RegExp('{{\\s*([a-zA-Z._0-9]+)\\s*}}', 'g');
284
- const title = envSpecificTitles?.[config.app.name]?.[lang]?.[key]
285
- || projectSpecificTitles?.[config.app.product]?.[lang]?.[key]
286
- || defaultTitles?.[lang]?.[key];
287
- return title?.replace(pattern, (_: string, placeholderKey: string) => extraData?.[placeholderKey] || config.app.emailConfig?.[placeholderKey] || placeholderKey);
285
+ return (merged[key] as string | undefined)?.replace(pattern, (_: string, placeholderKey: string) =>
286
+ String(dynamicData[placeholderKey] ?? placeholderKey)
287
+ );
288
288
  }