@shipeasy/sdk 1.2.0 → 2.0.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.
@@ -148,14 +148,14 @@ interface LabelAttrs {
148
148
  "data-label-desc"?: string;
149
149
  }
150
150
  declare function labelAttrs(key: string, variables?: Record<string, string | number>, desc?: string): LabelAttrs;
151
- /**
152
- * Universal i18n facade. Backed by the `window.i18n` global the loader
153
- * script installs. Returns the key itself when the loader hasn't run
154
- * (SSR, missing script tag, before profile fetch completes), so call
155
- * sites never need to null-check.
156
- */
157
151
  declare const i18n: {
158
- t(key: string, variables?: Record<string, string | number>): string;
152
+ /**
153
+ * Look up `key` in the active translation profile. When the profile
154
+ * hasn't been fetched yet (SSR, CDN downtime, missing key), interpolate
155
+ * `fallback` instead — `fallback` is the source-of-truth English copy
156
+ * and is mandatory so the page never renders a raw key.
157
+ */
158
+ t(key: string, fallback: string, variables?: Record<string, string | number>): string;
159
159
  /**
160
160
  * Translate a key and return a framework element (e.g. React <span>)
161
161
  * carrying `data-label` / `data-variables` attributes so the ShipEasy
@@ -168,7 +168,7 @@ declare const i18n: {
168
168
  * Falls back to a plain translated string if `createElement` was not
169
169
  * configured (e.g. server-side or in non-JSX contexts).
170
170
  */
171
- tEl(key: string, variables?: Record<string, string | number>, desc?: string): any;
171
+ tEl(key: string, fallback: string, variables?: Record<string, string | number>, desc?: string): any;
172
172
  /** Wire up the element creator once at app startup (call before any tEl use). */
173
173
  configure(opts: {
174
174
  createElement: (tag: string, props: object, children: string) => any;
@@ -148,14 +148,14 @@ interface LabelAttrs {
148
148
  "data-label-desc"?: string;
149
149
  }
150
150
  declare function labelAttrs(key: string, variables?: Record<string, string | number>, desc?: string): LabelAttrs;
151
- /**
152
- * Universal i18n facade. Backed by the `window.i18n` global the loader
153
- * script installs. Returns the key itself when the loader hasn't run
154
- * (SSR, missing script tag, before profile fetch completes), so call
155
- * sites never need to null-check.
156
- */
157
151
  declare const i18n: {
158
- t(key: string, variables?: Record<string, string | number>): string;
152
+ /**
153
+ * Look up `key` in the active translation profile. When the profile
154
+ * hasn't been fetched yet (SSR, CDN downtime, missing key), interpolate
155
+ * `fallback` instead — `fallback` is the source-of-truth English copy
156
+ * and is mandatory so the page never renders a raw key.
157
+ */
158
+ t(key: string, fallback: string, variables?: Record<string, string | number>): string;
159
159
  /**
160
160
  * Translate a key and return a framework element (e.g. React <span>)
161
161
  * carrying `data-label` / `data-variables` attributes so the ShipEasy
@@ -168,7 +168,7 @@ declare const i18n: {
168
168
  * Falls back to a plain translated string if `createElement` was not
169
169
  * configured (e.g. server-side or in non-JSX contexts).
170
170
  */
171
- tEl(key: string, variables?: Record<string, string | number>, desc?: string): any;
171
+ tEl(key: string, fallback: string, variables?: Record<string, string | number>, desc?: string): any;
172
172
  /** Wire up the element creator once at app startup (call before any tEl use). */
173
173
  configure(opts: {
174
174
  createElement: (tag: string, props: object, children: string) => any;
@@ -454,13 +454,15 @@ var FlagsClientBrowser = class {
454
454
  this.evalResult = data;
455
455
  }
456
456
  getFlag(name) {
457
+ if (this.evalResult === null) return false;
457
458
  const ov = readGateOverride(name);
458
459
  if (ov !== null) return ov;
459
- return this.evalResult?.flags[name] ?? false;
460
+ return this.evalResult.flags[name] ?? false;
460
461
  }
461
462
  getConfig(name, decode) {
463
+ if (this.evalResult === null) return void 0;
462
464
  const ov = readConfigOverride(name);
463
- const raw = ov !== void 0 ? ov : this.evalResult?.configs?.[name];
465
+ const raw = ov !== void 0 ? ov : this.evalResult.configs?.[name];
464
466
  if (raw === void 0) return void 0;
465
467
  if (!decode) return raw;
466
468
  try {
@@ -715,10 +717,27 @@ function labelAttrs(key, variables, desc) {
715
717
  return attrs;
716
718
  }
717
719
  var _createElement = null;
720
+ function interpolate(template, variables) {
721
+ if (!variables) return template;
722
+ let out = template;
723
+ for (const name of Object.keys(variables)) {
724
+ out = out.replace(new RegExp(`\\{\\{${name}\\}\\}`, "g"), String(variables[name]));
725
+ }
726
+ return out;
727
+ }
718
728
  var i18n = {
719
- t(key, variables) {
720
- if (typeof window !== "undefined" && window.i18n) return window.i18n.t(key, variables);
721
- return key;
729
+ /**
730
+ * Look up `key` in the active translation profile. When the profile
731
+ * hasn't been fetched yet (SSR, CDN downtime, missing key), interpolate
732
+ * `fallback` instead — `fallback` is the source-of-truth English copy
733
+ * and is mandatory so the page never renders a raw key.
734
+ */
735
+ t(key, fallback, variables) {
736
+ if (typeof window !== "undefined" && window.i18n) {
737
+ const v = window.i18n.t(key, variables);
738
+ if (v !== key) return v;
739
+ }
740
+ return interpolate(fallback, variables);
722
741
  },
723
742
  /**
724
743
  * Translate a key and return a framework element (e.g. React <span>)
@@ -732,9 +751,8 @@ var i18n = {
732
751
  * Falls back to a plain translated string if `createElement` was not
733
752
  * configured (e.g. server-side or in non-JSX contexts).
734
753
  */
735
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
736
- tEl(key, variables, desc) {
737
- const text = this.t(key, variables);
754
+ tEl(key, fallback, variables, desc) {
755
+ const text = this.t(key, fallback, variables);
738
756
  if (!_createElement) return text;
739
757
  return _createElement("span", labelAttrs(key, variables, desc), text);
740
758
  },
@@ -412,13 +412,15 @@ var FlagsClientBrowser = class {
412
412
  this.evalResult = data;
413
413
  }
414
414
  getFlag(name) {
415
+ if (this.evalResult === null) return false;
415
416
  const ov = readGateOverride(name);
416
417
  if (ov !== null) return ov;
417
- return this.evalResult?.flags[name] ?? false;
418
+ return this.evalResult.flags[name] ?? false;
418
419
  }
419
420
  getConfig(name, decode) {
421
+ if (this.evalResult === null) return void 0;
420
422
  const ov = readConfigOverride(name);
421
- const raw = ov !== void 0 ? ov : this.evalResult?.configs?.[name];
423
+ const raw = ov !== void 0 ? ov : this.evalResult.configs?.[name];
422
424
  if (raw === void 0) return void 0;
423
425
  if (!decode) return raw;
424
426
  try {
@@ -673,10 +675,27 @@ function labelAttrs(key, variables, desc) {
673
675
  return attrs;
674
676
  }
675
677
  var _createElement = null;
678
+ function interpolate(template, variables) {
679
+ if (!variables) return template;
680
+ let out = template;
681
+ for (const name of Object.keys(variables)) {
682
+ out = out.replace(new RegExp(`\\{\\{${name}\\}\\}`, "g"), String(variables[name]));
683
+ }
684
+ return out;
685
+ }
676
686
  var i18n = {
677
- t(key, variables) {
678
- if (typeof window !== "undefined" && window.i18n) return window.i18n.t(key, variables);
679
- return key;
687
+ /**
688
+ * Look up `key` in the active translation profile. When the profile
689
+ * hasn't been fetched yet (SSR, CDN downtime, missing key), interpolate
690
+ * `fallback` instead — `fallback` is the source-of-truth English copy
691
+ * and is mandatory so the page never renders a raw key.
692
+ */
693
+ t(key, fallback, variables) {
694
+ if (typeof window !== "undefined" && window.i18n) {
695
+ const v = window.i18n.t(key, variables);
696
+ if (v !== key) return v;
697
+ }
698
+ return interpolate(fallback, variables);
680
699
  },
681
700
  /**
682
701
  * Translate a key and return a framework element (e.g. React <span>)
@@ -690,9 +709,8 @@ var i18n = {
690
709
  * Falls back to a plain translated string if `createElement` was not
691
710
  * configured (e.g. server-side or in non-JSX contexts).
692
711
  */
693
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
694
- tEl(key, variables, desc) {
695
- const text = this.t(key, variables);
712
+ tEl(key, fallback, variables, desc) {
713
+ const text = this.t(key, fallback, variables);
696
714
  if (!_createElement) return text;
697
715
  return _createElement("span", labelAttrs(key, variables, desc), text);
698
716
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shipeasy/sdk",
3
- "version": "1.2.0",
3
+ "version": "2.0.0",
4
4
  "description": "Shipeasy SDK — feature gates, runtime configs, experiments, and metrics for the Shipeasy hosted service.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "homepage": "https://shipeasy.ai",