@copilotz/admin 0.9.35 → 0.9.36

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.js CHANGED
@@ -43,11 +43,44 @@ async function mergeHeaders(headers, getRequestHeaders) {
43
43
  async function parseJsonResponse(response) {
44
44
  const payload = await response.json().catch(() => null);
45
45
  if (!response.ok) {
46
- const message = payload?.message ?? payload?.data?.message ?? `Admin request failed (${response.status})`;
46
+ const message = payload?.message ?? payload?.data?.message ?? payload?.error?.message ?? `Admin request failed (${response.status})`;
47
47
  throw new Error(message);
48
48
  }
49
49
  return payload?.data ?? payload;
50
50
  }
51
+ async function parseJsonEnvelopeResponse(response) {
52
+ const payload = await response.json().catch(() => null);
53
+ if (!response.ok) {
54
+ const message = payload?.message ?? payload?.data?.message ?? payload?.error?.message ?? `Admin request failed (${response.status})`;
55
+ throw new Error(message);
56
+ }
57
+ return payload;
58
+ }
59
+ function isRecord(value) {
60
+ return typeof value === "object" && value !== null && !Array.isArray(value);
61
+ }
62
+ function normalizeMessagePageInfo(value, messages) {
63
+ const oldestFromData = messages[0]?.id ?? null;
64
+ const newestFromData = messages[messages.length - 1]?.id ?? null;
65
+ if (!isRecord(value)) {
66
+ return {
67
+ hasMoreBefore: false,
68
+ oldestMessageId: oldestFromData,
69
+ newestMessageId: newestFromData
70
+ };
71
+ }
72
+ return {
73
+ hasMoreBefore: value.hasMoreBefore === true,
74
+ oldestMessageId: typeof value.oldestMessageId === "string" ? value.oldestMessageId : oldestFromData,
75
+ newestMessageId: typeof value.newestMessageId === "string" ? value.newestMessageId : newestFromData
76
+ };
77
+ }
78
+ function normalizeMessagePage(payload) {
79
+ const candidate = isRecord(payload) && isRecord(payload.data) && Array.isArray(payload.data.data) ? payload.data : payload;
80
+ const data = isRecord(candidate) && Array.isArray(candidate.data) ? candidate.data : Array.isArray(candidate) ? candidate : [];
81
+ const pageInfo = isRecord(candidate) ? normalizeMessagePageInfo(candidate.pageInfo, data) : normalizeMessagePageInfo(void 0, data);
82
+ return { data, pageInfo };
83
+ }
51
84
  function createAdminClient(options = {}) {
52
85
  const baseUrl = resolveBaseUrl(options.baseUrl);
53
86
  const paths = { ...DEFAULT_PATHS, ...options.paths };
@@ -58,6 +91,13 @@ function createAdminClient(options = {}) {
58
91
  });
59
92
  return await parseJsonResponse(response);
60
93
  };
94
+ const requestEnvelopeJson = async (path, params) => {
95
+ const url = buildUrl(baseUrl, path, params);
96
+ const response = await fetch(url.toString(), {
97
+ headers: await mergeHeaders({}, options.getRequestHeaders)
98
+ });
99
+ return await parseJsonEnvelopeResponse(response);
100
+ };
61
101
  const writeJson = async (method, path, data, params) => {
62
102
  const url = buildUrl(baseUrl, path, params);
63
103
  const response = await fetch(url.toString(), {
@@ -133,13 +173,16 @@ function createAdminClient(options = {}) {
133
173
  getThread: async (threadId) => await requestJson(
134
174
  `${paths.threadsBase}/${encodeURIComponent(threadId)}`
135
175
  ),
136
- getThreadMessages: async (threadId, messageOptions = {}) => await requestJson(
137
- `${paths.threadsBase}/${encodeURIComponent(threadId)}/messages`,
138
- {
139
- limit: messageOptions.limit ? String(messageOptions.limit) : void 0,
140
- before: messageOptions.before
141
- }
142
- ),
176
+ getThreadMessages: async (threadId, messageOptions = {}) => {
177
+ const payload = await requestEnvelopeJson(
178
+ `${paths.threadsBase}/${encodeURIComponent(threadId)}/messages`,
179
+ {
180
+ limit: messageOptions.limit ? String(messageOptions.limit) : void 0,
181
+ before: messageOptions.before
182
+ }
183
+ );
184
+ return normalizeMessagePage(payload);
185
+ },
143
186
  getThreadEvent: async (threadId) => await requestJson(
144
187
  `${paths.threadsBase}/${encodeURIComponent(threadId)}/events`
145
188
  ),
@@ -2704,7 +2747,9 @@ function ThreadsPage({ context }) {
2704
2747
  align: "right",
2705
2748
  id: "participants",
2706
2749
  header: "Participants",
2707
- render: (thread) => formatNumber(thread.participantIds.length)
2750
+ render: (thread) => formatNumber(
2751
+ Array.isArray(thread.participantIds) ? thread.participantIds.length : 0
2752
+ )
2708
2753
  },
2709
2754
  {
2710
2755
  align: "right",
@@ -2755,8 +2800,8 @@ function ThreadInspector({
2755
2800
  ]).then(([nextThread, page]) => {
2756
2801
  if (!active) return;
2757
2802
  setThread(nextThread);
2758
- setMessages(page.data);
2759
- setPageInfo(page.pageInfo);
2803
+ setMessages(Array.isArray(page?.data) ? page.data : []);
2804
+ setPageInfo(page?.pageInfo ?? null);
2760
2805
  }).catch((cause) => {
2761
2806
  if (active) setError(cause instanceof Error ? cause.message : "Failed to load thread");
2762
2807
  }).finally(() => {
@@ -2776,8 +2821,11 @@ function ThreadInspector({
2776
2821
  before: pageInfo.oldestMessageId,
2777
2822
  limit: MESSAGE_PAGE_SIZE
2778
2823
  });
2779
- setMessages((current) => [...page.data, ...current]);
2780
- setPageInfo(page.pageInfo);
2824
+ setMessages((current) => [
2825
+ ...Array.isArray(page?.data) ? page.data : [],
2826
+ ...current
2827
+ ]);
2828
+ setPageInfo(page?.pageInfo ?? null);
2781
2829
  } finally {
2782
2830
  setIsLoadingMore(false);
2783
2831
  }