@ai-matrx/records 0.46.0 → 0.48.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.
@@ -3424,6 +3424,18 @@ type RecordsErrorCode =
3424
3424
  * through the ORDINARY write door — which is most of them.
3425
3425
  */
3426
3426
  | "needs_approval"
3427
+ /**
3428
+ * THE CALL NEVER REACHED THE STORE. Not a refusal — a transport failure: the
3429
+ * browser lost the network, the gateway answered with an HTTP status and no
3430
+ * body, the request was cancelled. supabase-js hands these back with an EMPTY
3431
+ * `code` (a `FetchError`) or with the HTTP status in it (`"404"`, `"502"`),
3432
+ * neither of which is a SQLSTATE, and until 2026-09-22 they all landed in
3433
+ * `internal` — which is the one classification that tells a screen nothing,
3434
+ * and which made the package print a sentence about ITSELF to the person
3435
+ * (lane TAILS-6). Nothing was written, and the same call can simply be made
3436
+ * again, which is what separates it from `internal`.
3437
+ */
3438
+ | "unreachable"
3427
3439
  /** Anything the mapper could not place. It still carries the store's own words. */
3428
3440
  | "internal";
3429
3441
  /** A refusal, in the store's own words. */
@@ -3437,6 +3449,26 @@ interface RecordsError {
3437
3449
  sqlstate?: string;
3438
3450
  /** Whatever the store put in DETAIL, parsed when it was json. */
3439
3451
  detail?: unknown;
3452
+ /**
3453
+ * TRUE when this package did not recognise the class it was handed, so a
3454
+ * caller can say so instead of reading the silence as "handled".
3455
+ *
3456
+ * 🚨 IT IS A FLAG AND A SEPARATE SENTENCE, NEVER AN APPENDIX TO `hint`
3457
+ * (lane TAILS-6, 2026-09-22). `mapPgError` used to append "@ai-matrx/records
3458
+ * did not recognise SQLSTATE … from checklistTemplates" ONTO `hint`, and
3459
+ * `hint` is the field every screen treats as THE REMEDY — the sentence a
3460
+ * person is told to act on. So a dropped connection on the Checklists tab
3461
+ * showed a plumbing company "Something went wrong at our end" over a line
3462
+ * about a TypeScript package and a SQLSTATE. A note this package writes about
3463
+ * ITSELF is for whoever debugs it and belongs nowhere a person reads.
3464
+ */
3465
+ unmapped?: boolean;
3466
+ /**
3467
+ * THIS PACKAGE'S OWN NOTE, for an engineer. Never the store's words and never
3468
+ * a person's: screens render it out of sight (a `title` attribute, a
3469
+ * screen-reader line) or not at all.
3470
+ */
3471
+ diagnostic?: string;
3440
3472
  }
