@oxyhq/core 10.1.1 → 10.1.3

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.
@@ -30,6 +30,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
30
30
  exports.AccountDialogController = void 0;
31
31
  exports.createAccountDialogController = createAccountDialogController;
32
32
  const loggerUtils_1 = require("../utils/loggerUtils");
33
+ const errorUtils_1 = require("../utils/errorUtils");
33
34
  const authWebUrl_1 = require("../utils/authWebUrl");
34
35
  const oauthPkce_1 = require("../utils/oauthPkce");
35
36
  const accountProjection_1 = require("./accountProjection");
@@ -245,10 +246,20 @@ class AccountDialogController {
245
246
  graph = await this.oxyServices.listAccounts();
246
247
  }
247
248
  catch (error) {
248
- // A graph-load failure is non-fatal: device rows still render. Surface the
249
- // message but keep going with whatever graph we already had.
250
- this.error = errorMessage(error);
251
- loggerUtils_1.logger.warn('[AccountDialogController] listAccounts failed', { component: 'AccountDialogController' }, error);
249
+ // A 401 here is the EXPECTED signed-out edge, not a failure: the bearer was
250
+ // stale/revoked, so `HttpService` already cleared it and emitted
251
+ // `onTokensChanged(null)`, which drops the graph via `reconcileAuth`. Log at
252
+ // debug and leave the dialog error-free — a signed-out device with zero
253
+ // accounts is a normal state, not a warning. Any other error (network, 5xx,
254
+ // malformed) IS unexpected: surface it and warn while keeping the prior graph
255
+ // so device rows still render.
256
+ if ((0, errorUtils_1.extractErrorStatus)(error) === 401) {
257
+ loggerUtils_1.logger.debug('[AccountDialogController] listAccounts unauthorized (signed out)', { component: 'AccountDialogController' }, error);
258
+ }
259
+ else {
260
+ this.error = errorMessage(error);
261
+ loggerUtils_1.logger.warn('[AccountDialogController] listAccounts failed', { component: 'AccountDialogController' }, error);
262
+ }
252
263
  }
253
264
  if (seq !== this.refreshSeq)
254
265
  return; // superseded by a newer refresh
@@ -288,9 +299,16 @@ class AccountDialogController {
288
299
  profiles = await this.oxyServices.getUsersByIds(ids);
289
300
  }
290
301
  catch (error) {
291
- // `getUsersByIds` already swallows per-chunk failures and returns `[]`;
292
- // this guards the unexpected total failure. Non-fatal keep prior map.
293
- loggerUtils_1.logger.warn('[AccountDialogController] getUsersByIds failed', { component: 'AccountDialogController' }, error);
302
+ // A 401 is the EXPECTED signed-out edge (stale/cleared bearer) — log at debug.
303
+ // `getUsersByIds` already swallows per-chunk failures and returns `[]`, so any
304
+ // OTHER error here is an unexpected total failure worth a warn. Either way keep
305
+ // the prior profile map.
306
+ if ((0, errorUtils_1.extractErrorStatus)(error) === 401) {
307
+ loggerUtils_1.logger.debug('[AccountDialogController] getUsersByIds unauthorized (signed out)', { component: 'AccountDialogController' }, error);
308
+ }
309
+ else {
310
+ loggerUtils_1.logger.warn('[AccountDialogController] getUsersByIds failed', { component: 'AccountDialogController' }, error);
311
+ }
294
312
  return;
295
313
  }
296
314
  if (seq !== this.refreshSeq)
@@ -63,12 +63,11 @@ const INLINE_NEEDS_NORMALIZATION = /[^\x20-\x7E]|^ | $| {2}/;
63
63
  /**
64
64
  * Same idea as {@link INLINE_NEEDS_NORMALIZATION}, for MULTILINE values: `\n`
65
65
  * joins the printable-ASCII fast-path alphabet, and the additional shapes a
66
- * normalized body can never contain are a space before a line break (trailing
67
- * horizontal whitespace) and a run of three line breaks (more than one blank
68
- * line). A single space AFTER a line break is legal — a one-space indent is
69
- * the author's, and normalization deliberately preserves it.
66
+ * normalized body can never contain are a space adjacent to a line break — on
67
+ * either side, since every line is trimmed — and a run of three line breaks
68
+ * (more than one blank line).
70
69
  */
