@oxyhq/core 3.17.0 → 3.18.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.
@@ -689,7 +689,9 @@ export function OxyServicesAuthMixin(Base) {
689
689
  continue;
690
690
  }
691
691
  const userId = e.user.id ?? e.user._id;
692
- if (!userId || !e.user.username || !e.user.name?.displayName) {
692
+ // `name.displayName` is optional on the contract — do NOT drop no-name
693
+ // accounts. Only an absent userId or username makes the entry unusable.
694
+ if (!userId || !e.user.username) {
693
695
  continue;
694
696
  }
695
697
  if (typeof e.authuser !== 'number') {
@@ -703,7 +705,9 @@ export function OxyServicesAuthMixin(Base) {
703
705
  user: {
704
706
  id: userId,
705
707
  username: e.user.username,
706
- name: e.user.name,
708
+ // `name.displayName` is optional; carry whatever structured name the
709
+ // server sent (possibly an empty object) and let consumers fall back.
710
+ name: e.user.name ?? {},
707
711
  avatar: e.user.avatar ?? null,
708
712
  email: e.user.email,
709
713
  color: e.user.color ?? null,
@@ -35,11 +35,15 @@ export function OxyServicesLinksMixin(Base) {
35
35
  * Resolve multiple link previews via `POST /links/previews` (body `{ urls }`).
36
36
  *
37
37
  * Inputs are de-duplicated and split into chunks of {@link LINK_PREVIEWS_CHUNK_SIZE}
38
- * (the server-side cap). Chunks run concurrently and their `data` maps are
38
+ * (the server-side cap). Chunks run concurrently and their result maps are
39
39
  * merged into a single result keyed by the REQUESTED url (the exact string
40
40
  * passed in `urls`) — matching the batch contract — so a caller can always
41
41
  * look its own input back up.
42
42
  *
43
+ * `makeRequest` unwraps the API's top-level `{ data }` envelope (same as
44
+ * `getUsersByIds`'s `makeServiceRequest<User[]>`), so each chunk response is
45
+ * already the `Record<url, LinkPreview>` map — merge it directly.
46
+ *
43
47
  * An empty / whitespace-only input resolves immediately with `{}` and
44
48
  * performs no network call. A failure in any chunk surfaces (via
45
49
  * `handleError`) rather than being swallowed.
@@ -55,7 +59,7 @@ export function OxyServicesLinksMixin(Base) {
55
59
  }
56
60
  try {
57
61
  const responses = await Promise.all(chunks.map((chunk) => this.makeRequest('POST', '/links/previews', { urls: chunk }, { cache: false })));
58
- return responses.reduce((merged, response) => Object.assign(merged, response?.data ?? {}), {});
62
+ return responses.reduce((merged, response) => Object.assign(merged, response ?? {}), {});
59
63
  }
60
64
  catch (error) {
61
65
  throw this.handleError(error);
@@ -138,13 +138,16 @@ export function OxyServicesSsoMixin(Base) {
138
138
  throw this.handleError(new Error('SSO exchange returned no sessionId'));
139
139
  }
140
140
  const userId = payload.user?.id ?? payload.user?._id;
141
- if (!userId || typeof payload.user?.username !== 'string' || typeof payload.user.name?.displayName !== 'string') {
141
+ if (!userId || typeof payload.user?.username !== 'string') {
142
142
  throw this.handleError(new Error('SSO exchange returned an invalid user'));
143
143
  }
144
144
  const user = {
145
145
  id: userId,
146
146
  username: payload.user.username,
147
- name: payload.user.name,
147
+ // `name.displayName` is optional on the contract. A no-name user is
148
+ // valid; carry whatever structured name the server sent (possibly an
149
+ // empty object) and let consumers fall back to a handle.
150
+ name: payload.user.name ?? {},
148
151
  avatar: payload.user.avatar,
149
152
  };
150
153
  // Plant the access token exactly like exchangeIdTokenForSession does.