@objectstack/types 17.2.0 → 17.4.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.
package/dist/index.js CHANGED
@@ -20,30 +20,40 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ DRIVER_TARGETED_TABLE: () => DRIVER_TARGETED_TABLE,
23
24
  GLOBAL_UNIQUE_CONFIRMATION_REQUIRED: () => GLOBAL_UNIQUE_CONFIRMATION_REQUIRED,
24
25
  GLOBAL_UNIQUE_ISOLATED_PRESCRIPTION: () => GLOBAL_UNIQUE_ISOLATED_PRESCRIPTION,
25
26
  INTERNAL_ERROR_MESSAGE: () => INTERNAL_ERROR_MESSAGE,
27
+ PLATFORM_OWNER_EMAIL_ENV: () => PLATFORM_OWNER_EMAIL_ENV,
28
+ SERVER_FAULT_LOG_PREFIX: () => SERVER_FAULT_LOG_PREFIX,
26
29
  VALIDATION_FAILED_STATUS: () => VALIDATION_FAILED_STATUS,
27
30
  _resetEnvDeprecationWarnings: () => _resetEnvDeprecationWarnings,
28
31
  buildGlobalUniqueStopMessage: () => buildGlobalUniqueStopMessage,
29
32
  collectConfiguredLocales: () => collectConfiguredLocales,
30
33
  collectGlobalUniques: () => collectGlobalUniques,
34
+ declareTargetedTable: () => declareTargetedTable,
31
35
  declaredIndexUniqueIsGlobal: () => declaredIndexUniqueIsGlobal,
32
36
  declaredUserMessage: () => declaredUserMessage,
33
37
  declaresServerFault: () => declaresServerFault,
34
38
  demotedDeclaredCode: () => demotedDeclaredCode,
39
+ describeFaultRequest: () => describeFaultRequest,
35
40
  describeGlobalUniqueFinding: () => describeGlobalUniqueFinding,
36
41
  emitDegradedBootBanner: () => emitDegradedBootBanner,
37
42
  fieldUniqueIsGlobal: () => fieldUniqueIsGlobal,
38
43
  fieldsFromZodIssues: () => fieldsFromZodIssues,
39
44
  globalUniqueFindingId: () => globalUniqueFindingId,
45
+ isEmailVerifiedUserRow: () => isEmailVerifiedUserRow,
40
46
  isMcpServerEnabled: () => isMcpServerEnabled,
47
+ isMissingTableError: () => isMissingTableError,
41
48
  isModuleNotFoundError: () => isModuleNotFoundError,
42
49
  isPlatformOwnedObject: () => isPlatformOwnedObject,
43
50
  isRelationSubObjectPhrase: () => isRelationSubObjectPhrase,
51
+ isSchemaAlreadyExistsError: () => isSchemaAlreadyExistsError,
52
+ isServerFault: () => isServerFault,
44
53
  isUnbackedConflictTargetError: () => isUnbackedConflictTargetError,
45
54
  isUniqueViolationError: () => isUniqueViolationError,
46
55
  keysetWalk: () => keysetWalk,
56
+ logServerFault: () => logServerFault,
47
57
  looksLikeInternalErrorLeak: () => looksLikeInternalErrorLeak,
48
58
  matchMissingColumnOfRelation: () => matchMissingColumnOfRelation,
49
59
  postureGatesGlobalUniques: () => postureGatesGlobalUniques,
