@object-ui/core 17.5.0 → 17.6.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 (70) hide show
  1. package/CHANGELOG.md +794 -0
  2. package/README.md +36 -22
  3. package/dist/actions/ActionEngine.d.ts +1 -1
  4. package/dist/actions/ActionEngine.js +1 -2
  5. package/dist/actions/ActionRunner.d.ts +82 -10
  6. package/dist/actions/ActionRunner.js +128 -22
  7. package/dist/actions/actionKeys.d.ts +68 -8
  8. package/dist/actions/actionKeys.js +81 -9
  9. package/dist/actions/actionResponse.js +1 -1
  10. package/dist/actions/index.d.ts +1 -0
  11. package/dist/actions/index.js +1 -0
  12. package/dist/actions/recordIdParam.d.ts +77 -0
  13. package/dist/actions/recordIdParam.js +37 -0
  14. package/dist/actions/serverActionHandler.d.ts +1 -1
  15. package/dist/actions/serverActionHandler.js +1 -1
  16. package/dist/evaluator/ExpressionEvaluator.d.ts +42 -1
  17. package/dist/evaluator/ExpressionEvaluator.js +42 -1
  18. package/dist/evaluator/SafeExpressionParser.js +0 -4
  19. package/dist/evaluator/declaredPredicate.js +1 -1
  20. package/dist/evaluator/fieldRules.d.ts +19 -0
  21. package/dist/evaluator/fieldRules.js +30 -6
  22. package/dist/evaluator/index.d.ts +1 -0
  23. package/dist/evaluator/index.js +1 -0
  24. package/dist/evaluator/listConditional.d.ts +49 -2
  25. package/dist/evaluator/listConditional.js +70 -6
  26. package/dist/evaluator/optionRules.d.ts +55 -0
  27. package/dist/evaluator/optionRules.js +60 -0
  28. package/dist/evaluator/rowPredicateCanon.d.ts +67 -0
  29. package/dist/evaluator/rowPredicateCanon.js +208 -0
  30. package/dist/index.d.ts +4 -0
  31. package/dist/index.js +17 -0
  32. package/dist/registry/Registry.d.ts +41 -19
  33. package/dist/theme/index.d.ts +1 -1
  34. package/dist/theme/index.js +1 -1
  35. package/dist/types/index.d.ts +92 -13
  36. package/dist/utils/chart-presentation.d.ts +205 -0
  37. package/dist/utils/chart-presentation.js +280 -0
  38. package/dist/utils/chart-series.d.ts +140 -26
  39. package/dist/utils/chart-series.js +380 -39
  40. package/dist/utils/column-identity.d.ts +43 -0
  41. package/dist/utils/column-identity.js +47 -1
  42. package/dist/utils/dataset-format.js +18 -6
  43. package/dist/utils/debug.js +7 -0
  44. package/dist/utils/expand-fields.d.ts +97 -7
  45. package/dist/utils/expand-fields.js +97 -7
  46. package/dist/utils/filter-tokens.js +0 -1
  47. package/dist/utils/freeze-schema.d.ts +38 -1
  48. package/dist/utils/freeze-schema.js +10 -0
  49. package/dist/utils/humanize-label.d.ts +60 -0
  50. package/dist/utils/humanize-label.js +62 -0
  51. package/dist/utils/managedBy.d.ts +27 -2
  52. package/dist/utils/normalize-list-view.d.ts +10 -0
  53. package/dist/utils/normalize-list-view.js +63 -1
  54. package/dist/utils/number-display.d.ts +7 -3
  55. package/dist/utils/predicate-fields.d.ts +29 -4
  56. package/dist/utils/predicate-fields.js +44 -4
  57. package/dist/utils/retired-field-types.d.ts +90 -0
  58. package/dist/utils/retired-field-types.js +124 -0
  59. package/dist/utils/sort-query.d.ts +12 -10
  60. package/dist/utils/unmaterialized-fields.d.ts +52 -0
  61. package/dist/utils/unmaterialized-fields.js +57 -0
  62. package/dist/validation/index.d.ts +1 -0
  63. package/dist/validation/index.js +1 -0
  64. package/dist/validation/schema-validator.js +105 -0
  65. package/dist/validation/server-owned-value.d.ts +62 -0
  66. package/dist/validation/server-owned-value.js +99 -0
  67. package/dist/validation/validators/object-validation-engine.js +0 -2
  68. package/package.json +4 -4
  69. package/dist/__benchmarks__/core.bench.d.ts +0 -8
  70. package/dist/__benchmarks__/core.bench.js +0 -53
