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