@@ -55,13 +65,21 @@ __export(index_exports, {
55
65
  resolveMcpStdioAutoStart: () => resolveMcpStdioAutoStart,
56
66
  resolveMultiOrgEnabled: () => resolveMultiOrgEnabled,
57
67
  resolveOrgLimit: () => resolveOrgLimit,
68
+ resolveOrgMembershipLimit: () => resolveOrgMembershipLimit,
69
+ resolvePlatformOwnerEmail: () => resolvePlatformOwnerEmail,
58
70
  resolveSandboxTimeoutMs: () => resolveSandboxTimeoutMs,
59
71
  resolveSearchPinyinEnabled: () => resolveSearchPinyinEnabled,
60
72
  resolveTenancyPosture: () => resolveTenancyPosture,
61
73
  resolveThrownHttpError: () => resolveThrownHttpError,
62
74
  sendError: () => sendError,
63
75
  sendOk: () => sendOk,
76
+ serverFaultLogMessage: () => serverFaultLogMessage,
77
+ serverFaultLogMeta: () => serverFaultLogMeta,
78
+ serverFaultProvenance: () => serverFaultProvenance,
64
79
  stampSearchPinyinEnabled: () => stampSearchPinyinEnabled,
80
+ strandedDecisionDetails: () => strandedDecisionDetails,
81
+ strandedDecisionFailure: () => strandedDecisionFailure,
82
+ targetedTableOf: () => targetedTableOf,
65
83
  unconfirmedGlobalUniques: () => unconfirmedGlobalUniques,
66
84
  uniqueViolationColumn: () => uniqueViolationColumn,
67
85
  validationFailure: () => validationFailure,
@@ -86,6 +104,12 @@ function emitDegradedBootBanner(message) {
86
104
  }
87
105
  }
88
106
 
107
+ // src/email-verified.ts
108
+ function isEmailVerifiedUserRow(row) {
109
+ const v = row?.email_verified;
110
+ return v === true || v === 1 || v === "1" || v === "true";
111
+ }
112
+
89
113
  // src/env.ts
90
114
  var import_security = require("@objectstack/spec/security");
91
115
  var _warnedKeys = /* @__PURE__ */ new Set();
@@ -131,6 +155,13 @@ function resolveTenancyPosture() {
131
155
  }
132
156
  return resolveMultiOrgEnabled() ? "isolated" : "single";
133
157
  }