@@ -5,22 +5,30 @@
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
- import type { SchemaNode } from '../types/index.js';
8
+ import type { ComponentInput } from '@object-ui/types';
9
9
  export type ComponentRenderer<T = any> = T;
10
- export type ComponentInput = {
11
- name: string;
12
- type: 'string' | 'number' | 'boolean' | 'enum' | 'array' | 'object' | 'color' | 'date' | 'code' | 'file' | 'slot';
13
- label?: string;
14
- defaultValue?: any;
15
- required?: boolean;
16
- enum?: string[] | {
17
- label: string;
18
- value: any;
19
- }[];
20
- description?: string;
21
- advanced?: boolean;
22
- inputType?: string;
23
- };
10
+ /**
11
+ * What a registration DECLARES about one authorable prop.
12
+ *
13
+ * This is the declaration the component registrations themselves import, so it
14
+ * is the one an author's manifest is ultimately built from — and it is now
15
+ * RE-EXPORTED from `@object-ui/types` rather than restated here
16
+ * (objectui#4972), the disposition objectui#4580 ruled for the identical
17
+ * shape: *a structural copy would reproduce the defect the moment either side
18
+ * moved.* This package already depends on `@object-ui/types`, so the edge
19
+ * exists and adds no cycle, and `src/types/index.ts` re-exports `SchemaNode`
20
+ * from there the same way.
21
+ *
22
+ * The copy this replaces had ALREADY moved, which is why the card is not
23
+ * hypothetical: it carried nine keys while `base.ts` carried thirteen, so
24
+ * `min` / `max` / `step` / `placeholder` were missing from *the copy every
25
+ * registration actually imports*. Those four keys were therefore unwritable at
26
+ * any real registration — a plain TS error — while `ComponentInputSchema` (the
27
+ * zod schema) and `ComponentMeta.inputs` both accepted them. The publication
28
+ * face advertised four keys the authoring face rejected; the divergence was
29
+ * dormant only because no registration had tried to write one yet.
30
+ */
31
+ export type { ComponentInput } from '@object-ui/types';
24
32
  export type ComponentMeta = {
25
33
  label?: string;
26
34
  icon?: string;
@@ -45,7 +53,11 @@ export type ComponentMeta = {
45
53
  skipFallback?: boolean;
46
54
  /**
47
55
  * How a HOST must associate its own visible label with what this component
48
- * renders (objectui#3961). Read by the form renderer; absent ⇒ `'control'`.
56
+ * renders (objectui#3961, extended by objectui#4857). Read by the form
57
+ * renderer; absent ⇒ `'control'`. This closed three-value vocabulary is the
58
+ * single repo-wide answer to "how does a host learn what a widget will
59
+ * render" (maintainer ruling of 2026-08-17, joint with objectui#4871) — no
60
+ * host may keep a local variant of it.
49
61
  *
50
62
  * - `'control'` — the component's outermost rendered element is a LABELABLE
51
63
  * HTML element (`input` / `textarea` / `select` / `button` / …), so the host
@@ -58,7 +70,18 @@ export type ComponentMeta = {
58
70
  * nothing and contributes no accessible name (`HTMLLabelElement.control` is
59
71
  * `null`) — so the host must instead give its label an `id` and hand the
60
72
  * component `aria-labelledby`, which associates by IDREF and works on any
61
- * element.
73
+ * element. The COMPONENT consumes those keys on its own surface.
74
+ * - `'display'` — the rendered surface is a pure display in EVERY state:
75
+ * there is no focusable control and the component itself spreads nothing
76
+ * (computed / system-generated values such as `formula` / `summary` /
77
+ * `auto_number` / `vector`). The host must not emit a `<label for>` at all
78
+ * — no labelable element will ever exist for it to reach, in the editable
79
+ * state as much as the readonly one — and instead wraps the component's
80
+ * output in the host's own container carrying the field id,
81
+ * `aria-labelledby`, `aria-describedby` and `role="group"` (the
82
+ * objectui#4788 channel, driven by this declaration rather than by
83
+ * `readonly` alone). Unlike `'group'`, the WIDGET is not expected to
84
+ * consume anything: the host's wrapper is the named surface.
62
85
  *
63
86
  * This is a DECLARATION, not a guess: the host cannot infer it from the DOM a
64
87
  * widget happens to render, and a widget that fails to declare it falls back
@@ -66,10 +89,9 @@ export type ComponentMeta = {
66
89
  * label-association tests (objectui#3952) instead of silently producing an
67
90
  * unlabelled group.
68
91
  */
69
- labelling?: 'control' | 'group';
92
+ labelling?: 'control' | 'group' | 'display';
70
93
  inputs?: ComponentInput[];
71
94
  defaultProps?: Record<string, any>;
72
- defaultChildren?: SchemaNode[];
73
95
  examples?: Record<string, any>;
74
96
  isContainer?: boolean;
75
97
  resizable?: boolean;
@@ -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';
@@ -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';
@@ -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, and core's own entry surface is unchanged (`dist/index.d.ts`
34
- * is byte-identical across the change — measured, both rounds).
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
- * ⛔ Deliberately NOT reconciled with `@object-ui/types`' `ComponentRendererProps`
44
- * (objectui#4594). The two declarations differ — types' is generic
45
- * (`< TSchema extends BaseSchema = BaseSchema >`), this one is not — but that
46
- * card measured **zero consumers** of this declaration, so reconciling it here
47
- * would be an unmeasured change riding a card that was scoped to `SchemaNode`.
48
- * It stays dual-declared until #4594 is dispatched on its own evidence.
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 interface ComponentRendererProps {
51
- schema: SchemaNode;
52
- [key: string]: any;
53
- }
132
+ export type { ComponentRendererProps } from '@object-ui/types';
@@ -0,0 +1,205 @@
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-presentation — the AUTHORED half of a dataset-bound chart, lowered onto
10
+ * the bindings {@link buildChartSeries} derived from the dataset selection.
11
+ *
12
+ * `chart-series.ts` beside this file owns the DATA half: which columns become
13
+ * series, which rows, which buckets. This file owns everything the author gets
14
+ * to say about how that data LOOKS — the ruled data/presentation split of
15
+ * objectui#4229, stated once:
16
+ *
17
+ * - **Data (derived, never forwarded)** — series MEMBERSHIP and the column each
18
+ * binding reads. Concretely `buildChartSeries`' `dataKey`s, `xAxisKey`, and
19
+ * the spec's two binding keys `ChartSeries.name` and `ChartAxis.field`.
20
+ * - **Presentation (authored, merged forward)** — everything else on those same
21
+ * objects: `series[].type` (the per-series mark), `series[].yAxis` (which
22
+ * axis it binds to), `label`/`color`/`stack`/`variant`/`dashArray`/`opacity`,
23
+ * the axis definitions' `title`/`format`/`min`/`max`/`stepSize`/
24
+ * `showGridLines`/`position`/`logarithmic`, and the chart chrome
25
+ * (`showLegend`, `showDataLabels`, `colors`, `annotations`, …).
26
+ *
27
+ * ## Why it lives in `@object-ui/core` rather than in one plugin
28
+ *
29
+ * It was written for `plugin-dashboard`'s `DatasetWidget` (#3135 → objectstack#7016
30
+ * → #4229) and lifted here by objectui#4877, when `plugin-report`'s embedded
31
+ * report chart turned out to need the SAME merge over the same spec shapes: the
32
+ * report was forwarding six keys and dropping every authored chrome key the
33
+ * schema declares, and re-deriving this beside the dashboard's copy is exactly
34
+ * the duplication objectui#4389 filed as a defect (two longhand copies of the
35
+ * analytics label net, one per plugin, drifting apart).
36
+ *
37
+ * Everything here is a pure data transform over plain records, so it sits below
38
+ * both plugins with no React and no i18n — the same layering `chart-series.ts`
39
+ * already has (see {@link OptionLabelTranslator} there for why an i18n-resolved
40
+ * string always arrives as an ARGUMENT rather than being read here).
41
+ *
42
+ * ## Two entry points, because the two surfaces declare axes differently
43
+ *
44
+ * A dashboard widget's `chartConfig` spells its axes as spec `ChartAxis`
45
+ * OBJECTS. A report's `chart.xAxis` / `chart.yAxis` are bare dimension/measure
46
+ * NAME strings — on that surface the axes are pure DATA (they ARE the selection)
47
+ * and carry no presentation at all. So:
48
+ *
49
+ * - {@link mergeAuthoredPresentation} is the object-axis entry point: series
50
+ * merge + axis presentation, for a caller whose axes are `ChartAxis` objects.
51
+ * - {@link mergeAuthoredSeries} is the series merge ALONE, for a caller whose
52
+ * axes are names. That split is structural, not a guard: handing a bare
53
+ * string to {@link mergeAuthoredPresentation} would run it through
54
+ * `axisPresentation`, which reads nothing off a string and would synthesise a
55
+ * `yAxis: [{}]` entry — a y-axis declaring nothing but its own existence,
56
+ * which is precisely how the COUNT of entries turns on a secondary axis. A
57
+ * surface that cannot author axis presentation should not be able to reach
58
+ * the code that reads it.
59
+ */
60
+ import type { ChartSeriesBinding } from './chart-series.js';
61
+ /** Authored spec `ChartSeries` presentation, in the renderer's internal spelling. */
62
+ export interface AuthoredSeriesPresentation {
63
+ label?: string;
64
+ /** Spec `ChartSeries.type`, narrowed — see {@link seriesPresentation}. */
65
+ chartType?: 'bar' | 'line' | 'area';
66
+ yAxis?: 'left' | 'right';
67
+ color?: string;
68
+ stack?: string;
69
+ variant?: 'primary' | 'comparison';
70
+ dashArray?: string;
71
+ opacity?: number;
72
+ }
73
+ /** A derived series binding with the author's presentation merged onto it. */
74
+ export type MergedChartSeries = ChartSeriesBinding & AuthoredSeriesPresentation;
75
+ /**
76
+ * One authored `ChartSeries`, minus its `name` — i.e. everything about it that
77
+ * is presentation rather than membership.
78
+ *
79
+ * `type` is narrowed to the three families that COMPOSE on one cartesian plot,
80
+ * because this array reaches the renderer already speaking the internal shape
81
+ * (`ChartRenderer` forwards a `dataKey`-shaped array untouched, so
82
+ * `normalizeChartSchema`'s own identical narrowing never sees it). Without the
83
+ * narrowing a `type: 'pie'` would not merely be inert — it would count as a
84
+ * family disagreement in `effectiveChartFamily`, flip the whole chart into a
85
+ * combo, and then draw that series as a bar anyway.
86
+ */
87
+ export declare function seriesPresentation(raw: Record<string, unknown>): AuthoredSeriesPresentation;
88
+ /**
89
+ * One authored `ChartAxis`, minus its `field` — the axis's presentation.
90
+ *
91
+ * `field` is the one DATA key on an axis (it names the plotted column), and
92
+ * dropping it here is what keeps membership with the dataset **structurally**
93
+ * rather than by a guard: `normalizeChartSchema` synthesises series out of
94
+ * `yAxis[].field` when a chart declares no series, so a forwarded `field`
95
+ * would be a live membership channel on an empty selection. With it gone the
96
+ * axis carries scale and chrome only, and the count of entries — which is what
97
+ * turns on the secondary axis (`yAxes.length > 1`) — survives, including for
98
+ * an entry that declares nothing but its own existence.
99
+ *
100
+ * Keys the renderer does not read on a given axis are dropped by
101
+ * `normalizeChartSchema`, the ONE normalization layer (#2880 S1): today it
102
+ * keeps `format`/`title`/`showGridLines` on the x-axis and the full set on the
103
+ * y-axes. That narrowing is deliberately NOT mirrored here — a second copy
104
+ * would drift from the renderer's real capability the moment it grew.
105
+ */
106
+ export declare function axisPresentation(raw: unknown): Record<string, unknown>;
107
+ /**
108
+ * Merge an authored `series[]` array's PRESENTATION onto the bindings the
109
+ * dataset selection derived — the series half of #4229's split, and the whole
110
+ * of it for a surface whose axes are names rather than objects (see the file
111
+ * header).
112
+ *
113
+ * The match rule is **by name/key**: an authored `series[].name` is paired with
114
+ * the derived binding whose `dataKey` it equals, and the pairing decides
115
+ * nothing but presentation:
116
+ *
117
+ * - an authored entry naming a measure that is NOT in the dataset selection is
118
+ * **ignored** — membership belongs to the dataset, so an author cannot add,
119
+ * remove or re-point a series from the chart config;
120
+ * - a derived series with no authored entry keeps the family default, so every
121
+ * surface that never wrote `series` renders byte-for-byte as before;
122
+ * - where both exist the **explicit binding wins** (#2880 S2), which is the
123
+ * whole point: `type: 'line'` + `yAxis: 'right'` is how the spec says "this
124
+ * measure is a line on the secondary axis".
125
+ *
126
+ * Matching on `name` only is deliberate: `name` is the spec's authorable key
127
+ * for a series (`dataKey` is a declared ALIAS of it, resolved where the
128
+ * metadata is parsed), so reading a second spelling here would fossilize a
129
+ * dialect this renderer has no business accepting (AGENTS.md #0.1).
130
+ *
131
+ * The FIRST entry naming a measure wins; a later duplicate cannot silently
132
+ * reconfigure a series the author already described.
133
+ *
134
+ * @param derived the bindings {@link buildChartSeries} produced from the selection
135
+ * @param authoredSeries the authored `series` array (anything, incl. absent)
136
+ */
137
+ export declare function mergeAuthoredSeries(derived: ChartSeriesBinding[], authoredSeries: unknown): MergedChartSeries[];
138
+ /**
139
+ * Merge an authored chart config's PRESENTATION onto the series and axes the
140
+ * dataset selection derived — the one place that happens for a surface whose
141
+ * axes are spec `ChartAxis` OBJECTS (#4229).
142
+ *
143
+ * The series half is {@link mergeAuthoredSeries}; see it for the match rule and
144
+ * for why membership is safe. The axes half reads `xAxis` / `yAxis` through
145
+ * {@link axisPresentation}, which is why a surface spelling those as bare NAME
146
+ * strings must call `mergeAuthoredSeries` directly instead (file header).
147
+ *
148
+ * @param derived the bindings {@link buildChartSeries} produced from the selection
149
+ * @param raw the authored chart config (anything, incl. absent)
150
+ * @returns the merged series, plus the presentation-only axes to spread onto
151
+ * the chart schema (absent when the author declared none)
152
+ */
153
+ export declare function mergeAuthoredPresentation(derived: ChartSeriesBinding[], raw: unknown): {
154
+ series: MergedChartSeries[];
155
+ axes: Record<string, unknown>;
156
+ };
157
+ /**
158
+ * Lower an authored chart config's CHROME (spec `ChartConfigSchema` /
159
+ * `ReportChartSchema` — the same keys on both) onto the chart schema a
160
+ * dataset-bound surface hands the renderer.
161
+ *
162
+ * ## Why this is a whitelist and not a spread
163
+ *
164
+ * Until #3135 NONE of a dashboard widget's `chartConfig` reached the renderer:
165
+ * the widget read `options` and nothing else, so an author who wrote
166
+ * `showLegend: false` still got a legend and one who wrote `true` only got one
167
+ * because "on" is the renderer's default. #3135 lowered that single flag and
168
+ * left the rest declared and inert. objectstack#7016 lowered the rest of the
169
+ * keys that are actually DELIVERED, admitting a key only when both of these
170
+ * hold:
171
+ *
172
+ * 1. **The chart block draws it end to end.** `{ type: 'chart' }` resolves to
173
+ * `ChartRenderer` → `AdvancedChartImpl`, which draws `title`/`subtitle` in
174
+ * its ChartFrame, turns `description` into the chart container's
175
+ * `role="img"` + `aria-label`, applies `height` as that container's inline
176
+ * height, reads `colors` as the positional palette, prints
177
+ * `showDataLabels` as a Recharts `LabelList`, draws `annotations` as
178
+ * ReferenceLine/ReferenceArea and honours `interaction` as the tooltip
179
+ * toggle plus `Brush`. Forwarding a key the renderer ignores would only
180
+ * move declared-but-not-delivered one layer down, which is the failure this
181
+ * exists to remove.
182
+ * 2. **It does not fight the dataset derivation.** `type` stays out: the
183
+ * calling surface's own type already picks the chart family, which is the
184
+ * dataset path's chart-family channel.
185
+ *
186
+ * `aria` is the one declared key with **no reader at all**: `AdvancedChartImpl`
187
+ * has no `aria` prop, and `SchemaRenderer`'s ARIA injection reads the FLAT
188
+ * `ariaLabel`/`ariaDescribedBy`/`role`, never a nested `aria` object. It is
189
+ * therefore left unforwarded on purpose (criterion 1) rather than papered over
190
+ * with a caller-side flattening that would also collide with the accessible
191
+ * name `description` already sets — reported back to objectstack#5175's
192
+ * narrowing half instead.
193
+ *
194
+ * `title` IS emitted here. A caller that paints the title itself (the report
195
+ * renderer's own `h3` above the chart) must drop it from the result, or the
196
+ * chart draws a second one.
197
+ *
198
+ * @param raw the authored chart config (anything, incl. absent)
199
+ * @param fieldCategoryColors per-category colours resolved from the category
200
+ * dimension's own select/lookup option colours, merged UNDER an explicit
201
+ * author map (see the `colors` note below)
202
+ * @returns only the keys that resolved, so the caller can spread it over the
203
+ * derived chart schema and every undeclared key keeps the renderer's default
204
+ */
205
+ export declare function chartConfigPresentation(raw: unknown, fieldCategoryColors?: Record<string, string> | null): Record<string, unknown>;