@object-ui/core 16.0.0 → 17.1.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 (56) hide show
  1. package/CHANGELOG.md +1589 -1
  2. package/dist/actions/ActionRunner.d.ts +88 -16
  3. package/dist/actions/ActionRunner.js +164 -81
  4. package/dist/actions/actionKeys.d.ts +118 -0
  5. package/dist/actions/actionKeys.js +243 -0
  6. package/dist/actions/index.d.ts +1 -0
  7. package/dist/actions/index.js +1 -0
  8. package/dist/adapters/ApiDataSource.d.ts +11 -1
  9. package/dist/adapters/ApiDataSource.js +21 -1
  10. package/dist/adapters/ValueDataSource.d.ts +10 -2
  11. package/dist/adapters/ValueDataSource.js +9 -0
  12. package/dist/adapters/batchTransaction.d.ts +49 -0
  13. package/dist/adapters/batchTransaction.js +118 -0
  14. package/dist/adapters/index.d.ts +1 -0
  15. package/dist/adapters/index.js +1 -0
  16. package/dist/evaluator/ExpressionEvaluator.d.ts +10 -0
  17. package/dist/evaluator/ExpressionEvaluator.js +48 -0
  18. package/dist/evaluator/SafeExpressionParser.js +5 -2
  19. package/dist/evaluator/fieldRules.d.ts +0 -2
  20. package/dist/evaluator/fieldRules.js +3 -2
  21. package/dist/evaluator/optionLint.js +5 -2
  22. package/dist/evaluator/optionRules.d.ts +35 -6
  23. package/dist/evaluator/optionRules.js +18 -23
  24. package/dist/index.d.ts +5 -0
  25. package/dist/index.js +8 -0
  26. package/dist/registry/Registry.d.ts +81 -2
  27. package/dist/registry/Registry.js +102 -2
  28. package/dist/registry/public-blocks.js +52 -1
  29. package/dist/theme/ThemeEngine.js +0 -12
  30. package/dist/utils/chart-series.d.ts +28 -0
  31. package/dist/utils/chart-series.js +55 -0
  32. package/dist/utils/column-identity.d.ts +110 -0
  33. package/dist/utils/column-identity.js +210 -0
  34. package/dist/utils/dashboard-filters.d.ts +2 -2
  35. package/dist/utils/dataset-format.d.ts +18 -1
  36. package/dist/utils/dataset-format.js +14 -1
  37. package/dist/utils/expand-fields.js +8 -8
  38. package/dist/utils/export-filename.js +4 -1
  39. package/dist/utils/filter-converter.d.ts +47 -0
  40. package/dist/utils/filter-converter.js +94 -7
  41. package/dist/utils/filter-tokens.d.ts +101 -0
  42. package/dist/utils/filter-tokens.js +173 -0
  43. package/dist/utils/managedBy.d.ts +119 -0
  44. package/dist/utils/managedBy.js +147 -0
  45. package/dist/utils/normalize-list-view.d.ts +99 -0
  46. package/dist/utils/normalize-list-view.js +255 -0
  47. package/dist/utils/record-title.js +0 -0
  48. package/dist/utils/sort-values.d.ts +52 -0
  49. package/dist/utils/sort-values.js +125 -0
  50. package/dist/validation/index.d.ts +9 -1
  51. package/dist/validation/index.js +9 -1
  52. package/dist/validation/validators/index.d.ts +7 -1
  53. package/dist/validation/validators/index.js +7 -1
  54. package/dist/validation/validators/object-validation-engine.d.ts +151 -31
  55. package/dist/validation/validators/object-validation-engine.js +275 -142
  56. package/package.json +4 -4
