@fewchurs/react 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.
package/dist/index.mjs CHANGED
@@ -4,7 +4,7 @@
4
4
  import { createContext, useContext, useEffect, useMemo, useRef, useState } from "react";
5
5
 
6
6
  // src/client/version.ts
7
- var SDK_VERSION = "1.3.0";
7
+ var SDK_VERSION = "1.4.0";
8
8
 
9
9
  // src/client/constants.ts
10
10
  var SDK_HEADER = `react/${SDK_VERSION}`;
@@ -226,7 +226,9 @@ function createFewchursClient(options = {}) {
226
226
  await delay(retryDelayMs);
227
227
  continue;
228
228
  }
229
- return { ok: false, error: networkError(messageOf(error)) };
229
+ const failure2 = networkError(messageOf(error));
230
+ logError(failure2);
231
+ return { ok: false, error: failure2 };
230
232
  }
231
233
  if (response.ok) {
232
234
  const payload = await readJson(response);
@@ -237,7 +239,7 @@ function createFewchursClient(options = {}) {
237
239
  continue;
238
240
  }
239
241
  const failure = errorFromResponse(response.status, await readJson(response));
240
- warnAboutKey(failure);
242
+ logError(failure);
241
243
  return { ok: false, error: failure };
242
244
  }
243
245
  return { ok: false, error: networkError() };
@@ -328,14 +330,15 @@ function delay(ms) {
328
330
  function messageOf(error) {
329
331
  return error instanceof Error ? error.message : "Network request failed.";
330
332
  }
331
- var warnedAboutKey = false;
332
- function warnAboutKey(error) {
333
- if (error.code !== "invalid_key" || warnedAboutKey) return;
333
+ var INVALID_KEY_HELP = "The API key was rejected. Check FEWCHURS_API_KEY (server) or the apiKey passed to FewchursProvider, and that the key is active in your Fewchurs dashboard.";
334
+ var loggedErrors = /* @__PURE__ */ new Set();
335
+ function logError(error) {
334
336
  if (typeof process !== "undefined" && process.env?.NODE_ENV === "production") return;
335
- warnedAboutKey = true;
336
- console.warn(
337
- error.status === 403 ? `[fewchurs] ${error.message}` : "[fewchurs] The API key was rejected. Check FEWCHURS_API_KEY (server) or the apiKey passed to FewchursProvider, and that the key is active in your Fewchurs dashboard."
338
- );
337
+ const isInvalidKey = error.code === "invalid_key" && error.status === 401;
338
+ const detail = isInvalidKey ? INVALID_KEY_HELP : error.message;
339
+ if (loggedErrors.has(detail)) return;
340
+ loggedErrors.add(detail);
341
+ console.warn(`[fewchurs] : ${detail}`);
339
342
  }
340
343
 
341
344
  // src/identity/deviceId.ts
@@ -765,6 +768,12 @@ var DEFAULT_LABELS = {
765
768
  loading: "Loading\u2026",
766
769
  loadMore: "Load more",
767
770
  retry: "Try again",
771
+ errorInvalidKeyTitle: "Invalid API key",
772
+ errorInvalidKeyDetail: "We can't connect to this board right now. The owner of this site needs to check its setup.",
773
+ errorWrongAppTitle: "Wrong platform",
774
+ errorWrongAppDetail: "This board isn't set up for this site or app yet. Its owner needs to add it in Fewchurs.",
775
+ errorTitle: "Something went wrong",
776
+ errorDetail: "We couldn't load the requests. Please try again.",
768
777
  comments: "Comments",
769
778
  commentPlaceholder: "Add a comment",
770
779
  postComment: "Post",
@@ -1240,6 +1249,12 @@ function Bar({ width, height }) {
1240
1249
 
1241
1250
  // src/components/FeatureList.tsx
1242
1251
  import { Fragment, jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
1252
+ function errorCopy(error, labels) {
1253
+ if (error.code !== "invalid_key") {
1254
+ return { title: labels.errorTitle, detail: labels.errorDetail };
1255
+ }
1256
+ return error.status === 403 ? { title: labels.errorWrongAppTitle, detail: labels.errorWrongAppDetail } : { title: labels.errorInvalidKeyTitle, detail: labels.errorInvalidKeyDetail };
1257
+ }
1243
1258
  function FeatureList() {
1244
1259
  const { initialFeatureId } = useBoard();
1245
1260
  return /* @__PURE__ */ jsxs6(Fragment, { children: [
@@ -1269,17 +1284,11 @@ function Listing({ excludeId }) {
1269
1284
  return showDeclined || feature.status !== "declined";
1270
1285
  });
1271
1286
  if (error && visible.length === 0) {
1287
+ const { title, detail } = errorCopy(error, labels);
1272
1288
  return /* @__PURE__ */ jsxs6("div", { className: cx("fw-empty"), role: "alert", children: [
1273
- /* @__PURE__ */ jsx9("p", { children: userMessage(error) }),
1274
- /* @__PURE__ */ jsx9(
1275
- "button",
1276
- {
1277
- type: "button",
1278
- className: cx("fw-btn", "fw-btn--ghost"),
1279
- onClick: () => void refresh(),
1280
- children: labels.retry
1281
- }
1282
- )
1289
+ /* @__PURE__ */ jsx9("p", { className: cx("fw-empty__title"), children: title }),
1290
+ /* @__PURE__ */ jsx9("p", { className: cx("fw-empty__detail"), children: detail }),
1291
+ /* @__PURE__ */ jsx9("button", { type: "button", className: cx("fw-btn-text"), onClick: () => void refresh(), children: labels.retry })
1283
1292
  ] });
1284
1293
  }
1285
1294
  if (isLoading && visible.length === 0) {