@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.cjs CHANGED
@@ -120,11 +120,44 @@ async function mergeHeaders(headers, getRequestHeaders) {
120
120
  async function parseJsonResponse(response) {
121
121
  const payload = await response.json().catch(() => null);
122
122
  if (!response.ok) {
123
- const message = payload?.message ?? payload?.data?.message ?? `Admin request failed (${response.status})`;
123
+ const message = payload?.message ?? payload?.data?.message ?? payload?.error?.message ?? `Admin request failed (${response.status})`;
124
124
  throw new Error(message);
125
125
  }
126
126
  return payload?.data ?? payload;
127
127
  }
128
+ async function parseJsonEnvelopeResponse(response) {
129
+ const payload = await response.json().catch(() => null);
130
+ if (!response.ok) {
131
+ const message = payload?.message ?? payload?.data?.message ?? payload?.error?.message ?? `Admin request failed (${response.status})`;
132
+ throw new Error(message);
133
+ }
134
+ return payload;
135
+ }
136
+ function isRecord(value) {
137
+ return typeof value === "object" && value !== null && !Array.isArray(value);
138
+ }
139
+ function normalizeMessagePageInfo(value, messages) {
140
+ const oldestFromData = messages[0]?.id ?? null;
141
+ const newestFromData = messages[messages.length - 1]?.id ?? null;
142
+ if (!isRecord(value)) {
143
+ return {
144
+ hasMoreBefore: false,
145
+ oldestMessageId: oldestFromData,
146
+ newestMessageId: newestFromData
147
+ };
148
+ }
149
+ return {
150
+ hasMoreBefore: value.hasMoreBefore === true,
151
+ oldestMessageId: typeof value.oldestMessageId === "string" ? value.oldestMessageId : oldestFromData,
152
+ newestMessageId: typeof value.newestMessageId === "string" ? value.newestMessageId : newestFromData
153
+ };
154
+ }
155
+ function normalizeMessagePage(payload) {
156
+ const candidate = isRecord(payload) && isRecord(payload.data) && Array.isArray(payload.data.data) ? payload.data : payload;
157
+ const data = isRecord(candidate) && Array.isArray(candidate.data) ? candidate.data : Array.isArray(candidate) ? candidate : [];
158
+ const pageInfo = isRecord(candidate) ? normalizeMessagePageInfo(candidate.pageInfo, data) : normalizeMessagePageInfo(void 0, data);
159
+ return { data, pageInfo };
160
+ }
128
161
  function createAdminClient(options = {}) {
129
162
  const baseUrl = resolveBaseUrl(options.baseUrl);
130
163
  const paths = { ...DEFAULT_PATHS, ...options.paths };
@@ -135,6 +168,13 @@ function createAdminClient(options = {}) {
135
168
  });
136
169
  return await parseJsonResponse(response);
137
170
  };
171
+ const requestEnvelopeJson = async (path, params) => {
172
+ const url = buildUrl(baseUrl, path, params);
173
+ const response = await fetch(url.toString(), {
174
+ headers: await mergeHeaders({}, options.getRequestHeaders)
175
+ });
176
+ return await parseJsonEnvelopeResponse(response);
177
+ };
138
178
  const writeJson = async (method, path, data, params) => {
139
179
  const url = buildUrl(baseUrl, path, params);
140
180
  const response = await fetch(url.toString(), {
@@ -210,13 +250,16 @@ function createAdminClient(options = {}) {
210
250
  getThread: async (threadId) => await requestJson(
211
251
  `${paths.threadsBase}/${encodeURIComponent(threadId)}`
212
252
  ),
213
- getThreadMessages: async (threadId, messageOptions = {}) => await requestJson(
214
- `${paths.threadsBase}/${encodeURIComponent(threadId)}/messages`,
215
- {
216
- limit: messageOptions.limit ? String(messageOptions.limit) : void 0,
217
- before: messageOptions.before
218
- }
219
- ),
253
+ getThreadMessages: async (threadId, messageOptions = {}) => {
254
+ const payload = await requestEnvelopeJson(
255
+ `${paths.threadsBase}/${encodeURIComponent(threadId)}/messages`,
256
+ {
257
+ limit: messageOptions.limit ? String(messageOptions.limit) : void 0,
258
+ before: messageOptions.before
259
+ }
260
+ );
261
+ return normalizeMessagePage(payload);
262
+ },
220
263
  getThreadEvent: async (threadId) => await requestJson(
221
264
  `${paths.threadsBase}/${encodeURIComponent(threadId)}/events`
222
265
  ),
@@ -2759,7 +2802,9 @@ function ThreadsPage({ context }) {
2759
2802
  align: "right",
2760
2803
  id: "participants",
2761
2804
  header: "Participants",
2762
- render: (thread) => formatNumber(thread.participantIds.length)
2805
+ render: (thread) => formatNumber(
2806
+ Array.isArray(thread.participantIds) ? thread.participantIds.length : 0
2807
+ )
2763
2808
  },
2764
2809
  {
2765
2810
  align: "right",
@@ -2810,8 +2855,8 @@ function ThreadInspector({
2810
2855
  ]).then(([nextThread, page]) => {
2811
2856
  if (!active) return;
2812
2857
  setThread(nextThread);
2813
- setMessages(page.data);
2814
- setPageInfo(page.pageInfo);
2858
+ setMessages(Array.isArray(page?.data) ? page.data : []);
2859
+ setPageInfo(page?.pageInfo ?? null);
2815
2860
  }).catch((cause) => {
2816
2861
  if (active) setError(cause instanceof Error ? cause.message : "Failed to load thread");
2817
2862
  }).finally(() => {
@@ -2831,8 +2876,11 @@ function ThreadInspector({
2831
2876
  before: pageInfo.oldestMessageId,
2832
2877
  limit: MESSAGE_PAGE_SIZE
2833
2878
  });
2834
- setMessages((current) => [...page.data, ...current]);
2835
- setPageInfo(page.pageInfo);
2879
+ setMessages((current) => [
2880
+ ...Array.isArray(page?.data) ? page.data : [],
2881
+ ...current
2882
+ ]);
2883
+ setPageInfo(page?.pageInfo ?? null);
2836
2884
  } finally {
2837
2885
  setIsLoadingMore(false);
2838
2886
  }