@object-ui/core 17.6.0 → 18.0.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 +7260 -0
- package/README.md +228 -14
- package/dist/actions/ActionEngine.d.ts +4 -2
- package/dist/actions/ActionEngine.js +13 -8
- package/dist/actions/ActionRunner.d.ts +473 -69
- package/dist/actions/ActionRunner.js +792 -125
- package/dist/actions/TransactionManager.d.ts +7 -2
- package/dist/actions/UndoManager.d.ts +8 -13
- package/dist/actions/actionKeys.d.ts +9 -7
- package/dist/actions/actionKeys.js +67 -14
- package/dist/actions/actionResponse.js +2 -2
- package/dist/actions/index.d.ts +2 -0
- package/dist/actions/index.js +2 -0
- package/dist/actions/navigationTarget.d.ts +41 -0
- package/dist/actions/navigationTarget.js +20 -0
- package/dist/actions/recordDelete.d.ts +154 -0
- package/dist/actions/recordDelete.js +110 -0
- package/dist/adapters/ApiDataSource.d.ts +8 -4
- package/dist/adapters/ApiDataSource.js +19 -7
- 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/adapters/resolveDataSource.d.ts +9 -6
- package/dist/adapters/resolveDataSource.js +9 -12
- package/dist/builder/schema-builder.d.ts +38 -81
- package/dist/builder/schema-builder.js +33 -152
- package/dist/data-scope/ViewDataProvider.d.ts +8 -25
- package/dist/data-scope/ViewDataProvider.js +27 -54
- 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/deadlineSettled.d.ts +40 -0
- package/dist/evaluator/deadlineSettled.js +45 -0
- 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 +208 -31
- package/dist/evaluator/index.d.ts +2 -0
- package/dist/evaluator/index.js +2 -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 +105 -0
- package/dist/evaluator/subjectPermissions.js +86 -0
- package/dist/evaluator/unevaluablePredicate.d.ts +57 -0
- package/dist/evaluator/unevaluablePredicate.js +70 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +83 -2
- package/dist/protocols/index.d.ts +0 -1
- package/dist/protocols/index.js +9 -1
- package/dist/registry/Registry.d.ts +382 -34
- package/dist/registry/Registry.js +247 -12
- 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/affordanceGrants.d.ts +371 -0
- package/dist/utils/affordanceGrants.js +252 -0
- 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 +165 -5
- package/dist/utils/chart-series.js +123 -18
- 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 +346 -0
- package/dist/utils/date-display.js +644 -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 +81 -9
- package/dist/utils/expand-fields.js +81 -9
- package/dist/utils/extract-records.d.ts +65 -5
- package/dist/utils/extract-records.js +65 -8
- package/dist/utils/filter-converter.d.ts +158 -6
- package/dist/utils/filter-converter.js +1098 -24
- 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 +135 -11
- package/dist/utils/normalize-list-view.js +243 -64
- 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 +141 -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 +225 -83
- package/dist/validation/server-owned-value.d.ts +5 -1
- package/dist/validation/server-owned-value.js +5 -1
- 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
|
@@ -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
|
//
|
|
@@ -0,0 +1,371 @@
|
|
|
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
|
+
* The affordance-to-grant map (objectui#12082): ONE table naming, for every
|
|
10
|
+
* console affordance that offers a write, the grant the caller must hold for
|
|
11
|
+
* it — and ONE resolver every such affordance reads.
|
|
12
|
+
*
|
|
13
|
+
* ## The family this closes
|
|
14
|
+
*
|
|
15
|
+
* Each console surface used to decide on its own which grant its affordance
|
|
16
|
+
* reads, and each surface that decided wrongly was found and fixed alone
|
|
17
|
+
* (objectui#4296, #10107, #11000, #12047). objectui#12082 is the member that
|
|
18
|
+
* hurt most: a create form gated its fields on the EDIT grant, so a
|
|
19
|
+
* create-only role could not fill the form it was allowed to submit. The same
|
|
20
|
+
* pass found the record header not reading the update grant at all, and a
|
|
21
|
+
* lookup offering "Create new" with no grant read either (objectui#12081). The
|
|
22
|
+
* cause is one shape — an affordance spelling its own permission logic — so
|
|
23
|
+
* the fix is one table every affordance reads, not another one-off repair.
|
|
24
|
+
*
|
|
25
|
+
* ## What a row says
|
|
26
|
+
*
|
|
27
|
+
* `crud` — the resolved CRUD-affordance bit the affordance also needs: the
|
|
28
|
+
* object's managed-object policy (ADR-0103, the spec's
|
|
29
|
+
* `resolveCrudAffordances`) intersected with the server's effective API
|
|
30
|
+
* operation set (`/me/permissions` `apiOperations`, objectstack#3391), both
|
|
31
|
+
* through {@link resolveEffectiveCrudAffordances}. `null` for an affordance
|
|
32
|
+
* whose write does not go through the object's generic data door (an
|
|
33
|
+
* attachment upload goes through the storage route; the import template has
|
|
34
|
+
* its own endpoint), so that door's operation set says nothing about it.
|
|
35
|
+
*
|
|
36
|
+
* `grant` — the caller's object grant it exercises, asked as `can(object,
|
|
37
|
+
* grant)` (`MePermissionsProvider` maps `create` → `allowCreate`, `update` →
|
|
38
|
+
* `allowEdit`, `delete` → `allowDelete`).
|
|
39
|
+
*
|
|
40
|
+
* `field` — for an affordance that offers FIELDS to write, the field-level
|
|
41
|
+
* question asked of each one: `create` for an insert, `write` for an update.
|
|
42
|
+
* They differ only for a field the permission set does not mention, which the
|
|
43
|
+
* server's field step lets through so that object admission decides: on an
|
|
44
|
+
* insert that is `allowCreate`, on an update `allowEdit`. A field the set marks
|
|
45
|
+
* `editable: false` is refused on both, and the resolver answers that the same
|
|
46
|
+
* way for both questions. So a create form follows what the server enforces on
|
|
47
|
+
* insert, and adds no rule the server does not have.
|
|
48
|
+
*
|
|
49
|
+
* The `write` question is the server's whole update rule for the field, so it
|
|
50
|
+
* also carries the one field whose update needs an OBJECT grant beyond
|
|
51
|
+
* `allowEdit`: the record's owner, the field the spec's `SystemFieldName`
|
|
52
|
+
* constant names `OWNER_ID`. The server refuses an update that writes it without
|
|
53
|
+
* the transfer grant (`allowTransfer`, or `modifyAllRecords`), so the resolver
|
|
54
|
+
* answers `write` for it with that grant too (objectui#12103). Every row that
|
|
55
|
+
* asks `write` therefore offers the owner field only to a caller who may
|
|
56
|
+
* transfer the record — the in-place edit, the list's in-cell edit and an edit
|
|
57
|
+
* form alike, with no row of its own to forget.
|
|
58
|
+
*
|
|
59
|
+
* ## The verdict
|
|
60
|
+
*
|
|
61
|
+
* An affordance shows when the managed-object policy, the effective API
|
|
62
|
+
* operation set AND the caller's grant all allow it ({@link resolveAffordance}).
|
|
63
|
+
* Its `userActions` predicates (the #2614 object form) are surfaced only then:
|
|
64
|
+
* a predicate narrows, and never re-opens what policy, operation set or grant
|
|
65
|
+
* closed.
|
|
66
|
+
*
|
|
67
|
+
* ## Fail-open, as before
|
|
68
|
+
*
|
|
69
|
+
* With no permission provider mounted, `usePermissions()` answers `can` with
|
|
70
|
+
* `true` and `isLoaded` with `false`, so every grant here reads open and the
|
|
71
|
+
* field question is not asked at all — a standalone embed, a designer preview
|
|
72
|
+
* and a public surface behave as they did before permissions existed, and the
|
|
73
|
+
* server still enforces (the `fieldWriteGate.ts` contract in
|
|
74
|
+
* `@object-ui/plugin-form`). The policy half is not a per-principal answer and
|
|
75
|
+
* does not fail open with it, exactly as `resolveEffectiveCrudAffordances`
|
|
76
|
+
* never did.
|
|
77
|
+
*
|
|
78
|
+
* ## Adding an affordance
|
|
79
|
+
*
|
|
80
|
+
* Add its row here and read it through {@link resolveAffordance} (or
|
|
81
|
+
* {@link resolveFieldAffordance} for fields). The enumeration pin in
|
|
82
|
+
* `@object-ui/plugin-form` (`affordanceGrantMap-12082.test.tsx`) runs every row
|
|
83
|
+
* against four grant shapes and holds the row set to its own expectation table,
|
|
84
|
+
* and its census refuses a console source file that reads a CRUD grant without
|
|
85
|
+
* this map.
|
|
86
|
+
*
|
|
87
|
+
* An affordance that reads NO grant is invisible to a census of grant reads —
|
|
88
|
+
* the calendar's quick-create and drag-to-reschedule and the kanban card move
|
|
89
|
+
* were such affordances until they gained their rows. So the same pin also
|
|
90
|
+
* counts the WRITES: every call site that invokes a create, update or delete on
|
|
91
|
+
* a data source has an entry there naming the row it sits behind and the file
|
|
92
|
+
* that reads it, or the reason it has none. A write site added without an entry
|
|
93
|
+
* turns that pin red.
|
|
94
|
+
*/
|
|
95
|
+
import { type RowCrudPredicates, type SchemaLike } from './managedBy.js';
|
|
96
|
+
/** The caller's object grant an affordance exercises. */
|
|
97
|
+
export type AffordanceGrant = 'create' | 'update' | 'delete';
|
|
98
|
+
/**
|
|
99
|
+
* The field-level question a field affordance asks: `create` follows the
|
|
100
|
+
* server's insert rule, `write` its update rule.
|
|
101
|
+
*/
|
|
102
|
+
export type FieldAffordanceGrant = 'create' | 'write';
|
|
103
|
+
/** One row of {@link AFFORDANCE_GRANTS}. */
|
|
104
|
+
export interface AffordanceGrantRow {
|
|
105
|
+
/** The resolved CRUD-affordance bit it also needs, or `null` for none. */
|
|
106
|
+
readonly crud: 'create' | 'import' | 'edit' | 'delete' | null;
|
|
107
|
+
/** The caller's object grant it exercises. */
|
|
108
|
+
readonly grant: AffordanceGrant;
|
|
109
|
+
/** For an affordance that offers fields to write: the field-level question. */
|
|
110
|
+
readonly field?: FieldAffordanceGrant;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Every console affordance that offers a write → the grant it reads. Each
|
|
114
|
+
* row's comment names the affordance and the object the grant is asked of;
|
|
115
|
+
* where no object is named, it is the object the surface shows.
|
|
116
|
+
*/
|
|
117
|
+
export declare const AFFORDANCE_GRANTS: {
|
|
118
|
+
/** A create form's fields (every `ObjectForm` layout) and its form-wide lock. */
|
|
119
|
+
readonly createFormFields: {
|
|
120
|
+
readonly crud: "create";
|
|
121
|
+
readonly grant: "create";
|
|
122
|
+
readonly field: "create";
|
|
123
|
+
};
|
|
124
|
+
/** An edit form's fields (every `ObjectForm` layout) and its form-wide lock. */
|
|
125
|
+
readonly editFormFields: {
|
|
126
|
+
readonly crud: "edit";
|
|
127
|
+
readonly grant: "update";
|
|
128
|
+
readonly field: "write";
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* The record page's Edit — the header CTA and the record body's in-place
|
|
132
|
+
* editing (the details body and the highlights strip), each of whose fields
|
|
133
|
+
* asks the update question (objectui#12103) — and the record overlay's
|
|
134
|
+
* inline edit, the same body in the overlay the calendar, kanban and gantt
|
|
135
|
+
* open (`RecordDetailPanel` in `@object-ui/plugin-detail`).
|
|
136
|
+
*/
|
|
137
|
+
readonly recordEdit: {
|
|
138
|
+
readonly crud: "edit";
|
|
139
|
+
readonly grant: "update";
|
|
140
|
+
readonly field: "write";
|
|
141
|
+
};
|
|
142
|
+
/** The record page's Delete. */
|
|
143
|
+
readonly recordDelete: {
|
|
144
|
+
readonly crud: "delete";
|
|
145
|
+
readonly grant: "delete";
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* An object list's New: the console list page's toolbar button and phone
|
|
149
|
+
* "+", and the `object-view` node's toolbar button (`@object-ui/plugin-view`).
|
|
150
|
+
*/
|
|
151
|
+
readonly listNew: {
|
|
152
|
+
readonly crud: "create";
|
|
153
|
+
readonly grant: "create";
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* An object list's Import, and the import wizard's writable target fields —
|
|
157
|
+
* and the AI build panel's spreadsheet import (`ExcelImportBar` in
|
|
158
|
+
* `@object-ui/app-shell`), the wizard's second mount, asked of the object it
|
|
159
|
+
* imports into.
|
|
160
|
+
*/
|
|
161
|
+
readonly listImport: {
|
|
162
|
+
readonly crud: "import";
|
|
163
|
+
readonly grant: "create";
|
|
164
|
+
readonly field: "create";
|
|
165
|
+
};
|
|
166
|
+
/** The import wizard's template download — its endpoint answers 403 without the create grant. */
|
|
167
|
+
readonly importTemplate: {
|
|
168
|
+
readonly crud: null;
|
|
169
|
+
readonly grant: "create";
|
|
170
|
+
};
|
|
171
|
+
/** A list's inline (in-cell) editing, each of whose cells asks the update question (objectui#12103). */
|
|
172
|
+
readonly listInlineEdit: {
|
|
173
|
+
readonly crud: "edit";
|
|
174
|
+
readonly grant: "update";
|
|
175
|
+
readonly field: "write";
|
|
176
|
+
};
|
|
177
|
+
/** A list's bulk Delete. */
|
|
178
|
+
readonly listBulkDelete: {
|
|
179
|
+
readonly crud: "delete";
|
|
180
|
+
readonly grant: "delete";
|
|
181
|
+
};
|
|
182
|
+
/**
|
|
183
|
+
* A grid row's Edit — and the writes that update the same rows in place: a
|
|
184
|
+
* grid's bulk field update (a `bulkActionDefs` `update` operation, with its
|
|
185
|
+
* undo and retry), and a gantt task's in-chart edits (a bar's drag, resize
|
|
186
|
+
* and progress, its title edited in place, and its dependency links).
|
|
187
|
+
*/
|
|
188
|
+
readonly rowEdit: {
|
|
189
|
+
readonly crud: "edit";
|
|
190
|
+
readonly grant: "update";
|
|
191
|
+
};
|
|
192
|
+
/** A grid row's Delete — and a gantt row's Delete. */
|
|
193
|
+
readonly rowDelete: {
|
|
194
|
+
readonly crud: "delete";
|
|
195
|
+
readonly grant: "delete";
|
|
196
|
+
};
|
|
197
|
+
/** A grid's inline add-record row. */
|
|
198
|
+
readonly gridAddRow: {
|
|
199
|
+
readonly crud: "create";
|
|
200
|
+
readonly grant: "create";
|
|
201
|
+
};
|
|
202
|
+
/**
|
|
203
|
+
* A related list's "+ New", asked of the CHILD object — and a line-items
|
|
204
|
+
* panel's or a master-detail form's add-a-line (its Add, entry row and
|
|
205
|
+
* Duplicate), which creates a child under the same parent.
|
|
206
|
+
*/
|
|
207
|
+
readonly relatedNew: {
|
|
208
|
+
readonly crud: "create";
|
|
209
|
+
readonly grant: "create";
|
|
210
|
+
};
|
|
211
|
+
/** A related list row's Edit, asked of the child object. */
|
|
212
|
+
readonly relatedRowEdit: {
|
|
213
|
+
readonly crud: "edit";
|
|
214
|
+
readonly grant: "update";
|
|
215
|
+
};
|
|
216
|
+
/**
|
|
217
|
+
* A related list row's Delete, asked of the child object — and a line-items
|
|
218
|
+
* panel's or a master-detail EDIT form's remove-a-line, which deletes that
|
|
219
|
+
* child on Save.
|
|
220
|
+
*/
|
|
221
|
+
readonly relatedRowDelete: {
|
|
222
|
+
readonly crud: "delete";
|
|
223
|
+
readonly grant: "delete";
|
|
224
|
+
};
|
|
225
|
+
/**
|
|
226
|
+
* Setup's Clone of a declared item (objectui#12982): a declared sharing
|
|
227
|
+
* rule's Clone creates an organization rule, asked of the object the
|
|
228
|
+
* environment authors such items as (`sys_sharing_rule`).
|
|
229
|
+
*/
|
|
230
|
+
readonly declarationClone: {
|
|
231
|
+
readonly crud: "create";
|
|
232
|
+
readonly grant: "create";
|
|
233
|
+
};
|
|
234
|
+
/** A lookup picker's "Create new", asked of the TARGET object. */
|
|
235
|
+
readonly lookupCreateNew: {
|
|
236
|
+
readonly crud: "create";
|
|
237
|
+
readonly grant: "create";
|
|
238
|
+
};
|
|
239
|
+
/** The record Attachments panel's Upload, asked of `sys_attachment` (storage route, not the data door). */
|
|
240
|
+
readonly attachmentUpload: {
|
|
241
|
+
readonly crud: null;
|
|
242
|
+
readonly grant: "create";
|
|
243
|
+
};
|
|
244
|
+
/** The record Attachments panel's per-row delete, asked of `sys_attachment`. */
|
|
245
|
+
readonly attachmentDelete: {
|
|
246
|
+
readonly crud: null;
|
|
247
|
+
readonly grant: "delete";
|
|
248
|
+
};
|
|
249
|
+
/**
|
|
250
|
+
* The record feed's comment composer and its reply composer, asked of
|
|
251
|
+
* `sys_comment`: each creates a comment row.
|
|
252
|
+
*/
|
|
253
|
+
readonly feedComment: {
|
|
254
|
+
readonly crud: "create";
|
|
255
|
+
readonly grant: "create";
|
|
256
|
+
};
|
|
257
|
+
/**
|
|
258
|
+
* The record feed's reaction control, adding the caller's reaction (its Add
|
|
259
|
+
* button, or an emoji the caller has not reacted with), asked of
|
|
260
|
+
* `sys_comment_reaction`: it creates the caller's own reaction row.
|
|
261
|
+
*/
|
|
262
|
+
readonly feedReactionAdd: {
|
|
263
|
+
readonly crud: "create";
|
|
264
|
+
readonly grant: "create";
|
|
265
|
+
};
|
|
266
|
+
/**
|
|
267
|
+
* The same control taking the caller's reaction back, asked of
|
|
268
|
+
* `sys_comment_reaction`: it deletes the caller's own reaction row.
|
|
269
|
+
*/
|
|
270
|
+
readonly feedReactionRemove: {
|
|
271
|
+
readonly crud: "delete";
|
|
272
|
+
readonly grant: "delete";
|
|
273
|
+
};
|
|
274
|
+
/**
|
|
275
|
+
* The same control on a deployment with no `sys_comment_reaction` (the
|
|
276
|
+
* reactions column store), asked of `sys_comment`: a click updates the
|
|
277
|
+
* comment's `reactions` column.
|
|
278
|
+
*/
|
|
279
|
+
readonly feedReactionColumn: {
|
|
280
|
+
readonly crud: "edit";
|
|
281
|
+
readonly grant: "update";
|
|
282
|
+
};
|
|
283
|
+
/**
|
|
284
|
+
* The record feed's Edit on a comment or reply the caller wrote, asked of
|
|
285
|
+
* `sys_comment`: it updates that comment row (objectui#12268). Whose comment
|
|
286
|
+
* it is decides only which rows offer it; the server's own rule decides the
|
|
287
|
+
* write.
|
|
288
|
+
*/
|
|
289
|
+
readonly feedCommentEdit: {
|
|
290
|
+
readonly crud: "edit";
|
|
291
|
+
readonly grant: "update";
|
|
292
|
+
};
|
|
293
|
+
/** The same rows' Delete, asked of `sys_comment`: it deletes that comment row. */
|
|
294
|
+
readonly feedCommentDelete: {
|
|
295
|
+
readonly crud: "delete";
|
|
296
|
+
readonly grant: "delete";
|
|
297
|
+
};
|
|
298
|
+
/** A calendar's quick-create: an empty-day click, or a time-range drag in the week / day grid. */
|
|
299
|
+
readonly calendarQuickCreate: {
|
|
300
|
+
readonly crud: "create";
|
|
301
|
+
readonly grant: "create";
|
|
302
|
+
};
|
|
303
|
+
/** A calendar's drag-to-reschedule: moving or resizing an event writes its date fields. */
|
|
304
|
+
readonly calendarReschedule: {
|
|
305
|
+
readonly crud: "edit";
|
|
306
|
+
readonly grant: "update";
|
|
307
|
+
};
|
|
308
|
+
/** A kanban's card move: a cross-column drop writes the record's `groupBy` field. */
|
|
309
|
+
readonly kanbanCardMove: {
|
|
310
|
+
readonly crud: "edit";
|
|
311
|
+
readonly grant: "update";
|
|
312
|
+
};
|
|
313
|
+
};
|
|
314
|
+
/** A console affordance with a row in {@link AFFORDANCE_GRANTS}. */
|
|
315
|
+
export type ConsoleAffordance = keyof typeof AFFORDANCE_GRANTS;
|
|
316
|
+
/** The affordances that offer fields to write. */
|
|
317
|
+
export type FieldAffordance = {
|
|
318
|
+
[K in ConsoleAffordance]: (typeof AFFORDANCE_GRANTS)[K] extends {
|
|
319
|
+
field: FieldAffordanceGrant;
|
|
320
|
+
} ? K : never;
|
|
321
|
+
}[ConsoleAffordance];
|
|
322
|
+
/**
|
|
323
|
+
* The principal surface {@link resolveAffordance} reads — structurally the
|
|
324
|
+
* subset of `usePermissions()` that answers it, declared here so this module
|
|
325
|
+
* stays React-free and binds to no provider.
|
|
326
|
+
*/
|
|
327
|
+
export interface AffordanceGrantPrincipal {
|
|
328
|
+
/** `usePermissions().can` — `true` for every grant with no provider mounted. */
|
|
329
|
+
can(object: string, grant: AffordanceGrant): boolean;
|
|
330
|
+
/** The server's effective API operation set for an object; `undefined` leaves the policy as it is. */
|
|
331
|
+
getObjectApiOperations?(object: string): readonly string[] | undefined;
|
|
332
|
+
}
|
|
333
|
+
/** The principal surface {@link resolveFieldAffordance} reads. */
|
|
334
|
+
export interface FieldAffordancePrincipal {
|
|
335
|
+
/** `false` with no provider mounted: no field question is asked. */
|
|
336
|
+
isLoaded: boolean;
|
|
337
|
+
checkField(object: string, field: string, action: FieldAffordanceGrant): boolean;
|
|
338
|
+
}
|
|
339
|
+
/** What an affordance is resolved against. */
|
|
340
|
+
export interface AffordanceSource {
|
|
341
|
+
/** The schema of the object the grant is asked of; `null` reads as the default bucket. */
|
|
342
|
+
objectSchema?: SchemaLike | null;
|
|
343
|
+
/** That object's name. Absent: no grant and no operation set can be asked, so both read open. */
|
|
344
|
+
objectName?: string | null;
|
|
345
|
+
/** The caller's permissions; absent reads open, as no provider does. */
|
|
346
|
+
perms?: AffordanceGrantPrincipal | null;
|
|
347
|
+
}
|
|
348
|
+
/** One affordance's verdict. */
|
|
349
|
+
export interface AffordanceVerdict {
|
|
350
|
+
/** Policy ∧ effective API operation set ∧ the caller's grant. */
|
|
351
|
+
readonly allowed: boolean;
|
|
352
|
+
/** The row's `userActions` predicate envelope — only when {@link allowed}. */
|
|
353
|
+
readonly predicates?: RowCrudPredicates;
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Resolve one affordance: its row's CRUD-affordance bit (managed-object policy
|
|
357
|
+
* ∧ the effective API operation set) AND the caller's grant.
|
|
358
|
+
*/
|
|
359
|
+
export declare function resolveAffordance(affordance: ConsoleAffordance, { objectSchema, objectName, perms }?: AffordanceSource): AffordanceVerdict;
|
|
360
|
+
/**
|
|
361
|
+
* The field-level half of a field affordance: may the caller write `field`
|
|
362
|
+
* through it? Asks the resolver the row's question (`create` or `write`); with
|
|
363
|
+
* no provider mounted (`isLoaded` false) it asks nothing and answers `true`.
|
|
364
|
+
*/
|
|
365
|
+
export declare function resolveFieldAffordance(affordance: FieldAffordance, perms: FieldAffordancePrincipal | null | undefined, objectName: string, field: string): boolean;
|
|
366
|
+
/**
|
|
367
|
+
* The form row for a form's mode: a create form's fields ask the create
|
|
368
|
+
* question, every other form that writes asks the edit question, and a `view`
|
|
369
|
+
* form writes nothing (`undefined`).
|
|
370
|
+
*/
|
|
371
|
+
export declare function formFieldsAffordance(mode: string | undefined): 'createFormFields' | 'editFormFields' | undefined;
|