@cosmicdrift/kumiko-locale-de 0.317.0 → 0.319.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-locale-de",
3
- "version": "0.317.0",
3
+ "version": "0.319.0",
4
4
  "description": "German UI and mail copy for Kumiko framework screens. Opt in by mounting localeDe() + localeDeClient().",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
@@ -28,7 +28,7 @@
28
28
  }
29
29
  },
30
30
  "dependencies": {
31
- "@cosmicdrift/kumiko-framework": "0.317.0"
31
+ "@cosmicdrift/kumiko-framework": "0.319.0"
32
32
  },
33
33
  "publishConfig": {
34
34
  "registry": "https://registry.npmjs.org",
@@ -276,6 +276,45 @@ export const frameworkEnCatalog: Readonly<Record<string, string>> = {
276
276
  "auth.verifyEmail.successBody": "Thanks! You can sign in now.",
277
277
  "auth.verifyEmail.successTitle": "Email verified",
278
278
  "auth.verifyEmail.verifying": "Verifying email …",
279
+ "billing-foundation.errors.alreadyOnPlan": "This tenant is already on that plan.",
280
+ "billing-foundation.errors.foreignProviderCustomer":
281
+ "This customer account does not belong to your tenant.",
282
+ "billing-foundation.errors.noActiveSubscription":
283
+ "This tenant has no active subscription to switch.",
284
+ "billing-foundation.errors.planSwitchNotSupported":
285
+ "This provider does not support switching plans.",
286
+ "billing-foundation.errors.planTiersShareProduct":
287
+ "Each plan needs its own Stripe product. Contact support.",
288
+ "billing-foundation.errors.priceUnavailable": "This plan's price is temporarily unavailable.",
289
+ "billing-foundation.errors.providerHasNoPriceCatalog":
290
+ "This provider has no known prices configured.",
291
+ "billing-foundation.errors.providerMismatch":
292
+ "This tenant's subscription is on a different provider than the plan catalog. Contact support to migrate.",
293
+ "billing-foundation.errors.redirectOriginNotAllowed":
294
+ "This redirect URL is not allowed for this app.",
295
+ "billing-foundation.errors.subscriptionExists":
296
+ "This tenant already has an active subscription. Switch plans instead.",
297
+ "billing-foundation.errors.unknownPrice": "This price is not recognized.",
298
+ "billing-foundation.plans.billingDisabled":
299
+ "Billing is not active yet. Your current plan stays in place.",
300
+ "billing-foundation.plans.choose": "Choose {plan}",
301
+ "billing-foundation.plans.currentPlan": "Current plan",
302
+ "billing-foundation.plans.everyInterval.day": "every {count} days",
303
+ "billing-foundation.plans.everyInterval.month": "every {count} months",
304
+ "billing-foundation.plans.everyInterval.week": "every {count} weeks",
305
+ "billing-foundation.plans.everyInterval.year": "every {count} years",
306
+ "billing-foundation.plans.cancelScheduled": "Your subscription is scheduled to end on {date}.",
307
+ "billing-foundation.plans.manage": "Manage subscription",
308
+ "billing-foundation.plans.paymentPending": "Payment is still being completed.",
309
+ "billing-foundation.plans.reactivate": "Reactivate subscription",
310
+ "billing-foundation.plans.perInterval.day": "/ day",
311
+ "billing-foundation.plans.perInterval.month": "/ month",
312
+ "billing-foundation.plans.perInterval.week": "/ week",
313
+ "billing-foundation.plans.perInterval.year": "/ year",
314
+ "billing-foundation.plans.priceUnavailable": "Price not available",
315
+ "billing-foundation.plans.purchaseNotAllowed": "Only administrators can change the plan.",
316
+ "billing-foundation.plans.subscriptionPending": "Your plan change is being processed.",
317
+ "billing-foundation.plans.switch": "Switch to {plan}",
279
318
  "cap-counter:entity:cap-counter:field:capName": "Cap",
280
319
  "cap-counter:entity:cap-counter:field:lastSoftWarnedAt": "Last soft warning",
281
320
  "cap-counter:entity:cap-counter:field:periodStart": "Period start",
@@ -573,6 +612,8 @@ export const frameworkEnCatalog: Readonly<Record<string, string>> = {
573
612
  "kumiko.widget.drawer.restore": "Restore drawer width",
574
613
  "kumiko.widget.error.title": "Couldn't load.",
575
614
  "kumiko.widget.loading": "Loading…",
615
+ "kumiko.planCard.current": "Current plan",
616
+ "kumiko.planCard.priceUnavailable": "Price not available",
576
617
  "kumiko.widget.step-bar.done": "Done",
577
618
  "kumiko.widget.upload.done": "Uploaded",
578
619
  "kumiko.widget.upload.error": "Failed",
@@ -682,6 +723,7 @@ export const frameworkEnCatalog: Readonly<Record<string, string>> = {
682
723
  "screen:auth-mfa-disable.title": "Disable two-factor authentication",
683
724
  "screen:auth-mfa-enable.title": "Two-factor authentication",
684
725
  "screen:auth-mfa-regenerate-recovery.title": "Generate new recovery codes",
726
+ "screen:billing-plans.title": "Billing",
685
727
  "screen:branding-settings.title": "Branding",
686
728
  "screen:cap-list.title": "Usage caps",
687
729
  "screen:delivery-log.title": "Delivery log",
@@ -42,6 +42,15 @@ describe("locale-de formal overrides", () => {
42
42
  );
43
43
  });
44
44
 
45
+ test("localeDeClient always ships the formal overrides under de-x-formal", () => {
46
+ for (const address of ["informal", "formal"] as const) {
47
+ const formal = localeDeClient({ address }).translations["de-x-formal"];
48
+ expect(formal["auth.resetPassword.intro"]).toBe(
49
+ localeDeFormalOverrides["auth.resetPassword.intro"],
50
+ );
51
+ }
52
+ });
53
+
45
54
  test("localeDeClient defaults to informal and switches to formal on request", () => {
46
55
  expect(localeDeClient().translations["de"]["auth.resetPassword.intro"]).toBe(
47
56
  "Wähle ein neues Passwort mit mindestens 8 Zeichen.",
@@ -0,0 +1,8 @@
1
+ [
2
+ {
3
+ "version": "0.319.0",
4
+ "type": "improvement",
5
+ "title": "German strings for the new billing-plans cancel-scheduled banner and reactivate label",
6
+ "detail": "Adds German i18n strings for the cancel-scheduled info banner and the\n\"Reactivate subscription\" button label introduced by billing-foundation's\ncancel/reactivate change."
7
+ }
8
+ ]
package/src/formal.ts CHANGED
@@ -82,6 +82,10 @@ export const localeDeFormalOverrides: Readonly<Record<string, string>> = {
82
82
  "auth.verifyEmail.errorBody":
83
83
  "Der Link ist ungültig oder abgelaufen. Bitte fordern Sie eine neue Bestätigungs-Mail an.",
84
84
  "auth.verifyEmail.successBody": "Danke! Sie können sich jetzt anmelden.",
85
+ "billing-foundation.plans.billingDisabled":
86
+ "Die Abrechnung ist noch nicht aktiv. Ihr aktueller Tarif bleibt bestehen.",
87
+ "billing-foundation.plans.cancelScheduled": "Ihr Abo endet am {date}.",
88
+ "billing-foundation.plans.subscriptionPending": "Ihr Tarifwechsel wird gerade verarbeitet.",
85
89
  "custom-fields.form.createMode": "Speichern Sie zuerst den Eintrag, um Custom-Felder zu setzen.",
86
90
  "dispatcher.errors.network":
87
91
  "Netzwerkfehler. Bitte überprüfen Sie Ihre Verbindung und versuchen Sie es erneut.",
package/src/strings.ts CHANGED
@@ -288,6 +288,46 @@ export const localeDeBundle: Readonly<Record<string, string>> = {
288
288
  "auth.verifyEmail.successBody": "Danke! Du kannst dich jetzt anmelden.",
289
289
  "auth.verifyEmail.successTitle": "E-Mail bestätigt",
290
290
  "auth.verifyEmail.verifying": "E-Mail wird bestätigt …",
291
+ "billing-foundation.errors.alreadyOnPlan": "Dieser Mandant ist bereits auf diesem Tarif.",
292
+ "billing-foundation.errors.foreignProviderCustomer":
293
+ "Dieses Kundenkonto gehört nicht zu diesem Mandanten.",
294
+ "billing-foundation.errors.noActiveSubscription":
295
+ "Dieser Mandant hat kein aktives Abo zum Wechseln.",
296
+ "billing-foundation.errors.planSwitchNotSupported":
297
+ "Dieser Anbieter unterstützt keinen Tarifwechsel.",
298
+ "billing-foundation.errors.planTiersShareProduct":
299
+ "Jeder Tarif braucht ein eigenes Stripe-Produkt. Bitte den Support kontaktieren.",
300
+ "billing-foundation.errors.priceUnavailable":
301
+ "Der Preis dieses Tarifs ist vorübergehend nicht verfügbar.",
302
+ "billing-foundation.errors.providerHasNoPriceCatalog":
303
+ "Für diesen Anbieter sind keine Preise konfiguriert.",
304
+ "billing-foundation.errors.providerMismatch":
305
+ "Das Abo dieses Mandanten läuft über einen anderen Anbieter als der Tarifkatalog. Bitte den Support für eine Migration kontaktieren.",
306
+ "billing-foundation.errors.redirectOriginNotAllowed":
307
+ "Diese Weiterleitungs-URL ist für diese App nicht erlaubt.",
308
+ "billing-foundation.errors.subscriptionExists":
309
+ "Dieser Mandant hat bereits ein aktives Abo. Wechsle stattdessen den Tarif.",
310
+ "billing-foundation.errors.unknownPrice": "Dieser Preis ist nicht bekannt.",
311
+ "billing-foundation.plans.billingDisabled":
312
+ "Die Abrechnung ist noch nicht aktiv. Dein aktueller Tarif bleibt bestehen.",
313
+ "billing-foundation.plans.choose": "{plan} wählen",
314
+ "billing-foundation.plans.currentPlan": "Aktueller Tarif",
315
+ "billing-foundation.plans.everyInterval.day": "alle {count} Tage",
316
+ "billing-foundation.plans.everyInterval.month": "alle {count} Monate",
317
+ "billing-foundation.plans.everyInterval.week": "alle {count} Wochen",
318
+ "billing-foundation.plans.everyInterval.year": "alle {count} Jahre",
319
+ "billing-foundation.plans.cancelScheduled": "Dein Abo endet am {date}.",
320
+ "billing-foundation.plans.manage": "Abo verwalten",
321
+ "billing-foundation.plans.paymentPending": "Zahlung wird noch abgeschlossen.",
322
+ "billing-foundation.plans.reactivate": "Abo reaktivieren",
323
+ "billing-foundation.plans.perInterval.day": "/ Tag",
324
+ "billing-foundation.plans.perInterval.month": "/ Monat",
325
+ "billing-foundation.plans.perInterval.week": "/ Woche",
326
+ "billing-foundation.plans.perInterval.year": "/ Jahr",
327
+ "billing-foundation.plans.priceUnavailable": "Preis nicht verfügbar",
328
+ "billing-foundation.plans.purchaseNotAllowed": "Nur Administratoren können den Tarif ändern.",
329
+ "billing-foundation.plans.subscriptionPending": "Dein Tarifwechsel wird gerade verarbeitet.",
330
+ "billing-foundation.plans.switch": "Zu {plan} wechseln",
291
331
  "cap-counter:entity:cap-counter:field:capName": "Limit",
292
332
  "cap-counter:entity:cap-counter:field:lastSoftWarnedAt": "Letzte Soft-Warnung",
293
333
  "cap-counter:entity:cap-counter:field:periodStart": "Periodenstart",
@@ -591,6 +631,8 @@ export const localeDeBundle: Readonly<Record<string, string>> = {
591
631
  "kumiko.widget.drawer.restore": "Drawer-Breite zurücksetzen",
592
632
  "kumiko.widget.error.title": "Konnte nicht geladen werden.",
593
633
  "kumiko.widget.loading": "Lade…",
634
+ "kumiko.planCard.current": "Aktueller Tarif",
635
+ "kumiko.planCard.priceUnavailable": "Preis nicht verfügbar",
594
636
  "kumiko.widget.step-bar.done": "Erledigt",
595
637
  "kumiko.widget.upload.done": "Hochgeladen",
596
638
  "kumiko.widget.upload.error": "Fehlgeschlagen",
@@ -701,6 +743,7 @@ export const localeDeBundle: Readonly<Record<string, string>> = {
701
743
  "screen:auth-mfa-disable.title": "Zwei-Faktor-Authentifizierung deaktivieren",
702
744
  "screen:auth-mfa-enable.title": "Zwei-Faktor-Authentifizierung",
703
745
  "screen:auth-mfa-regenerate-recovery.title": "Neue Recovery-Codes erzeugen",
746
+ "screen:billing-plans.title": "Abrechnung",
704
747
  "screen:branding-settings.title": "Branding",
705
748
  "screen:cap-list.title": "Nutzungslimits",
706
749
  "screen:delivery-log.title": "Zustellprotokoll",
package/src/web.ts CHANGED
@@ -1,15 +1,28 @@
1
- import { type GermanAddress, germanBundleFor } from "./formal";
1
+ import { formalLocaleTag } from "@cosmicdrift/kumiko-framework/ui-types";
2
+ import { type GermanAddress, germanBundleFor, localeDeFormalOverrides } from "./formal";
2
3
  import { localeDeBundle } from "./strings";
3
4
 
4
5
  export type { GermanAddress };
5
6
  export { localeDeBundle };
6
7
 
8
+ const GERMAN = "de" as const;
9
+ const GERMAN_FORMAL = formalLocaleTag(GERMAN);
10
+
11
+ // `address` sets the default wording under "de"; the formal overrides are
12
+ // always shipped under "de-x-formal" too, so a surface wrapped in
13
+ // FormalityProvider("formal") says "Sie" even when the app default is "du".
7
14
  export function localeDeClient(options?: { readonly address?: GermanAddress }): {
8
15
  readonly name: "locale-de";
9
- readonly translations: { readonly de: Readonly<Record<string, string>> };
16
+ readonly translations: {
17
+ readonly [GERMAN]: Readonly<Record<string, string>>;
18
+ readonly [GERMAN_FORMAL]: Readonly<Record<string, string>>;
19
+ };
10
20
  } {
11
21
  return {
12
22
  name: "locale-de",
13
- translations: { de: germanBundleFor(options?.address ?? "informal") },
23
+ translations: {
24
+ [GERMAN]: germanBundleFor(options?.address ?? "informal"),
25
+ [GERMAN_FORMAL]: localeDeFormalOverrides,
26
+ },
14
27
  };
15
28
  }