158
+ var PLATFORM_OWNER_EMAIL_ENV = "OS_PLATFORM_OWNER_EMAIL";
159
+ function resolvePlatformOwnerEmail() {
160
+ const raw = globalThis.process?.env?.[PLATFORM_OWNER_EMAIL_ENV];
161
+ if (raw == null) return void 0;
162
+ const trimmed = String(raw).trim();
163
+ return trimmed === "" ? void 0 : trimmed;
164
+ }
134
165
  function resolveAllowDegradedTenancy() {
135
166
  const raw = readEnvWithDeprecation("OS_ALLOW_DEGRADED_TENANCY", [], { silent: true });
136
167
  if (raw == null) return false;
@@ -170,6 +201,12 @@ function resolveOrgLimit() {
170
201
  const n = Number.parseInt(String(raw), 10);
171
202
  return Number.isFinite(n) && n > 0 ? n : void 0;
172
203
  }
204
+ function resolveOrgMembershipLimit() {
205
+ const raw = readEnvWithDeprecation("OS_ORG_MEMBERSHIP_LIMIT", [], { silent: true });
206
+ if (raw == null || String(raw).trim() === "") return void 0;
207
+ const n = Number.parseInt(String(raw), 10);
208
+ return Number.isFinite(n) && n > 0 ? n : void 0;
209
+ }
173
210
  function resolveSearchPinyinEnabled(opts) {
174
211
  const raw = readEnvWithDeprecation("OS_SEARCH_PINYIN_ENABLED", [], { silent: true });
175
212
  if (raw != null && String(raw).trim() !== "") {
@@ -321,11 +358,78 @@ function isModuleNotFoundError(err) {
321
358
  return msg.includes("Cannot find module") || msg.includes("Cannot find package");
322
359
  }
323
360
 
361
+ // src/server-fault-log.ts
362
+ var SERVER_FAULT_LOG_PREFIX = "[5xx]";
363
+ function isServerFault(status) {
364
+ return typeof status === "number" && status >= 500;
365
+ }
366
+ function toError(thrown) {
367
+ if (thrown === void 0 || thrown === null) return void 0;
368
+ if (thrown instanceof Error) return thrown;
369
+ const wrapped = new Error(typeof thrown === "string" ? thrown : safeStringify(thrown));
370
+ wrapped.stack = void 0;
371
+ return wrapped;
372
+ }
373
+ function safeStringify(value) {
374
+ try {
375
+ return JSON.stringify(value) ?? String(value);
376
+ } catch {
377
+ return String(value);
378
+ }
379
+ }
380
+ function serverFaultLogMessage(input) {
381
+ const err = toError(input.error);
382
+ const text = err?.message || input.message || "Unhandled server fault";
383
+ const where = [input.request?.method, input.request?.path].filter(Boolean).join(" ");
384
+ return `${SERVER_FAULT_LOG_PREFIX} ${input.status}${where ? ` ${where}` : ""} \u2014 ${text}`;
385
+ }
386
+ function serverFaultLogMeta(input) {
387
+ return {
388
+ status: input.status,
389
+ ...input.code !== void 0 ? { code: input.code } : {},
390
+ ...input.request?.method !== void 0 ? { method: input.request.method } : {},
391
+ ...input.request?.path !== void 0 ? { path: input.request.path } : {},
392
+ ...input.request?.requestId !== void 0 ? { requestId: input.request.requestId } : {}
393
+ };
394
+ }
395
+ function logServerFault(input, logger) {
396
+ if (!isServerFault(input.status)) return false;
397
+ const message = serverFaultLogMessage(input);
398
+ const meta = serverFaultLogMeta(input);
399
+ const err = toError(input.error);
400
+ try {
401
+ if (logger) {
402
+ logger.error(message, err, meta);
403
+ return true;
404
+ }
405
+ const sink = globalThis.console;
406
+ sink?.error?.(message, { ...meta, ...err?.stack ? { stack: err.stack } : {} });
407
+ return true;
408
+ } catch {
409
+ return false;
410
+ }
411
+ }
412
+ function describeFaultRequest(req) {
413
+ const r = req;
414
+ if (!r || typeof r !== "object") return {};
415
+ const str = (v) => typeof v === "string" && v ? v : void 0;
416
+ const headerId = r.headers ? str(r.headers["x-request-id"]) ?? str(r.headers["X-Request-Id"]) : void 0;
417
+ const method = str(r.method);
418
+ const path = str(r.path) ?? str(r.url) ?? str(r.originalUrl);
419
+ const requestId = str(r.requestId) ?? headerId;
420
+ return {
421
+ ...method !== void 0 ? { method } : {},
422
+ ...path !== void 0 ? { path } : {},
423
+ ...requestId !== void 0 ? { requestId } : {}
424
+ };
425
+ }
426
+
324
427
  // src/response-envelope.ts
325
428
  function sendOk(res, data, status = 200) {
326
429
  res.status(status).json({ success: true, data });
327
430
  }
328
431
  function sendError(res, status, code, message, extra) {
432
+ logServerFault({ status, code, message, ...extra?.requestId ? { request: { requestId: extra.requestId } } : {} });
329
433
  res.status(status).json({ success: false, error: { code, message, ...extra } });
330
434
  }
331
435
 
@@ -390,10 +494,33 @@ function declaredUserMessage(error) {
390
494
  const declared = error?.userMessage;
391
495
  return typeof declared === "string" && declared.trim().length > 0 ? declared : void 0;
392
496
  }
497
+ function serverFaultProvenance(thrown) {
498
+ if (thrown.status < 500) return void 0;
499
+ return thrown.declaredStatus === void 0 ? "undeclared" : "declared";
500
+ }
393
501
  function demotedDeclaredCode(thrown) {
502
+ if (serverFaultProvenance(thrown) === "undeclared") return void 0;
394
503
  return thrown.declaredCode !== void 0 && thrown.declaredCode !== thrown.code ? thrown.declaredCode : void 0;
395
504
  }
396
505
 
506
+ // src/stranded-decision.ts
507
+ var CARRIER = "strandedDecision";
508
+ function strandedDecisionDetails(err) {
509
+ const carried = err?.[CARRIER];
510
+ if (!carried || typeof carried !== "object") return void 0;
511
+ const d = carried;
512
+ if (d.finalized !== true) return void 0;
513
+ if (typeof d.decision !== "string" || d.decision === "") return void 0;
514
+ if (typeof d.runId !== "string" || d.runId === "") return void 0;
515
+ if (typeof d.repairable !== "boolean") return void 0;
516
+ return { finalized: true, decision: d.decision, runId: d.runId, repairable: d.repairable };
517
+ }
518
+ function strandedDecisionFailure(message, details) {
519
+ const err = new Error(message);
520
+ err[CARRIER] = details;
521
+ return err;
522
+ }
523
+
397
524
  // src/relation-sub-object.ts
398
525
  function matchMissingColumnOfRelation(message) {
399
526
  return MISSING_COLUMN_OF_RELATION.exec(message)?.[1];
@@ -406,7 +533,7 @@ var RELATION_SUB_OBJECT = /["'`][^"'`]+["'`]\s+of relation\s/i;
406
533
 
407
534
  // src/unique-violation.ts
408
535
  var UNIQUE_VIOLATION = {
409
- codes: /* @__PURE__ */ new Set(["23505", "ER_DUP_ENTRY", "SQLITE_CONSTRAINT_UNIQUE"]),
536
+ codes: /* @__PURE__ */ new Set(["23505", "ER_DUP_ENTRY", "SQLITE_CONSTRAINT_UNIQUE", "UNIQUE_VIOLATION"]),
410
537
  errnos: /* @__PURE__ */ new Set([1062]),
411
538
  message: /unique constraint failed|violates unique constraint|unique violation|duplicate key|duplicate entry/i
412
539
  };
@@ -470,16 +597,199 @@ function uniqueViolationColumn(error) {
470
597
  return findUniqueViolationColumn(error, 0);
471
598
  }
472
599
 
600
+ // src/driver-error-classification.ts
601
+ var RELATION_IN_PHRASE = [
602
+ // SQLite / libsql: `no such table: sys_metadata_history`, and the
603
+ // schema-qualified `no such table: main.orders` it uses when it resolved
604
+ // the name itself (views, triggers) or the caller qualified it.
605
+ /no such table:\s*([^\s'"`;,()]+)/i,
606
+ // PostgreSQL: `relation "sys_metadata_history" does not exist`
607
+ /relation\s+["'`]([^"'`]+)["'`]\s+does not exist/i,
608
+ // MySQL / MariaDB: `Table 'app.sys_metadata_history' doesn't exist`
609
+ /table\s+["'`]([^"'`]+)["'`]\s+doesn'?t exist/i,
610
+ // MySQL / MariaDB: `Unknown table 'app.t'`
611
+ /unknown table\s+["'`]([^"'`]+)["'`]/i
612
+ ];
613
+ function normaliseRelationName(name) {
614
+ const afterQualifier = name.slice(name.lastIndexOf(".") + 1);
615
+ const namespaceEnd = afterQualifier.lastIndexOf("__");
616
+ const bare = namespaceEnd === -1 ? afterQualifier : afterQualifier.slice(namespaceEnd + 2);
617
+ return bare.toLowerCase();
618
+ }
619
+ function phraseNamesAnotherRelation(message, readObject) {
620
+ const expected = normaliseRelationName(readObject);
621
+ if (expected === "") return false;
622
+ let named = false;
623
+ for (const pattern of RELATION_IN_PHRASE) {
624
+ const captured = pattern.exec(message)?.[1];
625
+ if (captured === void 0) continue;
626
+ const candidate = normaliseRelationName(captured);
627
+ if (candidate === "") continue;
628
+ if (candidate === expected) return false;
629
+ named = true;
630
+ }
631
+ return named;
632
+ }
633
+ var ALREADY_EXISTS = {
634
+ codes: /* @__PURE__ */ new Set([
635
+ // PostgreSQL SQLSTATE (class 42 — syntax error or access rule violation)
636
+ "42P07",
637
+ // duplicate_table
638
+ "42701",
639
+ // duplicate_column
640
+ "42710",
641
+ // duplicate_object — index / constraint already exists
642
+ // MySQL / MariaDB (mysql2 puts the symbolic name on `code`)
643
+ "ER_TABLE_EXISTS_ERROR",
644
+ // 1050
645
+ "ER_DUP_FIELDNAME",
646
+ // 1060
647
+ "ER_DUP_KEYNAME"
648
+ // 1061
649
+ ]),
650
+ errnos: /* @__PURE__ */ new Set([1050, 1060, 1061]),
651
+ /**
652
+ * Message fallback for drivers that carry no machine-readable code —
653
+ * notably SQLite, whose `code` is the undifferentiated `SQLITE_ERROR` for
654
+ * every DDL failure, so the message is the only signal available:
655
+ * - `table sys_metadata already exists`
656
+ * - `duplicate column name: environment_id`
657
+ * - `index idx_x already exists`
658
+ * Postgres phrases its own as `relation "x" already exists` /
659
+ * `column "x" of relation "y" already exists`, which matches the same test.
660
+ */
661
+ message: /already exists|duplicate column name|duplicate key name/i
662
+ };
663
+ var MISSING_TABLE = {
664
+ codes: /* @__PURE__ */ new Set([
665
+ "42P01",
666
+ // PostgreSQL undefined_table
667
+ "ER_NO_SUCH_TABLE"
668
+ // MySQL / MariaDB 1146
669
+ ]),
670
+ errnos: /* @__PURE__ */ new Set([1146]),
671
+ /**
672
+ * - SQLite / libsql: `no such table: sys_metadata_history`
673
+ * - PostgreSQL: `relation "sys_metadata_history" does not exist`
674
+ * - MySQL/MariaDB: `Table 'app.sys_metadata_history' doesn't exist`
675
+ */
676
+ message: /no such table|relation ["'`][^"'`]+["'`] does not exist|table ["'`][^"'`]+["'`] doesn'?t exist|unknown table/i,
677
+ excludes: {
678
+ /**
679
+ * Exactly the three SQLSTATEs the docblock above already names as
680
+ * must-stay-loud neighbours of `does not exist`. They are listed here
681
+ * rather than merely trusted to miss the message test, because two of
682
+ * them (42703 columns, 42704 constraints/triggers) have a phrasing that
683
+ * *does* hit it, and because a code is a fact where prose is a guess.
684
+ *
685
+ * Postgres-shaped on purpose: measured, neither MySQL
686
+ * (`Unknown column 'label' in 'field list'`) nor SQLite
687
+ * (`no such column: bogus`, `table t has no column named label`)
688
+ * phrases a sub-object failure so that a missing-table phrase falls out
689
+ * of it, so there is nothing there to exclude. Adding their codes would
690
+ * be surface with no defect behind it.
691
+ */
692
+ codes: /* @__PURE__ */ new Set([
693
+ "42703",
694
+ // undefined_column
695
+ "42704",
696
+ // undefined_object — constraint, trigger, role, type, …
697
+ "3D000"
698
+ // invalid_catalog_name — `database "x" does not exist`
699
+ ]),
700
+ /**
701
+ * `«sub-object» "x" of relation "y" …` — Postgres' phrasing for a
702
+ * failure about something *inside* a relation, which therefore says the
703
+ * relation itself is present. The two in-repo siblings that carry this
704
+ * phrase are `mapDataError` (`packages/rest`, #5352) and
705
+ * `service-analytics`'s missing-column subtraction (#6035/PR #6346).
706
+ *
707
+ * [#6615] All three now read one home — `@objectstack/types` — instead
708
+ * of three hand-kept copies, so the phrase can no longer be taught to
709
+ * the repo a fourth time or drift in one package only. [#13279] This
710
+ * file now lives in that same home, so the read is a sibling import. The **width**
711
+ * difference that used to justify the copy is preserved and is the
712
+ * reason the home exports two functions rather than one: those two
713
+ * *extract* the column name to phrase a better error, so a miss costs a
714
+ * vaguer message; this one *excludes*, so a miss restores the
715
+ * corruption. {@link isRelationSubObjectPhrase} is therefore the wider
716
+ * question — it drops their `column`/`[a-z0-9_]+`/`does not exist`
717
+ * anchors: any sub-object, any quoted identifier, any verdict.
718
+ * Over-matching here only ever converts a benign verdict into a loud
719
+ * one, which is the direction this whole module already errs in.
720
+ */
721
+ matchesMessage: isRelationSubObjectPhrase,
722
+ /**
723
+ * [#13324] "…and the relation it names is not the one you read."
724
+ *
725
+ * The sibling of the phrase above, reached one step further out. That
726
+ * one recognises a failure about something INSIDE a relation, which
727
+ * therefore says the relation is present; this one recognises a failure
728
+ * about a DIFFERENT relation, which says nothing at all about the one
729
+ * the caller read. Both end the question with `false` for the same
730
+ * reason: the licence this predicate grants — "there are no rows, so
731
+ * there is nothing to be inconsistent with" — is about the table that
732
+ * was READ, and neither phrase is evidence about it.
733
+ */
734
+ namesAnotherRelation: phraseNamesAnotherRelation
735
+ }
736
+ };
737
+ var MAX_CAUSE_DEPTH2 = 4;
738
+ var DRIVER_TARGETED_TABLE = /* @__PURE__ */ Symbol.for("objectstack.driver.targetedTable");
739
+ function declareTargetedTable(error, table) {
740
+ if (typeof table !== "string" || table === "") return error;
741
+ if (targetedTableOf(error) !== null) return error;
742
+ Object.defineProperty(error, DRIVER_TARGETED_TABLE, { value: table, enumerable: false });
743
+ return error;
744
+ }
745
+ function targetedTableOf(error) {
746
+ if (error === null || typeof error !== "object" && typeof error !== "function") return null;
747
+ const table = error[DRIVER_TARGETED_TABLE];
748
+ return typeof table === "string" && table !== "" ? table : null;
749
+ }
750
+ function excludedByReadObject(message, signature, relation) {
751
+ if (typeof relation !== "string" || relation === "") return false;
752
+ return signature.excludes?.namesAnotherRelation?.(message, relation) === true;
753
+ }
754
+ function matchesDriverError(error, signature, depth, readObject) {
755
+ if (error === null || error === void 0 || depth > MAX_CAUSE_DEPTH2) return false;
756
+ if (typeof error === "string") {
757
+ if (signature.excludes?.matchesMessage(error)) return false;
758
+ if (excludedByReadObject(error, signature, readObject)) return false;
759
+ return signature.message.test(error);
760
+ }
761
+ if (typeof error !== "object") return false;
762
+ const err = error;
763
+ const relation = targetedTableOf(err) ?? readObject;
764
+ const excludes = signature.excludes;
765
+ if (excludes) {
766
+ if (typeof err.code === "string" && excludes.codes.has(err.code)) return false;
767
+ if (typeof err.message === "string" && excludes.matchesMessage(err.message)) return false;
768
+ if (typeof err.message === "string" && excludedByReadObject(err.message, signature, relation))
769
+ return false;
770
+ }
771
+ if (typeof err.code === "string" && signature.codes.has(err.code)) return true;
772
+ if (typeof err.errno === "number" && signature.errnos.has(err.errno)) return true;
773
+ if (typeof err.message === "string" && signature.message.test(err.message)) return true;
774
+ return matchesDriverError(err.cause, signature, depth + 1, relation);
775
+ }
776
+ function isSchemaAlreadyExistsError(error, depth = 0) {
777
+ return matchesDriverError(error, ALREADY_EXISTS, depth);
778
+ }
779
+ function isMissingTableError(error, readObject, depth = 0) {
780
+ return matchesDriverError(error, MISSING_TABLE, depth, readObject);
781
+ }
782
+
473
783
  // src/unbacked-conflict-target.ts
474
784
  var UNBACKED_CONFLICT_TARGET = {
475
785
  message: /ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint|there is no unique or exclusion constraint matching the ON CONFLICT specification/i
476
786
  };
477
- var MAX_CAUSE_DEPTH2 = 4;
787
+ var MAX_CAUSE_DEPTH3 = 4;
478
788
  function isUnbackedConflictTargetError(error) {
479
789
  return matchesUnbackedConflictTarget(error, 0);
480
790
  }
481
791
  function matchesUnbackedConflictTarget(error, depth) {
482
- if (error === null || error === void 0 || depth > MAX_CAUSE_DEPTH2) return false;
792
+ if (error === null || error === void 0 || depth > MAX_CAUSE_DEPTH3) return false;
483
793
  if (typeof error === "string") return UNBACKED_CONFLICT_TARGET.message.test(error);
484
794
  if (typeof error !== "object") return false;
485
795
  const err = error;
@@ -586,30 +896,40 @@ function postureGatesGlobalUniques(posture) {
586
896
  }
587
897
  // Annotate the CommonJS export names for ESM import in node:
588
898
  0 && (module.exports = {
899
+ DRIVER_TARGETED_TABLE,
589
900
  GLOBAL_UNIQUE_CONFIRMATION_REQUIRED,
590
901
  GLOBAL_UNIQUE_ISOLATED_PRESCRIPTION,
591
902
  INTERNAL_ERROR_MESSAGE,
903
+ PLATFORM_OWNER_EMAIL_ENV,
904
+ SERVER_FAULT_LOG_PREFIX,
592
905
  VALIDATION_FAILED_STATUS,
593
906
  _resetEnvDeprecationWarnings,
594
907
  buildGlobalUniqueStopMessage,
595
908
  collectConfiguredLocales,
596
909
  collectGlobalUniques,
910
+ declareTargetedTable,
597
911
  declaredIndexUniqueIsGlobal,
598
912
  declaredUserMessage,
599
913
  declaresServerFault,
600
914
  demotedDeclaredCode,
915
+ describeFaultRequest,
601
916
  describeGlobalUniqueFinding,
602
917
  emitDegradedBootBanner,
603
918
  fieldUniqueIsGlobal,
604
919
  fieldsFromZodIssues,
605
920
  globalUniqueFindingId,
921
+ isEmailVerifiedUserRow,
606
922
  isMcpServerEnabled,
923
+ isMissingTableError,
607
924
  isModuleNotFoundError,
608
925
  isPlatformOwnedObject,
609
926
  isRelationSubObjectPhrase,
927
+ isSchemaAlreadyExistsError,
928
+ isServerFault,
610
929
  isUnbackedConflictTargetError,
611
930
  isUniqueViolationError,
612
931
  keysetWalk,
932
+ logServerFault,
613
933
  looksLikeInternalErrorLeak,
614
934
  matchMissingColumnOfRelation,
615
935
  postureGatesGlobalUniques,
@@ -621,13 +941,21 @@ function postureGatesGlobalUniques(posture) {
621
941
  resolveMcpStdioAutoStart,
622
942
  resolveMultiOrgEnabled,
623
943
  resolveOrgLimit,
944
+ resolveOrgMembershipLimit,
945
+ resolvePlatformOwnerEmail,
624
946
  resolveSandboxTimeoutMs,
625
947
  resolveSearchPinyinEnabled,
626
948
  resolveTenancyPosture,
627
949
  resolveThrownHttpError,
628
950
  sendError,
629
951
  sendOk,
952
+ serverFaultLogMessage,
953
+ serverFaultLogMeta,
954
+ serverFaultProvenance,
630
955
  stampSearchPinyinEnabled,
956
+ strandedDecisionDetails,
957
+ strandedDecisionFailure,
958
+ targetedTableOf,
631
959
  unconfirmedGlobalUniques,
632
960
  uniqueViolationColumn,
633
961
  validationFailure,