3441
3473
  type RecordsResult<T> = {
3442
3474
  ok: true;
@@ -5110,6 +5142,19 @@ interface PortalPrincipal {
5110
5142
  is_active: boolean;
5111
5143
  invited_at: Timestamp;
5112
5144
  revoked_at: Timestamp | null;
5145
+ /**
5146
+ * THE LINK THE OFFICE COPIES FOR THIS PERSON — `/invitations/portal/accept/<token>`, the
5147
+ * path `custom.portal_invite` handed back when they were asked, read off the same
5148
+ * `iam.invitations` row and never re-templated.
5149
+ *
5150
+ * 🚨 `null` IS AN ANSWER, NOT AN ABSENCE, and a screen must say which. It is null when they
5151
+ * have already followed the link, when the office took it back (a revoke withdraws the
5152
+ * invitation in the same statement), when it has expired, or when they were let in through
5153
+ * the server's own magic-link route, which binds without an invitation at all. In every one
5154
+ * of those cases there is genuinely no link to copy — so draw a sentence, never a dead
5155
+ * control. (TAILS-5, 2026-09-21; the gap PORTAL-BIND left named.)
5156
+ */
5157
+ accept_path: string | null;
5113
5158
  }
5114
5159
  /** Everything about ONE portal: what it shows, and who it was opened to. */
5115
5160
  interface PortalCard {
@@ -3424,6 +3424,18 @@ type RecordsErrorCode =
3424
3424
  * through the ORDINARY write door — which is most of them.
3425
3425
  */
3426
3426
  | "needs_approval"
3427
+ /**
3428
+ * THE CALL NEVER REACHED THE STORE. Not a refusal — a transport failure: the
3429
+ * browser lost the network, the gateway answered with an HTTP status and no
3430
+ * body, the request was cancelled. supabase-js hands these back with an EMPTY
3431
+ * `code` (a `FetchError`) or with the HTTP status in it (`"404"`, `"502"`),
3432
+ * neither of which is a SQLSTATE, and until 2026-09-22 they all landed in
3433
+ * `internal` — which is the one classification that tells a screen nothing,
3434
+ * and which made the package print a sentence about ITSELF to the person
3435
+ * (lane TAILS-6). Nothing was written, and the same call can simply be made
3436
+ * again, which is what separates it from `internal`.
3437
+ */
3438
+ | "unreachable"
3427
3439
  /** Anything the mapper could not place. It still carries the store's own words. */
3428
3440
  | "internal";
3429
3441
  /** A refusal, in the store's own words. */
@@ -3437,6 +3449,26 @@ interface RecordsError {
3437
3449
  sqlstate?: string;
3438
3450
  /** Whatever the store put in DETAIL, parsed when it was json. */
3439
3451
  detail?: unknown;
3452
+ /**
3453
+ * TRUE when this package did not recognise the class it was handed, so a
3454
+ * caller can say so instead of reading the silence as "handled".
3455
+ *
3456
+ * 🚨 IT IS A FLAG AND A SEPARATE SENTENCE, NEVER AN APPENDIX TO `hint`
3457
+ * (lane TAILS-6, 2026-09-22). `mapPgError` used to append "@ai-matrx/records
3458
+ * did not recognise SQLSTATE … from checklistTemplates" ONTO `hint`, and
3459
+ * `hint` is the field every screen treats as THE REMEDY — the sentence a
3460
+ * person is told to act on. So a dropped connection on the Checklists tab
3461
+ * showed a plumbing company "Something went wrong at our end" over a line
3462
+ * about a TypeScript package and a SQLSTATE. A note this package writes about
3463
+ * ITSELF is for whoever debugs it and belongs nowhere a person reads.
3464
+ */
3465
+ unmapped?: boolean;
3466
+ /**
3467
+ * THIS PACKAGE'S OWN NOTE, for an engineer. Never the store's words and never
3468
+ * a person's: screens render it out of sight (a `title` attribute, a
3469
+ * screen-reader line) or not at all.
3470
+ */
3471
+ diagnostic?: string;
3440
3472
  }
3441
3473
  type RecordsResult<T> = {
3442
3474
  ok: true;
@@ -5110,6 +5142,19 @@ interface PortalPrincipal {
5110
5142
  is_active: boolean;
5111
5143
  invited_at: Timestamp;
5112
5144
  revoked_at: Timestamp | null;
5145
+ /**
5146
+ * THE LINK THE OFFICE COPIES FOR THIS PERSON — `/invitations/portal/accept/<token>`, the
5147
+ * path `custom.portal_invite` handed back when they were asked, read off the same
5148
+ * `iam.invitations` row and never re-templated.
5149
+ *
5150
+ * 🚨 `null` IS AN ANSWER, NOT AN ABSENCE, and a screen must say which. It is null when they
5151
+ * have already followed the link, when the office took it back (a revoke withdraws the
5152
+ * invitation in the same statement), when it has expired, or when they were let in through
5153
+ * the server's own magic-link route, which binds without an invitation at all. In every one
5154
+ * of those cases there is genuinely no link to copy — so draw a sentence, never a dead
5155
+ * control. (TAILS-5, 2026-09-21; the gap PORTAL-BIND left named.)
5156
+ */
5157
+ accept_path: string | null;
5113
5158
  }
5114
5159
  /** Everything about ONE portal: what it shows, and who it was opened to. */
5115
5160
  interface PortalCard {
@@ -2329,19 +2329,34 @@ function parseDetail(details) {
2329
2329
  return details;
2330
2330
  }
2331
2331
  }
2332
+ function isNotASqlstate(code) {
2333
+ if (!code) return true;
2334
+ return /^[0-9]{3}$/.test(code);
2335
+ }
2332
2336
  function mapPgError(error, where) {
2333
- const sqlstate = error.code ?? void 0;
2334
- const code = (sqlstate ? BY_SQLSTATE[sqlstate] : void 0) ?? "internal";
2337
+ const raw = error.code ?? void 0;
2338
+ const sqlstate = raw && raw !== "" ? raw : void 0;
2335
2339
  const mapped = {
2336
- code,
2340
+ code: "internal",
2337
2341
  message: error.message,
2338
2342
  ...error.hint ? { hint: error.hint } : {},
2339
2343
  ...sqlstate ? { sqlstate } : {}
2340
2344
  };
2345
+ if (isNotASqlstate(sqlstate)) {
2346
+ mapped.code = "unreachable";
2347
+ } else {
2348
+ mapped.code = BY_SQLSTATE[sqlstate] ?? "internal";
2349
+ }
2341
2350
  const detail = parseDetail(error.details);
2342
2351
  if (detail !== void 0) mapped.detail = detail;
2343
- if (code === "internal") {
2344
- mapped.hint = (mapped.hint ? `${mapped.hint} ` : "") + `(@ai-matrx/records did not recognise SQLSTATE ${sqlstate ?? "(none)"} from ${where}; the message above is the store's own and is the thing to act on.)`;
2352
+ if (mapped.code === "internal") {
2353
+ mapped.unmapped = true;
2354
+ mapped.diagnostic = `@ai-matrx/records did not recognise SQLSTATE ${sqlstate ?? "(none)"} from ${where}; the store's own message is the thing to act on.`;
2355
+ } else if (mapped.code === "unreachable") {
2356
+ mapped.unmapped = true;
2357
+ mapped.diagnostic = `@ai-matrx/records never reached the store from ${where}: ${raw ? `the transport answered ${raw}` : "no response"} \u2014 ${error.message}`;
2358
+ mapped.message = "We could not reach your data.";
2359
+ delete mapped.hint;
2345
2360
  }
2346
2361
  return mapped;
2347
2362
  }