71
- const MULTILINE_NEEDS_NORMALIZATION = /[^\x20-\x7E\n]|^[ \n]|[ \n]$| {2}| \n|\n{3}/;
70
+ const MULTILINE_NEEDS_NORMALIZATION = /[^\x20-\x7E\n]|^[ \n]|[ \n]$| {2}| \n|\n |\n{3}/;
72
71
  /** Any run of whitespace, including tabs, line breaks and Unicode spaces. */
73
72
  const ANY_WHITESPACE_RUN = /\s+/g;
74
73
  /**
@@ -90,8 +89,18 @@ const LINE_BREAK_FORMS = /\r\n|\r|\p{Zl}|\p{Zp}/gu;
90
89
  * Applied AFTER {@link LINE_BREAK_FORMS}, so no line break can hide in it.
91
90
  */
92
91
  const HORIZONTAL_WHITESPACE_RUN = /[^\S\n]+/g;
93
- /** Horizontal whitespace at the end of a line — the blank-line spoiler. */
92
+ /**
93
+ * Horizontal whitespace at the END of a line — the blank-line spoiler: it is
94
+ * what makes an "empty" line non-empty and hides it from {@link EXCESS_BLANK_LINES}.
95
+ */
94
96
  const TRAILING_HORIZONTAL_WHITESPACE = / +\n/g;
97
+ /**
98
+ * Horizontal whitespace at the START of a line: source-markup indentation. HTML
99
+ * collapses it by spec, so it is invisible where the text came from and carries
100
+ * no meaning — it only becomes visible once a client renders the value with
101
+ * `white-space: pre-wrap`.
102
+ */
103
+ const LEADING_HORIZONTAL_WHITESPACE = /\n +/g;
95
104
  /** Three or more line breaks: more than one blank line between paragraphs. */
96
105
  const EXCESS_BLANK_LINES = /\n{3,}/g;
97
106
  /**
@@ -135,20 +144,23 @@ function normalizeInlineText(value) {
135
144
  * 2. Unify every line-break form (CRLF, lone CR, U+2028, U+2029) to `\n`.
136
145
  * 3. Collapse runs of HORIZONTAL whitespace (spaces, tabs, NBSP and friends)
137
146
  * to a single space. Line breaks are untouched.
138
- * 4. Strip the horizontal whitespace at the END of each line.
147
+ * 4. Strip the horizontal whitespace at BOTH ends of every line.
139
148
  * 5. Collapse three or more line breaks to exactly one blank line (`\n\n`).
140
- * 6. Trim both ends.
149
+ * 6. Trim both ends of the value.
141
150
  *
142
151
  * STEP 4 MUST PRECEDE STEP 5 — this is the whole point of the function. A
143
152
  * "blank" line that actually contains spaces (`"a\n \n \nb"`) breaks the
144
153
  * run of `\n` characters, so a bare `\n{3,}` collapse (step 5 alone) never sees
145
154
  * it and the extra blank lines survive into the UI. That is exactly the bug in
146
- * federated post bodies. Removing the trailing horizontal whitespace first
147
- * turns those lines into real, empty lines, which step 5 then collapses.
155
+ * federated post bodies. Trimming each line first turns those lines into real,
156
+ * empty lines, which step 5 then collapses.
148
157
  *
149
- * A single space at the START of a line is preserved: only RUNS of horizontal
150
- * whitespace collapse, and an indent is not trailing whitespace, so a one-space
151
- * indent is treated as the author's and left alone.
158
+ * Every line is trimmed on BOTH sides, so a leading indent is removed outright
159
+ * rather than reduced to one space. Step 3 has already destroyed whatever indent
160
+ * the author wrote (`" Mundo"` `" Mundo"`), so a surviving space would not
161
+ * be the author's intent — it would be an arbitrary remnant of exactly the
162
+ * source-markup indentation this function exists to erase, and `pre-wrap` renders
163
+ * it. Indentation is invisible in HTML by spec; it must be invisible here too.
152
164
  *
153
165
  * A value that is empty or whitespace-only returns `''`.
154
166
  *
@@ -163,6 +175,7 @@ function normalizeMultilineText(value) {
163
175
  .replace(LINE_BREAK_FORMS, '\n')
164
176
  .replace(HORIZONTAL_WHITESPACE_RUN, ' ')
165
177
  .replace(TRAILING_HORIZONTAL_WHITESPACE, '\n')
178
+ .replace(LEADING_HORIZONTAL_WHITESPACE, '\n')
166
179
  .replace(EXCESS_BLANK_LINES, '\n\n')
167
180
  .trim();
168
181
  }