@@ -6,23 +6,92 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  /**
9
- * @object-ui/core - Object-Level Validation Engine
10
- *
11
- * ObjectStack Spec v2.0.1 compliant validation engine for object-level validation rules.
12
- * Supports all 9 validation types from the specification:
13
- * - ScriptValidation
14
- * - UniquenessValidation
15
- * - StateMachineValidation
16
- * - CrossFieldValidation
17
- * - AsyncValidation
18
- * - ConditionalValidation
19
- * - FormatValidation
20
- * - RangeValidation
9
+ * @object-ui/core - Object-Level Validation Engine — **DEPRECATED** (#3110)
10
+ *
11
+ * A client-side pre-check of the rules an object declares in
12
+ * `ObjectSchema.validations`. The authority is the server
13
+ * (`objectql/src/validation/rule-validator.ts`), which evaluates the same rules
14
+ * on the write path.
15
+ *
16
+ * ## Why this is deprecated rather than finished
17
+ *
18
+ * Validation rules are ENFORCEMENT, and enforcement is single-implementation on
19
+ * the server by design. `evaluator/fieldRules.ts` draws that line explicitly:
20
+ * PRESENTATION predicates (`visibleWhen` / `readonlyWhen` / `requiredWhen`) are
21
+ * evaluated client-side by delegating to the canonical `ExpressionEngine`,
22
+ * "rather than re-implementing a parallel evaluator" (ADR-0036). This module is
23
+ * that parallel evaluator, on the enforcement side of the line.
24
+ *
25
+ * #3103 converged its semantics onto the server rule-for-rule, with eight
26
+ * mutation-tested gates — and it STILL left a known divergence: the server
27
+ * carries ADR-0113's legacy-violation exemption (reject only when the merged
28
+ * state violates AND this write makes it worse, so a pre-existing violation on
29
+ * an old row passes), and this engine does not. Editing an unrelated field on a
30
+ * legacy row would be blocked here and accepted there. That is the argument in
31
+ * one line: mirroring cross-repo behaviour is structurally unreliable, not
32
+ * unreliable-this-time.
33
+ *
34
+ * ## What to use instead
35
+ *
36
+ * Let the write fail and render the server's rejection — it is already
37
+ * structured (`field` / `code` / `message`, plus a label since objectstack#3957).
38
+ * If pre-submit feedback is wanted, the answer is a **validate-only (dry-run)
39
+ * write** on the server: identical UX, zero parity risk, and it also covers the
40
+ * two rule kinds a client can never check — `unique` (needs the database) and
41
+ * `json_schema` (ajv lives server-side).
42
+ *
43
+ * Nothing here has been removed or changed in behaviour; existing callers keep
44
+ * working. `validation-engine-stays-unwired.test.ts` fails if a production
45
+ * module starts importing this one, so the decision is a mechanism rather than
46
+ * this comment (#3017).
47
+ *
48
+ * ## When to revisit
49
+ *
50
+ * Offline writes (`OfflineConfig`). With no server to ask, a client evaluator
51
+ * stops being redundant and becomes necessary. The precondition then is
52
+ * conformance fixtures shipped by `@objectstack/spec` — golden
53
+ * (rule, record, verdict) triples both repos run in CI — because that is the
54
+ * only thing that turns cross-repo parity into a mechanism instead of a habit.
55
+ * Reverse the decision in #3110 before reversing it here.
56
+ *
57
+ * ## Semantics (unchanged, for as long as this exists)
58
+ *
59
+ * The rule types come from `@object-ui/types`, which derives them from
60
+ * `@objectstack/spec/data` (objectstack#4115). Semantics mirrored from the
61
+ * server:
62
+ *
63
+ * - **Polarity.** A `script` / `cross_field` `condition` and a `conditional`
64
+ * `when` express the FAILURE condition: predicate TRUE ⇒ rule VIOLATED.
65
+ * - **Fail-open on broken, fail-closed on violated.** A predicate that cannot
66
+ * be evaluated (parse error, unknown identifier, unusable expression
67
+ * envelope) is a broken rule, not a violated one — it is skipped, not
68
+ * reported. Likewise a malformed `regex`.
69
+ * - **Spec defaults, not falsy reads.** `active` defaults to `true` and
70
+ * `events` to `['insert','update']` — they arrive absent from `/meta`
71
+ * because the spec applies those defaults at parse time. Reading an absent
72
+ * `active` as "off" would silently disable every rule authored without it.
73
+ * - **`priority` orders execution** (lower first, stable).
74
+ * - **`format` and `state_machine` only fire when the write TOUCHES the
75
+ * field**, matching the server; emptiness and requiredness belong to the
76
+ * field-shape validator.
77
+ *
78
+ * Two documented divergences from the server, both in the safe direction:
79
+ *
80
+ * 1. The default evaluator is a small non-CEL parser (see
81
+ * `SimpleExpressionEvaluator`), so a predicate using real CEL constructs
82
+ * evaluates to nothing and fails open. Pass a CEL-backed
83
+ * `ValidationExpressionEvaluator` to close that gap.
84
+ * 2. `unique` / `async` / `range` rules are still dispatched. They are
85
+ * @deprecated objectui-local variants that the spec's `ValidationRuleSchema`
86
+ * rejects outright, so they cannot arrive from `/meta` — only a caller
87
+ * building rules by hand can produce one.
21
88
  *
22
89
  * @module object-validation-engine
23
90
  * @packageDocumentation
24
91
  */
