@object-ui/react 17.5.0 → 17.7.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.
Files changed (103) hide show
  1. package/CHANGELOG.md +4100 -0
  2. package/README.md +303 -46
  3. package/dist/LazyPluginLoader.d.ts +14 -7
  4. package/dist/LazyPluginLoader.js +14 -7
  5. package/dist/SchemaRenderer.d.ts +38 -7
  6. package/dist/SchemaRenderer.js +1603 -60
  7. package/dist/context/ActionContext.js +40 -1
  8. package/dist/context/DiscussionContext.d.ts +12 -0
  9. package/dist/context/DiscussionContext.js +2 -0
  10. package/dist/context/DrillNavigationContext.d.ts +13 -0
  11. package/dist/context/HostNavigationContext.d.ts +82 -0
  12. package/dist/context/HostNavigationContext.js +65 -0
  13. package/dist/context/InlineEditContext.d.ts +81 -1
  14. package/dist/context/InlineEditContext.js +8 -2
  15. package/dist/context/RecordContext.d.ts +48 -5
  16. package/dist/context/RecordContext.js +10 -1
  17. package/dist/context/RelatedRecordActionsContext.d.ts +20 -1
  18. package/dist/context/SchemaRendererContext.d.ts +54 -2
  19. package/dist/context/SchemaRendererContext.js +38 -5
  20. package/dist/context/ThemeContext.js +1 -1
  21. package/dist/context/actionRunnerTranslator.d.ts +27 -0
  22. package/dist/context/actionRunnerTranslator.js +37 -0
  23. package/dist/context/index.d.ts +13 -12
  24. package/dist/context/index.js +13 -12
  25. package/dist/element-data-source/ElementDataSourceGate.d.ts +163 -3
  26. package/dist/element-data-source/ElementDataSourceGate.js +407 -15
  27. package/dist/hooks/index.d.ts +37 -35
  28. package/dist/hooks/index.js +44 -35
  29. package/dist/hooks/useActionEngine.js +47 -4
  30. package/dist/hooks/useActionRunner.js +4 -0
  31. package/dist/hooks/useActionTextLocalizer.d.ts +21 -8
  32. package/dist/hooks/useActionTextLocalizer.js +33 -8
  33. package/dist/hooks/useCapabilityGate.js +6 -5
  34. package/dist/hooks/useConfigBagEvaluator.d.ts +30 -0
  35. package/dist/hooks/useConfigBagEvaluator.js +39 -0
  36. package/dist/hooks/useCrudShortcuts.js +1 -1
  37. package/dist/hooks/useDatasetDimensionLabels.js +1 -1
  38. package/dist/hooks/useDensityMode.d.ts +6 -2
  39. package/dist/hooks/useDensityMode.js +6 -2
  40. package/dist/hooks/useDiscovery.d.ts +1 -10
  41. package/dist/hooks/useDiscovery.js +1 -1
  42. package/dist/hooks/useETagCache.js +25 -4
  43. package/dist/hooks/useElementDataSource.d.ts +15 -2
  44. package/dist/hooks/useElementDataSource.js +29 -9
  45. package/dist/hooks/useExpression.d.ts +52 -38
  46. package/dist/hooks/useExpression.js +62 -42
  47. package/dist/hooks/useFilterScope.d.ts +22 -2
  48. package/dist/hooks/useFilterScope.js +29 -4
  49. package/dist/hooks/useGlobalUndo.d.ts +10 -0
  50. package/dist/hooks/useGlobalUndo.js +112 -46
  51. package/dist/hooks/useNavigationOverlay.d.ts +77 -12
  52. package/dist/hooks/useNavigationOverlay.js +119 -9
  53. package/dist/hooks/useOffline.js +65 -11
  54. package/dist/hooks/usePageAssignment.d.ts +8 -5
  55. package/dist/hooks/usePageAssignment.js +38 -17
  56. package/dist/hooks/usePageTransition.js +1 -1
  57. package/dist/hooks/usePageVariableActionBridge.js +2 -2
  58. package/dist/hooks/useRecordSearch.d.ts +34 -1
  59. package/dist/hooks/useRecordSearch.js +42 -7
  60. package/dist/hooks/useResolvedFilter.d.ts +46 -0
  61. package/dist/hooks/useResolvedFilter.js +130 -0
  62. package/dist/hooks/useSchemaPersistence.d.ts +7 -0
  63. package/dist/hooks/useSchemaPersistence.js +144 -5
  64. package/dist/hooks/useSettledSchema.d.ts +123 -0
  65. package/dist/hooks/useSettledSchema.js +186 -0
  66. package/dist/hooks/useViewData.d.ts +7 -2
  67. package/dist/hooks/useViewData.js +1 -1
  68. package/dist/hooks/useViewTransition.js +1 -1
  69. package/dist/index.d.ts +18 -11
  70. package/dist/index.js +54 -10
  71. package/dist/schema-input.d.ts +55 -14
  72. package/dist/schema-input.js +55 -12
  73. package/dist/utils/configBag.d.ts +68 -0
  74. package/dist/utils/configBag.js +70 -0
  75. package/dist/utils/error-message.d.ts +59 -0
  76. package/dist/utils/error-message.js +116 -1
  77. package/dist/utils/inlineAria.d.ts +61 -0
  78. package/dist/utils/inlineAria.js +70 -0
  79. package/dist/utils/nonGridRowCeiling.d.ts +44 -0
  80. package/dist/utils/nonGridRowCeiling.js +78 -0
  81. package/dist/utils/paramsBag.d.ts +28 -0
  82. package/dist/utils/paramsBag.js +146 -0
  83. package/dist/utils/propsBagDiagnostic.d.ts +196 -0
  84. package/dist/utils/propsBagDiagnostic.js +421 -0
  85. package/dist/utils/refusedDataPropDiagnostic.d.ts +44 -0
  86. package/dist/utils/refusedDataPropDiagnostic.js +94 -0
  87. package/dist/utils/unevaluatedExpression.d.ts +110 -0
  88. package/dist/utils/unevaluatedExpression.js +257 -0
  89. package/dist/utils/visibilityDiagnostic.d.ts +371 -0
  90. package/dist/utils/visibilityDiagnostic.js +551 -0
  91. package/package.json +10 -10
  92. package/dist/hooks/useClientNotifications.d.ts +0 -47
  93. package/dist/hooks/useClientNotifications.js +0 -162
  94. package/dist/spec-bridge/SpecBridge.d.ts +0 -28
  95. package/dist/spec-bridge/SpecBridge.js +0 -56
  96. package/dist/spec-bridge/bridges/form-view.d.ts +0 -82
  97. package/dist/spec-bridge/bridges/form-view.js +0 -126
  98. package/dist/spec-bridge/bridges/list-view.d.ts +0 -20
  99. package/dist/spec-bridge/bridges/list-view.js +0 -241
  100. package/dist/spec-bridge/index.d.ts +0 -11
  101. package/dist/spec-bridge/index.js +0 -10
  102. package/dist/spec-bridge/types.d.ts +0 -55
  103. package/dist/spec-bridge/types.js +0 -8
