@fonderie/client 1.11.1 → 1.13.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.
@@ -113,6 +113,7 @@ interface IRegisterInput {
113
113
  password: string;
114
114
  firstName?: string;
115
115
  lastName?: string;
116
+ locale?: string;
116
117
  }
117
118
 
118
119
  interface IResetPasswordInput {
@@ -417,6 +418,9 @@ interface ISetTemplateInput {
417
418
 
418
419
  new CourierAdminClient(opts: ICourierAdminClientOptions): CourierAdminClient
419
420
  .listTemplates(): Promise<IApiResponse<ITemplateEntry[]>>
421
+ .getTemplateCatalog(): Promise<IApiResponse<ITemplateCatalog>>
422
+ .getBuiltInTemplate(type: string, locale?: string | null | undefined): Promise<IApiResponse<IBuiltInTemplate>>
423
+ .resolveTemplate(type: string, locale?: string | null | undefined): Promise<IApiResponse<ITemplateResolution>>
420
424
  .getTemplate(type: string, locale?: string | null | undefined): Promise<IApiResponse<ITemplateEntry>>
421
425
  .setTemplate(type: string, input: ISetTemplateInput, locale?: string | null | undefined): Promise<IApiResponse<ITemplateEntry>>
422
426
  .deleteTemplate(type: string, locale?: string | null | undefined): Promise<IApiResponse<undefined>>
@@ -431,10 +435,22 @@ interface ITemplateGroup {
431
435
  system: boolean;
432
436
  }
433
437
 
438
+ interface ITemplateLanguage {
439
+ locale: string | null;
440
+ label: string;
441
+ saved: boolean;
442
+ builtIn: boolean;
443
+ active: boolean;
444
+ }
445
+
434
446
  function groupTemplatesByType(rows: readonly ITemplateEntry[]): ITemplateGroup[]
435
447
 
436
448
  function missingTemplateLocales(rows: readonly ITemplateEntry[], type: string): string[]
437
449
 
450
+ function suggestTemplateLocales(catalog: ITemplateCatalog, type: string): string[]
451
+
452
+ function templateLanguages(email: ITemplateCatalogEntry, defaultLocale: string): ITemplateLanguage[]
453
+
438
454
  interface IAddAddressInput {
439
455
  countryIso: string;
440
456
  zipPostalCode: string;
@@ -1465,6 +1481,43 @@ interface ISubscriptionResult {
1465
1481
  subscription: ISubscriptionDTO;
1466
1482
  }
1467
1483
 
1484
+ interface IBuiltInTemplate {
1485
+ type: string;
1486
+ locale: string;
1487
+ subject: string | null;
1488
+ html: string | null;
1489
+ text: string;
1490
+ }
1491
+
1492
+ interface ITemplateCatalog {
1493
+ defaultLocale: string;
1494
+ fallbacks: Record<string, string[]>;
1495
+ emails: ITemplateCatalogEntry[];
1496
+ }
1497
+
1498
+ interface ITemplateCatalogEntry {
1499
+ type: string;
1500
+ system: boolean;
1501
+ builtIn: {
1502
+ default: boolean;
1503
+ languages: string[];
1504
+ };
1505
+ versions: Array<{
1506
+ locale: string | null;
1507
+ active: boolean;
1508
+ version: number;
1509
+ updatedAt: string;
1510
+ }>;
1511
+ }
1512
+
1513
+ interface ITemplateResolution {
1514
+ requested: string;
1515
+ chain: string[];
1516
+ defaultLocale: string;
1517
+ sent: string;
1518
+ source: 'saved' | 'built-in';
1519
+ }
1520
+
1468
1521
  interface ITemplateEntry {
1469
1522
  system?: boolean;
1470
1523
  type: string;
package/dist/index.cjs CHANGED
@@ -56,7 +56,9 @@ __export(index_exports, {
56
56
  inferConfigValue: () => inferConfigValue,
57
57
  isAdminLocale: () => isAdminLocale,
58
58
  isMfaRequired: () => isMfaRequired,
59
- missingTemplateLocales: () => missingTemplateLocales
59
+ missingTemplateLocales: () => missingTemplateLocales,
60
+ suggestTemplateLocales: () => suggestTemplateLocales,
61
+ templateLanguages: () => templateLanguages
60
62
  });
61
63
  module.exports = __toCommonJS(index_exports);
62
64
 
@@ -2187,6 +2189,41 @@ var CourierAdminClient = class {
2187
2189
  })
2188
2190
  );
2189
2191
  }
2192
+ // Every email — saved or built-in only — with its languages and the app's
2193
+ // locales. The flat listTemplates() only sees saved rows.
2194
+ getTemplateCatalog() {
2195
+ return this.http.request(
2196
+ this.rebase({
2197
+ method: "GET",
2198
+ path: "/admin/template-catalog",
2199
+ token: this.adminToken
2200
+ })
2201
+ );
2202
+ }
2203
+ // Fonderie's own copy in a language (omitted: the English default). 404 when
2204
+ // none ships in that language.
2205
+ getBuiltInTemplate(type, locale) {
2206
+ const q = locale ? `?locale=${encodeURIComponent(locale)}` : "";
2207
+ return this.http.request(
2208
+ this.rebase({
2209
+ method: "GET",
2210
+ path: `/admin/templates/${encodeURIComponent(type)}/built-in${q}`,
2211
+ token: this.adminToken
2212
+ })
2213
+ );
2214
+ }
2215
+ // Who receives what: decided server-side by the same function a real send
2216
+ // runs, so the answer cannot drift from delivery.
2217
+ resolveTemplate(type, locale) {
2218
+ const q = locale ? `?locale=${encodeURIComponent(locale)}` : "";
2219
+ return this.http.request(
2220
+ this.rebase({
2221
+ method: "GET",
2222
+ path: `/admin/templates/${encodeURIComponent(type)}/resolve${q}`,
2223
+ token: this.adminToken
2224
+ })
2225
+ );
2226
+ }
2190
2227
  getTemplate(type, locale) {
2191
2228
  const q = locale ? `?locale=${encodeURIComponent(locale)}` : "";
2192
2229
  return this.http.request(
@@ -2280,6 +2317,40 @@ function missingTemplateLocales(rows, type) {
2280
2317
  const used = new Set(rows.map((r) => r.locale).filter((l) => l !== null && !has.has(l)));
2281
2318
  return [...used].sort();
2282
2319
  }
2320
+ function templateLanguages(email, defaultLocale) {
2321
+ const out = /* @__PURE__ */ new Map();
2322
+ const saved = new Map(email.versions.map((v) => [v.locale, v]));
2323
+ const base = saved.get(null);
2324
+ if (base || email.builtIn.default) {
2325
+ out.set("", {
2326
+ locale: null,
2327
+ label: defaultLocale,
2328
+ saved: Boolean(base),
2329
+ builtIn: email.builtIn.default,
2330
+ active: base ? base.active : true
2331
+ });
2332
+ }
2333
+ for (const lang of email.builtIn.languages) {
2334
+ const own = saved.get(lang);
2335
+ out.set(lang, { locale: lang, label: lang, saved: Boolean(own), builtIn: true, active: own ? own.active : true });
2336
+ }
2337
+ for (const v of email.versions) {
2338
+ if (v.locale === null || out.has(v.locale)) continue;
2339
+ out.set(v.locale, { locale: v.locale, label: v.locale, saved: true, builtIn: false, active: v.active });
2340
+ }
2341
+ return [...out.values()].sort((a, b) => a.label.localeCompare(b.label));
2342
+ }
2343
+ function suggestTemplateLocales(catalog4, type) {
2344
+ const email = catalog4.emails.find((e) => e.type === type);
2345
+ const has = new Set(email ? templateLanguages(email, catalog4.defaultLocale).map((l) => l.label) : []);
2346
+ const used = /* @__PURE__ */ new Set();
2347
+ for (const e of catalog4.emails) {
2348
+ for (const l of templateLanguages(e, catalog4.defaultLocale)) {
2349
+ if (l.locale !== null && !has.has(l.label)) used.add(l.label);
2350
+ }
2351
+ }
2352
+ return [...used].sort();
2353
+ }
2283
2354
 
2284
2355
  // src/types.ts
2285
2356
  function isMfaRequired(result) {
@@ -3008,7 +3079,9 @@ var templates = {
3008
3079
  newTemplate: "New template",
3009
3080
  hint: "Every email the app sends. Open one to edit its copy and preview it live.",
3010
3081
  loading: "Loading templates\u2026",
3011
- openLocale: "Open the {locale} version of {type}"
3082
+ openLocale: "Open the {locale} version of {type}",
3083
+ legend: "Solid: a version you saved. Dashed: Fonderie\u2019s built-in copy, not edited. Struck through: switched off.",
3084
+ languages: "Languages"
3012
3085
  },
3013
3086
  editor: {
3014
3087
  loading: "Loading template\u2026",
@@ -3031,7 +3104,17 @@ var templates = {
3031
3104
  unknownActor: "unknown",
3032
3105
  rollBack: "Roll back",
3033
3106
  confirmDelete: 'Delete "{type}"?',
3034
- confirmDeleteLocale: 'Delete the {locale} version of "{type}"? People in that locale will receive the default version.'
3107
+ confirmDeleteLocale: 'Delete the {locale} version of "{type}"? People in that locale will receive the default version.',
3108
+ builtInCopy: "Fonderie\u2019s built-in copy. Saving creates your own version of it.",
3109
+ resetToBuiltIn: "Reset to built-in",
3110
+ confirmReset: "Replace your {locale} version with Fonderie\u2019s built-in copy?",
3111
+ chain: "Fallback: {chain}",
3112
+ whoReceives: "Who receives what",
3113
+ whoPlaceholder: "A locale, e.g. fr-BE",
3114
+ check: "Check",
3115
+ receives: "A {requested} user receives the {sent} version.",
3116
+ sourceSaved: "It is your saved version.",
3117
+ sourceBuiltIn: "It is Fonderie\u2019s built-in copy."
3035
3118
  },
3036
3119
  create: {
3037
3120
  titleNew: "New template",
@@ -3050,7 +3133,8 @@ var templates = {
3050
3133
  errorText: "The plain-text body is required \u2014 it is what every email client can show.",
3051
3134
  exists: '"{type}" already exists \u2014 open it from the list to edit.',
3052
3135
  existsLocale: '"{type}" ({locale}) already exists \u2014 open it from the list to edit.',
3053
- untranslated: "Still the default copy: {fields}. Translate them before adding this locale."
3136
+ untranslated: "Still the default copy: {fields}. Translate them before adding this locale.",
3137
+ errorDefaultLocale: "{locale} is the default version of this email. Edit the default instead."
3054
3138
  }
3055
3139
  };
3056
3140
  var templates_default = templates;
@@ -3704,7 +3788,9 @@ var templates2 = {
3704
3788
  newTemplate: "Nueva plantilla",
3705
3789
  hint: "Cada correo que env\xEDa la aplicaci\xF3n. Abre uno para editar su contenido y ver la vista previa en directo.",
3706
3790
  loading: "Cargando plantillas\u2026",
3707
- openLocale: "Abrir la versi\xF3n {locale} de {type}"
3791
+ openLocale: "Abrir la versi\xF3n {locale} de {type}",
3792
+ legend: "S\xF3lido: una versi\xF3n que guardaste. Discontinuo: la versi\xF3n integrada de Fonderie, sin editar. Tachado: desactivada.",
3793
+ languages: "Idiomas"
3708
3794
  },
3709
3795
  editor: {
3710
3796
  loading: "Cargando plantilla\u2026",
@@ -3727,7 +3813,17 @@ var templates2 = {
3727
3813
  unknownActor: "desconocido",
3728
3814
  rollBack: "Restaurar",
3729
3815
  confirmDelete: '\xBFEliminar "{type}"?',
3730
- confirmDeleteLocale: '\xBFEliminar la versi\xF3n {locale} de "{type}"? Las personas de ese idioma recibir\xE1n la versi\xF3n predeterminada.'
3816
+ confirmDeleteLocale: '\xBFEliminar la versi\xF3n {locale} de "{type}"? Las personas de ese idioma recibir\xE1n la versi\xF3n predeterminada.',
3817
+ builtInCopy: "Versi\xF3n integrada de Fonderie. Al guardarla se crea tu propia versi\xF3n.",
3818
+ resetToBuiltIn: "Restablecer la versi\xF3n integrada",
3819
+ confirmReset: "\xBFReemplazar tu versi\xF3n {locale} por la versi\xF3n integrada de Fonderie?",
3820
+ chain: "Respaldo: {chain}",
3821
+ whoReceives: "Qui\xE9n recibe qu\xE9",
3822
+ whoPlaceholder: "Un idioma, p. ej. fr-BE",
3823
+ check: "Comprobar",
3824
+ receives: "Un usuario {requested} recibe la versi\xF3n {sent}.",
3825
+ sourceSaved: "Es tu versi\xF3n guardada.",
3826
+ sourceBuiltIn: "Es la versi\xF3n integrada de Fonderie."
3731
3827
  },
3732
3828
  create: {
3733
3829
  titleNew: "Nueva plantilla",
@@ -3746,7 +3842,8 @@ var templates2 = {
3746
3842
  errorText: "El cuerpo en texto plano es obligatorio \u2014 es lo que puede mostrar cualquier cliente de correo.",
3747
3843
  exists: '"{type}" ya existe \u2014 \xE1brela desde la lista para editarla.',
3748
3844
  existsLocale: '"{type}" ({locale}) ya existe \u2014 \xE1brela desde la lista para editarla.',
3749
- untranslated: "Todav\xEDa en la versi\xF3n predeterminada: {fields}. Trad\xFAcelos antes de a\xF1adir este idioma."
3845
+ untranslated: "Todav\xEDa en la versi\xF3n predeterminada: {fields}. Trad\xFAcelos antes de a\xF1adir este idioma.",
3846
+ errorDefaultLocale: "{locale} es la versi\xF3n predeterminada de este correo. Edita la predeterminada en su lugar."
3750
3847
  }
3751
3848
  };
3752
3849
  var templates_default2 = templates2;
@@ -4400,7 +4497,9 @@ var templates3 = {
4400
4497
  newTemplate: "Nouveau mod\xE8le",
4401
4498
  hint: "Chaque e-mail envoy\xE9 par l'application. Ouvrez-en un pour modifier son contenu et le pr\xE9visualiser en direct.",
4402
4499
  loading: "Chargement des mod\xE8les\u2026",
4403
- openLocale: "Ouvrir la version {locale} de {type}"
4500
+ openLocale: "Ouvrir la version {locale} de {type}",
4501
+ legend: "Plein : une version que vous avez enregistr\xE9e. Pointill\xE9s : la version int\xE9gr\xE9e de Fonderie, non modifi\xE9e. Barr\xE9 : d\xE9sactiv\xE9e.",
4502
+ languages: "Langues"
4404
4503
  },
4405
4504
  editor: {
4406
4505
  loading: "Chargement du mod\xE8le\u2026",
@@ -4423,7 +4522,17 @@ var templates3 = {
4423
4522
  unknownActor: "inconnu",
4424
4523
  rollBack: "Restaurer",
4425
4524
  confirmDelete: "Supprimer \xAB {type} \xBB ?",
4426
- confirmDeleteLocale: "Supprimer la version {locale} de \xAB {type} \xBB ? Les personnes de cette langue recevront la version par d\xE9faut."
4525
+ confirmDeleteLocale: "Supprimer la version {locale} de \xAB {type} \xBB ? Les personnes de cette langue recevront la version par d\xE9faut.",
4526
+ builtInCopy: "Version int\xE9gr\xE9e de Fonderie. L\u2019enregistrer cr\xE9e votre propre version.",
4527
+ resetToBuiltIn: "R\xE9tablir la version int\xE9gr\xE9e",
4528
+ confirmReset: "Remplacer votre version {locale} par la version int\xE9gr\xE9e de Fonderie ?",
4529
+ chain: "Repli : {chain}",
4530
+ whoReceives: "Qui re\xE7oit quoi",
4531
+ whoPlaceholder: "Une langue, p. ex. fr-BE",
4532
+ check: "V\xE9rifier",
4533
+ receives: "Un utilisateur {requested} re\xE7oit la version {sent}.",
4534
+ sourceSaved: "C\u2019est votre version enregistr\xE9e.",
4535
+ sourceBuiltIn: "C\u2019est la version int\xE9gr\xE9e de Fonderie."
4427
4536
  },
4428
4537
  create: {
4429
4538
  titleNew: "Nouveau mod\xE8le",
@@ -4442,7 +4551,8 @@ var templates3 = {
4442
4551
  errorText: "Le corps en texte brut est obligatoire \u2014 c\u2019est ce que tout client e-mail peut afficher.",
4443
4552
  exists: "\xAB {type} \xBB existe d\xE9j\xE0 \u2014 ouvrez-le depuis la liste pour le modifier.",
4444
4553
  existsLocale: "\xAB {type} \xBB ({locale}) existe d\xE9j\xE0 \u2014 ouvrez-le depuis la liste pour le modifier.",
4445
- untranslated: "Encore dans la version par d\xE9faut : {fields}. Traduisez-les avant d\u2019ajouter cette langue."
4554
+ untranslated: "Encore dans la version par d\xE9faut : {fields}. Traduisez-les avant d\u2019ajouter cette langue.",
4555
+ errorDefaultLocale: "{locale} est la version par d\xE9faut de cet e-mail. Modifiez plut\xF4t la version par d\xE9faut."
4446
4556
  }
4447
4557
  };
4448
4558
  var templates_default3 = templates3;
@@ -4531,6 +4641,8 @@ function formatAdminDate(value, locale = DEFAULT_ADMIN_LOCALE, style = "datetime
4531
4641
  inferConfigValue,
4532
4642
  isAdminLocale,
4533
4643
  isMfaRequired,
4534
- missingTemplateLocales
4644
+ missingTemplateLocales,
4645
+ suggestTemplateLocales,
4646
+ templateLanguages
4535
4647
  });
4536
4648
  //# sourceMappingURL=index.cjs.map