@object-ui/core 17.6.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 +6610 -0
- package/README.md +101 -14
- package/dist/actions/ActionEngine.d.ts +4 -2
- package/dist/actions/ActionEngine.js +13 -8
- package/dist/actions/ActionRunner.d.ts +288 -27
- package/dist/actions/ActionRunner.js +443 -63
- package/dist/actions/TransactionManager.d.ts +7 -2
- package/dist/actions/actionKeys.d.ts +9 -7
- package/dist/actions/actionKeys.js +57 -14
- package/dist/actions/actionResponse.js +2 -2
- package/dist/actions/index.d.ts +1 -0
- package/dist/actions/index.js +1 -0
- package/dist/actions/recordDelete.d.ts +118 -0
- package/dist/actions/recordDelete.js +112 -0
- 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 +86 -0
- package/dist/evaluator/ExpressionEvaluator.js +184 -12
- package/dist/evaluator/FormulaFunctions.d.ts +0 -10
- package/dist/evaluator/FormulaFunctions.js +166 -27
- package/dist/evaluator/declaredPredicate.d.ts +93 -9
- package/dist/evaluator/declaredPredicate.js +117 -16
- package/dist/evaluator/fieldRules.d.ts +88 -4
- package/dist/evaluator/fieldRules.js +203 -31
- package/dist/evaluator/index.d.ts +1 -0
- package/dist/evaluator/index.js +1 -0
- package/dist/evaluator/listConditional.d.ts +103 -34
- package/dist/evaluator/listConditional.js +127 -50
- package/dist/evaluator/optionRules.d.ts +77 -6
- package/dist/evaluator/optionRules.js +87 -10
- package/dist/evaluator/predicateInput.d.ts +15 -4
- package/dist/evaluator/predicateInput.js +35 -2
- package/dist/evaluator/rowPredicateCanon.d.ts +7 -18
- package/dist/evaluator/rowPredicateCanon.js +65 -115
- 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 +14 -0
- package/dist/index.js +80 -2
- package/dist/protocols/index.d.ts +0 -1
- package/dist/protocols/index.js +9 -1
- package/dist/registry/Registry.d.ts +358 -31
- 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/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 +95 -112
- package/dist/utils/chart-presentation.js +169 -104
- package/dist/utils/chart-series.d.ts +131 -5
- package/dist/utils/chart-series.js +98 -16
- 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 +389 -46
- 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/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 +76 -6
- package/dist/utils/expand-fields.js +76 -6
- 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 -33
- package/dist/utils/grouping-fields.d.ts +61 -0
- package/dist/utils/grouping-fields.js +84 -0
- package/dist/utils/managedBy.d.ts +3 -3
- 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 +121 -1
- package/dist/utils/normalize-list-view.js +186 -6
- package/dist/utils/number-display.d.ts +63 -14
- 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 +45 -12
- package/dist/utils/predicate-fields.js +137 -12
- 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/sort-query.d.ts +115 -15
- 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/without-denied-fields.d.ts +49 -0
- package/dist/utils/without-denied-fields.js +52 -0
- package/dist/validation/index.d.ts +8 -4
- package/dist/validation/index.js +8 -4
- package/dist/validation/schema-validator.d.ts +1 -1
- package/dist/validation/schema-validator.js +200 -82
- package/dist/validation/validators/object-validation-engine.d.ts +1 -1
- package/dist/validation/validators/object-validation-engine.js +14 -3
- package/package.json +8 -9
- 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
|
@@ -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
|
+
* Colour literals the renderers accept as-is.
|
|
10
|
+
*
|
|
11
|
+
* Hex accepts 3, 6 and 8 digits. The timeline's private regex accepted 3 and 6;
|
|
12
|
+
* `plugin-calendar`'s accepted 3, 6 and 8 — two in-repo spellings of the same
|
|
13
|
+
* question, and the narrow one is the only one under which a VALID CSS colour
|
|
14
|
+
* (`#rrggbbaa`) could fall past this rung and be replaced by a derived colour.
|
|
15
|
+
* Widening can only turn "not recognised" into "the author's colour"; it can
|
|
16
|
+
* never turn a colour into something else. So the wider spelling wins.
|
|
17
|
+
*/
|
|
18
|
+
const HEX_COLOR_RE = /^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i;
|
|
19
|
+
/** Does this string already name a colour the DOM can paint? */
|
|
20
|
+
export function isColorLiteral(value) {
|
|
21
|
+
return HEX_COLOR_RE.test(value) || value.startsWith('rgb') || value.startsWith('hsl');
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Build a `value -> option colour` lookup from a field definition's `options`.
|
|
25
|
+
* Returns an empty map for a field with no options, so callers need no guard.
|
|
26
|
+
*/
|
|
27
|
+
export function buildFieldColorMap(fieldDef) {
|
|
28
|
+
const options = fieldDef?.options;
|
|
29
|
+
if (!Array.isArray(options))
|
|
30
|
+
return {};
|
|
31
|
+
const map = {};
|
|
32
|
+
for (const opt of options) {
|
|
33
|
+
if (!opt || typeof opt !== 'object')
|
|
34
|
+
continue;
|
|
35
|
+
if (opt.value == null)
|
|
36
|
+
continue;
|
|
37
|
+
if (typeof opt.color === 'string' && opt.color)
|
|
38
|
+
map[String(opt.value)] = opt.color;
|
|
39
|
+
}
|
|
40
|
+
return map;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Build the per-field colour resolver: rung 1 (option colour) then rung 2 (the
|
|
44
|
+
* value is already a colour literal), else `undefined` so the caller runs its
|
|
45
|
+
* own last rung.
|
|
46
|
+
*
|
|
47
|
+
* A factory rather than a plain function because callers resolve one field
|
|
48
|
+
* across every row of a view — the option map is built once, not per record.
|
|
49
|
+
*
|
|
50
|
+
* @param fieldDef `objectSchema.fields[colorField]`, or `undefined` when the
|
|
51
|
+
* view has no schema in hand (an inline-data or `api`-provider view). With no
|
|
52
|
+
* options, rung 1 is a no-op and rung 2 still answers for literal colours.
|
|
53
|
+
*/
|
|
54
|
+
export function createFieldColorResolver(fieldDef) {
|
|
55
|
+
const colorByValue = buildFieldColorMap(fieldDef);
|
|
56
|
+
return (value) => {
|
|
57
|
+
if (value == null || value === '')
|
|
58
|
+
return undefined;
|
|
59
|
+
const key = String(value);
|
|
60
|
+
const optionColor = colorByValue[key];
|
|
61
|
+
if (optionColor)
|
|
62
|
+
return optionColor;
|
|
63
|
+
return isColorLiteral(key) ? key : undefined;
|
|
64
|
+
};
|
|
65
|
+
}
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI — the shared record-source readers: the ruled three-rung ladder
|
|
3
|
+
* (`resolveRecordSourceConfig`) and the object-name it resolves to
|
|
4
|
+
* (`resolveRecordSourceObjectName`)
|
|
5
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
6
|
+
*
|
|
7
|
+
* This source code is licensed under the MIT license found in the
|
|
8
|
+
* LICENSE file in the root directory of this source tree.
|
|
9
|
+
*/
|
|
10
|
+
import type { ViewData } from '@object-ui/types';
|
|
11
|
+
/**
|
|
12
|
+
* The object a view block is bound to, resolved ONCE for the whole renderer
|
|
13
|
+
* (`b041b9c0c`).
|
|
14
|
+
*
|
|
15
|
+
* ## The question this answers, and the one it does not
|
|
16
|
+
*
|
|
17
|
+
* There are TWO separately-ruled precedence questions about `objectName`, and
|
|
18
|
+
* they only look like one question when a single reader is asked to answer
|
|
19
|
+
* both:
|
|
20
|
+
*
|
|
21
|
+
* 1. **Which object does this block RESOLVE, at render time, when it carries
|
|
22
|
+
* more than one binding?** — the published three-rung record-source ladder
|
|
23
|
+
* (`data`, then `staticData`, then `objectName`), declared on both faces of
|
|
24
|
+
* the contract (`ObjectMapSchema.objectName` / `ObjectGanttSchema.objectName`
|
|
25
|
+
* in `@object-ui/types`, and the `.describe` on their zod twins — the map
|
|
26
|
+
* twin's reads *"objectName — the THIRD record source `getDataConfig`
|
|
27
|
+
* resolves, after `data` and `staticData`"*, naming `ObjectMap.tsx`'s local
|
|
28
|
+
* wrapper; the gantt twin names `resolveRecordSourceConfig` itself), ruled
|
|
29
|
+
* 2026-09-02 (landed as `77cb489b4`) and pinned by
|
|
30
|
+
* `objectql-record-source-refinement-6939.test.ts`. **That is this
|
|
31
|
+
* function.**
|
|
32
|
+
* 2. **How does `objectName` get POPULATED when it is absent?** — the
|
|
33
|
+
* authoring-time gap-fill in `normalizeListViewSchema` (objectui#7477,
|
|
34
|
+
* ruling B, landed as `00d2fa682`), where an `objectName` already on the schema WINS
|
|
35
|
+
* and the `data` block only fills a gap: *"it can never re-point a binding
|
|
36
|
+
* that already resolves."*
|
|
37
|
+
*
|
|
38
|
+
* The two are NOT merged and neither is re-pointed at the other. Merging them
|
|
39
|
+
* would override a standing maintainer ruling in whichever direction the merged
|
|
40
|
+
* reader happened to pick: at the sites below the binding that already resolves
|
|
41
|
+
* IS `data.object`, so ruling B's own words argue for keeping rung 1 as it is.
|
|
42
|
+
*
|
|
43
|
+
* ## Why `staticData` does not appear here
|
|
44
|
+
*
|
|
45
|
+
* The ladder's second rung wraps inline rows as `{ provider: 'value', items }`,
|
|
46
|
+
* which names no object at all. So for the object-NAME question the three-rung
|
|
47
|
+
* ladder reduces to two rungs — the resolved config's object when it names one,
|
|
48
|
+
* else the schema's own `objectName`, which is what a `value`/`api`-backed block
|
|
49
|
+
* still needs for metadata reads, i18n field labels and permission verdicts.
|
|
50
|
+
* Callers pass the ALREADY-RESOLVED config (their
|
|
51
|
+
* {@link resolveRecordSourceConfig} output, direct or through a local wrapper),
|
|
52
|
+
* so rung ordering is settled before this function is reached.
|
|
53
|
+
*
|
|
54
|
+
* ## No lenient rung was added (AGENTS.md #0.1)
|
|
55
|
+
*
|
|
56
|
+
* `ViewDataSchema`'s `object` provider is a `strictObject` carrying exactly
|
|
57
|
+
* `{ provider, object }` with `object` REQUIRED, so `{ provider: 'object' }`
|
|
58
|
+
* without an `object` is off-contract. This reader does not coerce that shape
|
|
59
|
+
* back to `objectName`; the two call sites that used to (`ObjectGrid`'s
|
|
60
|
+
* `'object' in dataConfig` test and `ObjectTree`'s header `?? schema.objectName`
|
|
61
|
+
* tail) keep their own tail at the site, so the collapse changes nothing they
|
|
62
|
+
* resolve today while the shared rung stays contract-strict.
|
|
63
|
+
*
|
|
64
|
+
* @param schema - The block's schema; only `objectName` is read.
|
|
65
|
+
* @param dataConfig - The RESOLVED data config — the caller's own
|
|
66
|
+
* {@link resolveRecordSourceConfig} output, `null` when nothing is bound.
|
|
67
|
+
* @returns The bound object's name, or `undefined` when neither the resolved
|
|
68
|
+
* config nor the schema names one.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```ts
|
|
72
|
+
* const dataConfig = useMemo(() => resolveRecordSourceConfig(schema, 'view-data'), [schema]);
|
|
73
|
+
* const objectName = resolveRecordSourceObjectName(schema, dataConfig);
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export declare function resolveRecordSourceObjectName(schema: {
|
|
77
|
+
objectName?: string;
|
|
78
|
+
} | null | undefined, dataConfig: {
|
|
79
|
+
provider?: string;
|
|
80
|
+
object?: string;
|
|
81
|
+
} | null | undefined): string | undefined;
|
|
82
|
+
/**
|
|
83
|
+
* Which arm of `data` a block's PUBLISHED row declares — the only shape rung 1
|
|
84
|
+
* of the ladder honours for that block (objectui#8348).
|
|
85
|
+
*
|
|
86
|
+
* Maintainer ruling, decision batch #83 (2026-09-08), verbatim: 「8348 以协议为准」
|
|
87
|
+
* — the contract decides. A renderer honours the `data` spelling its block's
|
|
88
|
+
* published row declares and no other: what `os validate` and the save gate
|
|
89
|
+
* refuse, the renderer refuses too.
|
|
90
|
+
*
|
|
91
|
+
* - `'view-data'` — the row is the spec's `ViewData` discriminated union, four
|
|
92
|
+
* strict OBJECT arms on `provider`. A bare array under `data` is NOT a record
|
|
93
|
+
* source for such a block.
|
|
94
|
+
* - `'array'` — the row is `z.array(...)`: an array of PRE-FETCHED RECORDS. The
|
|
95
|
+
* `{ provider, items }` config object is NOT a record source for such a
|
|
96
|
+
* block.
|
|
97
|
+
* - `'undeclared'` — no published face declares a `data` row for the block at
|
|
98
|
+
* all, so neither arm of the ruling reaches it and rung 1 keeps its pre-8348
|
|
99
|
+
* verbatim behaviour. ⛔ NOT a tolerance to copy: it is the honest answer for
|
|
100
|
+
* a block the ruling does not decide, and it is reported rather than guessed.
|
|
101
|
+
* No ladder block passes it any more: `object-tree`, the last one that did,
|
|
102
|
+
* gained a published row and moved to `'view-data'` (objectui#8348, ruling
|
|
103
|
+
* batch #136 item 3, Q1-C). It stays the answer
|
|
104
|
+
* {@link recordSourceDataArmForType} gives a type it does not list.
|
|
105
|
+
*
|
|
106
|
+
* The arm is passed BY THE CALL SITE rather than looked up from `schema.type`
|
|
107
|
+
* on purpose. Most of these renderers are registered twice — `object-grid`
|
|
108
|
+
* and the `view:grid` alias `grid`, `object-calendar` and `calendar`, and so on
|
|
109
|
+
* (the bare `gantt` and `map` keys are retired, objectui#8008 / objectui#10393)
|
|
110
|
+
* — so a node reaches the same component under either spelling, and a table
|
|
111
|
+
* keyed by `type` would answer for one tag and silently miss the other. A
|
|
112
|
+
* REQUIRED parameter makes the arm a compile-time obligation at each of the
|
|
113
|
+
* five sites instead.
|
|
114
|
+
*/
|
|
115
|
+
export type RecordSourceDataArm = 'view-data' | 'array' | 'undeclared';
|
|
116
|
+
/**
|
|
117
|
+
* The authored `data` shape a block ON THAT ARM may declare — the DECLARATION
|
|
118
|
+
* half of the same per-block ruling {@link authoredDataIsOnTheDeclaredArm}
|
|
119
|
+
* decides at RUNTIME (`ab856ed30`).
|
|
120
|
+
*
|
|
121
|
+
* ## The contradiction this closes
|
|
122
|
+
*
|
|
123
|
+
* {@link resolveRecordSourceConfig} used to declare its `data` parameter as a
|
|
124
|
+
* flat `ViewData`, while its own docblock, its REQUIRED `dataArm` parameter and
|
|
125
|
+
* its rung-1 predicate all say the honoured shape DIFFERS PER BLOCK — and
|
|
126
|
+
* `ViewData` is a discriminated union over four strict OBJECT arms with no
|
|
127
|
+
* array member. So the signature refused the one block whose published row IS
|
|
128
|
+
* the array arm, and the arm parameter that exists to make the row a
|
|
129
|
+
* compile-time obligation was the one thing the compiler ignored. The
|
|
130
|
+
* contradiction was held shut at `ObjectCalendar.tsx`'s call site by an
|
|
131
|
+
* `as ViewData | undefined` cast whose own comment reported it as an upstream
|
|
132
|
+
* defect rather than a licence.
|
|
133
|
+
*
|
|
134
|
+
* ⛔ The repair is NOT a union of the arms. `ViewData | unknown[]` would let a
|
|
135
|
+
* `'view-data'` site declare a bare array and a `'array'` site declare a
|
|
136
|
+
* provider block — each of them the shape that block's row REFUSES, each of
|
|
137
|
+
* them compiling — which is the repo-wide default {@link RecordSourceDataArm}'s
|
|
138
|
+
* docblock refuses by name: *"a default is how the second de-facto contract got
|
|
139
|
+
* in"* (AGENTS.md #0.1).
|
|
140
|
+
*
|
|
141
|
+
* - `'view-data'` — the spec's `ViewData`. UNCHANGED, and that matters: this
|
|
142
|
+
* is exactly what the flat declaration said, and it was right for the three
|
|
143
|
+
* blocks on this arm, so nothing moves for `object-grid`, `object-map` or
|
|
144
|
+
* `object-gantt`.
|
|
145
|
+
* - `'array'` — `unknown[]`, the shape `object-calendar`'s published row
|
|
146
|
+
* declares (`ComponentPropsMap['object-calendar'].data` is
|
|
147
|
+
* `z.array(z.unknown()).optional()`, *"Pre-fetched records"*).
|
|
148
|
+
* - `'undeclared'` — `unknown`. No published face declares a `data` row for
|
|
149
|
+
* such a block, so rung 1 keeps its pre-8348 verbatim behaviour and honours
|
|
150
|
+
* ANY truthy value. Anything narrower here would be a rule nobody has ruled.
|
|
151
|
+
*
|
|
152
|
+
* ⚠️ RUNTIME IS UNMOVED. This type is erased; {@link authoredDataIsOnTheDeclaredArm}
|
|
153
|
+
* still takes `unknown` and still decides rung 1 on the value's KIND, so every
|
|
154
|
+
* runtime verdict — including the off-arm ones — is byte-for-byte what it was.
|
|
155
|
+
* `record-source-config.behaviourNeutrality-7632.test.ts` passes its fixtures
|
|
156
|
+
* through `as any` precisely so it keeps measuring that, whatever the
|
|
157
|
+
* declaration says.
|
|
158
|
+
*
|
|
159
|
+
* ⚠️ DISTRIBUTIVE on purpose, and that is why this is a conditional type rather
|
|
160
|
+
* than a set of overloads. A caller holding a `RecordSourceDataArm`-typed
|
|
161
|
+
* VARIABLE instead of a literal gets `ViewData | unknown[] | unknown`, i.e.
|
|
162
|
+
* `unknown` — the honest answer when the arm is not decided at compile time.
|
|
163
|
+
* The same caller would match NONE of three literal-armed overloads, which
|
|
164
|
+
* would turn a working call into an error for no contract reason.
|
|
165
|
+
*/
|
|
166
|
+
export type AuthoredRecordSourceData<Arm extends RecordSourceDataArm> = Arm extends 'view-data' ? ViewData : Arm extends 'array' ? unknown[] : unknown;
|
|
167
|
+
/**
|
|
168
|
+
* The block's record source, resolved from the ruled three-rung ladder
|
|
169
|
+
* (`ce2aaefe1`), with rung 1 judged against the block's own published `data`
|
|
170
|
+
* row (objectui#8348).
|
|
171
|
+
*
|
|
172
|
+
* ## The ruled contract this is the ONE implementation of
|
|
173
|
+
*
|
|
174
|
+
* `data`, then `staticData`, then `objectName` — declared on both faces of the
|
|
175
|
+
* published contract and pinned by
|
|
176
|
+
* `objectql-record-source-refinement-6939.test.ts`. Quoted here from the
|
|
177
|
+
* `ObjectMapSchema` faces, whose `getDataConfig` is `ObjectMap.tsx`'s local
|
|
178
|
+
* wrapper around this function; the gantt and calendar faces name
|
|
179
|
+
* `resolveRecordSourceConfig` instead (objectui#9618):
|
|
180
|
+
*
|
|
181
|
+
* 1. **`data`** — *"Data source configuration. Read FIRST by `getDataConfig`"*,
|
|
182
|
+
* honoured ONLY on the arm `dataArm` names. Returned verbatim, so a config
|
|
183
|
+
* on the declared arm reaches the caller exactly as the author wrote it.
|
|
184
|
+
* 2. **`staticData`** — *"Inline records — read SECOND by `getDataConfig`,
|
|
185
|
+
* wrapped into a `{ provider: value }` config"*.
|
|
186
|
+
* 3. **`objectName`** — *"the THIRD record source `getDataConfig` resolves,
|
|
187
|
+
* after `data` and `staticData`"*, folded to `{ provider: 'object' }`.
|
|
188
|
+
*
|
|
189
|
+
* `null` when none of the three is present — the same "nothing is drawn" signal
|
|
190
|
+
* the zod `requireRecordSource` refinement is written against.
|
|
191
|
+
*
|
|
192
|
+
* This is the PRODUCER whose output {@link resolveRecordSourceObjectName} (the
|
|
193
|
+
* reader `b041b9c0c` published) consumes; that function's docblock describes the same
|
|
194
|
+
* ladder from the consuming end. Five plugins — calendar, gantt, grid, map and
|
|
195
|
+
* tree — each carried a hand-copy of this ladder with no gate holding them
|
|
196
|
+
* together, which is the AGENTS.md #0.1 drift class: a change to the ruled
|
|
197
|
+
* order had five edit sites and nothing noticed a missed one.
|
|
198
|
+
*
|
|
199
|
+
* ## Rung 1 is judged against the block's own row (objectui#8348)
|
|
200
|
+
*
|
|
201
|
+
* ⛔ This docblock used to state, as a fact about the whole ladder, that *"an
|
|
202
|
+
* array under `data` cannot be published"*. That is true of the blocks whose row
|
|
203
|
+
* is `ViewData` and FALSE of `object-calendar`, whose published row
|
|
204
|
+
* (`ComponentPropsMap['object-calendar'].data` on `@objectstack/spec` 17.4.0) is
|
|
205
|
+
* `z.array(z.unknown()).optional()` — *"Pre-fetched records — skips the internal
|
|
206
|
+
* fetch"*. Both directions of that disagreement were live at once: the renderers
|
|
207
|
+
* honoured the `{ provider, items }` object on a block whose row refuses it by
|
|
208
|
+
* kind, and `ObjectGrid` / `ObjectMap` lifted a bare array on blocks whose row
|
|
209
|
+
* refuses THAT by kind. Decision batch #83 settled it — the row decides — and
|
|
210
|
+
* `dataArm` is where each block says which row it has.
|
|
211
|
+
*
|
|
212
|
+
* JUDGED, per block, against that block's `ComponentPropsMap` row in the
|
|
213
|
+
* INSTALLED `@objectstack/spec` — and ⛔ the verdicts are not written down here
|
|
214
|
+
* as facts, because a spec release can move a row (AGENTS.md #9). Each pin
|
|
215
|
+
* below derives the arm from the row at test time and compares it with what the
|
|
216
|
+
* block passes, so a moved row turns it red:
|
|
217
|
+
*
|
|
218
|
+
* - `object-grid` — `'view-data'`; `gridBareArrayDataRefused-8348.test.tsx`,
|
|
219
|
+
* its "the spec row is what all of the above is judged against" test. The
|
|
220
|
+
* row's own description names the refusal: *"the bare-array shortcut is
|
|
221
|
+
* refused — see migration `object-grid-data-view-data-converged`"*.
|
|
222
|
+
* - `object-calendar` — `'array'`; the test of the same name in
|
|
223
|
+
* `ObjectCalendar.dataObjectArmRefused-8348.test.tsx`. The registration
|
|
224
|
+
* publishes the same arm (`{ name: 'data', type: 'array' }`).
|
|
225
|
+
* - `object-map`, `object-gantt`, `object-tree` — `'view-data'`; one
|
|
226
|
+
* `dataArmSpecRow-8348` pin per block, in each plugin's own tests. These
|
|
227
|
+
* three rows are what ruling batch #136 item 3 (Q1-C) had the protocol
|
|
228
|
+
* gain; until they were installable, map and gantt were judged through this
|
|
229
|
+
* repo's own `ObjectMapSchema.data` / `ObjectGanttSchema.data` and tree
|
|
230
|
+
* passed `'undeclared'`. The tree's row declares `data`, so the ruling's
|
|
231
|
+
* 「协议没有的能力删」 clause did not fire for it: it keeps the object arm and
|
|
232
|
+
* loses only the bare-array spelling. Its `staticData` rung is declared by
|
|
233
|
+
* the same row and is unchanged.
|
|
234
|
+
*
|
|
235
|
+
* ## The DECLARATION follows the arm too (`ab856ed30`)
|
|
236
|
+
*
|
|
237
|
+
* The `data` member below is {@link AuthoredRecordSourceData}`<Arm>`, not a flat
|
|
238
|
+
* `ViewData`: the arm decides what a site may DECLARE exactly as it decides
|
|
239
|
+
* what rung 1 HONOURS. Read that type's docblock for why it is arm-indexed
|
|
240
|
+
* rather than a union of the arms, and for the reading that says nothing at
|
|
241
|
+
* runtime moved.
|
|
242
|
+
*
|
|
243
|
+
* ## No lenient rung was added (AGENTS.md #0.1)
|
|
244
|
+
*
|
|
245
|
+
* **Null tolerance** stays out: all five copies dereference `schema` unguarded
|
|
246
|
+
* and would throw on `null`; no site passes one, so no `?.` was added.
|
|
247
|
+
*
|
|
248
|
+
* `ObjectCalendar`'s copy guarded with `'data' in schema && schema.data`. That
|
|
249
|
+
* `in` test was a TYPESCRIPT narrowing device, not a behavioural one: when the
|
|
250
|
+
* property is absent the read yields `undefined`, which is falsy either way, so
|
|
251
|
+
* the guard could never change which rung is taken. The optional-property
|
|
252
|
+
* parameter below admits a schema that declares neither key directly, which is
|
|
253
|
+
* why the guard is gone rather than flattened away. The equivalence itself is
|
|
254
|
+
* pinned, not argued, by `CALENDAR_IN_GUARD` in
|
|
255
|
+
* `record-source-config.behaviourNeutrality-7632.test.ts`.
|
|
256
|
+
*
|
|
257
|
+
* ⛔ This passage used to explain that guard by the PROPS UNION the calendar
|
|
258
|
+
* plugin once carried — `ObjectGridSchema | CalendarSchema`, whose second
|
|
259
|
+
* member declared neither `data` nor `staticData`. objectui#8651 RETIRED that
|
|
260
|
+
* union (`ObjectCalendarComponentProps.schema` is the published
|
|
261
|
+
* `ObjectCalendarSchema` today), so the sentence explained the guard by a type
|
|
262
|
+
* no reader could look up. Rewritten rather than deleted: the guard's history
|
|
263
|
+
* is still why this parameter's members are optional.
|
|
264
|
+
*
|
|
265
|
+
* @param schema - The block's schema; only `data`, `staticData` and
|
|
266
|
+
* `objectName` are read. Its `data` member is typed by the arm — see
|
|
267
|
+
* {@link AuthoredRecordSourceData}.
|
|
268
|
+
* @param dataArm - The arm the CALLING BLOCK's published `data` row declares.
|
|
269
|
+
* Required: there is no repo-wide default, because the answer differs per
|
|
270
|
+
* block and a default is how the second de-facto contract got in.
|
|
271
|
+
* @returns The resolved data config, or `null` when nothing is bound.
|
|
272
|
+
*
|
|
273
|
+
* @example
|
|
274
|
+
* ```ts
|
|
275
|
+
* const dataConfig = useMemo(() => resolveRecordSourceConfig(schema, 'view-data'), [schema]);
|
|
276
|
+
* const objectName = resolveRecordSourceObjectName(schema, dataConfig);
|
|
277
|
+
* ```
|
|
278
|
+
*/
|
|
279
|
+
export declare function resolveRecordSourceConfig<Arm extends RecordSourceDataArm>(schema: {
|
|
280
|
+
objectName?: string;
|
|
281
|
+
data?: AuthoredRecordSourceData<Arm>;
|
|
282
|
+
staticData?: any[];
|
|
283
|
+
}, dataArm: Arm): ViewData | null;
|
|
284
|
+
/**
|
|
285
|
+
* Which `data` arm the block registered under `type` declares.
|
|
286
|
+
*
|
|
287
|
+
* `'undeclared'` for every type not listed above — the same verdict the ladder
|
|
288
|
+
* gives a block no published face declares a `data` row for, and the same
|
|
289
|
+
* behaviour those types have today. That default is deliberately the
|
|
290
|
+
* NO-CHANGE direction: a caller acting on this reading (today:
|
|
291
|
+
* `SchemaRenderer`'s props spread) leaves an unlisted type exactly as it was,
|
|
292
|
+
* so a block that has never been measured is never silently re-decided by this
|
|
293
|
+
* table's mere existence.
|
|
294
|
+
*
|
|
295
|
+
* @param type - The node's registry key, either spelling.
|
|
296
|
+
* @returns The arm that type's published `data` row declares.
|
|
297
|
+
*/
|
|
298
|
+
export declare function recordSourceDataArmForType(type: string | null | undefined): RecordSourceDataArm;
|