@@ -0,0 +1,371 @@
1
+ /**
2
+ * ObjectUI
3
+ * Copyright (c) 2024-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ /**
9
+ * Diagnostic: a node-gate predicate could not be evaluated (objectui#5454,
10
+ * leg 3 of the 2026-08-21 ruling; production coverage added by objectui#6038,
11
+ * maintainer ruling 2026-08-25 option B; the `disabled` / `disabledOn` gate
12
+ * added by objectui#6445).
13
+ *
14
+ * ## The defect this names
15
+ *
16
+ * `SchemaRenderer`'s visibility chain is FAIL-SOFT: `evaluateCondition` answers
17
+ * an unevaluable predicate with `true`. On the four negated legs (`visible` /
18
+ * `visibleWhen` / `visibleOn` / `visibility`) that `true` means SHOWN — so "this
19
+ * predicate is broken" and "this predicate said yes" reach the screen as the
20
+ * same pixel. An author who mistyped a root, or who wrote a `record.*` gate
21
+ * before objectui#5454 bound the row, saw their block render and had no signal
22
+ * at all that the gate had not been consulted.
23
+ *
24
+ * One of the three evaluation paths was already loud — a `{ dialect: 'cel' }`
25
+ * envelope routes to `evalFieldPredicate`, which warns (objectstack#5149). The
26
+ * bare-expression and `${…}` template paths were mute. So whether an author
27
+ * heard about their own typo depended on which dialect they happened to write
28
+ * it in, which is the arbitrariness this module removes.
29
+ *
30
+ * ## What it deliberately does NOT do
31
+ *
32
+ * It changes NO verdict. `evaluateCondition` already returned `true` for every
33
+ * unevaluable predicate on every one of its paths, and the caller reproduces
34
+ * exactly that from its catch — including on the two NON-negated legs
35
+ * (`hidden` / `hiddenOn`), where the same `true` means HIDE — and, since
36
+ * objectui#6445, on the `disabled` / `disabledOn` gate, where it means GREYED
37
+ * OUT. Flipping fail-soft to fail-closed is a shipped-behaviour change tracked
38
+ * separately upstream (objectstack#5149, appeal 1, undecided); this module is
39
+ * the diagnostic half only, on every gate wired to it.
40
+ *
41
+ * ## Why a separate module
42
+ *
43
+ * Same reason as `unevaluatedExpression.ts` next door: exporting non-components
44
+ * from the module that exports `SchemaRenderer` breaks Fast Refresh
45
+ * (`react-refresh/only-export-components`), and a format/emit split lets the
46
+ * pins assert the words a developer will actually read rather than that a spy
47
+ * was called — a diagnostic whose only test is the latter goes green the moment
48
+ * someone no-ops it.
49
+ */
50
+ /**
51
+ * Prefix every diagnostic line starts with. Exported so tests can match on it
52
+ * and so an app can filter it out of its console transport if it must.
53
+ */
54
+ export declare const UNRESOLVABLE_VISIBILITY_PREFIX = "[ObjectUI] A visibility predicate could not be evaluated";
55
+ /**
56
+ * The same opening line for the ENABLEMENT gate (`disabled` / `disabledOn`,
57
+ * objectui#6445). A sibling constant rather than a widened one: the six
58
+ * visibility legs keep the bytes they ship today (objectui#6487 pinned them),
59
+ * and calling a `disabled` predicate a "visibility predicate" would send an
60
+ * author to the wrong gate on the first line - the one line a console filter
61
+ * and a `grep` both read.
62
+ *
63
+ * Same posture as its sibling in every other respect: same reporter, same
64
+ * severity, same dedupe `Set`, same key shape, same test-only reset. Only the
65
+ * words that would be FALSE on this gate differ.
66
+ */
67
+ export declare const UNRESOLVABLE_ENABLEMENT_PREFIX = "[ObjectUI] An enablement predicate could not be evaluated";
68
+ /**
69
+ * Which SCOPE the faulting predicate was evaluated against (objectui#6487).
70
+ *
71
+ * ## Why the reporter needs to be told, rather than deducing it
72
+ *
73
+ * The closing paragraph of the message names the ROOTS an author can bind. That
74
+ * is the half of the report an author acts on: a fault is usually a mistyped or
75
+ * unbound root, and "which roots exist here" is the answer. It is therefore the
76
+ * one part of the copy that is NOT true on every surface — the callers below
77
+ * build genuinely different bags — and it was printed unconditionally in the
78
+ * node tier's spelling, so an app-shell author was sent to check `record` and
79
+ * `page.<var>`, which nothing at that tier binds.
80
+ *
81
+ * The alternative fix — generalising the copy to "whatever this surface binds"
82
+ * plus a docs link — was refused deliberately: the concrete root names are the
83
+ * whole value of the paragraph, and advice that names no roots is correct
84
+ * everywhere and useful nowhere.
85
+ *
86
+ * Deducing the tier from the `type` slot was refused too. `type` carries the
87
+ * SCHEMA NODE TYPE at the node tier and a surface label at the other two
88
+ * (`page:tabs`, `app-shell:visible`), and `page:tabs` is a real registry key —
89
+ * so a `page:tabs` NODE faulting its own `visibleWhen` inside `SchemaRenderer`
90
+ * is indistinguishable, by `type` alone, from one of its ITEM predicates. An
91
+ * explicit argument cannot collide that way.
92
+ *
93
+ * ## The tiers, each derived from the code that builds the bag
94
+ *
95
+ * `'page-component'` — the node gate. `SchemaRenderer.tsx` builds
96
+ * `new ExpressionEvaluator({ ...predicateScope, current_user, [record], data,
97
+ * page })`, so the roots the SPEC declares for the tier (`ui/page.zod.ts`:
98
+ * *"Binds `record`, `current_user`, `page.<var>`"*) are the roots it binds.
99
+ * `page:tabs` ITEM predicates (`containers.tsx`) are this tier as well: they
100
+ * build the same three roots (plus the row spread flat, and `data` aliased to
101
+ * the row rather than to the adapter — both undeclared breadth that the spec
102
+ * does not promise and this paragraph therefore does not advertise).
103
+ *
104
+ * `'app-shell'` — the chrome gate. `ExpressionProvider.tsx` builds
105
+ * `{ current_user, user, ctx: { user }, os: { user }, features }`.
106
+ * There is no `record` and no `page` in it at all, which is the defect this
107
+ * type exists to fix. The four identity spellings are the ADR-0068 aliases and
108
+ * all four resolve; `features` is the deployment-flag root that provider's own
109
+ * docblock documents for exactly this kind of predicate.
110
+ *
111
+ * ⛔ No `app`. It was in that bag and in the paragraph below until
112
+ * objectui#8155 (ruled 2026-09-07): neither ADR-0068 nor
113
+ * `@objectstack/formula`'s `SCOPE_ROOTS` declares such a root, so
114
+ * `buildExpressionScope` stopped binding it. Naming it here would be worse
115
+ * than stale — this paragraph is printed at the exact moment a saved `app.*`
116
+ * predicate faults, so it would answer "why did my predicate not resolve?"
117
+ * with the root that is the reason.
118
+ *
119
+ * ⛔ No `data` either, since objectui#8166 (ruled 2026-09-10). It WAS bound at
120
+ * the app-shell tier and was already withheld from the paragraph below, on the
121
+ * grounds that every `ExpressionProvider` mount passes `data={{}}` — but
122
+ * `AppContent`'s own field-list evaluator passed the record under edit, so on
123
+ * that one leg an authored `data.*` resolved silently against the host's record
124
+ * instead of faulting. `buildExpressionScope` stopped binding it; a `data.*`
125
+ * predicate at this tier now reaches this reporter with the engine's
126
+ * `Unknown variable: data`, the same verdict the server gives it.
127
+ */
128
+ export type PredicateScopeTier = 'page-component' | 'app-shell';
129
+ /**
130
+ * WHICH GATE the faulting predicate was authored on (objectui#6445).
131
+ *
132
+ * ## Why the reporter has to be told, when it already prints the key
133
+ *
134
+ * `evaluateCondition` answers an unevaluable predicate with `true` on every one
135
+ * of its paths, and every caller reproduces that answer. What that `true` DOES
136
+ * to the node is not a property of the predicate - it is a property of the gate
137
+ * it was authored on, and the consequence paragraph has to say which:
138
+ *
139
+ * `'visibility'` - the visibility chain. Its `true` means SHOWN on the four
140
+ * negated legs, so the safe default does NOT bite: a predicate that could not be
141
+ * evaluated reads on screen exactly like one that said yes, which is why the
142
+ * console line is the only signal an author gets.
143
+ *
144
+ * `'enablement'` - `disabled` / `disabledOn`. The SAME `true` GREYS THE CONTROL
145
+ * OUT, so here the safe default is the one that BITES. The author is looking at
146
+ * a control they can see and cannot use; telling them the gate did not bite
147
+ * would be the opposite of what is on their screen, and would send them looking
148
+ * for a rendering bug rather than at their own predicate.
149
+ *
150
+ * ## Why a parameter, and not deduced from `key`
151
+ *
152
+ * Same reason {@link PredicateScopeTier} is a parameter (read its docblock): the
153
+ * caller knows, and a deduction is a table that goes quietly wrong the moment a
154
+ * spelling arrives that it has not heard of - a new alias, or a caller outside
155
+ * this repo - which would inherit a consequence sentence written about some
156
+ * other gate. That is the exact defect class this card and objectui#6487 both
157
+ * exist to remove, so it is not worth re-introducing to save an argument.
158
+ *
159
+ * `'concealment'` - `hidden` / `hiddenOn` (objectui#6503). These are visibility
160
+ * legs, but the only two whose verdict `SchemaRenderer` does NOT negate, so the
161
+ * SAME `true` that SHOWS a node on the four negated legs REMOVES it here. They
162
+ * resolved to `'visibility'` until objectui#6503 and were therefore handed the
163
+ * one sentence that is false about them: the gate did not merely bite, it bit
164
+ * hardest of the three, and the node is not on screen to be inspected at all.
165
+ * This is the third member objectui#6445's docblock predicted, in the shape it
166
+ * predicted - a table entry and a routing decision, no signature change.
167
+ *
168
+ * ## Why a third MEMBER, and not `'visibility'` plus a `negated` flag
169
+ *
170
+ * What varies is the consequence sentence, and it varies per GATE - not along
171
+ * an independent axis a caller could set to contradict the gate it passed
172
+ * alongside. Three flat members cannot be spelled inconsistently; a
173
+ * `(kind, negated)` pair can, and `('enablement', negated: true)` would name a
174
+ * combination no renderer in this repo produces. The table stays the one place
175
+ * that decides what a fail-soft default DID.
176
+ *
177
+ * ## What widening this union costs, stated because it is a published surface
178
+ *
179
+ * `PredicateGateKind` is re-exported from `packages/react/src/index.ts` - the
180
+ * package entry, and the chain stops there (no sibling package re-exports it,
181
+ * and no file outside `packages/react` names it). A consumer switching
182
+ * EXHAUSTIVELY over the union, or holding a `Record<PredicateGateKind, ...>`,
183
+ * gains a third case to answer. That is a type-level change only: no runtime
184
+ * signature moved, and every value that was accepted before still is.
185
+ */
186
+ export type PredicateGateKind = 'visibility' | 'enablement' | 'concealment';
187
+ /**
188
+ * Build the message. Separate from the emit so a test can assert the words,
189
+ * not merely that something was logged.
190
+ *
191
+ * `tier` defaults to `'page-component'` and `gate` to `'visibility'` so the
192
+ * historical five-argument call keeps printing the exact bytes it printed
193
+ * before (objectui#6487, objectui#6445) — the defaults are a compatibility
194
+ * shim for callers outside this repo, not something this repo leans on: every
195
+ * in-repo call site passes both explicitly, which is what makes each one a
196
+ * stated decision rather than an inherited one.
197
+ */
198
+ export declare function formatUnresolvableVisibilityMessage(type: unknown, id: unknown, key: string, raw: unknown, reason: string, tier?: PredicateScopeTier, gate?: PredicateGateKind): string;
199
+ /**
200
+ * Reports a NODE-GATE predicate that could not be evaluated — in DEVELOPMENT
201
+ * AND IN PRODUCTION since objectui#6038 (maintainer ruling 2026-08-25, option
202
+ * B: "the silence is no longer an accepted property").
203
+ *
204
+ * The visibility chain was the first gate wired to it and is still the default
205
+ * {@link PredicateGateKind}; `disabled` / `disabledOn` joined it in
206
+ * objectui#6445, which is why the name is now narrower than the function. It is
207
+ * kept anyway: this symbol is exported from the package entry and called from
208
+ * `@object-ui/app-shell` and `@object-ui/components`, so renaming it would be a
209
+ * cross-package edit that changes no behaviour, on a card scoped to one file's
210
+ * wiring. What has to stay true is the posture the name once described — ONE
211
+ * reporter, ONE dedupe `Set`, ONE severity, ONE reset — and a second reporter
212
+ * for the second gate is exactly what that rules out.
213
+ *
214
+ * `console.warn`, not `error`: the verdict is unchanged and the page still
215
+ * renders, so this is a diagnostic about a predicate — not the refusal
216
+ * `reportUnevaluatedExpressions` emits once raw source has reached the DOM.
217
+ *
218
+ * ## `err` takes a reason, not only an `Error`
219
+ *
220
+ * The dev caller catches a throw and passes the `Error`; the production caller
221
+ * is handed the evaluator's own reason STRING through `EvaluationOptions.onFault`
222
+ * (no throw is raised there, because raising one would cost a second
223
+ * evaluation). `String(err)` already covered that shape, so both callers reach
224
+ * the same `Reason:` text and the same dedupe entry — which is what makes "dev
225
+ * and production print the identical line" true rather than approximately true.
226
+ *
227
+ * ## `tier` is NOT in the dedupe key, and that is not an oversight
228
+ *
229
+ * The key stays `(type, key, predicate source)` — the rate limit objectui#6038
230
+ * pinned in both directions. Adding `tier` could only ever LOOSEN it, and it
231
+ * would take a `type` shared across two tiers to loosen anything: the app-shell
232
+ * site's `type` is the constant `'app-shell:visible'`, which no node tier can
233
+ * produce, and the two `'page-component'` callers are the same tier by
234
+ * definition. So the tier is free of the key by measurement, not by assumption.
235
+ *
236
+ * ## Neither is `gate`, and for a stronger reason (objectui#6445)
237
+ *
238
+ * `gate` is a FUNCTION of `key`, which is already in the dedupe key: the
239
+ * enablement gate is exactly `disabled` / `disabledOn` and the visibility gate
240
+ * is exactly the six legs of the visibility chain, two disjoint sets. So adding
241
+ * it could not separate two entries that `key` does not already separate, and
242
+ * the cross-gate direction is pinned rather than argued: the SAME predicate
243
+ * source authored on `disabled` and on `visibleWhen` produces TWO lines, not
244
+ * one - the new reporting site cannot be swallowed by a visibility entry, and
245
+ * cannot swallow one.
246
+ */
247
+ export declare function reportUnresolvableVisibilityPredicate(type: unknown, id: unknown, key: string, raw: unknown, err: unknown, tier?: PredicateScopeTier, gate?: PredicateGateKind): void;
248
+ /**
249
+ * Test-only reset for the dedupe above — for BOTH legs, which is the point of
250
+ * their sharing one `Set`. The `Set` is module state: without this, the second
251
+ * test to assert the same warning reads the first test's dedupe entry and sees
252
+ * silence — a green run that checked nothing.
253
+ */
254
+ export declare function __resetVisibilityPredicateWarnings(): void;
255
+ /**
256
+ * Prefix for the objectui#5687 leg. A SIBLING of the constant above, not a
257
+ * reuse of it, and the difference is deliberate.
258
+ *
259
+ * The maintainer ruling (2026-08-22, option A) says this path "emits the
260
+ * dev-only unresolvable-predicate report". What is load-bearing there — and
261
+ * what the dispatch restated — is the reporter's POSTURE: same module, same
262
+ * severity (`console.warn`), same dedupe key shape, same dedupe Set, same
263
+ * gate at the same call site, same test-only reset. All of that is shared
264
+ * below.
265
+ *
266
+ * ⚠️ The two legs stopped sharing that gate's VALUE in objectui#6038, and only
267
+ * that. The unresolvable leg now reports in production as well, because the
268
+ * 2026-08-25 ruling retired its silence; THIS leg stays dev-only under its own
269
+ * 2026-08-22 ruling, and the difference is not an oversight. A fault is a
270
+ * predicate that could not be evaluated, and shipping a live gate that has
271
+ * stopped biting is the class-1 defect production has to be able to see. This
272
+ * leg reports something else: a predicate that evaluated perfectly, against the
273
+ * wrong object. Its trigger is a LEXICAL scan of the predicate source with a
274
+ * stated false-positive residue (the deliberate-absence idioms below), which is
275
+ * a cost worth paying for an author at their keyboard and not for every user of
276
+ * every production page. The first LINE is not reused, because on this path it would
277
+ * state something false: the predicate did not fail to evaluate. It evaluated
278
+ * perfectly, against the wrong object, and produced a constant. Telling an
279
+ * author "could not be evaluated" would send them hunting for a syntax error
280
+ * that is not there.
281
+ */
282
+ export declare const ADAPTER_ONLY_DATA_PREDICATE_PREFIX = "[ObjectUI] A visibility predicate read `data.*` that the bound `data` does not answer";
283
+ /**
284
+ * The `disabled` / `disabledOn` sibling of the prefix above (objectui#6504,
285
+ * maintainer ruling 2026-08-27 option A). Same reason
286
+ * {@link UNRESOLVABLE_ENABLEMENT_PREFIX} is a sibling of
287
+ * {@link UNRESOLVABLE_VISIBILITY_PREFIX} rather than a reuse: calling a
288
+ * `disabled` predicate "a visibility predicate" would send an author to the
289
+ * wrong gate on the first line — the one line a console filter and a `grep`
290
+ * both read.
291
+ */
292
+ export declare const ADAPTER_ONLY_ENABLEMENT_PREDICATE_PREFIX = "[ObjectUI] An enablement predicate read `data.*` that the bound `data` does not answer";
293
+ /**
294
+ * Which gates the objectui#5687 constant-predicate diagnostic is wired to
295
+ * (objectui#6504, maintainer ruling 2026-08-27 option A: extend to the
296
+ * enablement gate, dev-only; option C — always-on — was excluded, outside
297
+ * the #5687 precedent).
298
+ *
299
+ * A NARROWER union than {@link PredicateGateKind} deliberately, not an
300
+ * oversight: `'concealment'` (`hidden` / `hiddenOn`) is not one of them. Both
301
+ * of this diagnostic's call sites are unchanged by this card — the visibility
302
+ * one (`SchemaRenderer.tsx`'s `evaluateVisibilityPredicate`) still calls
303
+ * {@link reportAdapterOnlyDataPredicate} with no `gate` argument at all, for
304
+ * the six-leg chain exactly as objectui#5687 shipped it, so `'concealment'`
305
+ * was never a value this table had to answer for. Giving it an entry nobody
306
+ * can reach would be a decision this ruling did not make; widening this type
307
+ * later is a decision for whichever card makes that call, not a `??` for this
308
+ * table to paper over now.
309
+ */
310
+ export type AdapterOnlyPredicateGateKind = Extract<PredicateGateKind, 'visibility' | 'enablement'>;
311
+ /**
312
+ * Built separately from the emit, for the same reason as the message above.
313
+ *
314
+ * `gate` defaults to `'visibility'` so the historical four-argument call
315
+ * (objectui#5687) keeps printing the exact bytes it printed before —
316
+ * objectui#6504's own call site in `evaluateVisibilityPredicate`
317
+ * (`SchemaRenderer.tsx`) is one of those unchanged callers, passing no `gate`
318
+ * at all. `evaluateEnablementPredicate` is the one caller that states
319
+ * `'enablement'` explicitly, matching {@link formatUnresolvableVisibilityMessage}'s
320
+ * own compatibility-default pattern.
321
+ */
322
+ export declare function formatAdapterOnlyDataMessage(type: unknown, id: unknown, key: string, raw: unknown, unresolved: string[], gate?: AdapterOnlyPredicateGateKind): string;
323
+ /**
324
+ * Dev-build diagnostic for a node-gate predicate that reads `data.*` and gets
325
+ * `undefined` back from the adapter (objectui#5687, maintainer ruling
326
+ * 2026-08-22 option A).
327
+ *
328
+ * ## It changes NO verdict, and it is not allowed to
329
+ *
330
+ * The ruling is explicit that the node tier keeps its documented
331
+ * `data` = adapter semantics: no verdict change, no interpolation change. This
332
+ * function returns `void`, is called for its console output only, and the
333
+ * caller passes the evaluator's answer through untouched. The constant-false
334
+ * still hides the block; the author now hears about it.
335
+ *
336
+ * ## Why it lives beside `reportUnresolvableVisibilityPredicate`
337
+ *
338
+ * They are two halves of ONE silence. objectui#5454 made the THROWING paths
339
+ * loud; measured on this base, a `{ dialect: 'cel' }` envelope reading
340
+ * `data.status` already throws and is already reported by that function. The
341
+ * bare-string and `${…}` template dialects do not throw for the same
342
+ * predicate — they resolve `undefined == 'draft'` to a clean `false` — so the
343
+ * author heard about the identical authoring mistake only if they happened to
344
+ * write it in the CEL dialect. That is the same dialect-dependent arbitrariness
345
+ * objectui#5454 existed to remove, one path further along.
346
+ *
347
+ * Sharing the module means sharing the LIFECYCLE, which is the part that has to
348
+ * match: one dedupe Set, one reset, one severity. (One gate, too, until
349
+ * objectui#6038 — see the prefix constant above for why only the sibling leg
350
+ * crossed into production.) The dedupe
351
+ * key is tagged with this leg's name so the two diagnostics cannot silence each
352
+ * other for the same (type, key, source) triple — they are different faults,
353
+ * and a node that faults one way is not evidence about the other.
354
+ *
355
+ * ## `gate` (objectui#6504) — NOT in the dedupe key, for the reason
356
+ * {@link reportUnresolvableVisibilityPredicate}'s own docblock gives for the
357
+ * same omission
358
+ *
359
+ * `gate` is a FUNCTION of `key`: the enablement gate is exactly `disabled` /
360
+ * `disabledOn` and the visibility gate this leg is called for is the six-leg
361
+ * chain, two disjoint sets. Adding it to the dedupe key could not separate two
362
+ * entries `key` does not already separate — and the cross-gate direction is
363
+ * the one that would matter if it could: the SAME predicate source authored on
364
+ * `disabled` and on (say) `visibleWhen` must produce TWO lines, which it does
365
+ * today because `key` differs, with or without `gate` in the tuple.
366
+ *
367
+ * Defaults to `'visibility'` — the objectui#5687 call site
368
+ * (`evaluateVisibilityPredicate`) is unchanged by this card and still calls
369
+ * this function with five arguments.
370
+ */
371
+ export declare function reportAdapterOnlyDataPredicate(type: unknown, id: unknown, key: string, raw: unknown, boundData: unknown, gate?: AdapterOnlyPredicateGateKind): void;