25
92
  import type { ObjectValidationRule } from '@object-ui/types';
93
+ /** Write contexts a rule can run on. The spec retired `delete` (objectstack#3184). */
94
+ export type ObjectValidationEvent = 'insert' | 'update';
26
95
  /**
27
96
  * Validation context for object-level validations
28
97
  */
@@ -56,63 +125,114 @@ export interface ValidationExpressionEvaluator {
56
125
  evaluate(expression: string, context: Record<string, any>): any;
57
126
  }
58
127
  /**
59
- * Object-Level Validation Engine
60
- * Implements ObjectStack Spec v2.0.1 validation framework
128
+ * Object-Level Validation Engine — the client pre-check described at the top of
129
+ * this module.
130
+ *
131
+ * @deprecated (#3110) Validation rules are enforcement, and enforcement is
132
+ * single-implementation on the server (`objectql`'s rule-validator). Render the
133
+ * server's rejection instead; for pre-submit feedback, use a validate-only
134
+ * (dry-run) write. Still functional and still correct as of #3103 — but it
135
+ * cannot stay in step with the server without a conformance-fixture mechanism
136
+ * that does not exist yet. See the module header.
61
137
  */
62
138
  export declare class ObjectValidationEngine {
63
139
  private expressionEvaluator;
64
140
  private uniquenessChecker?;
65
141
  constructor(expressionEvaluator?: ValidationExpressionEvaluator, uniquenessChecker?: (fields: string[], values: Record<string, any>, scope?: string, context?: ObjectValidationContext) => Promise<boolean>);
66
142
  /**
67
- * Validate a record against a set of validation rules
143
+ * Validate a record against a set of validation rules.
144
+ *
145
+ * Rules run in `priority` order (lower first, stable within a priority), and
146
+ * only when `active` is not explicitly `false` and `events` covers this write
147
+ * context — reading the spec's defaults, not the falsiness of an absent key.
68
148
  */
69
- validateRecord(rules: ObjectValidationRule[], context: ObjectValidationContext, event?: 'insert' | 'update' | 'delete'): Promise<ObjectValidationResult[]>;
149
+ validateRecord(rules: ObjectValidationRule[], context: ObjectValidationContext, event?: ObjectValidationEvent): Promise<ObjectValidationResult[]>;
70
150
  /**
71
- * Validate a single rule
151
+ * Validate a single rule.
152
+ *
153
+ * `rule` is widened past `ObjectValidationRule` because a `conditional`'s
154
+ * `then` / `otherwise` branch may be any rule the SPEC's union admits —
155
+ * including `json_schema`, which this engine does not implement.
72
156
  */
73
157
  private validateRule;
74
158
  /**
75
- * Validate script-based rule
159
+ * The evaluation scope for a predicate.
160
+ *
161
+ * The server binds `{ record, previous }`, so a spec-authored predicate reads
162
+ * `record.amount`. objectui's own rules have always been written against the
163
+ * bare field name (`amount`). Both are bound — the roots last so a field
164
+ * literally called `record` cannot shadow them.
76
165
  */
77
- private validateScript;
166
+ private scopeFor;
167
+ /**
168
+ * Evaluate a `script` / `cross_field` predicate.
169
+ *
170
+ * Both variants share one path on the server, and so do they here. The
171
+ * predicate is the FAILURE condition: TRUE means the rule is violated. A
172
+ * predicate that cannot be evaluated is a BROKEN rule and fails open.
173
+ */
174
+ private validatePredicate;
78
175
  /**
79
176
  * Validate uniqueness constraint
80
177
  */
81
178
  private validateUniqueness;
82
179
  /**
83
- * Validate state machine transitions
180
+ * Validate state machine transitions (ADR-0020).
181
+ *
182
+ * A flat `field` plus a `{ from: [allowedTo] }` map. Semantics mirror the
183
+ * server-side rule-validator:
184
+ *
185
+ * INSERT
186
+ * - no `initialStates` declared → allow (legacy no-op)
187
+ * - field absent from the write → allow (requiredness is not our job)
188
+ * - value empty → allow (ditto)
189
+ * - value ∉ initialStates → reject (the FSM entry point, #3165)
190
+ *
191
+ * UPDATE
192
+ * - field absent from the write → allow (no transition to police)
193
+ * - no prior record → allow (cannot reason)
194
+ * - field unchanged, or cleared → allow (no transition)
195
+ * - `from` not declared in the map → lenient allow (unconstrained)
196
+ * - `to` ∉ transitions[from] → reject
84
197
  */
85
198
  private validateStateMachine;
86
- /**
87
- * Validate cross-field constraints
88
- */
89
- private validateCrossField;
90
199
  /**
91
200
  * Validate async/remote validation
92
201
  */
93
202
  private validateAsync;
94
203
  /**
95
- * Validate conditional rules
204
+ * Validate a conditional rule.
205
+ *
206
+ * Evaluates `when`, then recurses into `then` (TRUE) or `otherwise` (FALSE).
207
+ * The nested rule supplies the violation; an un-evaluable `when` is a broken
208
+ * rule and fails open. A branch whose own `active` is explicitly `false` is
209
+ * skipped, matching the server.
96
210
  */
97
211
  private validateConditional;
98
212
  /**
99
- * Validate format/pattern
213
+ * Validate a field's format against `regex` and/or a named `format`.
214
+ *
215
+ * Mirrors the server: the rule only fires when the write TOUCHES the field and
216
+ * the value is non-empty (requiredness and type-shape belong to the
217
+ * field-level validator, so an absent or blank value is not a format
218
+ * violation). Both checks apply when both are declared. A `regex` that will
219
+ * not compile is a BROKEN rule — logged and skipped, never a violation.
100
220
  */
101
221
  private validateFormat;
102
222
  /**
103
223
  * Validate range constraints
104
224
  */
105
225
  private validateRange;
106
- /**
107
- * Get predefined regex pattern
108
- */
109
- private getPredefinedPattern;
110
226
  }
111
227
  /**
112
228
  * Default instance
229
+ *
230
+ * @deprecated (#3110) See `ObjectValidationEngine`.
113
231
  */
114
232
  export declare const defaultObjectValidationEngine: ObjectValidationEngine;
115
233
  /**
116
234
  * Convenience function to validate a record
235
+ *
236
+ * @deprecated (#3110) See `ObjectValidationEngine`.
117
237
  */
118
- export declare function validateRecord(rules: ObjectValidationRule[], context: ObjectValidationContext, event?: 'insert' | 'update' | 'delete'): Promise<ObjectValidationResult[]>;
238
+ export declare function validateRecord(rules: ObjectValidationRule[], context: ObjectValidationContext, event?: ObjectValidationEvent): Promise<ObjectValidationResult[]>;