@object-ui/core 17.5.0 → 17.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7404 -0
- package/README.md +127 -26
- package/dist/actions/ActionEngine.d.ts +5 -3
- package/dist/actions/ActionEngine.js +14 -10
- package/dist/actions/ActionRunner.d.ts +363 -30
- package/dist/actions/ActionRunner.js +544 -58
- package/dist/actions/TransactionManager.d.ts +7 -2
- package/dist/actions/actionKeys.d.ts +75 -13
- package/dist/actions/actionKeys.js +131 -16
- package/dist/actions/actionResponse.js +3 -3
- package/dist/actions/index.d.ts +2 -0
- package/dist/actions/index.js +2 -0
- package/dist/actions/recordDelete.d.ts +118 -0
- package/dist/actions/recordDelete.js +112 -0
- package/dist/actions/recordIdParam.d.ts +77 -0
- package/dist/actions/recordIdParam.js +37 -0
- package/dist/actions/serverActionHandler.d.ts +1 -1
- package/dist/actions/serverActionHandler.js +1 -1
- package/dist/adapters/ValueDataSource.d.ts +6 -1
- package/dist/adapters/ValueDataSource.js +1090 -98
- package/dist/adapters/batchTransaction.d.ts +1 -1
- package/dist/adapters/batchTransaction.js +1 -1
- package/dist/builder/schema-builder.d.ts +38 -81
- package/dist/builder/schema-builder.js +33 -152
- package/dist/data-scope/ViewDataProvider.d.ts +1 -1
- package/dist/data-scope/ViewDataProvider.js +21 -1
- package/dist/data-scope/element-data-source.d.ts +261 -7
- package/dist/data-scope/element-data-source.js +342 -52
- package/dist/data-scope/index.d.ts +9 -4
- package/dist/data-scope/index.js +9 -4
- package/dist/evaluator/ExpressionEvaluator.d.ts +128 -1
- package/dist/evaluator/ExpressionEvaluator.js +226 -13
- package/dist/evaluator/FormulaFunctions.d.ts +0 -10
- package/dist/evaluator/FormulaFunctions.js +166 -27
- package/dist/evaluator/SafeExpressionParser.js +0 -4
- package/dist/evaluator/declaredPredicate.d.ts +93 -9
- package/dist/evaluator/declaredPredicate.js +118 -17
- package/dist/evaluator/fieldRules.d.ts +107 -4
- package/dist/evaluator/fieldRules.js +231 -35
- package/dist/evaluator/index.d.ts +2 -0
- package/dist/evaluator/index.js +2 -0
- package/dist/evaluator/listConditional.d.ts +125 -9
- package/dist/evaluator/listConditional.js +167 -26
- package/dist/evaluator/optionRules.d.ts +126 -0
- package/dist/evaluator/optionRules.js +141 -4
- package/dist/evaluator/predicateInput.d.ts +15 -4
- package/dist/evaluator/predicateInput.js +35 -2
- package/dist/evaluator/rowPredicateCanon.d.ts +56 -0
- package/dist/evaluator/rowPredicateCanon.js +158 -0
- package/dist/evaluator/subjectPermissions.d.ts +76 -0
- package/dist/evaluator/subjectPermissions.js +44 -0
- package/dist/evaluator/unevaluablePredicate.d.ts +57 -0
- package/dist/evaluator/unevaluablePredicate.js +70 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +97 -2
- package/dist/protocols/index.d.ts +0 -1
- package/dist/protocols/index.js +9 -1
- package/dist/registry/Registry.d.ts +397 -48
- package/dist/registry/Registry.js +263 -11
- package/dist/registry/WidgetRegistry.js +7 -3
- package/dist/registry/html-tier-intrinsics.d.ts +90 -0
- package/dist/registry/html-tier-intrinsics.js +110 -0
- package/dist/registry/public-blocks.d.ts +8 -0
- package/dist/registry/public-blocks.js +57 -0
- package/dist/theme/ThemeEngine.js +1 -1
- package/dist/theme/index.d.ts +1 -1
- package/dist/theme/index.js +1 -1
- package/dist/types/index.d.ts +92 -13
- package/dist/utils/chart-category-key.d.ts +82 -0
- package/dist/utils/chart-category-key.js +84 -0
- package/dist/utils/chart-measure-key.d.ts +64 -0
- package/dist/utils/chart-measure-key.js +65 -0
- package/dist/utils/chart-presentation.d.ts +188 -0
- package/dist/utils/chart-presentation.js +345 -0
- package/dist/utils/chart-series.d.ts +271 -31
- package/dist/utils/chart-series.js +478 -55
- package/dist/utils/column-identity.d.ts +43 -0
- package/dist/utils/column-identity.js +47 -1
- package/dist/utils/column-sortability.d.ts +157 -0
- package/dist/utils/column-sortability.js +217 -0
- package/dist/utils/dashboard-filters.d.ts +38 -6
- package/dist/utils/dashboard-filters.js +107 -61
- package/dist/utils/dataset-format.d.ts +211 -30
- package/dist/utils/dataset-format.js +407 -52
- package/dist/utils/date-display.d.ts +354 -0
- package/dist/utils/date-display.js +463 -0
- package/dist/utils/date-macros.js +7 -0
- package/dist/utils/debug.js +7 -0
- package/dist/utils/drill-down.d.ts +78 -0
- package/dist/utils/drill-down.js +93 -0
- package/dist/utils/emptiness.d.ts +96 -0
- package/dist/utils/emptiness.js +101 -0
- package/dist/utils/expand-fields.d.ts +171 -11
- package/dist/utils/expand-fields.js +171 -11
- package/dist/utils/extract-records.d.ts +65 -5
- package/dist/utils/extract-records.js +65 -8
- package/dist/utils/filter-converter.d.ts +152 -4
- package/dist/utils/filter-converter.js +1092 -22
- package/dist/utils/filter-tokens.d.ts +49 -5
- package/dist/utils/filter-tokens.js +105 -34
- package/dist/utils/freeze-schema.d.ts +38 -1
- package/dist/utils/freeze-schema.js +10 -0
- package/dist/utils/grouping-fields.d.ts +61 -0
- package/dist/utils/grouping-fields.js +84 -0
- package/dist/utils/humanize-label.d.ts +60 -0
- package/dist/utils/humanize-label.js +62 -0
- package/dist/utils/managedBy.d.ts +30 -5
- package/dist/utils/managedBy.js +5 -5
- package/dist/utils/native-date-value.d.ts +48 -0
- package/dist/utils/native-date-value.js +167 -0
- package/dist/utils/non-grid-row-ceiling.d.ts +143 -0
- package/dist/utils/non-grid-row-ceiling.js +141 -0
- package/dist/utils/normalize-list-view.d.ts +131 -1
- package/dist/utils/normalize-list-view.js +248 -6
- package/dist/utils/number-display.d.ts +70 -17
- package/dist/utils/number-display.js +34 -12
- package/dist/utils/object-aggregate-query.d.ts +113 -0
- package/dist/utils/object-aggregate-query.js +50 -0
- package/dist/utils/parent-scope.d.ts +123 -0
- package/dist/utils/parent-scope.js +140 -0
- package/dist/utils/predicate-fields.d.ts +62 -4
- package/dist/utils/predicate-fields.js +169 -4
- package/dist/utils/record-color.d.ts +75 -0
- package/dist/utils/record-color.js +65 -0
- package/dist/utils/record-source.d.ts +298 -0
- package/dist/utils/record-source.js +331 -0
- package/dist/utils/record-title.d.ts +148 -8
- package/dist/utils/record-title.js +220 -26
- package/dist/utils/reference-keys.d.ts +21 -22
- package/dist/utils/reference-keys.js +532 -29
- package/dist/utils/retired-field-types.d.ts +90 -0
- package/dist/utils/retired-field-types.js +124 -0
- package/dist/utils/sort-query.d.ts +128 -26
- package/dist/utils/sort-query.js +240 -13
- package/dist/utils/text-comparand.d.ts +92 -0
- package/dist/utils/text-comparand.js +99 -0
- package/dist/utils/unmaterialized-fields.d.ts +52 -0
- package/dist/utils/unmaterialized-fields.js +57 -0
- package/dist/utils/without-denied-fields.d.ts +49 -0
- package/dist/utils/without-denied-fields.js +52 -0
- package/dist/validation/index.d.ts +9 -4
- package/dist/validation/index.js +9 -4
- package/dist/validation/schema-validator.d.ts +1 -1
- package/dist/validation/schema-validator.js +305 -82
- package/dist/validation/server-owned-value.d.ts +62 -0
- package/dist/validation/server-owned-value.js +99 -0
- package/dist/validation/validators/object-validation-engine.d.ts +1 -1
- package/dist/validation/validators/object-validation-engine.js +14 -5
- package/package.json +8 -9
- package/dist/__benchmarks__/core.bench.d.ts +0 -8
- package/dist/__benchmarks__/core.bench.js +0 -53
- package/dist/data-scope/DataScopeManager.d.ts +0 -127
- package/dist/data-scope/DataScopeManager.js +0 -229
- package/dist/protocols/ResponsiveProtocol.d.ts +0 -73
- package/dist/protocols/ResponsiveProtocol.js +0 -158
- package/dist/validation/validation-engine.d.ts +0 -88
- package/dist/validation/validation-engine.js +0 -434
|
@@ -21,6 +21,14 @@
|
|
|
21
21
|
*
|
|
22
22
|
* This is a single, reviewable source of truth for the public surface — prefer
|
|
23
23
|
* editing this list over scattering `tier` flags across registration sites.
|
|
24
|
+
*
|
|
25
|
+
* ⛔ The html tier's intrinsic elements (`h1`, `p`, `a`, the sectioning tags, …)
|
|
26
|
+
* do NOT belong here. They reach the published manifest through the second
|
|
27
|
+
* roster beside this one, `HTML_TIER_INTRINSICS`, stamped `tier: 'html'`, so
|
|
28
|
+
* that the manifest's other reader — the objectstack gate that whitelists a
|
|
29
|
+
* `kind:'html'` page's tags — accepts them without this curated JSON-surface
|
|
30
|
+
* vocabulary growing (objectui#10735). Listing one here would widen the
|
|
31
|
+
* vocabulary silently; `html-tier-intrinsics.test.ts` pins the two disjoint.
|
|
24
32
|
*/
|
|
25
33
|
export const PUBLIC_BLOCKS = [
|
|
26
34
|
// ── Tier A — object-aware blocks (the contract core) ──────────────────────
|
|
@@ -34,6 +42,23 @@ export const PUBLIC_BLOCKS = [
|
|
|
34
42
|
'object-gantt',
|
|
35
43
|
'object-timeline',
|
|
36
44
|
'object-map',
|
|
45
|
+
// Curated by objectui#10064, which is a NARROWING being undone rather than a
|
|
46
|
+
// widening: `@objectstack/spec` already declares `object-tree` on
|
|
47
|
+
// `ComponentPropsMap`, and @object-ui/plugin-tree has registered the renderer
|
|
48
|
+
// all along — this roster was the one face that withheld it, so the tier sat
|
|
49
|
+
// narrower than the declaration. Everything downstream reported that
|
|
50
|
+
// faithfully and could not fix it: `getPublicConfigs()` is what both manifest
|
|
51
|
+
// producers serialize, so the framework's tracked `sdui.manifest.json` could
|
|
52
|
+
// never carry a block the contract says exists, and moving the objectui pin
|
|
53
|
+
// could not help while the pinned source had nothing to carry
|
|
54
|
+
// (objectstack#18407, whose parity-gate half waits on this entry).
|
|
55
|
+
//
|
|
56
|
+
// The `tree` alias the same module registers is deliberately NOT here: it is
|
|
57
|
+
// a second spelling of this one block and @objectstack/spec declares no such
|
|
58
|
+
// key, so curating it would widen the vocabulary past the declaration — the
|
|
59
|
+
// opposite act — and leave an authoring model two names for one block, which
|
|
60
|
+
// is the ground `record:chatter` is held out on above.
|
|
61
|
+
'object-tree',
|
|
37
62
|
'object-metric',
|
|
38
63
|
'object-chart',
|
|
39
64
|
'dashboard',
|
|
@@ -102,6 +127,38 @@ export const PUBLIC_BLOCKS = [
|
|
|
102
127
|
'tabs',
|
|
103
128
|
'accordion',
|
|
104
129
|
'container',
|
|
130
|
+
// The neutral block container, minted by the 2026-08-29 ruling as the JSON
|
|
131
|
+
// surface's replacement for the deprecated `div` (objectui#3965, PR #6878).
|
|
132
|
+
// It landed on every other declaration face — interface, zod mirror,
|
|
133
|
+
// `SchemaRegistry`, registration, docs page, and 27 catalog fixtures — and
|
|
134
|
+
// this list was the one face it missed, so the vocabulary taught a type the
|
|
135
|
+
// contract did not carry (`3619792bf`).
|
|
136
|
+
//
|
|
137
|
+
// MEASURED before it was added, because "add it and see" is how a gate
|
|
138
|
+
// discovers a new population at merge time. `registry-inputs-spec-parity`
|
|
139
|
+
// (apps/console) does NOT judge it, and not by tolerance: its coverage set is
|
|
140
|
+
// SPEC-shaped — `Object.keys(ComponentPropsMap)`, filtered to what this repo
|
|
141
|
+
// registers with inputs. It never reads this list, and membership here is
|
|
142
|
+
// neither necessary nor sufficient for being judged: `element:record_picker`
|
|
143
|
+
// is judged while absent from this list, and `flex` / `grid` / `stack` /
|
|
144
|
+
// `card` / `container` are all listed here and all unjudged, because
|
|
145
|
+
// `@objectstack/spec@17` carries no entry for ANY Tier B layout primitive. So
|
|
146
|
+
// `box` joins a spec-less population five types deep rather than opening a
|
|
147
|
+
// new one; it needs no spec entry, and no gate needed loosening to accept it.
|
|
148
|
+
//
|
|
149
|
+
// ⚠️ And "not on this list" never meant "not on an authoring surface". `box`
|
|
150
|
+
// has been validated all along through the OTHER consumer of the same
|
|
151
|
+
// `inputs`: `components/src/renderers/layout/page.tsx` builds the JSX-page
|
|
152
|
+
// compiler's manifest from `getKnownTypes()`, registry-wide. What this list
|
|
153
|
+
// gates is `getPublicConfigs()` — the curated AI-authoring vocabulary, and
|
|
154
|
+
// through `sdui-parser/scripts/gen-manifest.ts` the published
|
|
155
|
+
// `sdui.manifest.json` and `sdui-intrinsics.d.ts`. THAT is the surface `box`
|
|
156
|
+
// was missing from, which is a narrower and truer statement of the gap than
|
|
157
|
+
// "the contract does not know it".
|
|
158
|
+
//
|
|
159
|
+
// The measurement is pinned next to the roster census in `apps/console`, over
|
|
160
|
+
// the DERIVED container population rather than over this list.
|
|
161
|
+
'box',
|
|
105
162
|
'page:header',
|
|
106
163
|
'text',
|
|
107
164
|
'image',
|
|
@@ -124,7 +124,7 @@ export function generateColorVars(colors) {
|
|
|
124
124
|
// (`fontSize` / `fontWeight` / `lineHeight` / `letterSpacing`, plus
|
|
125
125
|
// `fontFamily.heading` / `fontFamily.mono`) became TOMBSTONES: the schema now
|
|
126
126
|
// rejects them by name and their prescription points at `theme.customVars`, the
|
|
127
|
-
// declared — and since #5021 the only — door for a custom property. A
|
|
127
|
+
// declared — and since objectstack-ai/objectstack#5021 the only — door for a custom property. A
|
|
128
128
|
// `--z-modal` or a `--duration-fast` is authored there now, emitted verbatim as
|
|
129
129
|
// `--<key>: <value>`.
|
|
130
130
|
//
|
package/dist/theme/index.d.ts
CHANGED
|
@@ -5,4 +5,4 @@
|
|
|
5
5
|
* This source code is licensed under the MIT license found in the
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
|
-
export { hexToHSL, toCSSColor, generateColorVars, generateTypographyVars, generateBorderRadiusVars, generateShadowVars, generateThemeVars, mergeThemes, resolveThemeInheritance, resolveMode, contrastRatio, meetsContrastLevel, } from './ThemeEngine';
|
|
8
|
+
export { hexToHSL, toCSSColor, generateColorVars, generateTypographyVars, generateBorderRadiusVars, generateShadowVars, generateThemeVars, mergeThemes, resolveThemeInheritance, resolveMode, contrastRatio, meetsContrastLevel, } from './ThemeEngine.js';
|
package/dist/theme/index.js
CHANGED
|
@@ -11,4 +11,4 @@ export { hexToHSL, toCSSColor, generateColorVars, generateTypographyVars, genera
|
|
|
11
11
|
// 17.0.0-rc.3 (objectstack#5021) — see ThemeEngine's RETIRED THEME BLOCKS
|
|
12
12
|
// note. `theme.customVars` is the declared door for a `--duration-*` or
|
|
13
13
|
// `--z-*` now.
|
|
14
|
-
generateThemeVars, mergeThemes, resolveThemeInheritance, resolveMode, contrastRatio, meetsContrastLevel, } from './ThemeEngine';
|
|
14
|
+
generateThemeVars, mergeThemes, resolveThemeInheritance, resolveMode, contrastRatio, meetsContrastLevel, } from './ThemeEngine.js';
|
package/dist/types/index.d.ts
CHANGED
|
@@ -30,24 +30,103 @@
|
|
|
30
30
|
* rather than restated, so there is exactly one declaration left to disagree
|
|
31
31
|
* with — a structural copy would reproduce the defect the moment either side
|
|
32
32
|
* moved. This package already depends on `@object-ui/types`, so the edge exists
|
|
33
|
-
* and adds no cycle
|
|
34
|
-
*
|
|
33
|
+
* and adds no cycle.
|
|
34
|
+
*
|
|
35
|
+
* ## The entry-surface sentence that used to close this block is WITHDRAWN
|
|
36
|
+
*
|
|
37
|
+
* It read: *core's own entry surface is unchanged (`dist/index.d.ts` is
|
|
38
|
+
* byte-identical across the change — measured, both rounds)*. The reading was
|
|
39
|
+
* real, and it certified nothing (objectui#5673).
|
|
40
|
+
*
|
|
41
|
+
* `core/dist/index.d.ts` is emitted from a barrel that only FORWARDS this
|
|
42
|
+
* symbol, and forwarding never restates a shape — not `export *`, and not the
|
|
43
|
+
* `export type { SchemaNode, … } from './types/index.js'` line that names it.
|
|
44
|
+
* Only the module that DECLARES the symbol can move. So that file is
|
|
45
|
+
* byte-identical under any change to a re-exported declaration's shape, naming
|
|
46
|
+
* the symbol or not, and a gauge that cannot fail for the change class it is
|
|
47
|
+
* quoted against has discharged nothing.
|
|
48
|
+
*
|
|
49
|
+
* ## The gauge that can fail — and how to prove it can, before believing it
|
|
50
|
+
*
|
|
51
|
+
* 1. Watch the emitted `.d.ts` of the module that DECLARES the symbol. For
|
|
52
|
+
* `SchemaNode` that is `@object-ui/types`' `dist/base.d.ts`, in another
|
|
53
|
+
* package — not core's entry, and not core's own `dist/types/index.d.ts`
|
|
54
|
+
* either, which forwards exactly as the entry does. For the shape claim
|
|
55
|
+
* itself, resolve the symbol through the TypeScript CHECKER from
|
|
56
|
+
* `core/dist/index.d.ts`.
|
|
57
|
+
* 2. Build both legs from a cleared `dist/` AND a cleared
|
|
58
|
+
* `tsconfig.tsbuildinfo` — the build info lives outside `dist/`, so
|
|
59
|
+
* composite `tsc` skips emit if it survives and two stale trees compare
|
|
60
|
+
* equal for free.
|
|
61
|
+
* 3. CALIBRATE: inject a probe key into the declaring module, rebuild, and
|
|
62
|
+
* require the hash you are watching to MOVE; drop the probe, rebuild, and
|
|
63
|
+
* require it to come back to its original value. A probe that leaves your
|
|
64
|
+
* hash unmoved means the gauge is not wired to this symbol — that is what
|
|
65
|
+
* failure looks like here, and no "byte-identical" sentence may be written
|
|
66
|
+
* from a gauge that just failed it.
|
|
67
|
+
*
|
|
68
|
+
* Run against this file's own claim — probe: one additive optional key on
|
|
69
|
+
* `BaseSchema`, the shape `SchemaNode` publishes — `@object-ui/types`'
|
|
70
|
+
* `dist/base.d.ts` moved and came back, while `core/dist/index.d.ts` and
|
|
71
|
+
* `core/dist/types/index.d.ts` held one hash across all three legs. The
|
|
72
|
+
* withdrawn sentence was watching the two files that cannot move.
|
|
35
73
|
*
|
|
36
74
|
* The collision is only observable from a package that resolves BOTH through
|
|
37
75
|
* `node_modules`; the pin therefore lives in `@object-ui/react`
|
|
38
76
|
* (`src/__tests__/SchemaNode.reconciliation.test.ts`), not here.
|
|
39
77
|
*/
|
|
40
78
|
export type { SchemaNode } from '@object-ui/types';
|
|
41
|
-
import type { SchemaNode } from '@object-ui/types';
|
|
42
79
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
80
|
+
* One `ComponentRendererProps` (objectui#4594).
|
|
81
|
+
*
|
|
82
|
+
* This package used to hand-declare `interface ComponentRendererProps
|
|
83
|
+
* { schema: SchemaNode; [key: string]: any }` here — two lines below `SchemaNode`
|
|
84
|
+
* and against `@object-ui/types`' generic
|
|
85
|
+
* `ComponentRendererProps< TSchema extends BaseSchema = BaseSchema >`. Same name,
|
|
86
|
+
* two packages the same consumers import together: the second such pair in this
|
|
87
|
+
* one file, and the third across this fault line after `SchemaNode` (#4580) and
|
|
88
|
+
* `ComponentInput` (#4972).
|
|
89
|
+
*
|
|
90
|
+
* **`@object-ui/types`' generic declaration wins**, and is RE-EXPORTED rather
|
|
91
|
+
* than restated, so there is exactly one declaration left to disagree with — a
|
|
92
|
+
* structural copy would reproduce the defect the moment either side moved.
|
|
93
|
+
*
|
|
94
|
+
* Reconciled now, at **zero consumers** — re-verified on the merged ref rather
|
|
95
|
+
* than inherited from the card: repo-wide, `ComponentRendererProps` occurred only
|
|
96
|
+
* at the two declarations, each package's own entry re-export, and one line of
|
|
97
|
+
* `packages/components/CHANGELOG.md` recording that nothing used it. Zero
|
|
98
|
+
* consumers is why this is cheap today and would not stay cheap: the day someone
|
|
99
|
+
* imports it, which declaration they get decides whether a primitive node is
|
|
100
|
+
* admissible.
|
|
101
|
+
*
|
|
102
|
+
* ## What the re-export moves, and how that was measured
|
|
103
|
+
*
|
|
104
|
+
* It is NOT surface-neutral, and the gauge that would have said so is vacuous.
|
|
105
|
+
* `core/dist/index.d.ts` is emitted from a barrel that only FORWARDS this
|
|
106
|
+
* symbol — its `export type { … }` line names it, and naming is not restating
|
|
107
|
+
* — so that file is byte-identical under ANY change to a re-exported
|
|
108
|
+
* declaration's shape and cannot fail for this change class (objectui#5673,
|
|
109
|
+
* where the `SchemaNode` block above withdraws the same reading and carries the
|
|
110
|
+
* probe calibration that tells a live gauge from this one).
|
|
111
|
+
*
|
|
112
|
+
* Measured instead by resolving the symbol through the TypeScript CHECKER from
|
|
113
|
+
* `core/dist/index.d.ts`, over a `dist/` + `tsconfig.tsbuildinfo` clean rebuild
|
|
114
|
+
* on both legs (the build info lives outside `dist/`, so composite `tsc` skips
|
|
115
|
+
* emit if it survives and two stale trees compare equal for free):
|
|
116
|
+
*
|
|
117
|
+
* ```
|
|
118
|
+
* before ComponentRendererProps schema: BaseSchema | string | number | boolean | null | undefined
|
|
119
|
+
* after ComponentRendererProps<TSchema> schema: TSchema (TSchema extends BaseSchema = BaseSchema)
|
|
120
|
+
* ```
|
|
121
|
+
*
|
|
122
|
+
* So `schema` NARROWS back to the object form — core's copy had silently widened
|
|
123
|
+
* when #4608 made `SchemaNode` a re-export of types' union, which is the interim
|
|
124
|
+
* state this card closes — and the type gains a parameter. Nothing downstream
|
|
125
|
+
* can observe either move, because nothing imports it.
|
|
126
|
+
*
|
|
127
|
+
* The collision is only observable from a package that resolves BOTH through
|
|
128
|
+
* `node_modules`; the pin therefore lives in `@object-ui/react`
|
|
129
|
+
* (`src/__tests__/ComponentRendererProps.reconciliation.test.ts`), not here —
|
|
130
|
+
* same position, same reason, as `SchemaNode`'s pin above.
|
|
49
131
|
*/
|
|
50
|
-
export
|
|
51
|
-
schema: SchemaNode;
|
|
52
|
-
[key: string]: any;
|
|
53
|
-
}
|
|
132
|
+
export type { ComponentRendererProps } from '@object-ui/types';
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* chart-category-key — the ONE answer to "which result column carries the
|
|
10
|
+
* CATEGORY?" for an object-bound chart (objectui#8269).
|
|
11
|
+
*
|
|
12
|
+
* The mirror of `chart-measure-key` (objectui#8266) on the other axis. That
|
|
13
|
+
* card landed `chartMeasureKey` over the contract's `chartAggregateValueKey`;
|
|
14
|
+
* the contract publishes a CATEGORY sibling in the same module —
|
|
15
|
+
* `chartAggregateCategoryKey` — and nothing in this repository read it.
|
|
16
|
+
*
|
|
17
|
+
* ## The disagreement this replaces
|
|
18
|
+
*
|
|
19
|
+
* Both dashboard relays composed the category binding as a LITERAL FLOOR:
|
|
20
|
+
*
|
|
21
|
+
* const xAxisKey = options.xField || 'name';
|
|
22
|
+
*
|
|
23
|
+
* and handed it to the `object-chart` node without ever consulting the
|
|
24
|
+
* `aggregate` that decides it. An object-bound aggregate returns one row per
|
|
25
|
+
* group, keyed by the raw `groupBy` field, so a widget declaring
|
|
26
|
+
* `aggregate: { function: 'count', groupBy: 'status' }` and no `options.xField`
|
|
27
|
+
* bound `'name'` against rows keyed `'status'`.
|
|
28
|
+
*
|
|
29
|
+
* Unlike the measure half, this one is LOUD: `hasNoCategoryKey`
|
|
30
|
+
* (`plugin-charts/src/AdvancedChartImpl.tsx`, framework#4033) fires and the
|
|
31
|
+
* author reads "This chart cannot plot its category axis: no row has a `name`
|
|
32
|
+
* field." The diagnostic is wrong-CAUSE — it names a binding the author never
|
|
33
|
+
* wrote and never mentions the `groupBy` they did — so it points at the wrong
|
|
34
|
+
* layer. Being loud makes it a lesser harm than objectui#8266, not a
|
|
35
|
+
* non-defect: measured over the rows a fieldless count returns,
|
|
36
|
+
* `[{status:'open',count:2},{status:'paid',count:5}]`, an `xAxisKey` of
|
|
37
|
+
* `'name'` refuses under BOTH series bindings, i.e. objectui#8266's fix does
|
|
38
|
+
* not reach this authoring shape at all.
|
|
39
|
+
*
|
|
40
|
+
* ## Why the answer is delegated rather than restated
|
|
41
|
+
*
|
|
42
|
+
* Restating the rule here would make this file a second opinion of a question
|
|
43
|
+
* the contract already answers — the objectui#5042 / #7544 / #8193 / #8168
|
|
44
|
+
* drift shape that `chart-measure-key` exists to end. So the rule stays
|
|
45
|
+
* upstream in `@objectstack/spec/ui` and this is the seam objectui-side callers
|
|
46
|
+
* share.
|
|
47
|
+
*
|
|
48
|
+
* ## ⚠️ NOT the same function as `resolveChartCategoryField`
|
|
49
|
+
*
|
|
50
|
+
* `plugin-charts`' own `resolveChartCategoryField` (objectui#8168) reads
|
|
51
|
+
* `aggregate.groupBy` first too — which is exactly why `ObjectChart` does NOT
|
|
52
|
+
* refuse this shape at its own level, and then forwards `schema.xAxisKey`
|
|
53
|
+
* verbatim as the render binding anyway. But the two answer DIFFERENT
|
|
54
|
+
* questions and must not be collapsed:
|
|
55
|
+
*
|
|
56
|
+
* - `resolveChartCategoryField` answers "which FIELD is the category?" — its
|
|
57
|
+
* structured-`groupBy` leg returns `node.field`, because its two readers
|
|
58
|
+
* are the refusal (does the author name a category at all?) and the
|
|
59
|
+
* field-metadata probe that loads that field's option labels and colours.
|
|
60
|
+
* - this function answers "which COLUMN do the returned rows carry it
|
|
61
|
+
* under?" — `groupBy.alias ?? groupBy.field` per the contract, because an
|
|
62
|
+
* `alias` (admitted by `ChartGroupBySchema`) renames the projected column.
|
|
63
|
+
*
|
|
64
|
+
* They coincide whenever no alias is written, which is why the distinction is
|
|
65
|
+
* easy to miss; conflating them would either bind an axis to a column the rows
|
|
66
|
+
* do not carry, or probe field metadata for a field that does not exist.
|
|
67
|
+
*/
|
|
68
|
+
import { type ChartAggregateLike } from '@objectstack/spec/ui';
|
|
69
|
+
/**
|
|
70
|
+
* The result column a chart's category axis / x-axis binding must name.
|
|
71
|
+
*
|
|
72
|
+
* `fallback` is the caller's own floor, used ONLY when the contract has no
|
|
73
|
+
* answer — a chart that declares no `aggregate` at all (its rows are raw
|
|
74
|
+
* records or authored literals, where the author's `xField` is the right key),
|
|
75
|
+
* an UNGROUPED aggregate (one row, no category column), or a `groupBy` shape
|
|
76
|
+
* `ChartGroupBySchema` already rejects. It is never a second opinion about an
|
|
77
|
+
* aggregate the contract CAN answer for.
|
|
78
|
+
*
|
|
79
|
+
* @param aggregate the chart's inline aggregate, or `undefined`
|
|
80
|
+
* @param fallback the key to bind when the contract has no answer
|
|
81
|
+
*/
|
|
82
|
+
export declare function chartCategoryKey(aggregate: ChartAggregateLike | undefined, fallback: string): string;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* chart-category-key — the ONE answer to "which result column carries the
|
|
10
|
+
* CATEGORY?" for an object-bound chart (objectui#8269).
|
|
11
|
+
*
|
|
12
|
+
* The mirror of `chart-measure-key` (objectui#8266) on the other axis. That
|
|
13
|
+
* card landed `chartMeasureKey` over the contract's `chartAggregateValueKey`;
|
|
14
|
+
* the contract publishes a CATEGORY sibling in the same module —
|
|
15
|
+
* `chartAggregateCategoryKey` — and nothing in this repository read it.
|
|
16
|
+
*
|
|
17
|
+
* ## The disagreement this replaces
|
|
18
|
+
*
|
|
19
|
+
* Both dashboard relays composed the category binding as a LITERAL FLOOR:
|
|
20
|
+
*
|
|
21
|
+
* const xAxisKey = options.xField || 'name';
|
|
22
|
+
*
|
|
23
|
+
* and handed it to the `object-chart` node without ever consulting the
|
|
24
|
+
* `aggregate` that decides it. An object-bound aggregate returns one row per
|
|
25
|
+
* group, keyed by the raw `groupBy` field, so a widget declaring
|
|
26
|
+
* `aggregate: { function: 'count', groupBy: 'status' }` and no `options.xField`
|
|
27
|
+
* bound `'name'` against rows keyed `'status'`.
|
|
28
|
+
*
|
|
29
|
+
* Unlike the measure half, this one is LOUD: `hasNoCategoryKey`
|
|
30
|
+
* (`plugin-charts/src/AdvancedChartImpl.tsx`, framework#4033) fires and the
|
|
31
|
+
* author reads "This chart cannot plot its category axis: no row has a `name`
|
|
32
|
+
* field." The diagnostic is wrong-CAUSE — it names a binding the author never
|
|
33
|
+
* wrote and never mentions the `groupBy` they did — so it points at the wrong
|
|
34
|
+
* layer. Being loud makes it a lesser harm than objectui#8266, not a
|
|
35
|
+
* non-defect: measured over the rows a fieldless count returns,
|
|
36
|
+
* `[{status:'open',count:2},{status:'paid',count:5}]`, an `xAxisKey` of
|
|
37
|
+
* `'name'` refuses under BOTH series bindings, i.e. objectui#8266's fix does
|
|
38
|
+
* not reach this authoring shape at all.
|
|
39
|
+
*
|
|
40
|
+
* ## Why the answer is delegated rather than restated
|
|
41
|
+
*
|
|
42
|
+
* Restating the rule here would make this file a second opinion of a question
|
|
43
|
+
* the contract already answers — the objectui#5042 / #7544 / #8193 / #8168
|
|
44
|
+
* drift shape that `chart-measure-key` exists to end. So the rule stays
|
|
45
|
+
* upstream in `@objectstack/spec/ui` and this is the seam objectui-side callers
|
|
46
|
+
* share.
|
|
47
|
+
*
|
|
48
|
+
* ## ⚠️ NOT the same function as `resolveChartCategoryField`
|
|
49
|
+
*
|
|
50
|
+
* `plugin-charts`' own `resolveChartCategoryField` (objectui#8168) reads
|
|
51
|
+
* `aggregate.groupBy` first too — which is exactly why `ObjectChart` does NOT
|
|
52
|
+
* refuse this shape at its own level, and then forwards `schema.xAxisKey`
|
|
53
|
+
* verbatim as the render binding anyway. But the two answer DIFFERENT
|
|
54
|
+
* questions and must not be collapsed:
|
|
55
|
+
*
|
|
56
|
+
* - `resolveChartCategoryField` answers "which FIELD is the category?" — its
|
|
57
|
+
* structured-`groupBy` leg returns `node.field`, because its two readers
|
|
58
|
+
* are the refusal (does the author name a category at all?) and the
|
|
59
|
+
* field-metadata probe that loads that field's option labels and colours.
|
|
60
|
+
* - this function answers "which COLUMN do the returned rows carry it
|
|
61
|
+
* under?" — `groupBy.alias ?? groupBy.field` per the contract, because an
|
|
62
|
+
* `alias` (admitted by `ChartGroupBySchema`) renames the projected column.
|
|
63
|
+
*
|
|
64
|
+
* They coincide whenever no alias is written, which is why the distinction is
|
|
65
|
+
* easy to miss; conflating them would either bind an axis to a column the rows
|
|
66
|
+
* do not carry, or probe field metadata for a field that does not exist.
|
|
67
|
+
*/
|
|
68
|
+
import { chartAggregateCategoryKey } from '@objectstack/spec/ui';
|
|
69
|
+
/**
|
|
70
|
+
* The result column a chart's category axis / x-axis binding must name.
|
|
71
|
+
*
|
|
72
|
+
* `fallback` is the caller's own floor, used ONLY when the contract has no
|
|
73
|
+
* answer — a chart that declares no `aggregate` at all (its rows are raw
|
|
74
|
+
* records or authored literals, where the author's `xField` is the right key),
|
|
75
|
+
* an UNGROUPED aggregate (one row, no category column), or a `groupBy` shape
|
|
76
|
+
* `ChartGroupBySchema` already rejects. It is never a second opinion about an
|
|
77
|
+
* aggregate the contract CAN answer for.
|
|
78
|
+
*
|
|
79
|
+
* @param aggregate the chart's inline aggregate, or `undefined`
|
|
80
|
+
* @param fallback the key to bind when the contract has no answer
|
|
81
|
+
*/
|
|
82
|
+
export function chartCategoryKey(aggregate, fallback) {
|
|
83
|
+
return chartAggregateCategoryKey(aggregate) ?? fallback;
|
|
84
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* chart-measure-key — the ONE answer to "which result column carries the
|
|
10
|
+
* measure?" for an object-bound chart (objectui#8266).
|
|
11
|
+
*
|
|
12
|
+
* ## The disagreement this replaces
|
|
13
|
+
*
|
|
14
|
+
* The question was answered independently in three places, and for a FIELDLESS
|
|
15
|
+
* `count` — the normal way to author "how many records per status", and the
|
|
16
|
+
* most common dashboard chart there is — two of them answered differently:
|
|
17
|
+
*
|
|
18
|
+
* - the ROW PROJECTION (`aggregateValueKey` / `aggregateRecords` /
|
|
19
|
+
* `runAggregate`'s alias, all in `plugin-charts/src/ObjectChart.tsx`) keys
|
|
20
|
+
* the value column `'count'`, the alias the engine projects `COUNT(*)`
|
|
21
|
+
* under;
|
|
22
|
+
* - the SERIES BINDING, spelled twice in `plugin-dashboard`
|
|
23
|
+
* (`DashboardGridLayout.tsx` and `DashboardRenderer.tsx`), read
|
|
24
|
+
* `aggregate.field || (options.yField || 'value')` and so bound `'value'`.
|
|
25
|
+
*
|
|
26
|
+
* A `dataKey` naming a column no row carries plots nothing, and nothing says
|
|
27
|
+
* so: measured on `origin/main` `0fa7a9c83`, rows `[{status:'open',count:2},
|
|
28
|
+
* {status:'paid',count:5}]` with `series:[{dataKey:'value'}]` rendered a
|
|
29
|
+
* `.recharts-surface` with the category ticks "open"/"paid", **0 bars, 0
|
|
30
|
+
* rectangles**, no refusal and no empty state — the same rows under
|
|
31
|
+
* `dataKey:'count'` drew 2 rectangles. An empty chart reads as "no data yet",
|
|
32
|
+
* which is exactly what an author with a genuinely empty object also sees.
|
|
33
|
+
*
|
|
34
|
+
* ## Why the answer is delegated rather than restated
|
|
35
|
+
*
|
|
36
|
+
* `chartAggregateValueKey` in `@objectstack/spec/ui` is the CONTRACT's own
|
|
37
|
+
* derivation — "the VALUE column an object-bound aggregate produces … what a
|
|
38
|
+
* chart's series / y-axis binding must name". Producers and checkers already
|
|
39
|
+
* read it. Restating the rule here would make this file a fourth opinion of the
|
|
40
|
+
* same question, which is the shape (objectui#5042 / #7544 / #8193 / #8168)
|
|
41
|
+
* this module exists to end. So the rule lives upstream in the spec and this is
|
|
42
|
+
* the seam objectui-side callers share, exactly as `humanizeLabel` (objectui#5444)
|
|
43
|
+
* and `buildChartSeries` (ADR-0021) already are.
|
|
44
|
+
*
|
|
45
|
+
* ⛔ The inverse fix — making the row projection key a fieldless count
|
|
46
|
+
* `'value'` — is not available: it contradicts a pin the tree already carries
|
|
47
|
+
* (`ObjectChart.aggregateResultColumns.test.ts`) and renames the column every
|
|
48
|
+
* other consumer reads, including the engine's own `COUNT(*)` alias.
|
|
49
|
+
*/
|
|
50
|
+
import { type ChartAggregateLike } from '@objectstack/spec/ui';
|
|
51
|
+
export type { ChartAggregateLike };
|
|
52
|
+
/**
|
|
53
|
+
* The result column a chart's series must bind to.
|
|
54
|
+
*
|
|
55
|
+
* `fallback` is the caller's own floor, used ONLY when the contract has no
|
|
56
|
+
* answer — a chart that declares no `aggregate` at all (its rows are raw
|
|
57
|
+
* records or authored literals, where the author's `yField` is the right key),
|
|
58
|
+
* or an aggregate shape `ChartAggregateSchema` already rejects. It is never a
|
|
59
|
+
* second opinion about an aggregate the contract CAN answer for.
|
|
60
|
+
*
|
|
61
|
+
* @param aggregate the chart's inline aggregate, or `undefined`
|
|
62
|
+
* @param fallback the key to bind when the contract has no answer
|
|
63
|
+
*/
|
|
64
|
+
export declare function chartMeasureKey(aggregate: ChartAggregateLike | undefined, fallback: string): string;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* chart-measure-key — the ONE answer to "which result column carries the
|
|
10
|
+
* measure?" for an object-bound chart (objectui#8266).
|
|
11
|
+
*
|
|
12
|
+
* ## The disagreement this replaces
|
|
13
|
+
*
|
|
14
|
+
* The question was answered independently in three places, and for a FIELDLESS
|
|
15
|
+
* `count` — the normal way to author "how many records per status", and the
|
|
16
|
+
* most common dashboard chart there is — two of them answered differently:
|
|
17
|
+
*
|
|
18
|
+
* - the ROW PROJECTION (`aggregateValueKey` / `aggregateRecords` /
|
|
19
|
+
* `runAggregate`'s alias, all in `plugin-charts/src/ObjectChart.tsx`) keys
|
|
20
|
+
* the value column `'count'`, the alias the engine projects `COUNT(*)`
|
|
21
|
+
* under;
|
|
22
|
+
* - the SERIES BINDING, spelled twice in `plugin-dashboard`
|
|
23
|
+
* (`DashboardGridLayout.tsx` and `DashboardRenderer.tsx`), read
|
|
24
|
+
* `aggregate.field || (options.yField || 'value')` and so bound `'value'`.
|
|
25
|
+
*
|
|
26
|
+
* A `dataKey` naming a column no row carries plots nothing, and nothing says
|
|
27
|
+
* so: measured on `origin/main` `0fa7a9c83`, rows `[{status:'open',count:2},
|
|
28
|
+
* {status:'paid',count:5}]` with `series:[{dataKey:'value'}]` rendered a
|
|
29
|
+
* `.recharts-surface` with the category ticks "open"/"paid", **0 bars, 0
|
|
30
|
+
* rectangles**, no refusal and no empty state — the same rows under
|
|
31
|
+
* `dataKey:'count'` drew 2 rectangles. An empty chart reads as "no data yet",
|
|
32
|
+
* which is exactly what an author with a genuinely empty object also sees.
|
|
33
|
+
*
|
|
34
|
+
* ## Why the answer is delegated rather than restated
|
|
35
|
+
*
|
|
36
|
+
* `chartAggregateValueKey` in `@objectstack/spec/ui` is the CONTRACT's own
|
|
37
|
+
* derivation — "the VALUE column an object-bound aggregate produces … what a
|
|
38
|
+
* chart's series / y-axis binding must name". Producers and checkers already
|
|
39
|
+
* read it. Restating the rule here would make this file a fourth opinion of the
|
|
40
|
+
* same question, which is the shape (objectui#5042 / #7544 / #8193 / #8168)
|
|
41
|
+
* this module exists to end. So the rule lives upstream in the spec and this is
|
|
42
|
+
* the seam objectui-side callers share, exactly as `humanizeLabel` (objectui#5444)
|
|
43
|
+
* and `buildChartSeries` (ADR-0021) already are.
|
|
44
|
+
*
|
|
45
|
+
* ⛔ The inverse fix — making the row projection key a fieldless count
|
|
46
|
+
* `'value'` — is not available: it contradicts a pin the tree already carries
|
|
47
|
+
* (`ObjectChart.aggregateResultColumns.test.ts`) and renames the column every
|
|
48
|
+
* other consumer reads, including the engine's own `COUNT(*)` alias.
|
|
49
|
+
*/
|
|
50
|
+
import { chartAggregateValueKey } from '@objectstack/spec/ui';
|
|
51
|
+
/**
|
|
52
|
+
* The result column a chart's series must bind to.
|
|
53
|
+
*
|
|
54
|
+
* `fallback` is the caller's own floor, used ONLY when the contract has no
|
|
55
|
+
* answer — a chart that declares no `aggregate` at all (its rows are raw
|
|
56
|
+
* records or authored literals, where the author's `yField` is the right key),
|
|
57
|
+
* or an aggregate shape `ChartAggregateSchema` already rejects. It is never a
|
|
58
|
+
* second opinion about an aggregate the contract CAN answer for.
|
|
59
|
+
*
|
|
60
|
+
* @param aggregate the chart's inline aggregate, or `undefined`
|
|
61
|
+
* @param fallback the key to bind when the contract has no answer
|
|
62
|
+
*/
|
|
63
|
+
export function chartMeasureKey(aggregate, fallback) {
|
|
64
|
+
return chartAggregateValueKey(aggregate) ?? fallback;
|
|
65
|
+
}
|