@burdenoff/fe-libs 2026.918.2 → 2026.920.1
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/dist/shared/assistant/adminModeSendGate.d.ts +43 -0
- package/dist/shared/assistant/adminModeSendGate.d.ts.map +1 -1
- package/dist/shared/assistant/adminModeSendGate.js +33 -18
- package/dist/shared/assistant/i18nManifest.d.ts +5 -0
- package/dist/shared/assistant/i18nManifest.d.ts.map +1 -1
- package/dist/shared/assistant/i18nManifest.js +6 -1
- package/dist/shared/assistant/index.d.ts +1 -0
- package/dist/shared/assistant/index.d.ts.map +1 -1
- package/dist/shared/assistant/modeCapabilities.d.ts +25 -0
- package/dist/shared/assistant/modeCapabilities.d.ts.map +1 -1
- package/dist/shared/assistant/modeCapabilities.js +6 -2
- package/dist/shared/assistant/store.d.ts +26 -5
- package/dist/shared/assistant/store.d.ts.map +1 -1
- package/dist/shared/assistant/store.js +28 -18
- package/dist/shared/assistant/ui/AssistantApiCallsConsentDialog.d.ts +27 -10
- package/dist/shared/assistant/ui/AssistantApiCallsConsentDialog.d.ts.map +1 -1
- package/dist/shared/assistant/ui/AssistantApiCallsConsentDialog.js +22 -16
- package/dist/shared/assistant/ui/AssistantChatArea.d.ts.map +1 -1
- package/dist/shared/assistant/ui/AssistantChatArea.js +363 -347
- package/dist/shared/assistant/writeModeConsent.d.ts +99 -0
- package/dist/shared/assistant/writeModeConsent.d.ts.map +1 -0
- package/dist/shared/assistant/writeModeConsent.js +48 -0
- package/dist/shared/providers/shell/I18nProvider.d.ts.map +1 -1
- package/dist/shared/providers/shell/I18nProvider.js +33 -39
- package/dist/shared/providers/shell/resolveTranslation.d.ts +23 -0
- package/dist/shared/providers/shell/resolveTranslation.d.ts.map +1 -0
- package/dist/shared/providers/shell/resolveTranslation.js +11 -0
- package/dist/shared-assistant.js +110 -109
- package/package.json +2 -2
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { AssistantModeConfig } from './conversation';
|
|
2
|
+
import { AssistantTr } from './i18n';
|
|
3
|
+
import { AssistantMode } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* The single flag this module replaces, as it sits in storage written by
|
|
6
|
+
* fe-libs 2026.919.1 and earlier.
|
|
7
|
+
*/
|
|
8
|
+
export declare const LEGACY_WRITE_CONSENT_KEY = "apiCallsAcknowledged";
|
|
9
|
+
/**
|
|
10
|
+
* The write-capable modes this profile has accepted, read back from storage.
|
|
11
|
+
*
|
|
12
|
+
* - A stored list is kept, minus anything that is not a mode id and any repeat.
|
|
13
|
+
* Storage is data from another build, so it is checked, not trusted.
|
|
14
|
+
* - Otherwise a stored legacy flag of exactly `true` becomes `["api-calls"]`.
|
|
15
|
+
* - Otherwise nothing is acknowledged.
|
|
16
|
+
*
|
|
17
|
+
* ★ A stored list WINS over the legacy flag, and is never merged with it. This
|
|
18
|
+
* build never writes the flag, and an older build drops the list the next time
|
|
19
|
+
* it persists (its `partialize` does not know the key), so the two are not
|
|
20
|
+
* stored side by side by either. Should they ever be, the list is the newer
|
|
21
|
+
* decision. After a rollback and a roll-forward, the flag the older build wrote
|
|
22
|
+
* is migrated again, exactly as on first upgrade.
|
|
23
|
+
*/
|
|
24
|
+
export declare function restoreAcknowledgedWriteModes(persisted: unknown): AssistantMode[];
|
|
25
|
+
/** Has this profile accepted the write consent for `mode`? */
|
|
26
|
+
export declare function isWriteModeAcknowledged(acknowledged: readonly AssistantMode[], mode: AssistantMode): boolean;
|
|
27
|
+
/** Send-time consent and voice checks against the validated post-wait mode. */
|
|
28
|
+
export declare function writeModeSendRefusal(mode: AssistantMode, config: Pick<AssistantModeConfig, "writeCapable"> | undefined, acknowledged: readonly AssistantMode[], { dictated, confirmsWrites }: {
|
|
29
|
+
dictated: boolean;
|
|
30
|
+
confirmsWrites: boolean;
|
|
31
|
+
}): string | null;
|
|
32
|
+
/** `acknowledged` plus `mode`, unchanged (same array) if it is already there. */
|
|
33
|
+
export declare function withWriteModeAcknowledged(acknowledged: readonly AssistantMode[], mode: AssistantMode): readonly AssistantMode[];
|
|
34
|
+
/** A mode as the dialog needs it: the product's config, or just an id. */
|
|
35
|
+
export type WriteConsentMode = Pick<AssistantModeConfig, "id"> & Partial<Pick<AssistantModeConfig, "label" | "producesArtifacts">>;
|
|
36
|
+
/** Every line of the dialog, already translated. */
|
|
37
|
+
export interface WriteModeConsentCopy {
|
|
38
|
+
title: string;
|
|
39
|
+
body: string;
|
|
40
|
+
/** Whether the assistant stops for approval before a change — true or false, said plainly. */
|
|
41
|
+
safeguard: string;
|
|
42
|
+
confirm: string;
|
|
43
|
+
cancel: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* fe-libs' own English for the `apiCalls.consent*` keys — the exact strings the
|
|
47
|
+
* `tr()` calls in `writeModeConsentCopy` pass as their fallbacks.
|
|
48
|
+
*
|
|
49
|
+
* ★ Written out twice ON PURPOSE. `i18nManifest.test.ts` reads the fallback
|
|
50
|
+
* ARGUMENT of every `tr()` call with the TypeScript parser, so a call site that
|
|
51
|
+
* passed this table's value instead of a literal would drop out of the manifest
|
|
52
|
+
* — and a key missing from the manifest is a key no product seeds, which is how
|
|
53
|
+
* a string silently goes English in every locale. That test pins each call site
|
|
54
|
+
* to the manifest, and `writeModeConsent.test.ts` pins this table to the
|
|
55
|
+
* manifest too, so the three cannot drift apart without CI failing.
|
|
56
|
+
*/
|
|
57
|
+
export declare const TAKE_ACTION_ENGLISH: {
|
|
58
|
+
readonly "apiCalls.consentTitle": "Switch to Take action mode?";
|
|
59
|
+
readonly "apiCalls.consentBody": "In Take action mode the assistant can read AND change your data — creating records, logging activity, updating details, and more, on your behalf.";
|
|
60
|
+
readonly "apiCalls.consentConfirm": "Enable Take action";
|
|
61
|
+
readonly "apiCalls.consentCancel": "Stay in Ask";
|
|
62
|
+
};
|
|
63
|
+
/** A consent key whose English fe-libs writes itself. */
|
|
64
|
+
export type TakeActionConsentKey = keyof typeof TAKE_ACTION_ENGLISH;
|
|
65
|
+
/**
|
|
66
|
+
* What the consent dialog says when switching from `current` into `target`.
|
|
67
|
+
*
|
|
68
|
+
* ★★ A PRODUCT'S OWN WORDS ALWAYS WIN. `apiCalls.consent*` predate per-mode
|
|
69
|
+
* wording, and products have seeded them: FluidGrids authored all five in six
|
|
70
|
+
* languages FOR ITS OWN NAME for `api-calls` ("In Workflow mode … your
|
|
71
|
+
* FluidGrids data"), HealthyBowl's body names "your HealthyBowl data". So for
|
|
72
|
+
* `api-calls` those keys are asked FIRST, and whatever comes back that is not
|
|
73
|
+
* fe-libs' own English is what renders — in the reader's language, byte for
|
|
74
|
+
* byte as before this change.
|
|
75
|
+
*
|
|
76
|
+
* ★★ `writeConsent.*` renders only where there is no product copy to lose: a
|
|
77
|
+
* mode that is not `api-calls` (a build mode has no seeded consent copy at all),
|
|
78
|
+
* or an `api-calls` whose dictionary gave our own sentence back. It says the
|
|
79
|
+
* same thing through `{{mode}}`, which names the mode as its pill does — so a
|
|
80
|
+
* product that calls `api-calls` "Build" stops being told "Take action" without
|
|
81
|
+
* any product's translation turning English.
|
|
82
|
+
*
|
|
83
|
+
* ★ The cancel button keeps `apiCalls.consentCancel` ("Stay in Ask") only when
|
|
84
|
+
* the mode being LEFT is the one called Ask — that sentence is about `current`,
|
|
85
|
+
* not `target`. Leaving Build names Build.
|
|
86
|
+
*
|
|
87
|
+
* ★★ `confirmsWrites` decides the safeguard line, and the caller must derive it
|
|
88
|
+
* from what the SANDBOX does (`modeRequiresConfirmWrites`), never from a product
|
|
89
|
+
* flag. The old dialog promised a confirmation step for every write-capable
|
|
90
|
+
* mode; only `api-calls` boots with AI_ASSISTANT_CONFIRM_WRITES, so for any
|
|
91
|
+
* other mode that promise was false. It now says the opposite, plainly.
|
|
92
|
+
*/
|
|
93
|
+
export declare function writeModeConsentCopy(tr: AssistantTr, { target, current, confirmsWrites, }: {
|
|
94
|
+
target: WriteConsentMode;
|
|
95
|
+
/** The mode being left; absent is read as Ask, the mode everyone starts in. */
|
|
96
|
+
current?: WriteConsentMode | null;
|
|
97
|
+
confirmsWrites: boolean;
|
|
98
|
+
}): WriteModeConsentCopy;
|
|
99
|
+
//# sourceMappingURL=writeModeConsent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writeModeConsent.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/writeModeConsent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAM1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C;;;GAGG;AACH,eAAO,MAAM,wBAAwB,yBAAyB,CAAC;AAc/D;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,OAAO,GAAG,aAAa,EAAE,CAiBjF;AAED,8DAA8D;AAC9D,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,SAAS,aAAa,EAAE,EACtC,IAAI,EAAE,aAAa,GAClB,OAAO,CAET;AAED,+EAA+E;AAC/E,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,cAAc,CAAC,GAAG,SAAS,EAC7D,YAAY,EAAE,SAAS,aAAa,EAAE,EACtC,EAAE,QAAQ,EAAE,cAAc,EAAE,EAAE;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,cAAc,EAAE,OAAO,CAAA;CAAE,GAC3E,MAAM,GAAG,IAAI,CAQf;AAED,iFAAiF;AACjF,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,SAAS,aAAa,EAAE,EACtC,IAAI,EAAE,aAAa,GAClB,SAAS,aAAa,EAAE,CAE1B;AAED,0EAA0E;AAC1E,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC,GAC5D,OAAO,CAAC,IAAI,CAAC,mBAAmB,EAAE,OAAO,GAAG,mBAAmB,CAAC,CAAC,CAAC;AAEpE,oDAAoD;AACpD,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,8FAA8F;IAC9F,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAmBD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB;;;;;CAMtB,CAAC;AAEX,yDAAyD;AACzD,MAAM,MAAM,oBAAoB,GAAG,MAAM,OAAO,mBAAmB,CAAC;AAuBpE;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,WAAW,EACf,EACE,MAAM,EACN,OAAO,EACP,cAAc,GACf,EAAE;IACD,MAAM,EAAE,gBAAgB,CAAC;IACzB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAClC,cAAc,EAAE,OAAO,CAAC;CACzB,GACA,oBAAoB,CA+DtB"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { ASSISTANT_MODE_FALLBACK_LABELS as e, assistantModeFallbackLabel as t } from "./modeCopy.js";
|
|
2
|
+
import { isAssistantModeId as n } from "./modeIds.js";
|
|
3
|
+
//#region src/shared/assistant/writeModeConsent.ts
|
|
4
|
+
var r = "apiCallsAcknowledged", i = "api-calls";
|
|
5
|
+
function a(e) {
|
|
6
|
+
if (typeof e != "object" || !e) return [];
|
|
7
|
+
let t = Object.fromEntries(Object.entries(e)), r = t.acknowledgedWriteModes;
|
|
8
|
+
if (Array.isArray(r)) {
|
|
9
|
+
let e = /* @__PURE__ */ new Set();
|
|
10
|
+
for (let t of r) n(t) && e.add(t);
|
|
11
|
+
return [...e];
|
|
12
|
+
}
|
|
13
|
+
return t.apiCallsAcknowledged === !0 ? [i] : [];
|
|
14
|
+
}
|
|
15
|
+
function o(e, t) {
|
|
16
|
+
return e.includes(t);
|
|
17
|
+
}
|
|
18
|
+
function s(e, t, n, { dictated: r, confirmsWrites: i }) {
|
|
19
|
+
return t?.writeCapable && !o(n, e) ? "Confirm this assistant mode before sending: choose it again in the mode selector." : r && (t?.writeCapable || i) ? "Voice can't be used in a mode that can change your data. Type your request instead." : null;
|
|
20
|
+
}
|
|
21
|
+
function c(e, t) {
|
|
22
|
+
return e.includes(t) ? e : [...e, t];
|
|
23
|
+
}
|
|
24
|
+
function l(e, n) {
|
|
25
|
+
return e(`mode.${n.id}`, n.label || t(n));
|
|
26
|
+
}
|
|
27
|
+
var u = (e, n) => (e.label || t(e)) === n, d = {
|
|
28
|
+
"apiCalls.consentTitle": "Switch to Take action mode?",
|
|
29
|
+
"apiCalls.consentBody": "In Take action mode the assistant can read AND change your data — creating records, logging activity, updating details, and more, on your behalf.",
|
|
30
|
+
"apiCalls.consentConfirm": "Enable Take action",
|
|
31
|
+
"apiCalls.consentCancel": "Stay in Ask"
|
|
32
|
+
};
|
|
33
|
+
function f(e, t) {
|
|
34
|
+
return t === d[e] ? null : t;
|
|
35
|
+
}
|
|
36
|
+
var p = { id: "assistant" };
|
|
37
|
+
function m(t, { target: n, current: r, confirmsWrites: i }) {
|
|
38
|
+
let a = l(t, n), o = n.id === "api-calls", s = !r || u(r, e.assistant);
|
|
39
|
+
return {
|
|
40
|
+
title: (o ? f("apiCalls.consentTitle", t("apiCalls.consentTitle", "Switch to Take action mode?")) : null) ?? t("writeConsent.title", "Switch to {{mode}} mode?", { mode: a }),
|
|
41
|
+
body: (o ? f("apiCalls.consentBody", t("apiCalls.consentBody", "In Take action mode the assistant can read AND change your data — creating records, logging activity, updating details, and more, on your behalf.")) : null) ?? t("writeConsent.body", "In {{mode}} mode the assistant can read AND change your data — creating records, logging activity, updating details, and more, on your behalf.", { mode: a }),
|
|
42
|
+
safeguard: i ? t("apiCalls.consentBody2", "It will describe what it is about to do and ask you to confirm before making a change. Only continue if you want the assistant to take actions for you.") : t("writeConsent.unconfirmed", "It does not stop to ask before each change — it makes changes as soon as it decides to. Only continue if you want the assistant to change your data without asking first."),
|
|
43
|
+
confirm: (o ? f("apiCalls.consentConfirm", t("apiCalls.consentConfirm", "Enable Take action")) : null) ?? t("writeConsent.confirm", "Enable {{mode}}", { mode: a }),
|
|
44
|
+
cancel: (s ? f("apiCalls.consentCancel", t("apiCalls.consentCancel", "Stay in Ask")) : null) ?? t("writeConsent.cancel", "Stay in {{mode}}", { mode: l(t, r ?? p) })
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
48
|
+
export { r as LEGACY_WRITE_CONSENT_KEY, d as TAKE_ACTION_ENGLISH, o as isWriteModeAcknowledged, a as restoreAcknowledgedWriteModes, c as withWriteModeAcknowledged, m as writeModeConsentCopy, s as writeModeSendRefusal };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"I18nProvider.d.ts","sourceRoot":"","sources":["../../../../src/shared/providers/shell/I18nProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"I18nProvider.d.ts","sourceRoot":"","sources":["../../../../src/shared/providers/shell/I18nProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAIf,MAAM,MAAM,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAWlF,MAAM,WAAW,qBAAqB;IACpC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,qBAAqB,CAAC;CAC/C;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,qBAAqB,CAAC;IACpC,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,CAAC,EAAE,CACD,GAAG,EAAE,MAAM,EACX,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAC3D,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KACrC,MAAM,CAAC;IACZ,uDAAuD;IACvD,SAAS,EAAE,OAAO,CAAC;IACnB,gDAAgD;IAChD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAID;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAErF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,SAAS,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,mBAAmB,CAAC;IACxC;;;OAGG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,SAAS,CAAC;CAC9B;AAoED;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,qBAAqB,GAAG,SAAS,EACvC,QAAQ,EAAE,qBAAqB,GAAG,SAAS,GAC1C,qBAAqB,CAsBvB;AAED,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,aAAoB,EACpB,YAAY,EAAE,kBAAyC,EACvD,UAA+B,EAC/B,SAAS,EACT,iBAAiB,EACjB,wBAA+B,EAC/B,gBAAgB,GACjB,EAAE,iBAAiB,2CAwMnB;AAED,wBAAgB,OAAO,qBAMtB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE9D"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { interpolate as e } from "./interpolate.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { resolveTranslationValue as t } from "./resolveTranslation.js";
|
|
3
|
+
import { createContext as n, use as r, useCallback as i, useEffect as a, useMemo as o, useRef as s, useState as c } from "react";
|
|
4
|
+
import { Fragment as l, jsx as u } from "react/jsx-runtime";
|
|
4
5
|
//#region src/shared/providers/shell/I18nProvider.tsx
|
|
5
|
-
var
|
|
6
|
+
var d = n(null), f = {
|
|
6
7
|
en: {},
|
|
7
8
|
es: {},
|
|
8
9
|
fr: {},
|
|
@@ -12,7 +13,7 @@ var u = t(null), d = {
|
|
|
12
13
|
ta: {},
|
|
13
14
|
hi: {},
|
|
14
15
|
ar: {}
|
|
15
|
-
},
|
|
16
|
+
}, p = {
|
|
16
17
|
attempted: /* @__PURE__ */ new Set(),
|
|
17
18
|
translations: {},
|
|
18
19
|
version: 0,
|
|
@@ -20,7 +21,7 @@ var u = t(null), d = {
|
|
|
20
21
|
this.attempted.clear(), this.translations = {}, this.version++;
|
|
21
22
|
}
|
|
22
23
|
};
|
|
23
|
-
function
|
|
24
|
+
function m(e, t, n) {
|
|
24
25
|
if (typeof window > "u") return n;
|
|
25
26
|
if (e) {
|
|
26
27
|
let t = localStorage.getItem(`bf-p-${e}-locale`);
|
|
@@ -28,13 +29,6 @@ function p(e, t, n) {
|
|
|
28
29
|
}
|
|
29
30
|
return localStorage.getItem(t) || n;
|
|
30
31
|
}
|
|
31
|
-
function m(e, t) {
|
|
32
|
-
if (!e) return;
|
|
33
|
-
let n = t.split("."), r = e;
|
|
34
|
-
for (let e of n) if (typeof r == "object" && r && e in r) r = r[e];
|
|
35
|
-
else return;
|
|
36
|
-
return typeof r == "string" ? r : void 0;
|
|
37
|
-
}
|
|
38
32
|
function h(e) {
|
|
39
33
|
return typeof e == "object" && !!e;
|
|
40
34
|
}
|
|
@@ -53,18 +47,18 @@ function g(e, t) {
|
|
|
53
47
|
}
|
|
54
48
|
return n;
|
|
55
49
|
}
|
|
56
|
-
function _({ children:
|
|
57
|
-
let [S, C] =
|
|
50
|
+
function _({ children: n, defaultLocale: r = "en", translations: h = f, storageKey: _ = "burdenoff-locale", profileId: v, fetchTranslations: y, showChildrenWhileLoading: b = !0, loadingComponent: x }) {
|
|
51
|
+
let [S, C] = c(() => m(v, _, r)), [w, T] = c({}), [E, D] = c(!!y), [O, k] = c(null), A = s(/* @__PURE__ */ new Set()), j = s(p.version), M = o(() => {
|
|
58
52
|
let e = { ...h };
|
|
59
53
|
for (let [t, n] of Object.entries(w)) if (n && Object.keys(n).length > 0) {
|
|
60
54
|
let r = t;
|
|
61
55
|
e[r] = g(h[r], n);
|
|
62
56
|
}
|
|
63
57
|
return e;
|
|
64
|
-
}, [h, w]), N =
|
|
58
|
+
}, [h, w]), N = i(async (e) => {
|
|
65
59
|
if (y) {
|
|
66
|
-
if (j.current !==
|
|
67
|
-
let t =
|
|
60
|
+
if (j.current !== p.version && (A.current.clear(), j.current = p.version), p.attempted.has(e)) {
|
|
61
|
+
let t = p.translations[e];
|
|
68
62
|
t && Object.keys(t).length > 0 && T((n) => !n[e] || Object.keys(n[e]).length === 0 ? {
|
|
69
63
|
...n,
|
|
70
64
|
[e]: t
|
|
@@ -75,7 +69,7 @@ function _({ children: t, defaultLocale: n = "en", translations: h = d, storageK
|
|
|
75
69
|
A.current.add(e), D(!0), k(null);
|
|
76
70
|
try {
|
|
77
71
|
let t = await y(e);
|
|
78
|
-
t && Object.keys(t).length > 0 && (
|
|
72
|
+
t && Object.keys(t).length > 0 && (p.attempted.add(e), p.translations[e] = t), T((n) => ({
|
|
79
73
|
...n,
|
|
80
74
|
[e]: t
|
|
81
75
|
}));
|
|
@@ -87,36 +81,36 @@ function _({ children: t, defaultLocale: n = "en", translations: h = d, storageK
|
|
|
87
81
|
}
|
|
88
82
|
}
|
|
89
83
|
}, [y]);
|
|
90
|
-
|
|
91
|
-
y && (
|
|
84
|
+
a(() => {
|
|
85
|
+
y && (p.attempted.has(S) && p.translations[S] && Object.keys(p.translations[S]).length > 0 || N(S));
|
|
92
86
|
}, [
|
|
93
87
|
y,
|
|
94
88
|
S,
|
|
95
89
|
N
|
|
96
|
-
]),
|
|
97
|
-
let e =
|
|
90
|
+
]), a(() => {
|
|
91
|
+
let e = m(v, _, r);
|
|
98
92
|
C(e), document.documentElement.setAttribute("lang", e);
|
|
99
93
|
}, [
|
|
100
94
|
v,
|
|
101
95
|
_,
|
|
102
|
-
|
|
96
|
+
r
|
|
103
97
|
]);
|
|
104
|
-
let P =
|
|
98
|
+
let P = i((e) => {
|
|
105
99
|
C(e), localStorage.setItem(_, e), v && localStorage.setItem(`bf-p-${v}-locale`, e), document.documentElement.setAttribute("lang", e);
|
|
106
|
-
}, [_, v]), F =
|
|
107
|
-
let
|
|
108
|
-
if (typeof
|
|
109
|
-
else if (
|
|
110
|
-
let { defaultValue: e, ...t } =
|
|
111
|
-
typeof e == "string" ?
|
|
100
|
+
}, [_, v]), F = i((n, i, a) => {
|
|
101
|
+
let o, s;
|
|
102
|
+
if (typeof i == "string") o = i, s = a;
|
|
103
|
+
else if (i && typeof i == "object") {
|
|
104
|
+
let { defaultValue: e, ...t } = i;
|
|
105
|
+
typeof e == "string" ? o = e : typeof e == "number" && (o = String(e)), s = t;
|
|
112
106
|
}
|
|
113
|
-
let
|
|
114
|
-
return
|
|
107
|
+
let c = t(M[S], n) ?? (S === r ? void 0 : t(M[r], n)) ?? (r === "en" ? void 0 : t(M.en, n)) ?? o ?? n;
|
|
108
|
+
return s ? e(c, s) : c;
|
|
115
109
|
}, [
|
|
116
110
|
S,
|
|
117
111
|
M,
|
|
118
|
-
|
|
119
|
-
]), I =
|
|
112
|
+
r
|
|
113
|
+
]), I = o(() => ({
|
|
120
114
|
locale: S,
|
|
121
115
|
translations: M[S] || {},
|
|
122
116
|
setLocale: P,
|
|
@@ -131,21 +125,21 @@ function _({ children: t, defaultLocale: n = "en", translations: h = d, storageK
|
|
|
131
125
|
E,
|
|
132
126
|
O
|
|
133
127
|
]);
|
|
134
|
-
return E && !b && x ? /* @__PURE__ */ l
|
|
128
|
+
return E && !b && x ? /* @__PURE__ */ u(l, { children: x }) : /* @__PURE__ */ u(d.Provider, {
|
|
135
129
|
value: I,
|
|
136
|
-
children:
|
|
130
|
+
children: n
|
|
137
131
|
});
|
|
138
132
|
}
|
|
139
133
|
function v() {
|
|
140
|
-
let e =
|
|
134
|
+
let e = r(d);
|
|
141
135
|
if (!e) throw Error("useI18n must be used within an I18nProvider");
|
|
142
136
|
return e;
|
|
143
137
|
}
|
|
144
138
|
function y() {
|
|
145
|
-
|
|
139
|
+
p.clear();
|
|
146
140
|
}
|
|
147
141
|
function b(e) {
|
|
148
|
-
return
|
|
142
|
+
return p.attempted.has(e);
|
|
149
143
|
}
|
|
150
144
|
//#endregion
|
|
151
145
|
export { _ as I18nProvider, y as clearTranslationCache, b as isTranslationAttempted, g as mergeTranslationDictionaries, v as useI18n };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { TranslationDictionary } from './I18nProvider';
|
|
2
|
+
/**
|
|
3
|
+
* Where a nested dictionary keeps the value of a key that is ALSO a branch.
|
|
4
|
+
*
|
|
5
|
+
* `healthybowl.common.confirm` ("Confirm") and `healthybowl.common.confirm.title`
|
|
6
|
+
* ("Are you sure?") cannot both live at one path of a nested object, so the
|
|
7
|
+
* leaf is stored beside its children as `confirm._`. The product extractors
|
|
8
|
+
* write that slot, the seed stores such a key literally as `….confirm._`, and
|
|
9
|
+
* the i18n export serves it nested — so the translation already reaches the
|
|
10
|
+
* client. Nothing read it: `t('healthybowl.common.confirm')` walked to the
|
|
11
|
+
* object and returned undefined, and the call site's inline English rendered
|
|
12
|
+
* in every locale (13 HealthyBowl keys, BOFF-7438; BOFF-7459).
|
|
13
|
+
*/
|
|
14
|
+
export declare const LEAF_SLOT = "_";
|
|
15
|
+
/**
|
|
16
|
+
* Resolve a dot-notated translation key from a dictionary: the string at that
|
|
17
|
+
* path, or — when the path names a branch — the string in its `_` slot.
|
|
18
|
+
*
|
|
19
|
+
* A branch with no `_` string still resolves to undefined, so the caller's
|
|
20
|
+
* fallback renders rather than "[object Object]".
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveTranslationValue(dictionary: TranslationDictionary | undefined, key: string): string | undefined;
|
|
23
|
+
//# sourceMappingURL=resolveTranslation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveTranslation.d.ts","sourceRoot":"","sources":["../../../../src/shared/providers/shell/resolveTranslation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAE5D;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,SAAS,MAAM,CAAC;AAE7B;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,qBAAqB,GAAG,SAAS,EAC7C,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,SAAS,CAgBpB"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
function e(e, t) {
|
|
2
|
+
if (!e) return;
|
|
3
|
+
let n = e;
|
|
4
|
+
for (let e of t.split(".")) if (typeof n == "object" && n && e in n) n = n[e];
|
|
5
|
+
else return;
|
|
6
|
+
if (typeof n == "string") return n;
|
|
7
|
+
let r = typeof n == "object" && n ? n._ : void 0;
|
|
8
|
+
return typeof r == "string" ? r : void 0;
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
export { e as resolveTranslationValue };
|