@fonderie/client 1.3.0 → 1.4.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.
@@ -49,6 +49,7 @@ new FonderieClient(opts: IFonderieClientOptions): FonderieClient
49
49
  .webhooks: WebhooksClient
50
50
  .customers: CustomersClient
51
51
  .media: MediaClient
52
+ .config: ConfigClient
52
53
  .setAccessToken(token: string | undefined): void
53
54
  .clearCache(): void
54
55
  .setWorkspaceId(workspaceId: string | undefined): void
@@ -1614,4 +1615,17 @@ type CastResult = {
1614
1615
  };
1615
1616
 
1616
1617
  type ConfigValueType = 'string' | 'number' | 'boolean' | 'json';
1618
+
1619
+ new ConfigClient(http: HttpClient, tokens: TokenStore): ConfigClient
1620
+ .load(): Promise<IRemoteConfigState>
1621
+ .get<T>(key: string, fallback: T): T
1622
+ .snapshot(): IRemoteConfigState
1623
+ .subscribe(listener: Listener): () => void
1624
+
1625
+ interface IRemoteConfigState {
1626
+ values: Readonly<Record<string, unknown>>;
1627
+ loadedAt: Date | null;
1628
+ isLoading: boolean;
1629
+ error: unknown;
1630
+ }
1617
1631
  ```
package/dist/index.cjs CHANGED
@@ -30,6 +30,7 @@ __export(index_exports, {
30
30
  CONFIG_KEY_PATTERN: () => CONFIG_KEY_PATTERN,
31
31
  CONFIG_VALUE_TYPES: () => CONFIG_VALUE_TYPES,
32
32
  ConfigAdminClient: () => ConfigAdminClient,
33
+ ConfigClient: () => ConfigClient,
33
34
  CourierAdminClient: () => CourierAdminClient,
34
35
  CustomersClient: () => CustomersClient,
35
36
  FonderieApiError: () => FonderieApiError,
@@ -1145,6 +1146,62 @@ var MediaClient = class {
1145
1146
  }
1146
1147
  };
1147
1148
 
1149
+ // src/modules/config.ts
1150
+ var ConfigClient = class {
1151
+ constructor(http, tokens) {
1152
+ this.http = http;
1153
+ this.tokens = tokens;
1154
+ }
1155
+ http;
1156
+ tokens;
1157
+ state = { values: {}, loadedAt: null, isLoading: false, error: null };
1158
+ listeners = /* @__PURE__ */ new Set();
1159
+ inFlight = null;
1160
+ // GET /config/public — fetch the public values into the shared snapshot.
1161
+ // Concurrent calls share one request. A failure keeps the previous values
1162
+ // (a flag that was on does not flicker off because one refresh failed) and
1163
+ // is reported in `error`; before any success, reads fall back to defaults.
1164
+ load() {
1165
+ if (this.inFlight) return this.inFlight;
1166
+ this.set({ isLoading: true });
1167
+ this.inFlight = this.http.request({
1168
+ method: "GET",
1169
+ path: "/config/public",
1170
+ // Sent when signed in, so per-user values can be served later
1171
+ // without a client change; the route itself is public.
1172
+ token: this.tokens.get()
1173
+ }).then(
1174
+ (res) => this.set({ values: res.result?.values ?? {}, loadedAt: /* @__PURE__ */ new Date(), isLoading: false, error: null }),
1175
+ (error) => this.set({ isLoading: false, error })
1176
+ ).finally(() => {
1177
+ this.inFlight = null;
1178
+ });
1179
+ return this.inFlight;
1180
+ }
1181
+ // One value, with the fallback used when the key is absent — before the
1182
+ // first load, when it failed, or when the server does not expose the key.
1183
+ // Pick the SAFE fallback (feature off), not the optimistic one.
1184
+ get(key, fallback) {
1185
+ return Object.hasOwn(this.state.values, key) ? this.state.values[key] : fallback;
1186
+ }
1187
+ // The whole current state (values, loadedAt, isLoading, error).
1188
+ snapshot() {
1189
+ return this.state;
1190
+ }
1191
+ // Called with the new state after every change; returns an unsubscribe.
1192
+ subscribe(listener) {
1193
+ this.listeners.add(listener);
1194
+ return () => {
1195
+ this.listeners.delete(listener);
1196
+ };
1197
+ }
1198
+ set(patch) {
1199
+ this.state = { ...this.state, ...patch };
1200
+ for (const listener of this.listeners) listener(this.state);
1201
+ return this.state;
1202
+ }
1203
+ };
1204
+
1148
1205
  // src/modules/webhooks.ts
1149
1206
  var WebhooksClient = class {
1150
1207
  constructor(http, tokens) {
@@ -1481,6 +1538,8 @@ var FonderieClient = class {
1481
1538
  webhooks;
1482
1539
  customers;
1483
1540
  media;
1541
+ /** Public remote config: flags and settings the server exposes to frontends. */
1542
+ config;
1484
1543
  http;
1485
1544
  tokens;
1486
1545
  workspaceId;
@@ -1504,6 +1563,7 @@ var FonderieClient = class {
1504
1563
  this.webhooks = new WebhooksClient(this.http, this.tokens);
1505
1564
  this.customers = new CustomersClient(this.http, this.tokens);
1506
1565
  this.media = new MediaClient(this.http, this.tokens);
1566
+ this.config = new ConfigClient(this.http, this.tokens);
1507
1567
  if (opts.workspaceId !== void 0) this.setWorkspaceId(opts.workspaceId);
1508
1568
  }
1509
1569
  // Single-flight refresh: POST /auth/refresh with the app-supplied refresh
@@ -2182,6 +2242,7 @@ function configKeyProblem(key) {
2182
2242
  CONFIG_KEY_PATTERN,
2183
2243
  CONFIG_VALUE_TYPES,
2184
2244
  ConfigAdminClient,
2245
+ ConfigClient,
2185
2246
  CourierAdminClient,
2186
2247
  CustomersClient,
2187
2248
  FonderieApiError,