@objectstack/lint 17.0.0-rc.3 → 17.0.0-rc.5
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/CHANGELOG.md +1938 -4
- package/dist/index.cjs +1651 -459
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +527 -155
- package/dist/index.d.ts +527 -155
- package/dist/index.js +1601 -440
- package/dist/index.js.map +1 -1
- package/dist/runtime.cjs +1466 -350
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.js +1449 -328
- package/dist/runtime.js.map +1 -1
- package/package.json +8 -6
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Manifest } from '@objectstack/sdui-parser';
|
|
2
|
+
import { Options } from 'ajv';
|
|
2
3
|
import { AccessMatrix } from '@objectstack/spec/security';
|
|
3
4
|
export { A as AUTHORING_COMMANDS, a as AUTHORING_RULES, b as AUTHORING_SURFACES, c as AuthoringCommand, d as AuthoringFinding, e as AuthoringRule, f as AuthoringRuleContext, g as AuthoringRuleInputTier, h as AuthoringRuleRun, i as AuthoringRuleTier, j as AuthoringSeverity, k as AuthoringSurface, E as EXPRESSION_INVALID, R as RuntimeGateResult, l as RuntimeStackContext, m as authoringRulesFor, r as runAuthoringRules, n as runRuntimeAuthoringRules, o as runtimeAuthoringRulesFor, p as runtimeGatedTypes, s as splitBySeverity, q as stackKeyForType } from './runtime-Cs64ShwN.cjs';
|
|
4
5
|
|
|
@@ -79,6 +80,8 @@ declare const CHART_FIELD_UNKNOWN = "chart-field-unknown";
|
|
|
79
80
|
declare const CHART_CONFIG_MISSING = "chart-config-missing";
|
|
80
81
|
declare const TABLE_COUNT_ONLY = "table-count-only";
|
|
81
82
|
declare const MEASURE_AGGREGATE_INCOHERENT = "measure-aggregate-incoherent";
|
|
83
|
+
declare const WIDGET_LEGACY_ANALYTICS_SHAPE = "widget-legacy-analytics-shape";
|
|
84
|
+
declare const WIDGET_LEGACY_ANALYTICS_UNRENDERABLE = "widget-legacy-analytics-unrenderable";
|
|
82
85
|
declare const DASHBOARD_FILTER_FIELD_UNKNOWN = "dashboard-filter-field-unknown";
|
|
83
86
|
type WidgetBindingSeverity = 'error' | 'warning';
|
|
84
87
|
interface WidgetBindingFinding {
|
|
@@ -95,7 +98,7 @@ interface WidgetBindingFinding {
|
|
|
95
98
|
/** How to fix (or deliberately suppress) it. */
|
|
96
99
|
hint: string;
|
|
97
100
|
}
|
|
98
|
-
type AnyRec$
|
|
101
|
+
type AnyRec$E = Record<string, unknown>;
|
|
99
102
|
/**
|
|
100
103
|
* Validate every dashboard widget's dataset binding. Returns the list of
|
|
101
104
|
* findings (empty = clean). Caller decides how to surface them: `error`
|
|
@@ -103,7 +106,7 @@ type AnyRec$C = Record<string, unknown>;
|
|
|
103
106
|
* should fail validate/build; `warning` findings are advisory and must
|
|
104
107
|
* never fail the build on their own.
|
|
105
108
|
*/
|
|
106
|
-
declare function validateWidgetBindings(stack: AnyRec$
|
|
109
|
+
declare function validateWidgetBindings(stack: AnyRec$E): WidgetBindingFinding[];
|
|
107
110
|
|
|
108
111
|
interface ExprIssue {
|
|
109
112
|
where: string;
|
|
@@ -116,12 +119,12 @@ interface ExprIssue {
|
|
|
116
119
|
*/
|
|
117
120
|
severity?: 'error' | 'warning';
|
|
118
121
|
}
|
|
119
|
-
type AnyRec$
|
|
122
|
+
type AnyRec$D = Record<string, unknown>;
|
|
120
123
|
/**
|
|
121
124
|
* Validate every predicate in the stack. Returns the list of issues (empty =
|
|
122
125
|
* clean). Caller decides how to surface / whether to fail the build.
|
|
123
126
|
*/
|
|
124
|
-
declare function validateStackExpressions(stack: AnyRec$
|
|
127
|
+
declare function validateStackExpressions(stack: AnyRec$D): ExprIssue[];
|
|
125
128
|
|
|
126
129
|
/**
|
|
127
130
|
* The corrective sentence, lifted **verbatim** from `unevaluableRuleError` in
|
|
@@ -153,10 +156,41 @@ interface NullGuardFinding {
|
|
|
153
156
|
/**
|
|
154
157
|
* Find every ordering/arithmetic operand that resolves to a nullable declared
|
|
155
158
|
* field and is not dominated by a real null guard. Returns `[]` for anything
|
|
156
|
-
* that does not parse
|
|
157
|
-
*
|
|
159
|
+
* that does not parse — this pass never invents a second syntax verdict.
|
|
160
|
+
*
|
|
161
|
+
* "Does not parse" is deliberately **not** this module's own opinion (#4812).
|
|
162
|
+
* The AST comes from `@objectstack/formula`'s `parseCelToAst`, the same front
|
|
163
|
+
* end `celEngine.compile`/`evaluate` use, so the set of sources this gate can
|
|
164
|
+
* reason about is exactly the set the platform accepts — rewrite (#3306) and
|
|
165
|
+
* `DEFAULT_LIMITS` included. This module used to build its own bare
|
|
166
|
+
* `new Environment({ unlistedVariablesAreDyn: true, enableOptionalTypes: true })`,
|
|
167
|
+
* which carried **no limits**: it parsed, and then adjudicated, predicates that
|
|
168
|
+
* `compile()` rejects outright at `Exceeded maxAstNodes (256)` / `maxDepth (32)`
|
|
169
|
+
* / `maxListElements (64)`. Two parse entries, two answers to "what can be
|
|
170
|
+
* parsed" — and this gate held the more permissive one.
|
|
171
|
+
*
|
|
172
|
+
* A source the canonical front end will not parse is therefore left entirely to
|
|
173
|
+
* the gate that owns that verdict: `validateExpression` runs at the very same
|
|
174
|
+
* call sites (`validate-expressions.ts` calls `check()` alongside
|
|
175
|
+
* `checkNullGuards()`) and reports the syntax fault or the bounds fault as a
|
|
176
|
+
* blocking error, with a message written for self-correction. Nothing is lost
|
|
177
|
+
* by staying silent here — and once the author fixes the fault the null-guard
|
|
178
|
+
* verdict comes back on the next run.
|
|
158
179
|
*/
|
|
159
180
|
declare function findUnguardedNullableOperands(source: string, opts: NullGuardOptions): NullGuardFinding[];
|
|
181
|
+
/**
|
|
182
|
+
* What the surface actually DOES once the predicate aborts (#4811).
|
|
183
|
+
*
|
|
184
|
+
* Both outcomes are bugs, but they are *opposite* bugs, and an author needs to
|
|
185
|
+
* be told which one they have: "your write will be refused" and "your rule will
|
|
186
|
+
* never fire" send you to different places. Never guess one — read the
|
|
187
|
+
* surface's runtime and name what it really implements.
|
|
188
|
+
*/
|
|
189
|
+
type NullGuardOutcome =
|
|
190
|
+
/** Validation rules + hook conditions: the fault propagates, the write is refused (#4761). */
|
|
191
|
+
'fail-closed'
|
|
192
|
+
/** Field `requiredWhen`: `rule-validator.ts` logs and skips, so nothing is enforced (#4811). */
|
|
193
|
+
| 'fail-open';
|
|
160
194
|
/**
|
|
161
195
|
* The publish-time message for one finding. Names the rule, the operand and the
|
|
162
196
|
* `!= null` fix (the three things the author needs), then closes with the
|
|
@@ -164,8 +198,11 @@ declare function findUnguardedNullableOperands(source: string, opts: NullGuardOp
|
|
|
164
198
|
*
|
|
165
199
|
* @param subject How the site names itself, e.g. `validation rule 'end_after_start'`.
|
|
166
200
|
* @param objectName The object whose field list decided nullability.
|
|
201
|
+
* @param finding The unguarded operand to report.
|
|
202
|
+
* @param outcome What this surface's runtime does with the abort. Defaults to
|
|
203
|
+
* `fail-closed` — what both #4763 surfaces do.
|
|
167
204
|
*/
|
|
168
|
-
declare function nullGuardMessage(subject: string, objectName: string | undefined, finding: NullGuardFinding): string;
|
|
205
|
+
declare function nullGuardMessage(subject: string, objectName: string | undefined, finding: NullGuardFinding, outcome?: NullGuardOutcome): string;
|
|
169
206
|
|
|
170
207
|
type ListViewModeSeverity = 'error' | 'warning';
|
|
171
208
|
interface ListViewModeFinding {
|
|
@@ -179,7 +216,7 @@ interface ListViewModeFinding {
|
|
|
179
216
|
hint: string;
|
|
180
217
|
}
|
|
181
218
|
declare const LIST_VIEW_FILTERS_IN_VIEWS_MODE = "list-view-filters-in-views-mode";
|
|
182
|
-
type AnyRec$
|
|
219
|
+
type AnyRec$C = Record<string, unknown>;
|
|
183
220
|
/**
|
|
184
221
|
* Flag ADR-0047 "views" mode violations on an object's built-in named views or a
|
|
185
222
|
* `defineView` default `list` / named `listViews`: `quickFilters`, or a `tabs`
|
|
@@ -189,7 +226,7 @@ type AnyRec$A = Record<string, unknown>;
|
|
|
189
226
|
*
|
|
190
227
|
* Feed the PRE-parse stack (normalizeStackInput output) — see file header.
|
|
191
228
|
*/
|
|
192
|
-
declare function validateListViewMode(stack: AnyRec$
|
|
229
|
+
declare function validateListViewMode(stack: AnyRec$C): ListViewModeFinding[];
|
|
193
230
|
|
|
194
231
|
type FunctionalCompletenessSeverity = 'error' | 'warning';
|
|
195
232
|
interface FunctionalCompletenessFinding {
|
|
@@ -222,12 +259,44 @@ interface FlowTriggerReadinessFinding {
|
|
|
222
259
|
}
|
|
223
260
|
declare const FLOW_TRIGGER_UNKNOWN_OBJECT = "flow-trigger-unknown-object";
|
|
224
261
|
declare const FLOW_DRAFT_STATUS_AMBIGUOUS = "flow-draft-status-ambiguous";
|
|
225
|
-
|
|
262
|
+
declare const FLOW_TRIGGER_UNKNOWN_EVENT = "flow-trigger-unknown-event";
|
|
263
|
+
/**
|
|
264
|
+
* #5496 — `config.timeRelative` is present but `TimeRelativeTriggerSchema`
|
|
265
|
+
* rejects it, so the sweep is never installed.
|
|
266
|
+
*
|
|
267
|
+
* Named for the DESCRIPTOR rather than for the rule that reads it, because this
|
|
268
|
+
* is the first of a family: every flow-node `config` slot whose contract a
|
|
269
|
+
* schema (or the engine) can already decide, yet which nothing checks at
|
|
270
|
+
* authoring time. `flow-<descriptor>-<verdict>` is the shape the next one takes.
|
|
271
|
+
*/
|
|
272
|
+
declare const FLOW_TIME_RELATIVE_DESCRIPTOR_INVALID = "flow-time-relative-descriptor-invalid";
|
|
273
|
+
/**
|
|
274
|
+
* #5647 — `config.timeRelative` is present but is not an object, so the engine
|
|
275
|
+
* never routes the flow to the time-relative trigger at all.
|
|
276
|
+
*
|
|
277
|
+
* The second id in the `flow-<descriptor>-<verdict>` family, and a DIFFERENT
|
|
278
|
+
* verdict from `…-INVALID` rather than a widening of it. The two partition the
|
|
279
|
+
* non-null values of one key along the engine's own routing predicate, so
|
|
280
|
+
* exactly one of them can ever fire on a given descriptor:
|
|
281
|
+
*
|
|
282
|
+
* - `typeof === 'object'` (including arrays and `Date`) — the engine ROUTES
|
|
283
|
+
* it, `TimeRelativeTriggerSchema` gets a verdict, and a bad shape is
|
|
284
|
+
* `…-INVALID`. That path has a bind-time warn; the rule moves it earlier.
|
|
285
|
+
* - anything else (`'daily'`, `7`, `true`, a function) — the engine routes it
|
|
286
|
+
* NOWHERE, so no schema and no trigger ever sees it. That is this id, and
|
|
287
|
+
* there is no runtime channel at all for it to be moved earlier from.
|
|
288
|
+
*/
|
|
289
|
+
declare const FLOW_TIME_RELATIVE_DESCRIPTOR_UNROUTABLE = "flow-time-relative-descriptor-unroutable";
|
|
290
|
+
type AnyRec$B = Record<string, unknown>;
|
|
226
291
|
/**
|
|
227
292
|
* Validate auto-launched flow trigger wiring against the stack definition.
|
|
228
|
-
*
|
|
293
|
+
*
|
|
294
|
+
* Pure — no I/O, no runtime, no mutation of `stack` — and safe on pre- or
|
|
295
|
+
* post-parse stacks. Its one dependency is the `@objectstack/spec` schema that
|
|
296
|
+
* owns the `timeRelative` descriptor's contract, which is the point: the rule
|
|
297
|
+
* ASKS that schema rather than restating it.
|
|
229
298
|
*/
|
|
230
|
-
declare function validateFlowTriggerReadiness(stack: AnyRec$
|
|
299
|
+
declare function validateFlowTriggerReadiness(stack: AnyRec$B): FlowTriggerReadinessFinding[];
|
|
231
300
|
|
|
232
301
|
type FlowTemplatePathSeverity = 'error' | 'warning';
|
|
233
302
|
interface FlowTemplatePathFinding {
|
|
@@ -242,12 +311,12 @@ interface FlowTemplatePathFinding {
|
|
|
242
311
|
}
|
|
243
312
|
declare const FLOW_TEMPLATE_UNKNOWN_FIELD = "flow-template-unknown-field";
|
|
244
313
|
declare const FLOW_TEMPLATE_LOOKUP_TRAVERSAL = "flow-template-lookup-traversal";
|
|
245
|
-
type AnyRec$
|
|
314
|
+
type AnyRec$A = Record<string, unknown>;
|
|
246
315
|
/**
|
|
247
316
|
* Validate `{record.<path>}` template references across every record-change
|
|
248
317
|
* flow. Pure and dependency-free; safe on pre- or post-parse stacks.
|
|
249
318
|
*/
|
|
250
|
-
declare function validateFlowTemplatePaths(stack: AnyRec$
|
|
319
|
+
declare function validateFlowTemplatePaths(stack: AnyRec$A): FlowTemplatePathFinding[];
|
|
251
320
|
|
|
252
321
|
type ReadonlyFlowWriteSeverity = 'error' | 'warning';
|
|
253
322
|
interface ReadonlyFlowWriteFinding {
|
|
@@ -262,12 +331,12 @@ interface ReadonlyFlowWriteFinding {
|
|
|
262
331
|
}
|
|
263
332
|
declare const FLOW_UPDATE_READONLY_FIELD = "flow-update-readonly-field";
|
|
264
333
|
declare const FLOW_UPDATE_READONLY_WHEN_FIELD = "flow-update-readonly-when-field";
|
|
265
|
-
type AnyRec$
|
|
334
|
+
type AnyRec$z = Record<string, unknown>;
|
|
266
335
|
/**
|
|
267
336
|
* Validate flow `update_record` writes against target-object readonly
|
|
268
337
|
* declarations. Pure and dependency-free; safe on pre- or post-parse stacks.
|
|
269
338
|
*/
|
|
270
|
-
declare function validateReadonlyFlowWrites(stack: AnyRec$
|
|
339
|
+
declare function validateReadonlyFlowWrites(stack: AnyRec$z): ReadonlyFlowWriteFinding[];
|
|
271
340
|
|
|
272
341
|
type ViewContainerSeverity = 'error' | 'warning';
|
|
273
342
|
interface ViewContainerFinding {
|
|
@@ -304,14 +373,14 @@ declare const STYLE_CLASSNAME_TAILWIND = "style-classname-tailwind";
|
|
|
304
373
|
declare const STYLE_RESPONSIVE_NO_BASE = "style-responsive-no-base";
|
|
305
374
|
declare const STYLE_UNKNOWN_CSS_PROPERTY = "style-unknown-css-property";
|
|
306
375
|
declare const STYLE_UNKNOWN_TOKEN = "style-unknown-token";
|
|
307
|
-
type AnyRec$
|
|
376
|
+
type AnyRec$y = Record<string, unknown>;
|
|
308
377
|
/**
|
|
309
378
|
* Validate every page's component tree for SDUI styling correctness (ADR-0065).
|
|
310
379
|
* Returns findings (empty = clean). `error` findings describe styles that are
|
|
311
380
|
* silently dropped and should fail validate/build; `warning` findings are
|
|
312
381
|
* advisory (typos, drift, footguns).
|
|
313
382
|
*/
|
|
314
|
-
declare function validateResponsiveStyles(stack: AnyRec$
|
|
383
|
+
declare function validateResponsiveStyles(stack: AnyRec$y): StyleFinding[];
|
|
315
384
|
|
|
316
385
|
type JsxPageSeverity = 'error' | 'warning';
|
|
317
386
|
interface JsxPageFinding {
|
|
@@ -324,8 +393,8 @@ interface JsxPageFinding {
|
|
|
324
393
|
message: string;
|
|
325
394
|
hint: string;
|
|
326
395
|
}
|
|
327
|
-
type AnyRec$
|
|
328
|
-
declare function validateJsxPages(stack: AnyRec$
|
|
396
|
+
type AnyRec$x = Record<string, unknown>;
|
|
397
|
+
declare function validateJsxPages(stack: AnyRec$x, opts?: {
|
|
329
398
|
manifest?: Manifest;
|
|
330
399
|
}): JsxPageFinding[];
|
|
331
400
|
|
|
@@ -338,8 +407,8 @@ interface ReactPageFinding {
|
|
|
338
407
|
message: string;
|
|
339
408
|
hint: string;
|
|
340
409
|
}
|
|
341
|
-
type AnyRec$
|
|
342
|
-
declare function validateReactPages(stack: AnyRec$
|
|
410
|
+
type AnyRec$w = Record<string, unknown>;
|
|
411
|
+
declare function validateReactPages(stack: AnyRec$w): ReactPageFinding[];
|
|
343
412
|
|
|
344
413
|
type ReactPropSeverity = 'error' | 'warning';
|
|
345
414
|
interface ReactPropFinding {
|
|
@@ -350,12 +419,13 @@ interface ReactPropFinding {
|
|
|
350
419
|
message: string;
|
|
351
420
|
hint: string;
|
|
352
421
|
}
|
|
353
|
-
type AnyRec$
|
|
422
|
+
type AnyRec$v = Record<string, unknown>;
|
|
354
423
|
declare const REACT_CHART_FIELD_UNKNOWN = "react-chart-field-unknown";
|
|
355
424
|
declare const REACT_CHART_AGGREGATE_INVALID = "react-chart-aggregate-invalid";
|
|
356
425
|
declare const REACT_CHART_AXIS_UNKNOWN = "react-chart-axis-unknown";
|
|
426
|
+
declare const REACT_CHART_DRILLDOWN_INVALID = "react-chart-drilldown-invalid";
|
|
357
427
|
declare const REACT_BLOCK_NEEDS_RECORD_CONTEXT = "react-block-needs-record-context";
|
|
358
|
-
declare function validateReactPageProps(stack: AnyRec$
|
|
428
|
+
declare function validateReactPageProps(stack: AnyRec$v): ReactPropFinding[];
|
|
359
429
|
|
|
360
430
|
type SourceStyleSeverity = 'error' | 'warning';
|
|
361
431
|
interface SourceStyleFinding {
|
|
@@ -367,8 +437,8 @@ interface SourceStyleFinding {
|
|
|
367
437
|
hint: string;
|
|
368
438
|
}
|
|
369
439
|
declare const PAGE_SOURCE_CLASSNAME = "page-source-className-tailwind";
|
|
370
|
-
type AnyRec$
|
|
371
|
-
declare function validatePageSourceStyling(stack: AnyRec$
|
|
440
|
+
type AnyRec$u = Record<string, unknown>;
|
|
441
|
+
declare function validatePageSourceStyling(stack: AnyRec$u): SourceStyleFinding[];
|
|
372
442
|
|
|
373
443
|
/**
|
|
374
444
|
* Build-time record-title diagnostics (ADR-0079).
|
|
@@ -412,34 +482,18 @@ interface RecordTitleFinding {
|
|
|
412
482
|
/** How to fix it. */
|
|
413
483
|
hint: string;
|
|
414
484
|
}
|
|
415
|
-
type AnyRec$
|
|
485
|
+
type AnyRec$t = Record<string, unknown>;
|
|
416
486
|
/**
|
|
417
487
|
* Validate every object's record-title declaration. Returns the list of
|
|
418
488
|
* findings (empty = clean). Both rules are advisory (`warning`): the caller
|
|
419
489
|
* must never fail the build on them alone — auto-provision + the `Record #<id>`
|
|
420
490
|
* floor guarantee a resolvable title at runtime.
|
|
421
491
|
*/
|
|
422
|
-
declare function validateRecordTitle(stack: AnyRec$
|
|
492
|
+
declare function validateRecordTitle(stack: AnyRec$t): RecordTitleFinding[];
|
|
423
493
|
|
|
424
|
-
/**
|
|
425
|
-
* Build-time semantic-role diagnostics (ADR-0085).
|
|
426
|
-
*
|
|
427
|
-
* The object-level semantic roles (`stageField`, `highlightFields` /
|
|
428
|
-
* deprecated `compactLayout`, `fieldGroups` + `Field.group`) are pointers
|
|
429
|
-
* into the object's own field map. A dangling pointer is Zod-valid but
|
|
430
|
-
* silently inert at render time — the exact "parsed, unmarked, silently
|
|
431
|
-
* inert" shape ADR-0078 prohibits — so the completeness lint flags it here,
|
|
432
|
-
* uniformly for `os build`/`os validate`, MCP authoring and hand authors.
|
|
433
|
-
*
|
|
434
|
-
* All three rules are warnings, not errors: every consumer degrades
|
|
435
|
-
* gracefully (an unknown `Field.group` renders in the ungrouped bucket, an
|
|
436
|
-
* unknown highlight name is skipped, an unknown `stageField` falls back to
|
|
437
|
-
* heuristics), so nothing is fully broken — but the author almost certainly
|
|
438
|
-
* typo'd a name and should be told at author time, not discover it by
|
|
439
|
-
* staring at an unchanged page.
|
|
440
|
-
*/
|
|
441
494
|
declare const FIELD_GROUP_UNDECLARED = "field-group-undeclared";
|
|
442
495
|
declare const FIELD_GROUP_EMPTY = "field-group-empty";
|
|
496
|
+
declare const FIELD_GROUP_SHADOWED = "field-group-shadowed";
|
|
443
497
|
declare const SEMANTIC_ROLE_FIELD_UNKNOWN = "semantic-role-field-unknown";
|
|
444
498
|
type SemanticRoleSeverity = 'error' | 'warning';
|
|
445
499
|
interface SemanticRoleFinding {
|
|
@@ -456,13 +510,13 @@ interface SemanticRoleFinding {
|
|
|
456
510
|
/** How to fix it. */
|
|
457
511
|
hint: string;
|
|
458
512
|
}
|
|
459
|
-
type AnyRec$
|
|
513
|
+
type AnyRec$s = Record<string, unknown>;
|
|
460
514
|
/**
|
|
461
515
|
* Validate every object's semantic-role pointers. Returns the list of
|
|
462
516
|
* findings (empty = clean). Advisory only — the caller must never fail the
|
|
463
517
|
* build on these alone.
|
|
464
518
|
*/
|
|
465
|
-
declare function validateSemanticRoles(stack: AnyRec$
|
|
519
|
+
declare function validateSemanticRoles(stack: AnyRec$s): SemanticRoleFinding[];
|
|
466
520
|
|
|
467
521
|
/**
|
|
468
522
|
* Build-time form-layout diagnostics (#2578).
|
|
@@ -505,12 +559,12 @@ interface FormLayoutFinding {
|
|
|
505
559
|
/** How to fix it. */
|
|
506
560
|
hint: string;
|
|
507
561
|
}
|
|
508
|
-
type AnyRec$
|
|
562
|
+
type AnyRec$r = Record<string, unknown>;
|
|
509
563
|
/**
|
|
510
564
|
* Validate authored form-view layout. Returns findings (empty = clean).
|
|
511
565
|
* Advisory only — the caller must never fail the build on these alone.
|
|
512
566
|
*/
|
|
513
|
-
declare function validateFormLayout(stack: AnyRec$
|
|
567
|
+
declare function validateFormLayout(stack: AnyRec$r): FormLayoutFinding[];
|
|
514
568
|
|
|
515
569
|
/**
|
|
516
570
|
* Build-time conditional-visibility diagnostics (ADR-0089 D3b).
|
|
@@ -572,7 +626,7 @@ interface VisibilityFinding {
|
|
|
572
626
|
/** How to fix it. */
|
|
573
627
|
hint: string;
|
|
574
628
|
}
|
|
575
|
-
type AnyRec$
|
|
629
|
+
type AnyRec$q = Record<string, unknown>;
|
|
576
630
|
/**
|
|
577
631
|
* Validate conditional-visibility keys across authored views and pages.
|
|
578
632
|
*
|
|
@@ -587,7 +641,7 @@ type AnyRec$o = Record<string, unknown>;
|
|
|
587
641
|
* `*.view.ts` / `*.page.ts` surfaces (so a `data.`-rooted predicate is flagged). The
|
|
588
642
|
* alias-deprecated check is layer-agnostic.
|
|
589
643
|
*/
|
|
590
|
-
declare function validateVisibilityPredicates(stack: AnyRec$
|
|
644
|
+
declare function validateVisibilityPredicates(stack: AnyRec$q, opts?: VisibilityOptions): VisibilityFinding[];
|
|
591
645
|
|
|
592
646
|
declare const CAPABILITY_REFERENCE_UNKNOWN = "capability-reference-unknown";
|
|
593
647
|
type CapabilityRefSeverity = 'error' | 'warning';
|
|
@@ -605,16 +659,17 @@ interface CapabilityRefFinding {
|
|
|
605
659
|
/** How to fix it. */
|
|
606
660
|
hint: string;
|
|
607
661
|
}
|
|
608
|
-
type AnyRec$
|
|
662
|
+
type AnyRec$p = Record<string, unknown>;
|
|
609
663
|
/**
|
|
610
664
|
* Validate every capability reference in a stack. Returns findings (empty =
|
|
611
665
|
* clean). Advisory only — callers must not fail the build on these alone.
|
|
612
666
|
*/
|
|
613
|
-
declare function validateCapabilityReferences(stack: AnyRec$
|
|
667
|
+
declare function validateCapabilityReferences(stack: AnyRec$p): CapabilityRefFinding[];
|
|
614
668
|
|
|
615
669
|
declare const APPROVAL_APPROVER_NOT_MEMBERSHIP_TIER = "approval-approver-not-membership-tier";
|
|
616
670
|
declare const APPROVAL_APPROVER_TYPE_DEPRECATED = "approval-approver-type-deprecated";
|
|
617
671
|
declare const APPROVAL_APPROVER_TYPE_UNKNOWN = "approval-approver-type-unknown";
|
|
672
|
+
declare const APPROVAL_APPROVER_TYPE_UNSUPPORTED = "approval-approver-type-unsupported";
|
|
618
673
|
declare const APPROVAL_ESCALATION_REASSIGN_NO_TARGET = "approval-escalation-reassign-no-target";
|
|
619
674
|
declare const APPROVAL_APPROVERS_MAY_RESOLVE_EMPTY = "approval-approvers-may-resolve-empty";
|
|
620
675
|
declare const APPROVAL_EXPRESSION_INVALID = "approval-expression-invalid";
|
|
@@ -635,12 +690,12 @@ interface ApprovalApproverFinding {
|
|
|
635
690
|
/** How to fix it. */
|
|
636
691
|
hint: string;
|
|
637
692
|
}
|
|
638
|
-
type AnyRec$
|
|
693
|
+
type AnyRec$o = Record<string, unknown>;
|
|
639
694
|
/**
|
|
640
695
|
* Validate the approvers of every Approval node in the stack's flows.
|
|
641
696
|
* Returns findings (empty = clean).
|
|
642
697
|
*/
|
|
643
|
-
declare function validateApprovalApprovers(stack: AnyRec$
|
|
698
|
+
declare function validateApprovalApprovers(stack: AnyRec$o): ApprovalApproverFinding[];
|
|
644
699
|
|
|
645
700
|
type SeedReplaySafetySeverity = 'error' | 'warning';
|
|
646
701
|
interface SeedReplaySafetyFinding {
|
|
@@ -654,7 +709,7 @@ interface SeedReplaySafetyFinding {
|
|
|
654
709
|
hint: string;
|
|
655
710
|
}
|
|
656
711
|
declare const SEED_INSERT_MODE_DUPLICATES_ON_REPLAY = "seed-insert-mode-duplicates-on-replay";
|
|
657
|
-
type AnyRec$
|
|
712
|
+
type AnyRec$n = Record<string, unknown>;
|
|
658
713
|
/**
|
|
659
714
|
* Flag every seed dataset declared with `mode: 'insert'` — the one non-idempotent
|
|
660
715
|
* mode, which duplicates its rows on every replay boot (framework#3434). Returns
|
|
@@ -664,7 +719,7 @@ type AnyRec$l = Record<string, unknown>;
|
|
|
664
719
|
* Reads `stack.data` (the `SeedSchema[]` fixtures). Safe on any shape — a stack
|
|
665
720
|
* with no `data` array yields no findings.
|
|
666
721
|
*/
|
|
667
|
-
declare function validateSeedReplaySafety(stack: AnyRec$
|
|
722
|
+
declare function validateSeedReplaySafety(stack: AnyRec$n): SeedReplaySafetyFinding[];
|
|
668
723
|
|
|
669
724
|
type SeedStateMachineSeverity = 'warning';
|
|
670
725
|
interface SeedStateMachineFinding {
|
|
@@ -678,7 +733,7 @@ interface SeedStateMachineFinding {
|
|
|
678
733
|
hint: string;
|
|
679
734
|
}
|
|
680
735
|
declare const SEED_VALUE_OUTSIDE_STATE_MACHINE = "seed-value-outside-state-machine";
|
|
681
|
-
type AnyRec$
|
|
736
|
+
type AnyRec$m = Record<string, unknown>;
|
|
682
737
|
/**
|
|
683
738
|
* Flag every seed record whose `state_machine`-governed field carries a value
|
|
684
739
|
* the machine does not declare (framework#3433 follow-up). Returns the findings
|
|
@@ -691,7 +746,7 @@ type AnyRec$k = Record<string, unknown>;
|
|
|
691
746
|
* unresolved `cel` Expression envelope, a number) is skipped: it cannot be
|
|
692
747
|
* statically compared to the declared-state set.
|
|
693
748
|
*/
|
|
694
|
-
declare function validateSeedStateMachine(stack: AnyRec$
|
|
749
|
+
declare function validateSeedStateMachine(stack: AnyRec$m): SeedStateMachineFinding[];
|
|
695
750
|
|
|
696
751
|
declare const SECURITY_OWD_UNSET = "security-owd-unset";
|
|
697
752
|
declare const SECURITY_OWD_ALIAS = "security-owd-alias";
|
|
@@ -702,6 +757,7 @@ declare const SECURITY_ROLE_WORD = "security-role-word";
|
|
|
702
757
|
declare const SECURITY_BOOK_AUDIENCE_UNKNOWN_SET = "security-book-audience-unknown-set";
|
|
703
758
|
declare const SECURITY_PRIVATE_NO_READSCOPE = "security-private-no-readscope";
|
|
704
759
|
declare const SECURITY_MASTER_DETAIL_UNGRANTED = "security-master-detail-ungranted";
|
|
760
|
+
declare const SECURITY_FLS_UNQUALIFIED_KEY = "security-fls-unqualified-key";
|
|
705
761
|
declare const SECURITY_GRANT_EXPIRED_AT_AUTHORING = "security-grant-expired-at-authoring";
|
|
706
762
|
declare const SECURITY_DELEGATION_MISSING_REASON = "security-delegation-missing-reason";
|
|
707
763
|
type SecuritySeverity = 'error' | 'warning' | 'info';
|
|
@@ -718,7 +774,7 @@ interface SecurityFinding {
|
|
|
718
774
|
/** How to fix it. */
|
|
719
775
|
hint: string;
|
|
720
776
|
}
|
|
721
|
-
type AnyRec$
|
|
777
|
+
type AnyRec$l = Record<string, unknown>;
|
|
722
778
|
/**
|
|
723
779
|
* Validate the security posture of a stack. Returns findings (empty = clean).
|
|
724
780
|
* `error` findings gate the build in `os compile`; `info` is advisory.
|
|
@@ -726,7 +782,7 @@ type AnyRec$j = Record<string, unknown>;
|
|
|
726
782
|
* `opts.nowMs` injects the clock for the ADR-0091 authoring-time expiry rule
|
|
727
783
|
* (tests); production callers omit it.
|
|
728
784
|
*/
|
|
729
|
-
declare function validateSecurityPosture(stack: AnyRec$
|
|
785
|
+
declare function validateSecurityPosture(stack: AnyRec$l, opts?: {
|
|
730
786
|
nowMs?: number;
|
|
731
787
|
}): SecurityFinding[];
|
|
732
788
|
|
|
@@ -759,13 +815,62 @@ declare function validateSecurityPosture(stack: AnyRec$j, opts?: {
|
|
|
759
815
|
* business-unit sharing rule on a PLATFORM-GLOBAL object (`tenancy.enabled:
|
|
760
816
|
* false`) has no organization column to scope against, so the grant spans every
|
|
761
817
|
* organization in the database — a cross-org BU grant by construction, and the
|
|
762
|
-
* "cross-org BU mega-tree" the ADR rejected, arrived at by accident.
|
|
818
|
+
* "cross-org BU mega-tree" the ADR rejected, arrived at by accident. It covers
|
|
819
|
+
* BOTH business-unit recipients, `business_unit` and `unit_and_subordinates`
|
|
820
|
+
* — see {@link BU_TREE_RECIPIENT_TYPES} for the word list and its deliberate
|
|
821
|
+
* complement.
|
|
763
822
|
*
|
|
764
823
|
* Both are `error`, per ADR-0049 discipline: each mirrors a real enforcement
|
|
765
824
|
* property (the Layer 0 wall's independence; the org-predicated BU resolver),
|
|
766
825
|
* so the lint moves the failure from silent-wrong-answer to author-time fix-it.
|
|
767
826
|
*
|
|
768
827
|
* Pure `(stack) => Finding[]`; accepts the NORMALIZED stack input.
|
|
828
|
+
*
|
|
829
|
+
* ## Scope — the keys this rule reads, and the ones it deliberately does not
|
|
830
|
+
*
|
|
831
|
+
* Every key below is one `@objectstack/spec` DECLARES. That is a contract, not
|
|
832
|
+
* a style preference: the rule is registered `input: 'parsed'`, so what it sees
|
|
833
|
+
* is what `ObjectStackSchema` returned. An undeclared key never survives to be
|
|
834
|
+
* read — the stack root strips it, and the `.strict()` sub-schemas reject the
|
|
835
|
+
* whole stack outright — so a branch keyed on one is inert for every stack an
|
|
836
|
+
* author can actually ship (#4984, #5009).
|
|
837
|
+
*
|
|
838
|
+
* | Read | Declared by |
|
|
839
|
+
* |---------------------------------------|------------------------------------|
|
|
840
|
+
* | `permissions[]` | `ObjectStackSchema` |
|
|
841
|
+
* | `permissions[].rowLevelSecurity[]` | `PermissionSetSchema` |
|
|
842
|
+
* | `…[].using` / `…[].check` | `RowLevelSecurityPolicySchema` |
|
|
843
|
+
* | `sharingRules[]` | `ObjectStackSchema` |
|
|
844
|
+
* | `sharingRules[].condition` / `.sharedWith` / `.object` | `SharingRuleSchema` |
|
|
845
|
+
* | `objects[].tenancy` / `.systemFields` | `ObjectSchema` |
|
|
846
|
+
*
|
|
847
|
+
* NOT read, and each for a reason that is a schema fact:
|
|
848
|
+
*
|
|
849
|
+
* - `permissionSets` / `sharing` — not declared on the stack root. The root
|
|
850
|
+
* STRIPS them, so after parse they are `undefined` no matter what the author
|
|
851
|
+
* wrote. The declared spellings are `permissions` and `sharingRules`.
|
|
852
|
+
* - `sharingRules[].objectName` — `SharingRuleSchema` is `.strict()` and knows
|
|
853
|
+
* it only as a rejected name; `object` is required, so the canonical read can
|
|
854
|
+
* never be missing on a rule that parsed.
|
|
855
|
+
* - `objects[].rowLevelSecurity` / `objects[].rls` — **object-level RLS is not
|
|
856
|
+
* an authoring surface at all.** `ObjectSchema` declares neither key (nor
|
|
857
|
+
* does `authorable-surface.json` list one: the sole entry is
|
|
858
|
+
* `security/PermissionSet:rowLevelSecurity`), and `ObjectSchema` is
|
|
859
|
+
* `.strict()`, so a stack carrying one does not parse — it is refused with
|
|
860
|
+
* "Unrecognized key(s) on this object". Until #5009 this file walked that
|
|
861
|
+
* non-existent surface for ~20 lines, complete with an `objects[N].
|
|
862
|
+
* rowLevelSecurity[M].using` diagnostic path. Nothing could reach it, and the
|
|
863
|
+
* cost was never the missed finding: the next author to read this rule (human
|
|
864
|
+
* or AI) came away believing object-level RLS was a real authorization
|
|
865
|
+
* surface and wrote more code against it (#5008 nearly did). RLS policies
|
|
866
|
+
* live on a permission set; that is the branch above.
|
|
867
|
+
*
|
|
868
|
+
* Alias tolerance belongs at the schema's refusal, not in a consumer (Prime
|
|
869
|
+
* Directive #12) — where it also converts a loud, named rejection into a
|
|
870
|
+
* silently-inert gate. `validate-org-axis-red-lines.test.ts` pins all of this
|
|
871
|
+
* structurally: every key read here is checked against the declaring schema's
|
|
872
|
+
* own `.shape`, and every `findings.push` site must be reachable by a fixture
|
|
873
|
+
* that passed `safeParse`.
|
|
769
874
|
*/
|
|
770
875
|
declare const ORG_AXIS_PERMISSION_INHERITANCE = "org-axis-permission-inheritance";
|
|
771
876
|
declare const ORG_AXIS_CROSS_ORG_BU_GRANT = "org-axis-cross-org-bu-grant";
|
|
@@ -788,18 +893,71 @@ interface OrgAxisFinding {
|
|
|
788
893
|
*/
|
|
789
894
|
declare function validateOrgAxisRedLines(stack: unknown): OrgAxisFinding[];
|
|
790
895
|
|
|
896
|
+
/** A `condition` outside the pushdown subset — the rule is never seeded. */
|
|
897
|
+
declare const SHARING_RULE_UNLOWERABLE_CONDITION = "sharing-rule-unlowerable-condition";
|
|
898
|
+
/** A `condition` reading `current_user.*` — unresolvable when grants are materialized. */
|
|
899
|
+
declare const SHARING_RULE_RUNTIME_VARIABLE_CONDITION = "sharing-rule-runtime-variable-condition";
|
|
900
|
+
type SharingRuleEnforceabilitySeverity = 'error' | 'warning';
|
|
901
|
+
interface SharingRuleEnforceabilityFinding {
|
|
902
|
+
severity: SharingRuleEnforceabilitySeverity;
|
|
903
|
+
/** Diagnostic rule id (`sharing-rule-*`). */
|
|
904
|
+
rule: string;
|
|
905
|
+
/** Human-readable location, e.g. `sharing rule "high_value_opps" on object "opportunity"`. */
|
|
906
|
+
where: string;
|
|
907
|
+
/** Config path, e.g. `sharingRules[2].condition`. */
|
|
908
|
+
path: string;
|
|
909
|
+
/** What is wrong. */
|
|
910
|
+
message: string;
|
|
911
|
+
/** How to fix it. */
|
|
912
|
+
hint: string;
|
|
913
|
+
}
|
|
791
914
|
/**
|
|
792
|
-
*
|
|
793
|
-
*
|
|
915
|
+
* Gate stack-declared sharing rules on the ONE thing their runtime consumer
|
|
916
|
+
* does with `condition`: lower it to a `criteria_json` filter.
|
|
917
|
+
*
|
|
918
|
+
* Pure `(stack) => Finding[]`; tolerates the normalized and the parsed tier.
|
|
919
|
+
*/
|
|
920
|
+
declare function validateSharingRuleEnforceability(stack: unknown): SharingRuleEnforceabilityFinding[];
|
|
921
|
+
|
|
922
|
+
/** A predicate outside the pushdown subset — the policy enforces nothing. */
|
|
923
|
+
declare const RLS_PREDICATE_UNENFORCEABLE = "rls-predicate-unenforceable";
|
|
924
|
+
/** A predicate that does not parse as CEL even after the legacy SQL bridge. */
|
|
925
|
+
declare const RLS_PREDICATE_UNPARSEABLE = "rls-predicate-unparseable";
|
|
926
|
+
type RlsPredicateSeverity = 'error' | 'warning';
|
|
927
|
+
interface RlsPredicateFinding {
|
|
928
|
+
severity: RlsPredicateSeverity;
|
|
929
|
+
/** Diagnostic rule id (`rls-predicate-*`). */
|
|
930
|
+
rule: string;
|
|
931
|
+
/** Human-readable location, e.g. `permission set "sales" policy "own_leads"`. */
|
|
932
|
+
where: string;
|
|
933
|
+
/** Config path, e.g. `permissions[2].rowLevelSecurity[0].using`. */
|
|
934
|
+
path: string;
|
|
935
|
+
/** What is wrong. */
|
|
936
|
+
message: string;
|
|
937
|
+
/** How to fix it. */
|
|
938
|
+
hint: string;
|
|
939
|
+
}
|
|
940
|
+
/**
|
|
941
|
+
* Gate every stack-declared RLS predicate on the ONE thing the runtime does
|
|
942
|
+
* with it: lower it to a FilterCondition (ADR-0056 D4).
|
|
943
|
+
*
|
|
944
|
+
* Pure `(stack) => Finding[]`; tolerates the normalized and the parsed tier
|
|
945
|
+
* (`using` / `check` are plain `z.string()`, identical in both).
|
|
946
|
+
*/
|
|
947
|
+
declare function validateRlsPredicateEnforceability(stack: unknown): RlsPredicateFinding[];
|
|
948
|
+
|
|
949
|
+
/**
|
|
950
|
+
* [ADR-0049 — references] Reference-integrity for dashboard header action
|
|
951
|
+
* targets (issue #3367).
|
|
794
952
|
*
|
|
795
953
|
* ADR-0049 established the "enforce-or-remove" gate for spec *properties*: a
|
|
796
954
|
* declared property the runtime does not honour is a false promise and must be
|
|
797
955
|
* enforced, marked experimental, or removed. This rule applies the SAME honesty
|
|
798
|
-
* principle to *references*. A dashboard header action
|
|
799
|
-
*
|
|
800
|
-
*
|
|
801
|
-
*
|
|
802
|
-
*
|
|
956
|
+
* principle to *references*. A dashboard header action names a target — a
|
|
957
|
+
* `script`/`modal` action, or a `url` route — that must actually resolve. A
|
|
958
|
+
* dangling target ships a button that renders and, on click, silently does
|
|
959
|
+
* nothing: a false affordance, exactly the failure ADR-0049 exists to prevent,
|
|
960
|
+
* just for a reference rather than a property.
|
|
803
961
|
*
|
|
804
962
|
* Nothing in the protocol schema can express this: `actionUrl` is a free string,
|
|
805
963
|
* so `{ actionType: 'script', actionUrl: 'export_dashboard_pdf' }` parses and
|
|
@@ -807,7 +965,24 @@ declare function validateOrgAxisRedLines(stack: unknown): OrgAxisFinding[];
|
|
|
807
965
|
*
|
|
808
966
|
* Surfaces checked:
|
|
809
967
|
* - dashboard `header.actions[]` — each `{ actionType, actionUrl }`
|
|
810
|
-
*
|
|
968
|
+
*
|
|
969
|
+
* ## The widget branch, and why it is gone (#5010)
|
|
970
|
+
*
|
|
971
|
+
* This rule used to check `widgets[].actionUrl` too, describing it as "the
|
|
972
|
+
* per-widget button" and claiming in this docblock that it "mirrors the objectui
|
|
973
|
+
* runtime dispatch". It did not: no renderer in either repo has ever drawn a
|
|
974
|
+
* per-widget action button — all 14 `actionUrl` reads in `DashboardRenderer` are
|
|
975
|
+
* scoped to `header.actions[]`. So the strictest arm of this rule (a dangling
|
|
976
|
+
* `script`/`modal` target is an ERROR, i.e. a failed build) was enforcing
|
|
977
|
+
* referential integrity for a button that could not render. An author could be
|
|
978
|
+
* blocked from shipping because a control that does not exist pointed at an
|
|
979
|
+
* action that also did not.
|
|
980
|
+
*
|
|
981
|
+
* That inversion — a rule written to delete false affordances, itself sustaining
|
|
982
|
+
* one — is why the widget keys were retired rather than the check merely
|
|
983
|
+
* relaxed: `widgets[].actionUrl` / `actionType` / `actionIcon` are now tombstoned
|
|
984
|
+
* in `@objectstack/spec` 17.0.0, so authoring one is a `tsc` error and a parse
|
|
985
|
+
* error carrying the prescription. There is no widget target left to resolve.
|
|
811
986
|
*
|
|
812
987
|
* Resolution mirrors the objectui runtime dispatch (`DashboardRenderer` +
|
|
813
988
|
* `DashboardView`) so the lint flags exactly what would fail to resolve at
|
|
@@ -860,13 +1035,13 @@ interface DashboardActionRefFinding {
|
|
|
860
1035
|
/** How to fix it. */
|
|
861
1036
|
hint: string;
|
|
862
1037
|
}
|
|
863
|
-
type AnyRec$
|
|
1038
|
+
type AnyRec$k = Record<string, unknown>;
|
|
864
1039
|
/**
|
|
865
|
-
* Validate every dashboard header
|
|
1040
|
+
* Validate every dashboard header action reference in a stack. Returns
|
|
866
1041
|
* findings (empty = clean). `script`/`modal` dead targets are errors; `url`
|
|
867
1042
|
* unresolved routes are warnings.
|
|
868
1043
|
*/
|
|
869
|
-
declare function validateDashboardActionRefs(stack: AnyRec$
|
|
1044
|
+
declare function validateDashboardActionRefs(stack: AnyRec$k): DashboardActionRefFinding[];
|
|
870
1045
|
|
|
871
1046
|
/**
|
|
872
1047
|
* Build-time filter-placeholder diagnostics (issue #3574).
|
|
@@ -964,12 +1139,12 @@ interface ObjectRefFinding {
|
|
|
964
1139
|
/** How to fix it. */
|
|
965
1140
|
hint: string;
|
|
966
1141
|
}
|
|
967
|
-
type AnyRec$
|
|
1142
|
+
type AnyRec$j = Record<string, unknown>;
|
|
968
1143
|
/**
|
|
969
1144
|
* Validate every object-name reference on the surfaces listed in the module
|
|
970
1145
|
* header. Returns findings (empty = clean).
|
|
971
1146
|
*/
|
|
972
|
-
declare function validateObjectReferences(stack: AnyRec$
|
|
1147
|
+
declare function validateObjectReferences(stack: AnyRec$j): ObjectRefFinding[];
|
|
973
1148
|
|
|
974
1149
|
type ReferenceIntegritySeverity = 'error' | 'warning';
|
|
975
1150
|
/**
|
|
@@ -1193,7 +1368,7 @@ interface SearchableFieldFinding {
|
|
|
1193
1368
|
* runtime would refuse are flagged (#4830).
|
|
1194
1369
|
*/
|
|
1195
1370
|
type SearchableFieldRole = 'canonical' | 'narrowing';
|
|
1196
|
-
type AnyRec$
|
|
1371
|
+
type AnyRec$i = Record<string, unknown>;
|
|
1197
1372
|
/**
|
|
1198
1373
|
* Validate every `searchableFields` declaration in the stack — the object's own
|
|
1199
1374
|
* (the canonical set, ADR-0061) and the list views that narrow it. Returns
|
|
@@ -1204,7 +1379,7 @@ type AnyRec$g = Record<string, unknown>;
|
|
|
1204
1379
|
* `validate-react-page-props` — the gate that already parses that source —
|
|
1205
1380
|
* runs the same `checkSearchableFieldList` core on it (#4329).
|
|
1206
1381
|
*/
|
|
1207
|
-
declare function validateSearchableFields(stack: AnyRec$
|
|
1382
|
+
declare function validateSearchableFields(stack: AnyRec$i): SearchableFieldFinding[];
|
|
1208
1383
|
|
|
1209
1384
|
declare const ACTION_NAME_UNDEFINED = "action-name-undefined";
|
|
1210
1385
|
type ActionNameRefSeverity = 'error' | 'warning';
|
|
@@ -1222,12 +1397,12 @@ interface ActionNameRefFinding {
|
|
|
1222
1397
|
/** How to fix it. */
|
|
1223
1398
|
hint: string;
|
|
1224
1399
|
}
|
|
1225
|
-
type AnyRec$
|
|
1400
|
+
type AnyRec$h = Record<string, unknown>;
|
|
1226
1401
|
/**
|
|
1227
1402
|
* Validate every name-bound action reference in a stack. Returns findings
|
|
1228
1403
|
* (empty = clean).
|
|
1229
1404
|
*/
|
|
1230
|
-
declare function validateActionNameRefs(stack: AnyRec$
|
|
1405
|
+
declare function validateActionNameRefs(stack: AnyRec$h): ActionNameRefFinding[];
|
|
1231
1406
|
|
|
1232
1407
|
/**
|
|
1233
1408
|
* [ADR-0078 Phase 3 — Tier-A `action-locations`] An action nobody placed.
|
|
@@ -1294,12 +1469,12 @@ interface ActionLocationsFinding {
|
|
|
1294
1469
|
/** How to fix it. */
|
|
1295
1470
|
hint: string;
|
|
1296
1471
|
}
|
|
1297
|
-
type AnyRec$
|
|
1472
|
+
type AnyRec$g = Record<string, unknown>;
|
|
1298
1473
|
/**
|
|
1299
1474
|
* Flag every action that declares no placement and that no view places by
|
|
1300
1475
|
* name. Returns findings (empty = clean).
|
|
1301
1476
|
*/
|
|
1302
|
-
declare function validateActionLocations(stack: AnyRec$
|
|
1477
|
+
declare function validateActionLocations(stack: AnyRec$g): ActionLocationsFinding[];
|
|
1303
1478
|
|
|
1304
1479
|
/**
|
|
1305
1480
|
* Shared page-component traversal for the lint rules that inspect
|
|
@@ -1325,7 +1500,29 @@ declare function validateActionLocations(stack: AnyRec$e): ActionLocationsFindin
|
|
|
1325
1500
|
* author never wrote, so those pages are skipped here and covered by
|
|
1326
1501
|
* `validate-jsx-pages` / `validate-react-page-props` instead.
|
|
1327
1502
|
*/
|
|
1328
|
-
type AnyRec$
|
|
1503
|
+
type AnyRec$f = Record<string, unknown>;
|
|
1504
|
+
/** A visited component plus everything needed to locate and bind it. */
|
|
1505
|
+
interface WalkedComponent {
|
|
1506
|
+
/** The component record itself. */
|
|
1507
|
+
component: AnyRec$f;
|
|
1508
|
+
/** Config path, e.g. `pages[0].regions[1].components[2]`. */
|
|
1509
|
+
path: string;
|
|
1510
|
+
/**
|
|
1511
|
+
* The object this component binds against, by precedence:
|
|
1512
|
+
* `dataSource.object` → `properties.object` → the page's `object`.
|
|
1513
|
+
* `undefined` when nothing in the chain names one.
|
|
1514
|
+
*/
|
|
1515
|
+
objectName?: string;
|
|
1516
|
+
}
|
|
1517
|
+
/** Is this page authored as `source` (so its `regions` must not be linted)? */
|
|
1518
|
+
declare function isSourceAuthoredPage(page: AnyRec$f): boolean;
|
|
1519
|
+
/**
|
|
1520
|
+
* Walk every component on a page, depth-first, yielding each with its config
|
|
1521
|
+
* path and resolved object binding. Source-authored pages yield nothing.
|
|
1522
|
+
*
|
|
1523
|
+
* `pagePath` is the caller's path prefix for the page (e.g. `pages[3]`).
|
|
1524
|
+
*/
|
|
1525
|
+
declare function walkPageComponents(page: AnyRec$f, pagePath: string): WalkedComponent[];
|
|
1329
1526
|
|
|
1330
1527
|
/**
|
|
1331
1528
|
* [ADR-0078 — completeness] Field-reference integrity for page components
|
|
@@ -1399,7 +1596,33 @@ interface PageFieldFinding {
|
|
|
1399
1596
|
hint: string;
|
|
1400
1597
|
}
|
|
1401
1598
|
|
|
1402
|
-
declare function validatePageFieldBindings(stack: AnyRec$
|
|
1599
|
+
declare function validatePageFieldBindings(stack: AnyRec$f): PageFieldFinding[];
|
|
1600
|
+
|
|
1601
|
+
/** A key authored in `properties` that the type's props schema does not declare. */
|
|
1602
|
+
declare const COMPONENT_PROPS_UNKNOWN_KEY = "component-props-unknown-key";
|
|
1603
|
+
/** A value in `properties` that the type's props schema rejects. */
|
|
1604
|
+
declare const COMPONENT_PROPS_INVALID = "component-props-invalid";
|
|
1605
|
+
/**
|
|
1606
|
+
* Advisory on every finding this rule emits — see the module header. The type
|
|
1607
|
+
* is a single literal rather than a union so the tier claim in
|
|
1608
|
+
* `authoring-rules.ts` is provable from this file's source, which is exactly
|
|
1609
|
+
* what `authoring-rule-wiring.test.ts` reads it for.
|
|
1610
|
+
*/
|
|
1611
|
+
type ComponentPropsSeverity = 'warning';
|
|
1612
|
+
interface ComponentPropsFinding {
|
|
1613
|
+
severity: ComponentPropsSeverity;
|
|
1614
|
+
/** Diagnostic rule id. */
|
|
1615
|
+
rule: string;
|
|
1616
|
+
/** Human-readable location, e.g. `page "task_detail" · record:highlights`. */
|
|
1617
|
+
where: string;
|
|
1618
|
+
/** Config path, e.g. `pages[0].regions[1].components[0].properties.titel`. */
|
|
1619
|
+
path: string;
|
|
1620
|
+
/** What is wrong. */
|
|
1621
|
+
message: string;
|
|
1622
|
+
/** How to fix it. */
|
|
1623
|
+
hint: string;
|
|
1624
|
+
}
|
|
1625
|
+
declare function validateComponentProps(stack: AnyRec$f): ComponentPropsFinding[];
|
|
1403
1626
|
|
|
1404
1627
|
/**
|
|
1405
1628
|
* [ADR-0021 — semantic layer] Chart-binding integrity for the surfaces the
|
|
@@ -1456,7 +1679,102 @@ interface ChartBindingFinding {
|
|
|
1456
1679
|
hint: string;
|
|
1457
1680
|
}
|
|
1458
1681
|
|
|
1459
|
-
declare function validateChartBindings(stack: AnyRec$
|
|
1682
|
+
declare function validateChartBindings(stack: AnyRec$f): ChartBindingFinding[];
|
|
1683
|
+
|
|
1684
|
+
type RuleCompilabilitySeverity = 'error';
|
|
1685
|
+
interface RuleCompilabilityFinding {
|
|
1686
|
+
severity: RuleCompilabilitySeverity;
|
|
1687
|
+
/** Stable diagnostic rule id (`--json` consumers and allowlists key on it). */
|
|
1688
|
+
rule: string;
|
|
1689
|
+
/** Human-readable location, e.g. `object 'account' · validation 'tax_id_format'`. */
|
|
1690
|
+
where: string;
|
|
1691
|
+
/** Config path, e.g. `objects.account.validations.tax_id_format.regex`. */
|
|
1692
|
+
path: string;
|
|
1693
|
+
message: string;
|
|
1694
|
+
hint: string;
|
|
1695
|
+
}
|
|
1696
|
+
/** A `format` rule whose `regex` `new RegExp(...)` refuses to compile. */
|
|
1697
|
+
declare const VALIDATION_RULE_REGEX_UNCOMPILABLE = "validation-rule-regex-uncompilable";
|
|
1698
|
+
/** A `json_schema` rule whose `schema` ajv refuses to compile. */
|
|
1699
|
+
declare const VALIDATION_RULE_SCHEMA_UNCOMPILABLE = "validation-rule-json-schema-uncompilable";
|
|
1700
|
+
/**
|
|
1701
|
+
* The ajv options the runtime's shared instance is constructed with
|
|
1702
|
+
* (`rule-validator.ts`). Exported so the parity test can assert BOTH halves —
|
|
1703
|
+
* that this object is what the gate compiles with, and that the runtime source
|
|
1704
|
+
* still says the same thing.
|
|
1705
|
+
*/
|
|
1706
|
+
declare const RUNTIME_AJV_OPTIONS: Options;
|
|
1707
|
+
type AnyRec$e = Record<string, unknown>;
|
|
1708
|
+
/** One authored validation rule, located for a finding. */
|
|
1709
|
+
interface WalkedValidationRule {
|
|
1710
|
+
/** The rule record itself — a top-level entry, or a `conditional` branch. */
|
|
1711
|
+
rule: AnyRec$e;
|
|
1712
|
+
/** The declaring object's `name`, or `(unnamed object)`. */
|
|
1713
|
+
objectName: string;
|
|
1714
|
+
/** The nesting-aware rule name as prose: `'outer' → 'inner'`. */
|
|
1715
|
+
label: string;
|
|
1716
|
+
/** Human-readable location: `object 'account' · validation 'outer' → 'inner'`. */
|
|
1717
|
+
where: string;
|
|
1718
|
+
/** Config path of the rule: `objects.account.validations.outer.then.inner`. */
|
|
1719
|
+
basePath: string;
|
|
1720
|
+
}
|
|
1721
|
+
/**
|
|
1722
|
+
* Reject every object validation rule whose static artifact — a `format` rule's
|
|
1723
|
+
* `regex`, a `json_schema` rule's `schema` — the runtime's own compiler cannot
|
|
1724
|
+
* compile. Pure `(stack) => Finding[]`; never throws.
|
|
1725
|
+
*/
|
|
1726
|
+
declare function validateRuleCompilability(stack: unknown): RuleCompilabilityFinding[];
|
|
1727
|
+
|
|
1728
|
+
type RuleSchemaFormatSeverity = 'error';
|
|
1729
|
+
interface RuleSchemaFormatFinding {
|
|
1730
|
+
severity: RuleSchemaFormatSeverity;
|
|
1731
|
+
/** Stable diagnostic rule id (`--json` consumers and allowlists key on it). */
|
|
1732
|
+
rule: string;
|
|
1733
|
+
/** Human-readable location, e.g. `object 'account' · validation 'support_shape'`. */
|
|
1734
|
+
where: string;
|
|
1735
|
+
/**
|
|
1736
|
+
* Config path of the offending keyword — the rule's `schema` key followed by
|
|
1737
|
+
* the RFC 6901 JSON Pointer into it, e.g.
|
|
1738
|
+
* `objects.account.validations.support_shape.schema#/properties/email/format`.
|
|
1739
|
+
*/
|
|
1740
|
+
path: string;
|
|
1741
|
+
message: string;
|
|
1742
|
+
hint: string;
|
|
1743
|
+
}
|
|
1744
|
+
/** A `json_schema` rule naming a `format` the runtime's ajv has not registered. */
|
|
1745
|
+
declare const VALIDATION_RULE_SCHEMA_UNKNOWN_FORMAT = "validation-rule-json-schema-unknown-format";
|
|
1746
|
+
/**
|
|
1747
|
+
* Depth cap on the schema walk. Not a cycle guard for parsed metadata — that is
|
|
1748
|
+
* a tree — but the same cheap promise `flow-walk.ts`'s `MAX_REGION_DEPTH` and
|
|
1749
|
+
* `validate-rule-compilability.ts`'s `MAX_RULE_NESTING_DEPTH` make: `os lint`
|
|
1750
|
+
* never parses, so it hands this walker whatever object the author's module
|
|
1751
|
+
* actually built, and `const s = { type: 'object' }; s.properties = { self: s };`
|
|
1752
|
+
* is a two-line accident. Well past any reviewable schema.
|
|
1753
|
+
*/
|
|
1754
|
+
declare const MAX_SCHEMA_WALK_DEPTH = 32;
|
|
1755
|
+
/**
|
|
1756
|
+
* The registered name closest to `name`, or `null` when nothing is close enough
|
|
1757
|
+
* to be worth suggesting.
|
|
1758
|
+
*
|
|
1759
|
+
* The budget scales with the typo's own length — three edits on a twelve-letter
|
|
1760
|
+
* name is a plausible slip, three edits on a four-letter one is a different word
|
|
1761
|
+
* — so a genuinely invented name (`shoe_size`) gets no suggestion instead of a
|
|
1762
|
+
* confident wrong one. Comparison is case-insensitive on the authored side so
|
|
1763
|
+
* `Email` is diagnosed as the case typo it is; ajv's own lookup is
|
|
1764
|
+
* case-SENSITIVE, which is exactly why `Email` is unregistered in the first
|
|
1765
|
+
* place. Ties break alphabetically, so the suggestion is stable.
|
|
1766
|
+
*/
|
|
1767
|
+
declare function nearestRegisteredFormat(name: string, registered: readonly string[]): string | null;
|
|
1768
|
+
/**
|
|
1769
|
+
* Reject every `json_schema` validation rule that names a `format` the runtime's
|
|
1770
|
+
* ajv has not registered — the keyword ajv logs once and drops, leaving the rule
|
|
1771
|
+
* declared and inert. Pure `(stack) => Finding[]`.
|
|
1772
|
+
*
|
|
1773
|
+
* Lazier than the compile gate on purpose: the registered set is only asked for
|
|
1774
|
+
* once a schema actually NAMES a format, so a stack whose `json_schema` rules
|
|
1775
|
+
* use none never loads ajv at all (`lazy-deps.test.ts` pins this).
|
|
1776
|
+
*/
|
|
1777
|
+
declare function validateRuleSchemaFormats(stack: unknown): RuleSchemaFormatFinding[];
|
|
1460
1778
|
|
|
1461
1779
|
declare const NAV_OBJECT_UNGRANTED = "nav-object-ungranted";
|
|
1462
1780
|
type NavAccessSeverity = 'error' | 'warning';
|
|
@@ -1474,12 +1792,12 @@ interface NavAccessFinding {
|
|
|
1474
1792
|
/** How to fix it. */
|
|
1475
1793
|
hint: string;
|
|
1476
1794
|
}
|
|
1477
|
-
type AnyRec$
|
|
1795
|
+
type AnyRec$d = Record<string, unknown>;
|
|
1478
1796
|
/**
|
|
1479
1797
|
* Validate that every object a stack's navigation exposes is readable by at
|
|
1480
1798
|
* least one permission set the stack declares. Returns findings (empty = clean).
|
|
1481
1799
|
*/
|
|
1482
|
-
declare function validateNavAccess(stack: AnyRec$
|
|
1800
|
+
declare function validateNavAccess(stack: AnyRec$d): NavAccessFinding[];
|
|
1483
1801
|
|
|
1484
1802
|
declare const TRANSLATION_TARGET_UNKNOWN = "translation-target-unknown";
|
|
1485
1803
|
declare const TRANSLATION_OPTION_KEY_UNKNOWN = "translation-option-key-unknown";
|
|
@@ -1498,12 +1816,35 @@ interface TranslationRefFinding {
|
|
|
1498
1816
|
/** How to fix it. */
|
|
1499
1817
|
hint: string;
|
|
1500
1818
|
}
|
|
1501
|
-
type AnyRec$
|
|
1819
|
+
type AnyRec$c = Record<string, unknown>;
|
|
1502
1820
|
/**
|
|
1503
1821
|
* Validate every reference a translation bundle makes against the metadata it
|
|
1504
1822
|
* claims to translate. Returns findings (empty = clean).
|
|
1505
1823
|
*/
|
|
1506
|
-
declare function validateTranslationReferences(stack: AnyRec$
|
|
1824
|
+
declare function validateTranslationReferences(stack: AnyRec$c): TranslationRefFinding[];
|
|
1825
|
+
|
|
1826
|
+
declare const TRANSLATION_SECTION_NAME_MISSING = "translation-section-name-missing";
|
|
1827
|
+
type TranslatableSectionSeverity = 'warning';
|
|
1828
|
+
interface TranslatableSectionFinding {
|
|
1829
|
+
/** Always `warning` — one heading stays in the source locale; nothing breaks. */
|
|
1830
|
+
severity: TranslatableSectionSeverity;
|
|
1831
|
+
/** Diagnostic rule id. */
|
|
1832
|
+
rule: string;
|
|
1833
|
+
/** Human-readable location, e.g. `object "crm_case" · view "case_views" · formViews.create`. */
|
|
1834
|
+
where: string;
|
|
1835
|
+
/** Config path, e.g. `views[0].formViews.create.sections[1]`. */
|
|
1836
|
+
path: string;
|
|
1837
|
+
/** What is wrong. */
|
|
1838
|
+
message: string;
|
|
1839
|
+
/** How to fix it. */
|
|
1840
|
+
hint: string;
|
|
1841
|
+
}
|
|
1842
|
+
type AnyRec$b = Record<string, unknown>;
|
|
1843
|
+
/**
|
|
1844
|
+
* Report every form/detail section that declares a heading but no `name`, on an
|
|
1845
|
+
* object the stack actually translates. Returns findings (empty = clean).
|
|
1846
|
+
*/
|
|
1847
|
+
declare function validateTranslatableSections(stack: AnyRec$b): TranslatableSectionFinding[];
|
|
1507
1848
|
|
|
1508
1849
|
/**
|
|
1509
1850
|
* [ADR-0064 §3] Skill ↔ agent surface affinity (issue #3820).
|
|
@@ -1842,45 +2183,6 @@ declare function buildAccessMatrix(stack: AnyRec$4): AccessMatrix;
|
|
|
1842
2183
|
*/
|
|
1843
2184
|
declare function diffAccessMatrix(before: AccessMatrix, after: AccessMatrix): string[];
|
|
1844
2185
|
|
|
1845
|
-
/**
|
|
1846
|
-
* Build-time lint for flow authoring ANTI-PATTERNS — metadata that is valid
|
|
1847
|
-
* (passes schema + expression checks) but is semantically a footgun at runtime.
|
|
1848
|
-
* Most are emitted as WARNINGS: they guide the author (very often an AI
|
|
1849
|
-
* generating templates) toward the robust pattern without failing the build on
|
|
1850
|
-
* a technically-legal construct.
|
|
1851
|
-
*
|
|
1852
|
-
* A finding carrying `severity: 'error'` FAILS the build. The bar is: **no
|
|
1853
|
-
* reading of the author's metadata does what it says, deterministically, on
|
|
1854
|
-
* every run.** Warning about such a shape is just a slower way of finding out.
|
|
1855
|
-
* That covers two kinds, and only these:
|
|
1856
|
-
*
|
|
1857
|
-
* - **The runtime refuses.** {@link FLOW_RUNAS_UNSCOPED} — a user-less trigger
|
|
1858
|
-
* with `runAs:'user'` has no identity to scope to, so the data operation is
|
|
1859
|
-
* refused outright (#3760).
|
|
1860
|
-
* - **The declaration is inert and the route silently differs from what is
|
|
1861
|
-
* written.** {@link FLOW_BRANCH_LABEL_UNMATCHED} — a decision computes a
|
|
1862
|
-
* branch no out-edge carries, so the branch is discarded and every out-edge
|
|
1863
|
-
* is considered instead. {@link FLOW_DEFAULT_EDGE_WITH_CONDITION} — an edge
|
|
1864
|
-
* that is both the default and conditional; the condition wins and the
|
|
1865
|
-
* marker routes nothing. Neither *fails*; both are wrong every time, and
|
|
1866
|
-
* silently, which is worse (#4414).
|
|
1867
|
-
*
|
|
1868
|
-
* The bar is deliberately about *provability*, not severity of consequence. A
|
|
1869
|
-
* shape with a legitimate reading stays a warning even when it is usually a
|
|
1870
|
-
* mistake — {@link FLOW_DECISION_UNCONDITIONAL_BRANCH} is normally a guard that
|
|
1871
|
-
* does not guard, but a decision with one guarded and one unconditional out-edge
|
|
1872
|
-
* is a legal "maybe notify, always continue" fan-out, and
|
|
1873
|
-
* {@link FLOW_MULTIPLE_DEFAULT_EDGES} can genuinely mean "when nothing matched,
|
|
1874
|
-
* do both". Failing a customer's build on a shape we cannot prove wrong is a
|
|
1875
|
-
* worse trade than letting the warning be ignored.
|
|
1876
|
-
*
|
|
1877
|
-
* #1874 — time-relative rules via record-change date-EQUALITY. A start-node
|
|
1878
|
-
* trigger condition like `end_date == daysFromNow(60)` on a `record-*` trigger
|
|
1879
|
-
* only fires if the record happens to be written on that exact day; the robust
|
|
1880
|
-
* shape is a daily SCHEDULE trigger + a range query. We flag the equality form
|
|
1881
|
-
* specifically (range operators `>=`/`<=` are not flagged — they're the building
|
|
1882
|
-
* block of the correct pattern), keeping false positives near zero.
|
|
1883
|
-
*/
|
|
1884
2186
|
interface FlowLintFinding {
|
|
1885
2187
|
where: string;
|
|
1886
2188
|
message: string;
|
|
@@ -1908,6 +2210,12 @@ declare const FLOW_BARE_DOLLAR_REF = "flow-bare-dollar-reference";
|
|
|
1908
2210
|
declare const FLOW_APPROVAL_REVISE_DEAD_END = "flow-approval-revise-dead-end";
|
|
1909
2211
|
declare const FLOW_APPROVAL_REVISE_UNMARKED_BACKEDGE = "flow-approval-revise-unmarked-backedge";
|
|
1910
2212
|
declare const FLOW_APPROVAL_REVISE_DISABLED = "flow-approval-revise-disabled";
|
|
2213
|
+
/**
|
|
2214
|
+
* #3823 — the `revise` edge targets a node that is not the service-owned revise
|
|
2215
|
+
* window. `error`: `ApprovalService.sendBack` refuses this metadata outright
|
|
2216
|
+
* (see {@link scanApprovalReviseLoops}).
|
|
2217
|
+
*/
|
|
2218
|
+
declare const FLOW_APPROVAL_REVISE_TARGET_NOT_SERVICE_OWNED = "flow-approval-revise-target-not-service-owned";
|
|
1911
2219
|
/**
|
|
1912
2220
|
* #3760 — renamed from `flow-schedule-runas-unscoped`. The old id named the
|
|
1913
2221
|
* *schedule*, which was never the boundary: the rule is about a trigger that
|
|
@@ -1923,8 +2231,22 @@ declare const FLOW_MULTIPLE_DEFAULT_EDGES = "flow-multiple-default-edges";
|
|
|
1923
2231
|
/** #4414 — `config.condition` on a node whose executor never reads it. */
|
|
1924
2232
|
declare const FLOW_INERT_NODE_CONDITION = "flow-inert-node-condition";
|
|
1925
2233
|
/**
|
|
1926
|
-
*
|
|
1927
|
-
*
|
|
2234
|
+
* #5482 — a `delete_record` / `update_record` node that declares `multi: true`
|
|
2235
|
+
* and bounds it with NOTHING: the whole-object write, by declaration.
|
|
2236
|
+
*
|
|
2237
|
+
* Named descriptor-first per the family note on
|
|
2238
|
+
* `flow-time-relative-descriptor-invalid` in `validate-flow-trigger-readiness.ts`
|
|
2239
|
+
* (`flow-<descriptor>-<verdict>`, #5496): the descriptor is the
|
|
2240
|
+
* `multi` bulk declaration on a write node, the verdict is that no predicate
|
|
2241
|
+
* bounds it. See {@link scanUnboundedBulkWrites} for why this is a warning and
|
|
2242
|
+
* how it divides labour with the #3810 run-time guard.
|
|
2243
|
+
*/
|
|
2244
|
+
declare const FLOW_MULTI_WRITE_UNFILTERED = "flow-multi-write-unfiltered";
|
|
2245
|
+
/**
|
|
2246
|
+
* Lint every flow for known authoring anti-patterns — its own graph AND every
|
|
2247
|
+
* nested ADR-0031 region (#5383). Returns a (possibly empty) list of findings;
|
|
2248
|
+
* never throws. A finding marked `severity: 'error'` fails the build, and since
|
|
2249
|
+
* #5383 it can be raised by a node inside a `loop` body too.
|
|
1928
2250
|
*/
|
|
1929
2251
|
declare function lintFlowPatterns(stack: AnyRec$3): FlowLintFinding[];
|
|
1930
2252
|
|
|
@@ -2003,36 +2325,86 @@ interface LintIssue {
|
|
|
2003
2325
|
fix?: string;
|
|
2004
2326
|
}
|
|
2005
2327
|
declare const UNIQUE_DOUBLE_DECLARATION = "unique/double-declaration";
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
*
|
|
2010
|
-
*
|
|
2011
|
-
*
|
|
2012
|
-
*
|
|
2013
|
-
*
|
|
2014
|
-
*
|
|
2015
|
-
*
|
|
2016
|
-
*
|
|
2017
|
-
*
|
|
2018
|
-
*
|
|
2019
|
-
*
|
|
2020
|
-
*
|
|
2021
|
-
*
|
|
2022
|
-
*
|
|
2023
|
-
*
|
|
2024
|
-
*
|
|
2025
|
-
*
|
|
2026
|
-
*
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
*
|
|
2328
|
+
declare const UNIQUE_UNSCOPED_DECLARED_INDEX = "unique/unscoped-declared-index";
|
|
2329
|
+
declare const UNIQUE_LEGACY_ORGANIZATION_COMPOSITE = "unique/legacy-organization-composite";
|
|
2330
|
+
/**
|
|
2331
|
+
* R11 (ADR-0120 D5a) — a declared index carries bare `unique: true`: the one
|
|
2332
|
+
* spelling whose scope is unstated.
|
|
2333
|
+
*
|
|
2334
|
+
* Positional intent is the #4986 trap: an author writes
|
|
2335
|
+
* `indexes: [{ fields: ['name'], unique: true }]` on an organization-scoped
|
|
2336
|
+
* object, intends "unique per organization", and silently gets
|
|
2337
|
+
* installation-wide. This rule fires on the SPELLING alone — deliberately no
|
|
2338
|
+
* tenancy or posture inference (`organization_id` is kernel-injected at
|
|
2339
|
+
* registration, not authored, so an authoring-time guess would be wrong half
|
|
2340
|
+
* the time; that dead end is documented on #4698). Both replacement words are
|
|
2341
|
+
* checkable at authoring time, which is what makes this the first gate in the
|
|
2342
|
+
* #4986 saga that can actually run here.
|
|
2343
|
+
*
|
|
2344
|
+
* 17.x: warning. Protocol 18 rejects the spelling at validate/publish (#5082).
|
|
2345
|
+
* Advisory — never fails a build in 17.x.
|
|
2346
|
+
*
|
|
2347
|
+
* Wiring: own AUTHORING_RULES entry (validate/build), and `lintDataModel`
|
|
2348
|
+
* calls it for `os lint` — each command reports each finding exactly once.
|
|
2349
|
+
*/
|
|
2350
|
+
declare function lintUnscopedDeclaredIndexes(objects: any[]): LintIssue[];
|
|
2351
|
+
/**
|
|
2352
|
+
* R10 (ADR-0120 D5b) — the same single column carries BOTH a field-level
|
|
2353
|
+
* `unique` and a declared single-column unique index (#3991), judged in the
|
|
2354
|
+
* scope vocabulary. Each side states (or positionally implies) a boundary —
|
|
2355
|
+
* field: `true`/`'organization'` = per-organization, `'global'` =
|
|
2356
|
+
* installation-wide; declared index: `'global'` (or bare `true`, its
|
|
2357
|
+
* deprecated spelling) = installation-wide, `'organization'` =
|
|
2358
|
+
* per-organization — giving four quadrants:
|
|
2359
|
+
*
|
|
2360
|
+
* - Different scopes (field per-organization × index `'global'`, or field
|
|
2361
|
+
* `'global'` × index `'organization'`): CONTRADICTION. The installation-wide
|
|
2362
|
+
* index is physically stricter and wins; the per-organization constraint
|
|
2363
|
+
* can never be tripped. One declared intent is silently dead.
|
|
2364
|
+
* - Same scope (both per-organization, or both installation-wide):
|
|
2365
|
+
* REDUNDANCY — the same index declared twice.
|
|
2366
|
+
*
|
|
2367
|
+
* Tenancy is deliberately NOT inferred here — the quadrants are judged from
|
|
2368
|
+
* the two spellings alone, which is exactly what the vocabulary buys
|
|
2369
|
+
* (pre-ADR-0120, the contradiction quadrant could only be described
|
|
2370
|
+
* conditionally on unknowable tenancy).
|
|
2371
|
+
*
|
|
2372
|
+
* A composite declared index (`['organization_id', 'email']`) stays exempt:
|
|
2373
|
+
* it is the legacy hand-written organization spelling and agrees with the
|
|
2374
|
+
* field-level default (its `'organization'` respelling nudge is ADR-0120 D5c,
|
|
2375
|
+
* a separate wave).
|
|
2031
2376
|
*
|
|
2032
2377
|
* Advisory. The resulting stack is well-defined — the cost is an intent that
|
|
2033
2378
|
* never takes effect, not a broken artifact — so this never fails a build.
|
|
2034
2379
|
*/
|
|
2035
2380
|
declare function lintUniqueDeclarations(objects: any[]): LintIssue[];
|
|
2381
|
+
/**
|
|
2382
|
+
* R12 (ADR-0120 D5c) — a declared unique index whose column list CONTAINS the
|
|
2383
|
+
* organization column: the hand-written per-organization composite (S6),
|
|
2384
|
+
* predating the vocabulary that can now say so.
|
|
2385
|
+
*
|
|
2386
|
+
* Why this is worth a nudge rather than left alone. The legacy spelling
|
|
2387
|
+
* `{ fields: ['organization_id', 'name'], unique: true }` says "per
|
|
2388
|
+
* organization" to a reader and materializes as a plain composite — and SQL
|
|
2389
|
+
* UNIQUE is NULL-distinct, so on every row where the organization column is
|
|
2390
|
+
* NULL it enforces **nothing** (#5030, measured). On a single-organization
|
|
2391
|
+
* deployment that is *every* row. The `'organization'` respelling is what closes
|
|
2392
|
+
* that hole: the driver makes the LISTED organization column NULL-safe in place
|
|
2393
|
+
* (`COALESCE(organization_id, '__global__')`), so the NULL rows become one
|
|
2394
|
+
* platform bucket that is unique among themselves.
|
|
2395
|
+
*
|
|
2396
|
+
* **Advisory, and deliberately no auto-fix.** ADR-0120 D5c is explicit that the
|
|
2397
|
+
* legacy spelling stays valid and unmigrated forever if untouched — zero forced
|
|
2398
|
+
* drift. Opting in is a real physical tightening that goes through the D4
|
|
2399
|
+
* ceremony (a `recreate_index` gated by the duplicate pre-flight probe), because
|
|
2400
|
+
* the rows the void constraint admitted may still be there. Fixing this on the
|
|
2401
|
+
* author's behalf would schedule that migration without asking.
|
|
2402
|
+
*
|
|
2403
|
+
* Not fired for `unique: 'organization'` — that IS the respelling — nor for a
|
|
2404
|
+
* unique declared on the organization column ALONE, which is not a composite and
|
|
2405
|
+
* has no per-organization reading to recover.
|
|
2406
|
+
*/
|
|
2407
|
+
declare function lintLegacyOrganizationComposites(objects: any[]): LintIssue[];
|
|
2036
2408
|
/**
|
|
2037
2409
|
* Lint the relationship / data-modeling conventions across the full object set.
|
|
2038
2410
|
* Pure and deterministic — safe to call from both the `lint` command and the
|
|
@@ -2040,4 +2412,4 @@ declare function lintUniqueDeclarations(objects: any[]): LintIssue[];
|
|
|
2040
2412
|
*/
|
|
2041
2413
|
declare function lintDataModel(objects: any[]): LintIssue[];
|
|
2042
2414
|
|
|
2043
|
-
export { ACTION_BODY_WRITE_EXCLUSIONS, ACTION_BODY_WRITE_PATTERNS, ACTION_BODY_WRITE_PATTERN_IDS, ACTION_BODY_WRITE_UNKNOWN_FIELD, ACTION_NAME_UNDEFINED, ACTION_NO_PLACEMENT, ACTION_RECORD_WRITE_DISCARDED, ACTION_RECORD_WRITE_PATTERNS, ACTION_RECORD_WRITE_PATTERN_IDS, AGENT_AUTHORING_WITHDRAWN, AI_SKILL_SURFACE_MISMATCH, AI_SKILL_TOOL_UNRESOLVED, APPROVAL_APPROVERS_MAY_RESOLVE_EMPTY, APPROVAL_APPROVER_CROSS_ORG_UNSUPPORTED, APPROVAL_APPROVER_NOT_MEMBERSHIP_TIER, APPROVAL_APPROVER_TYPE_DEPRECATED, APPROVAL_APPROVER_TYPE_UNKNOWN, APPROVAL_DECISION_OUTPUTS_RESERVED, APPROVAL_ESCALATION_REASSIGN_NO_TARGET, APPROVAL_EXPRESSION_INVALID, APPROVAL_EXPRESSION_NO_EMPTY_POLICY, AUTONUMBER_LITERAL_TOKEN, AUTONUMBER_OPTIONAL_FIELD, AUTONUMBER_SELF_REFERENCE, AUTONUMBER_UNKNOWN_FIELD, type ActionBodyWriteExclusion, type ActionBodyWriteFinding, type ActionBodyWriteSeverity, type ActionLocationsFinding, type ActionLocationsSeverity, type ActionNameRefFinding, type ActionNameRefSeverity, type AiAgentAuthoringFinding, type AiAgentAuthoringSeverity, type AiSurfaceAffinityFinding, type AiSurfaceAffinitySeverity, type AiToolRefFinding, type AiToolRefSeverity, type ApprovalApproverFinding, type ApprovalApproverSeverity, type AutonumberLintFinding, type BodyWritePatternExclusion, CAPABILITY_REFERENCE_UNKNOWN, CHART_AXIS_NOT_SELECTED, CHART_CONFIG_MISSING, CHART_DATASET_UNKNOWN, CHART_DIMENSION_UNKNOWN, CHART_FIELD_UNKNOWN, CHART_MEASURE_UNKNOWN, type CapabilityRefFinding, type CapabilityRefSeverity, type ChartBindingFinding, type ChartBindingSeverity, DASHBOARD_ACTION_ROUTE_UNRESOLVED, DASHBOARD_ACTION_TARGET_UNDEFINED, DASHBOARD_FILTER_FIELD_UNKNOWN, type DashboardActionRefFinding, type DashboardActionRefSeverity, type ExprIssue, type ExtractedHookBodyWrite, type ExtractedHookBodyWriteSet, FIELD_GROUP_EMPTY, FIELD_GROUP_UNDECLARED, FILTER_TOKEN_UNKNOWN, FLOW_APPROVAL_REVISE_DEAD_END, FLOW_APPROVAL_REVISE_DISABLED, FLOW_APPROVAL_REVISE_UNMARKED_BACKEDGE, FLOW_BARE_DOLLAR_REF, FLOW_BRANCH_LABEL_UNMATCHED, FLOW_DATE_EQUALITY_FILTER, FLOW_DECISION_UNCONDITIONAL_BRANCH, FLOW_DEFAULT_EDGE_WITH_CONDITION, FLOW_DOUBLE_BRACE_INTERP, FLOW_DRAFT_STATUS_AMBIGUOUS, FLOW_ERROR_LABEL_NOT_FAULT, FLOW_INERT_NODE_CONDITION, FLOW_MULTIPLE_DEFAULT_EDGES, FLOW_NODE_WRITE_UNKNOWN_FIELD, FLOW_PHANTOM_AGGREGATION, FLOW_RUNAS_UNSCOPED, FLOW_TEMPLATE_LOOKUP_TRAVERSAL, FLOW_TEMPLATE_UNKNOWN_FIELD, FLOW_TIME_RELATIVE_ANTIPATTERN, FLOW_TRIGGER_UNKNOWN_OBJECT, FLOW_UPDATE_READONLY_FIELD, FLOW_UPDATE_READONLY_WHEN_FIELD, FLOW_WRITE_NODE_TYPES, FLOW_WRITE_NODE_TYPES_DEFERRED, FORM_COLSPAN_ABSOLUTE, FORM_FIELD_UNKNOWN, type FilterTokenFinding, type FilterTokenSeverity, type FlowLintFinding, type FlowNodeWriteFinding, type FlowNodeWriteSeverity, type FlowTemplatePathFinding, type FlowTemplatePathSeverity, type FlowTriggerReadinessFinding, type FlowTriggerReadinessSeverity, type FlowWriteNodeDeferral, type FormLayoutFinding, type FormLayoutSeverity, type FunctionalCompletenessFinding, type FunctionalCompletenessSeverity, HOOK_BODY_WRITE_EXCLUSIONS, HOOK_BODY_WRITE_PATTERNS, HOOK_BODY_WRITE_PATTERN_IDS, HOOK_BODY_WRITE_UNKNOWN_FIELD, type HookBodyWriteFinding, type HookBodyWritePattern, type HookBodyWriteSeverity, type JsxPageFinding, type JsxPageSeverity, LIST_VIEW_FILTERS_IN_VIEWS_MODE, LIVENESS_DEAD_PROPERTY, LIVENESS_EXPERIMENTAL_PROPERTY, type LintIssue, type ListViewModeFinding, type ListViewModeSeverity, type LivenessLintFinding, MEASURE_AGGREGATE_INCOHERENT, NAV_OBJECT_UNGRANTED, NAV_TARGET_UNRESOLVED, NULL_GUARD_HINT, type NavAccessFinding, type NavAccessSeverity, type NavTargetRefFinding, type NavTargetRefSeverity, type NullGuardFinding, type NullGuardOptions, OBJECT_REFERENCE_UNKNOWN, OBJECT_REFERENCE_UNREGISTERED_PLATFORM, ORG_AXIS_CROSS_ORG_BU_GRANT, ORG_AXIS_PERMISSION_INHERITANCE, type ObjectRefFinding, type ObjectRefSeverity, type OrgAxisFinding, type OrgAxisSeverity, PAGE_FIELD_UNKNOWN, PAGE_SOURCE_CLASSNAME, type PageFieldFinding, type PageFieldSeverity, REACT_BLOCK_NEEDS_RECORD_CONTEXT, REACT_CHART_AGGREGATE_INVALID, REACT_CHART_AXIS_UNKNOWN, REACT_CHART_FIELD_UNKNOWN, REFERENCE_INTEGRITY_RULES, type ReactPageFinding, type ReactPageSeverity, type ReactPropFinding, type ReactPropSeverity, type ReadonlyFlowWriteFinding, type ReadonlyFlowWriteSeverity, type RecordTitleFinding, type RecordTitleSeverity, type ReferenceIntegrityFinding, type ReferenceIntegrityRule, type ReferenceIntegritySeverity, SEARCHABLE_FIELD_UNKNOWN, SEARCHABLE_FIELD_UNSEARCHABLE, SECURITY_ANCHOR_HIGH_PRIVILEGE, SECURITY_BOOK_AUDIENCE_UNKNOWN_SET, SECURITY_DELEGATION_MISSING_REASON, SECURITY_EXTERNAL_WIDER, SECURITY_GRANT_EXPIRED_AT_AUTHORING, SECURITY_MASTER_DETAIL_UNGRANTED, SECURITY_OWD_ALIAS, SECURITY_OWD_UNSET, SECURITY_PRIVATE_NO_READSCOPE, SECURITY_ROLE_WORD, SECURITY_WILDCARD_VAMA, SEED_INSERT_MODE_DUPLICATES_ON_REPLAY, SEED_VALUE_OUTSIDE_STATE_MACHINE, SEMANTIC_ROLE_FIELD_UNKNOWN, STYLE_CLASSNAME_TAILWIND, STYLE_NODE_MISSING_ID, STYLE_RESPONSIVE_NO_BASE, STYLE_UNKNOWN_CSS_PROPERTY, STYLE_UNKNOWN_TOKEN, type SearchableFieldFinding, type SearchableFieldRole, type SearchableFieldSeverity, type SecurityFinding, type SecuritySeverity, type SeedReplaySafetyFinding, type SeedReplaySafetySeverity, type SeedStateMachineFinding, type SeedStateMachineSeverity, type SemanticRoleFinding, type SemanticRoleSeverity, type Severity, type SourceStyleFinding, type SourceStyleSeverity, type StyleFinding, type StyleSeverity, TABLE_COUNT_ONLY, TITLE_FORMAT_RETIRED, TITLE_UNRESOLVABLE, TRANSLATION_OPTION_KEY_UNKNOWN, TRANSLATION_TARGET_UNKNOWN, type TranslationRefFinding, type TranslationRefSeverity, UNIQUE_DOUBLE_DECLARATION, VIEW_CONTAINER_SHAPE, VIEW_KEY_COLLISION, VIEW_REF_FORM_TARGET_KIND, VIEW_REF_FORM_TARGET_MISSING, VISIBILITY_ALIAS_DEPRECATED, VISIBILITY_ROOT_MISLAYERED, type ViewContainerFinding, type ViewContainerSeverity, type ViewRefFinding, type VisibilityFinding, type VisibilityLayer, type VisibilityOptions, type VisibilitySeverity, WIDGET_DATASET_UNKNOWN, WIDGET_DIMENSION_UNKNOWN, WIDGET_MEASURE_UNKNOWN, type WidgetBindingFinding, type WidgetBindingSeverity, buildAccessMatrix, diffAccessMatrix, extractHookBodyWriteSet, extractHookBodyWrites, findUnguardedNullableOperands, lintAutonumberFormats, lintDataModel, lintFlowPatterns, lintLivenessProperties, lintUniqueDeclarations, lintViewRefs, nullGuardMessage, validateActionBodyWrites, validateActionLocations, validateActionNameRefs, validateAiAgentAuthoring, validateAiSurfaceAffinity, validateAiToolReferences, validateApprovalApprovers, validateCapabilityReferences, validateChartBindings, validateDashboardActionRefs, validateFilterTokens, validateFlowNodeWrites, validateFlowTemplatePaths, validateFlowTriggerReadiness, validateFormLayout, validateFunctionalCompleteness, validateHookBodyWrites, validateJsxPages, validateListViewMode, validateNavAccess, validateNavTargetRefs, validateObjectReferences, validateOrgAxisRedLines, validatePageFieldBindings, validatePageSourceStyling, validateReactPageProps, validateReactPages, validateReadonlyFlowWrites, validateRecordTitle, validateReferenceIntegrity, validateResponsiveStyles, validateSearchableFields, validateSecurityPosture, validateSeedReplaySafety, validateSeedStateMachine, validateSemanticRoles, validateStackExpressions, validateTranslationReferences, validateViewContainers, validateVisibilityPredicates, validateWidgetBindings };
|
|
2415
|
+
export { ACTION_BODY_WRITE_EXCLUSIONS, ACTION_BODY_WRITE_PATTERNS, ACTION_BODY_WRITE_PATTERN_IDS, ACTION_BODY_WRITE_UNKNOWN_FIELD, ACTION_NAME_UNDEFINED, ACTION_NO_PLACEMENT, ACTION_RECORD_WRITE_DISCARDED, ACTION_RECORD_WRITE_PATTERNS, ACTION_RECORD_WRITE_PATTERN_IDS, AGENT_AUTHORING_WITHDRAWN, AI_SKILL_SURFACE_MISMATCH, AI_SKILL_TOOL_UNRESOLVED, APPROVAL_APPROVERS_MAY_RESOLVE_EMPTY, APPROVAL_APPROVER_CROSS_ORG_UNSUPPORTED, APPROVAL_APPROVER_NOT_MEMBERSHIP_TIER, APPROVAL_APPROVER_TYPE_DEPRECATED, APPROVAL_APPROVER_TYPE_UNKNOWN, APPROVAL_APPROVER_TYPE_UNSUPPORTED, APPROVAL_DECISION_OUTPUTS_RESERVED, APPROVAL_ESCALATION_REASSIGN_NO_TARGET, APPROVAL_EXPRESSION_INVALID, APPROVAL_EXPRESSION_NO_EMPTY_POLICY, AUTONUMBER_LITERAL_TOKEN, AUTONUMBER_OPTIONAL_FIELD, AUTONUMBER_SELF_REFERENCE, AUTONUMBER_UNKNOWN_FIELD, type ActionBodyWriteExclusion, type ActionBodyWriteFinding, type ActionBodyWriteSeverity, type ActionLocationsFinding, type ActionLocationsSeverity, type ActionNameRefFinding, type ActionNameRefSeverity, type AiAgentAuthoringFinding, type AiAgentAuthoringSeverity, type AiSurfaceAffinityFinding, type AiSurfaceAffinitySeverity, type AiToolRefFinding, type AiToolRefSeverity, type ApprovalApproverFinding, type ApprovalApproverSeverity, type AutonumberLintFinding, type BodyWritePatternExclusion, CAPABILITY_REFERENCE_UNKNOWN, CHART_AXIS_NOT_SELECTED, CHART_CONFIG_MISSING, CHART_DATASET_UNKNOWN, CHART_DIMENSION_UNKNOWN, CHART_FIELD_UNKNOWN, CHART_MEASURE_UNKNOWN, COMPONENT_PROPS_INVALID, COMPONENT_PROPS_UNKNOWN_KEY, type CapabilityRefFinding, type CapabilityRefSeverity, type ChartBindingFinding, type ChartBindingSeverity, type ComponentPropsFinding, type ComponentPropsSeverity, DASHBOARD_ACTION_ROUTE_UNRESOLVED, DASHBOARD_ACTION_TARGET_UNDEFINED, DASHBOARD_FILTER_FIELD_UNKNOWN, type DashboardActionRefFinding, type DashboardActionRefSeverity, type ExprIssue, type ExtractedHookBodyWrite, type ExtractedHookBodyWriteSet, FIELD_GROUP_EMPTY, FIELD_GROUP_SHADOWED, FIELD_GROUP_UNDECLARED, FILTER_TOKEN_UNKNOWN, FLOW_APPROVAL_REVISE_DEAD_END, FLOW_APPROVAL_REVISE_DISABLED, FLOW_APPROVAL_REVISE_TARGET_NOT_SERVICE_OWNED, FLOW_APPROVAL_REVISE_UNMARKED_BACKEDGE, FLOW_BARE_DOLLAR_REF, FLOW_BRANCH_LABEL_UNMATCHED, FLOW_DATE_EQUALITY_FILTER, FLOW_DECISION_UNCONDITIONAL_BRANCH, FLOW_DEFAULT_EDGE_WITH_CONDITION, FLOW_DOUBLE_BRACE_INTERP, FLOW_DRAFT_STATUS_AMBIGUOUS, FLOW_ERROR_LABEL_NOT_FAULT, FLOW_INERT_NODE_CONDITION, FLOW_MULTIPLE_DEFAULT_EDGES, FLOW_MULTI_WRITE_UNFILTERED, FLOW_NODE_WRITE_UNKNOWN_FIELD, FLOW_PHANTOM_AGGREGATION, FLOW_RUNAS_UNSCOPED, FLOW_TEMPLATE_LOOKUP_TRAVERSAL, FLOW_TEMPLATE_UNKNOWN_FIELD, FLOW_TIME_RELATIVE_ANTIPATTERN, FLOW_TIME_RELATIVE_DESCRIPTOR_INVALID, FLOW_TIME_RELATIVE_DESCRIPTOR_UNROUTABLE, FLOW_TRIGGER_UNKNOWN_EVENT, FLOW_TRIGGER_UNKNOWN_OBJECT, FLOW_UPDATE_READONLY_FIELD, FLOW_UPDATE_READONLY_WHEN_FIELD, FLOW_WRITE_NODE_TYPES, FLOW_WRITE_NODE_TYPES_DEFERRED, FORM_COLSPAN_ABSOLUTE, FORM_FIELD_UNKNOWN, type FilterTokenFinding, type FilterTokenSeverity, type FlowLintFinding, type FlowNodeWriteFinding, type FlowNodeWriteSeverity, type FlowTemplatePathFinding, type FlowTemplatePathSeverity, type FlowTriggerReadinessFinding, type FlowTriggerReadinessSeverity, type FlowWriteNodeDeferral, type FormLayoutFinding, type FormLayoutSeverity, type FunctionalCompletenessFinding, type FunctionalCompletenessSeverity, HOOK_BODY_WRITE_EXCLUSIONS, HOOK_BODY_WRITE_PATTERNS, HOOK_BODY_WRITE_PATTERN_IDS, HOOK_BODY_WRITE_UNKNOWN_FIELD, type HookBodyWriteFinding, type HookBodyWritePattern, type HookBodyWriteSeverity, type JsxPageFinding, type JsxPageSeverity, LIST_VIEW_FILTERS_IN_VIEWS_MODE, LIVENESS_DEAD_PROPERTY, LIVENESS_EXPERIMENTAL_PROPERTY, type LintIssue, type ListViewModeFinding, type ListViewModeSeverity, type LivenessLintFinding, MAX_SCHEMA_WALK_DEPTH, MEASURE_AGGREGATE_INCOHERENT, NAV_OBJECT_UNGRANTED, NAV_TARGET_UNRESOLVED, NULL_GUARD_HINT, type NavAccessFinding, type NavAccessSeverity, type NavTargetRefFinding, type NavTargetRefSeverity, type NullGuardFinding, type NullGuardOptions, OBJECT_REFERENCE_UNKNOWN, OBJECT_REFERENCE_UNREGISTERED_PLATFORM, ORG_AXIS_CROSS_ORG_BU_GRANT, ORG_AXIS_PERMISSION_INHERITANCE, type ObjectRefFinding, type ObjectRefSeverity, type OrgAxisFinding, type OrgAxisSeverity, PAGE_FIELD_UNKNOWN, PAGE_SOURCE_CLASSNAME, type PageFieldFinding, type PageFieldSeverity, REACT_BLOCK_NEEDS_RECORD_CONTEXT, REACT_CHART_AGGREGATE_INVALID, REACT_CHART_AXIS_UNKNOWN, REACT_CHART_DRILLDOWN_INVALID, REACT_CHART_FIELD_UNKNOWN, REFERENCE_INTEGRITY_RULES, RLS_PREDICATE_UNENFORCEABLE, RLS_PREDICATE_UNPARSEABLE, RUNTIME_AJV_OPTIONS, type ReactPageFinding, type ReactPageSeverity, type ReactPropFinding, type ReactPropSeverity, type ReadonlyFlowWriteFinding, type ReadonlyFlowWriteSeverity, type RecordTitleFinding, type RecordTitleSeverity, type ReferenceIntegrityFinding, type ReferenceIntegrityRule, type ReferenceIntegritySeverity, type RlsPredicateFinding, type RlsPredicateSeverity, type RuleCompilabilityFinding, type RuleCompilabilitySeverity, type RuleSchemaFormatFinding, type RuleSchemaFormatSeverity, SEARCHABLE_FIELD_UNKNOWN, SEARCHABLE_FIELD_UNSEARCHABLE, SECURITY_ANCHOR_HIGH_PRIVILEGE, SECURITY_BOOK_AUDIENCE_UNKNOWN_SET, SECURITY_DELEGATION_MISSING_REASON, SECURITY_EXTERNAL_WIDER, SECURITY_FLS_UNQUALIFIED_KEY, SECURITY_GRANT_EXPIRED_AT_AUTHORING, SECURITY_MASTER_DETAIL_UNGRANTED, SECURITY_OWD_ALIAS, SECURITY_OWD_UNSET, SECURITY_PRIVATE_NO_READSCOPE, SECURITY_ROLE_WORD, SECURITY_WILDCARD_VAMA, SEED_INSERT_MODE_DUPLICATES_ON_REPLAY, SEED_VALUE_OUTSIDE_STATE_MACHINE, SEMANTIC_ROLE_FIELD_UNKNOWN, SHARING_RULE_RUNTIME_VARIABLE_CONDITION, SHARING_RULE_UNLOWERABLE_CONDITION, STYLE_CLASSNAME_TAILWIND, STYLE_NODE_MISSING_ID, STYLE_RESPONSIVE_NO_BASE, STYLE_UNKNOWN_CSS_PROPERTY, STYLE_UNKNOWN_TOKEN, type SearchableFieldFinding, type SearchableFieldRole, type SearchableFieldSeverity, type SecurityFinding, type SecuritySeverity, type SeedReplaySafetyFinding, type SeedReplaySafetySeverity, type SeedStateMachineFinding, type SeedStateMachineSeverity, type SemanticRoleFinding, type SemanticRoleSeverity, type Severity, type SharingRuleEnforceabilityFinding, type SharingRuleEnforceabilitySeverity, type SourceStyleFinding, type SourceStyleSeverity, type StyleFinding, type StyleSeverity, TABLE_COUNT_ONLY, TITLE_FORMAT_RETIRED, TITLE_UNRESOLVABLE, TRANSLATION_OPTION_KEY_UNKNOWN, TRANSLATION_SECTION_NAME_MISSING, TRANSLATION_TARGET_UNKNOWN, type TranslatableSectionFinding, type TranslatableSectionSeverity, type TranslationRefFinding, type TranslationRefSeverity, UNIQUE_DOUBLE_DECLARATION, UNIQUE_LEGACY_ORGANIZATION_COMPOSITE, UNIQUE_UNSCOPED_DECLARED_INDEX, VALIDATION_RULE_REGEX_UNCOMPILABLE, VALIDATION_RULE_SCHEMA_UNCOMPILABLE, VALIDATION_RULE_SCHEMA_UNKNOWN_FORMAT, VIEW_CONTAINER_SHAPE, VIEW_KEY_COLLISION, VIEW_REF_FORM_TARGET_KIND, VIEW_REF_FORM_TARGET_MISSING, VISIBILITY_ALIAS_DEPRECATED, VISIBILITY_ROOT_MISLAYERED, type ViewContainerFinding, type ViewContainerSeverity, type ViewRefFinding, type VisibilityFinding, type VisibilityLayer, type VisibilityOptions, type VisibilitySeverity, WIDGET_DATASET_UNKNOWN, WIDGET_DIMENSION_UNKNOWN, WIDGET_LEGACY_ANALYTICS_SHAPE, WIDGET_LEGACY_ANALYTICS_UNRENDERABLE, WIDGET_MEASURE_UNKNOWN, type WalkedComponent, type WalkedValidationRule, type WidgetBindingFinding, type WidgetBindingSeverity, buildAccessMatrix, diffAccessMatrix, extractHookBodyWriteSet, extractHookBodyWrites, findUnguardedNullableOperands, isSourceAuthoredPage, lintAutonumberFormats, lintDataModel, lintFlowPatterns, lintLegacyOrganizationComposites, lintLivenessProperties, lintUniqueDeclarations, lintUnscopedDeclaredIndexes, lintViewRefs, nearestRegisteredFormat, nullGuardMessage, validateActionBodyWrites, validateActionLocations, validateActionNameRefs, validateAiAgentAuthoring, validateAiSurfaceAffinity, validateAiToolReferences, validateApprovalApprovers, validateCapabilityReferences, validateChartBindings, validateComponentProps, validateDashboardActionRefs, validateFilterTokens, validateFlowNodeWrites, validateFlowTemplatePaths, validateFlowTriggerReadiness, validateFormLayout, validateFunctionalCompleteness, validateHookBodyWrites, validateJsxPages, validateListViewMode, validateNavAccess, validateNavTargetRefs, validateObjectReferences, validateOrgAxisRedLines, validatePageFieldBindings, validatePageSourceStyling, validateReactPageProps, validateReactPages, validateReadonlyFlowWrites, validateRecordTitle, validateReferenceIntegrity, validateResponsiveStyles, validateRlsPredicateEnforceability, validateRuleCompilability, validateRuleSchemaFormats, validateSearchableFields, validateSecurityPosture, validateSeedReplaySafety, validateSeedStateMachine, validateSemanticRoles, validateSharingRuleEnforceability, validateStackExpressions, validateTranslatableSections, validateTranslationReferences, validateViewContainers, validateVisibilityPredicates, validateWidgetBindings, walkPageComponents };
|