@ouispec/bindings 0.0.0-stage → 0.1.1
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/LICENSE +21 -0
- package/README.md +18 -2
- package/dist/binding.d.ts +46 -0
- package/dist/binding.d.ts.map +1 -0
- package/dist/binding.js +51 -0
- package/dist/binding.js.map +1 -0
- package/dist/controls.d.ts +69 -0
- package/dist/controls.d.ts.map +1 -0
- package/dist/controls.js +334 -0
- package/dist/controls.js.map +1 -0
- package/dist/effect.d.ts +54 -0
- package/dist/effect.d.ts.map +1 -0
- package/dist/effect.js +88 -0
- package/dist/effect.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/interactive.d.ts +12 -0
- package/dist/interactive.d.ts.map +1 -0
- package/dist/interactive.js +21 -0
- package/dist/interactive.js.map +1 -0
- package/dist/jobs.d.ts +54 -0
- package/dist/jobs.d.ts.map +1 -0
- package/dist/jobs.js +74 -0
- package/dist/jobs.js.map +1 -0
- package/dist/json-schema.d.ts +36 -0
- package/dist/json-schema.d.ts.map +1 -0
- package/dist/json-schema.js +196 -0
- package/dist/json-schema.js.map +1 -0
- package/dist/jsx.d.ts +19 -0
- package/dist/jsx.d.ts.map +1 -0
- package/dist/jsx.js +2 -0
- package/dist/jsx.js.map +1 -0
- package/dist/manifest.d.ts +35 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +77 -0
- package/dist/manifest.js.map +1 -0
- package/dist/oui.d.ts +112 -0
- package/dist/oui.d.ts.map +1 -0
- package/dist/oui.js +514 -0
- package/dist/oui.js.map +1 -0
- package/dist/package-declaration.d.ts +24 -0
- package/dist/package-declaration.d.ts.map +1 -0
- package/dist/package-declaration.js +24 -0
- package/dist/package-declaration.js.map +1 -0
- package/dist/react.d.ts +74 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +179 -0
- package/dist/react.js.map +1 -0
- package/dist/registry.d.ts +103 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +146 -0
- package/dist/registry.js.map +1 -0
- package/dist/room.d.ts +79 -0
- package/dist/room.d.ts.map +1 -0
- package/dist/room.js +111 -0
- package/dist/room.js.map +1 -0
- package/dist/tier2-react.d.ts +35 -0
- package/dist/tier2-react.d.ts.map +1 -0
- package/dist/tier2-react.js +186 -0
- package/dist/tier2-react.js.map +1 -0
- package/dist/tier2.d.ts +68 -0
- package/dist/tier2.d.ts.map +1 -0
- package/dist/tier2.js +129 -0
- package/dist/tier2.js.map +1 -0
- package/package.json +74 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Closure Studio
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @ouispec/bindings
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Every UI capability declared once, in the code that implements it. A design-system control carries a binding (an id, a label, a description, and an input schema derived from its props) and registers its real handler under it, so the agent and the person go through the same code path.
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
npm install @ouispec/bindings
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
| Entry | What it has |
|
|
10
|
+
|---|---|
|
|
11
|
+
| `@ouispec/bindings` | The binding and control-table types, action effects (`effectKind`, `effectAccess`, `requiresApproval`), the room catalog contract, the generated manifest and knowledge and how they're read, and the registry of what is mounted. No dependencies on React, so the build-time generator reads it in plain Node. |
|
|
12
|
+
| `@ouispec/bindings/react` | `AgentBindingProvider`, `useAgentBinding`, `useAgentBindings`, `useRoomRegistration`, `useAgentProblems`, `useAgentFacts`. |
|
|
13
|
+
| `@ouispec/bindings/oui` | `connectBindings`, which turns what is mounted into the tab's OUI surfaces, and `createDeclaredJobTracker`, which follows a job on the product's declared events. |
|
|
14
|
+
|
|
15
|
+
A design system declares its control table in `package.json` under `oui.agentControls`; a room names its catalog under `oui.agentCatalog`. `@ouispec/cli` generates an app's surfaces and knowledge from them, and `@ouispec/testing` checks that a design system keeps the contract.
|
|
16
|
+
|
|
17
|
+
An app must have exactly one copy of this package and of `oui-spec`: two copies split the registry, and the agent sees no controls.
|
|
18
|
+
|
|
19
|
+
Start with [the integrator guide](https://github.com/wesreid/oui/blob/main/packages/contract/INTEGRATOR-GUIDE.md).
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The semantic binding a design-system control carries (ADR-0220 §2.2): what
|
|
3
|
+
* the control means, in the user's terms, declared where the page uses it.
|
|
4
|
+
*
|
|
5
|
+
* It uses a room catalog entry's vocabulary (`RoomEntryInfo`'s id, title and
|
|
6
|
+
* description; `ActionEffect`; `destructive`), so to the generator a page
|
|
7
|
+
* control and a room entry look the same. What is never written: the input
|
|
8
|
+
* schema, which is derived from the control's own props, and where the control
|
|
9
|
+
* is, which the generator derives from the page's component tree.
|
|
10
|
+
*/
|
|
11
|
+
import type { ActionEffect } from './effect.js';
|
|
12
|
+
import type { AgentBinding, AgentItem, AgentProp, NonAgentBinding } from '@ouispec/contract';
|
|
13
|
+
export type { AgentBinding, AgentItem, AgentProp, NonAgentBinding };
|
|
14
|
+
/**
|
|
15
|
+
* What using the control does.
|
|
16
|
+
* @deprecated Since 0.8: the one vocabulary is `ActionEffect` (ADR-0226 §2.6). Kept for one minor.
|
|
17
|
+
*/
|
|
18
|
+
export type BindingEffect = ActionEffect;
|
|
19
|
+
/**
|
|
20
|
+
* The `agent` prop of a composite with several callbacks (a card with open,
|
|
21
|
+
* duplicate and delete): one binding per slot, and the row they all belong to.
|
|
22
|
+
*/
|
|
23
|
+
export type AgentSlots<Slot extends string> = {
|
|
24
|
+
item?: AgentItem;
|
|
25
|
+
} & {
|
|
26
|
+
[K in Slot]?: AgentProp;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* One slot's binding of a composite's `agent` prop, with the row the whole
|
|
30
|
+
* composite is (a card's voice, a missing font's replacements) carried into
|
|
31
|
+
* it. A composite registers each slot with this, never with `agent?.slot`:
|
|
32
|
+
* the generator reads `item` beside the slots, so a slot registered without
|
|
33
|
+
* it is a row-keyed action whose rows the page never reports.
|
|
34
|
+
*/
|
|
35
|
+
export declare function slotBinding<Slot extends string>(slots: AgentSlots<Slot> | undefined | null, slot: Slot): AgentProp | undefined;
|
|
36
|
+
export declare function isNonAgent(prop: AgentProp | undefined | null): prop is NonAgentBinding;
|
|
37
|
+
export declare function isAgentBinding(prop: unknown): prop is AgentBinding;
|
|
38
|
+
/** Dotted lower-kebab segments, at least two: `area.control`. */
|
|
39
|
+
export declare const BINDING_ID_PATTERN: RegExp;
|
|
40
|
+
/** Longest tool name assistant runtimes accept. */
|
|
41
|
+
export declare const MAX_TOOL_NAME_LENGTH = 64;
|
|
42
|
+
/** The tool name for a binding or room entry id: `voices.detail.engine` → `voices_detail_engine`. */
|
|
43
|
+
export declare function toolName(id: string): string;
|
|
44
|
+
/** Why an id is not a valid binding id, or null. */
|
|
45
|
+
export declare function bindingIdProblem(id: string): string | null;
|
|
46
|
+
//# sourceMappingURL=binding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binding.d.ts","sourceRoot":"","sources":["../src/binding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAG7F,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC;AAEpE;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,YAAY,CAAC;AAEzC;;;GAGG;AACH,MAAM,MAAM,UAAU,CAAC,IAAI,SAAS,MAAM,IAAI;IAAE,IAAI,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG;KAAG,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,SAAS;CAAE,CAAC;AAEjG;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,SAAS,MAAM,EAC7C,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,GAAG,SAAS,GAAG,IAAI,EAC1C,IAAI,EAAE,IAAI,GACT,SAAS,GAAG,SAAS,CAIvB;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,IAAI,GAAG,IAAI,IAAI,eAAe,CAEtF;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,YAAY,CAOlE;AAED,iEAAiE;AACjE,eAAO,MAAM,kBAAkB,QAA6C,CAAC;AAE7E,mDAAmD;AACnD,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC,qGAAqG;AACrG,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,oDAAoD;AACpD,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ1D"}
|
package/dist/binding.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The semantic binding a design-system control carries (ADR-0220 §2.2): what
|
|
3
|
+
* the control means, in the user's terms, declared where the page uses it.
|
|
4
|
+
*
|
|
5
|
+
* It uses a room catalog entry's vocabulary (`RoomEntryInfo`'s id, title and
|
|
6
|
+
* description; `ActionEffect`; `destructive`), so to the generator a page
|
|
7
|
+
* control and a room entry look the same. What is never written: the input
|
|
8
|
+
* schema, which is derived from the control's own props, and where the control
|
|
9
|
+
* is, which the generator derives from the page's component tree.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* One slot's binding of a composite's `agent` prop, with the row the whole
|
|
13
|
+
* composite is (a card's voice, a missing font's replacements) carried into
|
|
14
|
+
* it. A composite registers each slot with this, never with `agent?.slot`:
|
|
15
|
+
* the generator reads `item` beside the slots, so a slot registered without
|
|
16
|
+
* it is a row-keyed action whose rows the page never reports.
|
|
17
|
+
*/
|
|
18
|
+
export function slotBinding(slots, slot) {
|
|
19
|
+
const prop = slots?.[slot];
|
|
20
|
+
if (!prop || isNonAgent(prop) || !slots?.item || prop.item)
|
|
21
|
+
return prop;
|
|
22
|
+
return { ...prop, item: slots.item };
|
|
23
|
+
}
|
|
24
|
+
export function isNonAgent(prop) {
|
|
25
|
+
return !!prop && typeof prop.nonAgent === 'string';
|
|
26
|
+
}
|
|
27
|
+
export function isAgentBinding(prop) {
|
|
28
|
+
return (!!prop &&
|
|
29
|
+
typeof prop === 'object' &&
|
|
30
|
+
typeof prop.id === 'string' &&
|
|
31
|
+
typeof prop.description === 'string');
|
|
32
|
+
}
|
|
33
|
+
/** Dotted lower-kebab segments, at least two: `area.control`. */
|
|
34
|
+
export const BINDING_ID_PATTERN = /^[a-z][a-z0-9-]*(\.[a-z0-9][a-z0-9-]*)+$/;
|
|
35
|
+
/** Longest tool name assistant runtimes accept. */
|
|
36
|
+
export const MAX_TOOL_NAME_LENGTH = 64;
|
|
37
|
+
/** The tool name for a binding or room entry id: `voices.detail.engine` → `voices_detail_engine`. */
|
|
38
|
+
export function toolName(id) {
|
|
39
|
+
return id.replace(/[.\-/]/g, '_');
|
|
40
|
+
}
|
|
41
|
+
/** Why an id is not a valid binding id, or null. */
|
|
42
|
+
export function bindingIdProblem(id) {
|
|
43
|
+
if (!BINDING_ID_PATTERN.test(id)) {
|
|
44
|
+
return `"${id}" must be dotted lower-kebab with at least two segments, like "voices.library"`;
|
|
45
|
+
}
|
|
46
|
+
if (toolName(id).length > MAX_TOOL_NAME_LENGTH) {
|
|
47
|
+
return `"${id}" makes a tool name longer than ${MAX_TOOL_NAME_LENGTH} characters`;
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=binding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binding.js","sourceRoot":"","sources":["../src/binding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAoBH;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CACzB,KAA0C,EAC1C,IAAU;IAEV,MAAM,IAAI,GAAG,KAAK,EAAE,CAAC,IAAI,CAA0B,CAAC;IACpD,IAAI,CAAC,IAAI,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,IAAI,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACxE,OAAO,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAkC;IAC3D,OAAO,CAAC,CAAC,IAAI,IAAI,OAAQ,IAAwB,CAAC,QAAQ,KAAK,QAAQ,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAa;IAC1C,OAAO,CACL,CAAC,CAAC,IAAI;QACN,OAAO,IAAI,KAAK,QAAQ;QACxB,OAAQ,IAAqB,CAAC,EAAE,KAAK,QAAQ;QAC7C,OAAQ,IAAqB,CAAC,WAAW,KAAK,QAAQ,CACvD,CAAC;AACJ,CAAC;AAED,iEAAiE;AACjE,MAAM,CAAC,MAAM,kBAAkB,GAAG,0CAA0C,CAAC;AAE7E,mDAAmD;AACnD,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEvC,qGAAqG;AACrG,MAAM,UAAU,QAAQ,CAAC,EAAU;IACjC,OAAO,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;AACpC,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,gBAAgB,CAAC,EAAU;IACzC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;QACjC,OAAO,IAAI,EAAE,gFAAgF,CAAC;IAChG,CAAC;IACD,IAAI,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,GAAG,oBAAoB,EAAE,CAAC;QAC/C,OAAO,IAAI,EAAE,mCAAmC,oBAAoB,aAAa,CAAC;IACpF,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What each kind of design-system control lets someone do, and the input
|
|
3
|
+
* schema that follows from its props (ADR-0220 §2.2).
|
|
4
|
+
*
|
|
5
|
+
* `deriveInputSchema` is the one derivation. A control runs it in the browser
|
|
6
|
+
* on its live props; the generator runs it at build time on the props it can
|
|
7
|
+
* read statically. So the schema a tool takes is never written by hand: a
|
|
8
|
+
* slider's range is its `min` and `max`, a select's options are its options.
|
|
9
|
+
*/
|
|
10
|
+
import type { AnyControlKind, ControlKind, ControlKindRegistration, ControlTable, JsonSchema, RegisteredControlKind, SchemaProps } from '@ouispec/contract';
|
|
11
|
+
export type { AnyControlKind, ControlDescriptor, ControlKind, ControlKindRegistration, ControlOption, ControlTable, ControlTableFile, EntriesDescriptor, KindSchemaDerivation, OptionsSource, RegisteredControlKind, SchemaPropName, SchemaPropSources, SchemaProps, SlotDescriptor, } from '@ouispec/contract';
|
|
12
|
+
/**
|
|
13
|
+
* Every built-in kind (`ControlKind`, documented in the contract). Closed: a
|
|
14
|
+
* design system adds a kind only by registering it (`registerControlKind`),
|
|
15
|
+
* under an `x-` name, in its control table.
|
|
16
|
+
*/
|
|
17
|
+
export declare const CONTROL_KINDS: readonly ControlKind[];
|
|
18
|
+
/** What each kind's action does, as knowledge and tool descriptions say it. */
|
|
19
|
+
export declare const CONTROL_VERBS: Readonly<Record<ControlKind, string>>;
|
|
20
|
+
/** The schema of a control's value, from its kind and props. */
|
|
21
|
+
/**
|
|
22
|
+
* How many of a choice's options its schema's description names. The enum
|
|
23
|
+
* always lists every value; the description is prose for the assistant, and a
|
|
24
|
+
* control with hundreds of options (a language picker) would otherwise fill
|
|
25
|
+
* the page state the assistant reads with option names and crowd out what the
|
|
26
|
+
* page shows.
|
|
27
|
+
*/
|
|
28
|
+
export declare const MAX_DESCRIBED_OPTIONS = 20;
|
|
29
|
+
export declare function deriveValueSchema(kind: AnyControlKind, props?: SchemaProps): JsonSchema | null;
|
|
30
|
+
export declare function isRegisteredKind(kind: string): kind is RegisteredControlKind;
|
|
31
|
+
/** Why a registration is not valid, or null. */
|
|
32
|
+
export declare function controlKindRegistrationProblem(registration: unknown): string | null;
|
|
33
|
+
/**
|
|
34
|
+
* Register a design system's control kind, so controls of that kind derive
|
|
35
|
+
* their value schema and verb. Registering the same kind again with the same
|
|
36
|
+
* definition does nothing; with another definition it throws, as does an
|
|
37
|
+
* invalid registration.
|
|
38
|
+
*/
|
|
39
|
+
export declare function registerControlKind(registration: ControlKindRegistration): void;
|
|
40
|
+
export declare function registeredControlKind(kind: string): ControlKindRegistration | undefined;
|
|
41
|
+
/** What using a control of this kind does, as a tool description starts. */
|
|
42
|
+
export declare function controlVerb(kind: AnyControlKind): string;
|
|
43
|
+
/** The item parameter an action takes when its control is one of a list's rows. */
|
|
44
|
+
export declare const ITEM_PROPERTY = "item";
|
|
45
|
+
export declare function itemSchema(items?: readonly {
|
|
46
|
+
key: string;
|
|
47
|
+
title: string;
|
|
48
|
+
}[]): JsonSchema;
|
|
49
|
+
/** Beyond this many rows, the item parameter names none of them; the page observation lists them. */
|
|
50
|
+
export declare const MAX_ITEM_ENUM = 100;
|
|
51
|
+
/**
|
|
52
|
+
* The input schema of the action a control makes: `{ value }` for a field,
|
|
53
|
+
* nothing for a button or dialog, and an `item` when it is one of a list's rows.
|
|
54
|
+
*/
|
|
55
|
+
export declare function deriveInputSchema(kind: AnyControlKind, props?: SchemaProps, options?: {
|
|
56
|
+
itemized?: boolean;
|
|
57
|
+
items?: readonly {
|
|
58
|
+
key: string;
|
|
59
|
+
title: string;
|
|
60
|
+
}[];
|
|
61
|
+
}): JsonSchema;
|
|
62
|
+
/** Where a control table file lists the kinds its design system registers. */
|
|
63
|
+
export declare const CONTROL_TABLE_KINDS_KEY = "$kinds";
|
|
64
|
+
/** A control table file's controls and the kinds it registers. */
|
|
65
|
+
export declare function readControlTable(file: unknown): {
|
|
66
|
+
controls: ControlTable;
|
|
67
|
+
kinds: readonly ControlKindRegistration[];
|
|
68
|
+
};
|
|
69
|
+
//# sourceMappingURL=controls.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controls.d.ts","sourceRoot":"","sources":["../src/controls.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,uBAAuB,EACvB,YAAY,EACZ,UAAU,EACV,qBAAqB,EACrB,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAO3B,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,WAAW,EACX,uBAAuB,EACvB,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,aAAa,EACb,qBAAqB,EACrB,cAAc,EACd,iBAAiB,EACjB,WAAW,EACX,cAAc,GACf,MAAM,mBAAmB,CAAC;AAE3B;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,WAAW,EAa/C,CAAC;AAEF,+EAA+E;AAC/E,eAAO,MAAM,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAa/D,CAAC;AASF,gEAAgE;AAChE;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAExC,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,GAAE,WAAgB,GAAG,UAAU,GAAG,IAAI,CAiIlG;AAQD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,qBAAqB,CAE5E;AAED,gDAAgD;AAChD,wBAAgB,8BAA8B,CAAC,YAAY,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAcnF;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,uBAAuB,GAAG,IAAI,CAS/E;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,uBAAuB,GAAG,SAAS,CAEvF;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAKxD;AA8CD,mFAAmF;AACnF,eAAO,MAAM,aAAa,SAAS,CAAC;AAEpC,wBAAgB,UAAU,CAAC,KAAK,CAAC,EAAE,SAAS;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,UAAU,CAQxF;AAED,qGAAqG;AACrG,eAAO,MAAM,aAAa,MAAM,CAAC;AAEjC;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,cAAc,EACpB,KAAK,GAAE,WAAgB,EACvB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAO,GACtF,UAAU,CAkBZ;AAID,8EAA8E;AAC9E,eAAO,MAAM,uBAAuB,WAAW,CAAC;AAEhD,kEAAkE;AAClE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG;IAAE,QAAQ,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,SAAS,uBAAuB,EAAE,CAAA;CAAE,CAMrH"}
|
package/dist/controls.js
ADDED
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What each kind of design-system control lets someone do, and the input
|
|
3
|
+
* schema that follows from its props (ADR-0220 §2.2).
|
|
4
|
+
*
|
|
5
|
+
* `deriveInputSchema` is the one derivation. A control runs it in the browser
|
|
6
|
+
* on its live props; the generator runs it at build time on the props it can
|
|
7
|
+
* read statically. So the schema a tool takes is never written by hand: a
|
|
8
|
+
* slider's range is its `min` and `max`, a select's options are its options.
|
|
9
|
+
*/
|
|
10
|
+
import { stableStringify } from './json-schema.js';
|
|
11
|
+
/**
|
|
12
|
+
* Every built-in kind (`ControlKind`, documented in the contract). Closed: a
|
|
13
|
+
* design system adds a kind only by registering it (`registerControlKind`),
|
|
14
|
+
* under an `x-` name, in its control table.
|
|
15
|
+
*/
|
|
16
|
+
export const CONTROL_KINDS = [
|
|
17
|
+
'button',
|
|
18
|
+
'toggle',
|
|
19
|
+
'text',
|
|
20
|
+
'number',
|
|
21
|
+
'choice',
|
|
22
|
+
'multi-choice',
|
|
23
|
+
'color',
|
|
24
|
+
'font',
|
|
25
|
+
'tabs',
|
|
26
|
+
'date',
|
|
27
|
+
'date-range',
|
|
28
|
+
'dialog',
|
|
29
|
+
];
|
|
30
|
+
/** What each kind's action does, as knowledge and tool descriptions say it. */
|
|
31
|
+
export const CONTROL_VERBS = {
|
|
32
|
+
button: 'Press',
|
|
33
|
+
toggle: 'Turn on or off',
|
|
34
|
+
text: 'Type into',
|
|
35
|
+
number: 'Set',
|
|
36
|
+
choice: 'Choose',
|
|
37
|
+
'multi-choice': 'Choose any of',
|
|
38
|
+
color: 'Set the colour of',
|
|
39
|
+
font: 'Choose the face of',
|
|
40
|
+
tabs: 'Select a tab of',
|
|
41
|
+
date: 'Set the date of',
|
|
42
|
+
'date-range': 'Set the dates of',
|
|
43
|
+
dialog: 'Close',
|
|
44
|
+
};
|
|
45
|
+
const INPUT_FORMATS = {
|
|
46
|
+
email: 'email',
|
|
47
|
+
url: 'uri',
|
|
48
|
+
date: 'date',
|
|
49
|
+
time: 'time',
|
|
50
|
+
};
|
|
51
|
+
/** The schema of a control's value, from its kind and props. */
|
|
52
|
+
/**
|
|
53
|
+
* How many of a choice's options its schema's description names. The enum
|
|
54
|
+
* always lists every value; the description is prose for the assistant, and a
|
|
55
|
+
* control with hundreds of options (a language picker) would otherwise fill
|
|
56
|
+
* the page state the assistant reads with option names and crowd out what the
|
|
57
|
+
* page shows.
|
|
58
|
+
*/
|
|
59
|
+
export const MAX_DESCRIBED_OPTIONS = 20;
|
|
60
|
+
export function deriveValueSchema(kind, props = {}) {
|
|
61
|
+
if (isRegisteredKind(kind))
|
|
62
|
+
return registeredValueSchema(kind, props);
|
|
63
|
+
switch (kind) {
|
|
64
|
+
case 'button':
|
|
65
|
+
case 'dialog':
|
|
66
|
+
return null;
|
|
67
|
+
case 'toggle':
|
|
68
|
+
return { type: 'boolean', description: 'true to turn it on, false to turn it off' };
|
|
69
|
+
case 'text': {
|
|
70
|
+
if (props.inputType === 'number')
|
|
71
|
+
return numberSchema(props);
|
|
72
|
+
const format = props.inputType ? INPUT_FORMATS[props.inputType] : undefined;
|
|
73
|
+
return {
|
|
74
|
+
type: 'string',
|
|
75
|
+
description: 'The text to put in the field, replacing what is there',
|
|
76
|
+
...(props.minLength !== undefined ? { minLength: props.minLength } : {}),
|
|
77
|
+
...(props.maxLength !== undefined ? { maxLength: props.maxLength } : {}),
|
|
78
|
+
...(props.pattern !== undefined ? { pattern: props.pattern } : {}),
|
|
79
|
+
...(format ? { format } : {}),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
case 'number':
|
|
83
|
+
return numberSchema(props);
|
|
84
|
+
case 'multi-choice': {
|
|
85
|
+
const options = (props.options ?? []).filter(o => !o.disabled);
|
|
86
|
+
const values = options.map(o => o.value);
|
|
87
|
+
const described = options.map(o => (String(o.value) === o.title ? o.title : `${o.value} = ${o.title}`));
|
|
88
|
+
return {
|
|
89
|
+
type: 'array',
|
|
90
|
+
description: 'The options to choose, replacing the ones chosen now; [] for none' +
|
|
91
|
+
(described.length ? `: ${described.join('; ')}` : ''),
|
|
92
|
+
items: {
|
|
93
|
+
type: values.every(v => typeof v === 'number') && values.length > 0 ? 'number' : 'string',
|
|
94
|
+
...(values.length ? { enum: values } : {}),
|
|
95
|
+
},
|
|
96
|
+
uniqueItems: true,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
case 'choice':
|
|
100
|
+
case 'tabs': {
|
|
101
|
+
const options = (props.options ?? []).filter(o => !o.disabled);
|
|
102
|
+
const values = options.map(o => o.value);
|
|
103
|
+
// Named in the description up to a limit; every value stays in the enum.
|
|
104
|
+
const described = options
|
|
105
|
+
.slice(0, MAX_DESCRIBED_OPTIONS)
|
|
106
|
+
.map(o => (String(o.value) === o.title ? o.title : `${o.value} = ${o.title}`));
|
|
107
|
+
const unnamed = options.length - described.length;
|
|
108
|
+
const schema = {
|
|
109
|
+
type: values.every(v => typeof v === 'number') && values.length > 0 ? 'number' : 'string',
|
|
110
|
+
description: (kind === 'tabs' ? 'The tab to select' : 'The option to choose') +
|
|
111
|
+
(described.length ? `: ${described.join('; ')}` : '') +
|
|
112
|
+
(unnamed > 0 ? `; and ${unnamed} more, any of which may be chosen` : ''),
|
|
113
|
+
...(values.length ? { enum: props.clearable ? [...values, null] : values } : {}),
|
|
114
|
+
};
|
|
115
|
+
if (props.clearable) {
|
|
116
|
+
return { ...schema, type: [schema.type, 'null'] };
|
|
117
|
+
}
|
|
118
|
+
return schema;
|
|
119
|
+
}
|
|
120
|
+
case 'color': {
|
|
121
|
+
const kinds = props.paintKinds ?? ['solid'];
|
|
122
|
+
const gradients = kinds.filter(k => k !== 'solid');
|
|
123
|
+
const css = {
|
|
124
|
+
type: 'string',
|
|
125
|
+
description: 'A CSS colour, e.g. "#eb0a1e" or "rgba(0,0,0,0.5)"',
|
|
126
|
+
};
|
|
127
|
+
const variants = [css];
|
|
128
|
+
if (gradients.length) {
|
|
129
|
+
variants.push({
|
|
130
|
+
type: 'object',
|
|
131
|
+
description: `A gradient paint: kind ${gradients.join(' or ')}, its stops from offset 0 to 1, and for a linear gradient its angle in degrees`,
|
|
132
|
+
properties: {
|
|
133
|
+
kind: { type: 'string', enum: gradients },
|
|
134
|
+
angle: { type: 'number', 'x-unit': '°' },
|
|
135
|
+
stops: {
|
|
136
|
+
type: 'array',
|
|
137
|
+
minItems: 2,
|
|
138
|
+
items: {
|
|
139
|
+
type: 'object',
|
|
140
|
+
properties: {
|
|
141
|
+
offset: { type: 'number', minimum: 0, maximum: 1 },
|
|
142
|
+
color: css,
|
|
143
|
+
},
|
|
144
|
+
required: ['offset', 'color'],
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
required: ['kind', 'stops'],
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
if (props.allowNone)
|
|
152
|
+
variants.push({ type: 'null', description: 'No paint' });
|
|
153
|
+
return variants.length === 1 ? css : { anyOf: variants, description: 'The paint to set' };
|
|
154
|
+
}
|
|
155
|
+
case 'font':
|
|
156
|
+
return {
|
|
157
|
+
type: 'object',
|
|
158
|
+
description: 'The face to set: a family by name, and optionally one of its styles and axis values',
|
|
159
|
+
properties: {
|
|
160
|
+
family: {
|
|
161
|
+
type: 'string',
|
|
162
|
+
description: 'The family name as the picker lists it',
|
|
163
|
+
...(props.options?.length && props.options.length <= MAX_ITEM_ENUM
|
|
164
|
+
? { enum: props.options.map(o => o.title) }
|
|
165
|
+
: {}),
|
|
166
|
+
},
|
|
167
|
+
style: { type: 'string', description: 'A named style of the family, e.g. "Bold Italic"' },
|
|
168
|
+
variation: {
|
|
169
|
+
type: 'object',
|
|
170
|
+
description: 'Variable-font axis values by tag, e.g. {"wght": 650}',
|
|
171
|
+
additionalProperties: { type: 'number' },
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
required: ['family'],
|
|
175
|
+
};
|
|
176
|
+
case 'date':
|
|
177
|
+
return { type: 'string', format: 'date', description: 'A date, YYYY-MM-DD' };
|
|
178
|
+
case 'date-range':
|
|
179
|
+
return {
|
|
180
|
+
type: 'object',
|
|
181
|
+
description: 'A range of dates, YYYY-MM-DD: its first day and its last, the start on or before the end',
|
|
182
|
+
properties: {
|
|
183
|
+
start: { type: 'string', format: 'date', description: 'The first day' },
|
|
184
|
+
end: { type: 'string', format: 'date', description: 'The last day' },
|
|
185
|
+
},
|
|
186
|
+
required: ['start', 'end'],
|
|
187
|
+
additionalProperties: false,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
// ─── Registered kinds ────────────────────────────────────────────────────────
|
|
192
|
+
const REGISTERED_KIND = /^x-[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
|
|
193
|
+
const registeredKinds = new Map();
|
|
194
|
+
export function isRegisteredKind(kind) {
|
|
195
|
+
return kind.startsWith('x-');
|
|
196
|
+
}
|
|
197
|
+
/** Why a registration is not valid, or null. */
|
|
198
|
+
export function controlKindRegistrationProblem(registration) {
|
|
199
|
+
const r = registration;
|
|
200
|
+
if (!r || typeof r !== 'object')
|
|
201
|
+
return 'a control kind registration is an object';
|
|
202
|
+
if (typeof r.kind !== 'string' || !REGISTERED_KIND.test(r.kind))
|
|
203
|
+
return `a registered control kind is named x-<lower-kebab>, not ${JSON.stringify(r.kind)}`;
|
|
204
|
+
if (typeof r.verb !== 'string' || !r.verb.trim())
|
|
205
|
+
return `${r.kind} needs the verb its tools start with`;
|
|
206
|
+
const d = r.deriveSchema;
|
|
207
|
+
if (!d || typeof d !== 'object' || !d.schema || typeof d.schema !== 'object')
|
|
208
|
+
return `${r.kind} needs deriveSchema.schema, the value's schema`;
|
|
209
|
+
for (const [pointer, prop] of Object.entries(d.props ?? {})) {
|
|
210
|
+
if (!pointer.startsWith('/'))
|
|
211
|
+
return `${r.kind}: "${pointer}" is not a JSON Pointer into its schema`;
|
|
212
|
+
if (typeof prop !== 'string')
|
|
213
|
+
return `${r.kind}: "${pointer}" names no prop`;
|
|
214
|
+
}
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Register a design system's control kind, so controls of that kind derive
|
|
219
|
+
* their value schema and verb. Registering the same kind again with the same
|
|
220
|
+
* definition does nothing; with another definition it throws, as does an
|
|
221
|
+
* invalid registration.
|
|
222
|
+
*/
|
|
223
|
+
export function registerControlKind(registration) {
|
|
224
|
+
const problem = controlKindRegistrationProblem(registration);
|
|
225
|
+
if (problem)
|
|
226
|
+
throw new Error(problem);
|
|
227
|
+
const existing = registeredKinds.get(registration.kind);
|
|
228
|
+
// The same definition, whatever its key order: a shipped table's `$kinds` are written with sorted keys.
|
|
229
|
+
if (existing && stableStringify(existing) !== stableStringify(registration)) {
|
|
230
|
+
throw new Error(`${registration.kind} is already registered with another definition`);
|
|
231
|
+
}
|
|
232
|
+
registeredKinds.set(registration.kind, registration);
|
|
233
|
+
}
|
|
234
|
+
export function registeredControlKind(kind) {
|
|
235
|
+
return registeredKinds.get(kind);
|
|
236
|
+
}
|
|
237
|
+
/** What using a control of this kind does, as a tool description starts. */
|
|
238
|
+
export function controlVerb(kind) {
|
|
239
|
+
if (!isRegisteredKind(kind))
|
|
240
|
+
return CONTROL_VERBS[kind];
|
|
241
|
+
const registration = registeredKinds.get(kind);
|
|
242
|
+
if (!registration)
|
|
243
|
+
throw new Error(`Control kind ${kind} is not registered`);
|
|
244
|
+
return registration.verb;
|
|
245
|
+
}
|
|
246
|
+
function registeredValueSchema(kind, props) {
|
|
247
|
+
const registration = registeredKinds.get(kind);
|
|
248
|
+
if (!registration)
|
|
249
|
+
throw new Error(`Control kind ${kind} is not registered`);
|
|
250
|
+
const schema = structuredClone(registration.deriveSchema.schema);
|
|
251
|
+
for (const [pointer, prop] of Object.entries(registration.deriveSchema.props ?? {})) {
|
|
252
|
+
const value = prop === 'options'
|
|
253
|
+
? props.options?.filter(o => !o.disabled).map(o => o.value)
|
|
254
|
+
: props[prop];
|
|
255
|
+
if (value !== undefined)
|
|
256
|
+
setAtPointer(schema, pointer, value);
|
|
257
|
+
}
|
|
258
|
+
return schema;
|
|
259
|
+
}
|
|
260
|
+
/** Set `value` at a JSON Pointer, making the objects on its way. */
|
|
261
|
+
function setAtPointer(target, pointer, value) {
|
|
262
|
+
const keys = pointer
|
|
263
|
+
.slice(1)
|
|
264
|
+
.split('/')
|
|
265
|
+
.map(k => k.replace(/~1/g, '/').replace(/~0/g, '~'));
|
|
266
|
+
let node = target;
|
|
267
|
+
for (const key of keys.slice(0, -1)) {
|
|
268
|
+
if (!node[key] || typeof node[key] !== 'object')
|
|
269
|
+
node[key] = {};
|
|
270
|
+
node = node[key];
|
|
271
|
+
}
|
|
272
|
+
node[keys[keys.length - 1]] = value;
|
|
273
|
+
}
|
|
274
|
+
function numberSchema(props) {
|
|
275
|
+
const unit = props.unit ? ` in ${props.unit}` : '';
|
|
276
|
+
const range = props.min !== undefined && props.max !== undefined
|
|
277
|
+
? `, from ${props.min} to ${props.max}${props.wrap ? ' (it wraps past either end)' : ''}`
|
|
278
|
+
: '';
|
|
279
|
+
return {
|
|
280
|
+
type: 'number',
|
|
281
|
+
description: `The value${unit}${range}`,
|
|
282
|
+
...(props.min !== undefined ? { minimum: props.min } : {}),
|
|
283
|
+
...(props.max !== undefined ? { maximum: props.max } : {}),
|
|
284
|
+
...(props.step !== undefined && props.step > 0 ? { multipleOf: props.step } : {}),
|
|
285
|
+
...(props.unit ? { 'x-unit': props.unit } : {}),
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
/** The item parameter an action takes when its control is one of a list's rows. */
|
|
289
|
+
export const ITEM_PROPERTY = 'item';
|
|
290
|
+
export function itemSchema(items) {
|
|
291
|
+
return {
|
|
292
|
+
type: 'string',
|
|
293
|
+
description: 'Which one: the id or the exact title of a row the page shows' +
|
|
294
|
+
(items && items.length ? ` (${items.length} on screen now)` : ''),
|
|
295
|
+
...(items && items.length && items.length <= MAX_ITEM_ENUM ? { enum: items.map(i => i.key) } : {}),
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
/** Beyond this many rows, the item parameter names none of them; the page observation lists them. */
|
|
299
|
+
export const MAX_ITEM_ENUM = 100;
|
|
300
|
+
/**
|
|
301
|
+
* The input schema of the action a control makes: `{ value }` for a field,
|
|
302
|
+
* nothing for a button or dialog, and an `item` when it is one of a list's rows.
|
|
303
|
+
*/
|
|
304
|
+
export function deriveInputSchema(kind, props = {}, options = {}) {
|
|
305
|
+
const properties = {};
|
|
306
|
+
const required = [];
|
|
307
|
+
const value = deriveValueSchema(kind, props);
|
|
308
|
+
if (value) {
|
|
309
|
+
properties.value = value;
|
|
310
|
+
required.push('value');
|
|
311
|
+
}
|
|
312
|
+
if (options.itemized) {
|
|
313
|
+
properties[ITEM_PROPERTY] = itemSchema(options.items);
|
|
314
|
+
required.push(ITEM_PROPERTY);
|
|
315
|
+
}
|
|
316
|
+
return {
|
|
317
|
+
type: 'object',
|
|
318
|
+
properties,
|
|
319
|
+
...(required.length ? { required } : {}),
|
|
320
|
+
additionalProperties: false,
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
// ─── The design system's controls ────────────────────────────────────────────
|
|
324
|
+
/** Where a control table file lists the kinds its design system registers. */
|
|
325
|
+
export const CONTROL_TABLE_KINDS_KEY = '$kinds';
|
|
326
|
+
/** A control table file's controls and the kinds it registers. */
|
|
327
|
+
export function readControlTable(file) {
|
|
328
|
+
const { [CONTROL_TABLE_KINDS_KEY]: kinds, ...controls } = (file ?? {});
|
|
329
|
+
return {
|
|
330
|
+
controls: controls,
|
|
331
|
+
kinds: Array.isArray(kinds) ? kinds : [],
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
//# sourceMappingURL=controls.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controls.js","sourceRoot":"","sources":["../src/controls.ts"],"names":[],"mappings":"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"}
|
package/dist/effect.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type OUIEffectKind } from 'oui-spec/spec';
|
|
2
|
+
import type { ActionEffect } from '@ouispec/contract';
|
|
3
|
+
/**
|
|
4
|
+
* What using an action does (ADR-0226 §2.6): one vocabulary for a
|
|
5
|
+
* design-system control's binding, a room catalog's entry and a generated API
|
|
6
|
+
* tool, so a page control, a room action and an API call are told apart by
|
|
7
|
+
* what they change, never by where they are declared.
|
|
8
|
+
*
|
|
9
|
+
* | Effect | What it changes | ADR-0210 access |
|
|
10
|
+
* |---|---|---|
|
|
11
|
+
* | `view`, `selection`, `navigate`, `open` | What is shown | read |
|
|
12
|
+
* | `edit` | The document, one undo step | write |
|
|
13
|
+
* | `file` | Imports or exports a file | write |
|
|
14
|
+
* | `mutate` | Backend data, through an API operation | write |
|
|
15
|
+
* | `job` | Starts work that outlives the call, settled on its outcome | write |
|
|
16
|
+
* | `transaction` | An irreversible external act: an order, a payment, a send, a publish | write, approved |
|
|
17
|
+
*
|
|
18
|
+
* A `transaction`, and any `write` declared `destructive`, runs only on an
|
|
19
|
+
* approval the person gave, bound to the call (ADR-0228).
|
|
20
|
+
*/
|
|
21
|
+
/** How long an approval for an action lasts at most, in minutes (ADR-0228 §2.3). */
|
|
22
|
+
export declare const MAX_APPROVAL_MINUTES = 30;
|
|
23
|
+
export type { ActionEffect, SimpleEffect, JobStatus, JobOutcome, JobSettlement } from '@ouispec/contract';
|
|
24
|
+
/**
|
|
25
|
+
* The effect kinds. The vocabulary, what each one may change, and what needs
|
|
26
|
+
* the person's approval are OUI's (`oui-spec`), so the browser that checks an
|
|
27
|
+
* approval and every declaration here read one definition.
|
|
28
|
+
*/
|
|
29
|
+
export type ActionEffectKind = OUIEffectKind;
|
|
30
|
+
/** Every effect, in the order of the table above. */
|
|
31
|
+
export declare const ACTION_EFFECT_KINDS: readonly ActionEffectKind[];
|
|
32
|
+
/** Whether an effect only changes what is shown, or changes something (ADR-0210 `effect`). */
|
|
33
|
+
export declare const EFFECT_ACCESS: Readonly<Record<ActionEffectKind, 'read' | 'write'>>;
|
|
34
|
+
/**
|
|
35
|
+
* An effect, or its bare kind: what an OUI surface carries for an action
|
|
36
|
+
* (`effect: 'transaction'`), and what any reader of effects accepts.
|
|
37
|
+
*/
|
|
38
|
+
export type EffectOrKind = ActionEffect | ActionEffectKind;
|
|
39
|
+
export declare function effectKind(effect: EffectOrKind): ActionEffectKind;
|
|
40
|
+
/** `read` or `write`, as ADR-0210 names it. An action that declares no effect is a `write`: nothing says it only shows. */
|
|
41
|
+
export declare function effectAccess(effect: EffectOrKind | undefined): 'read' | 'write';
|
|
42
|
+
/**
|
|
43
|
+
* Whether running the action needs the person's approval of the exact call
|
|
44
|
+
* (ADR-0228 §2.1): a `transaction` always, and a `write` declared destructive.
|
|
45
|
+
* A host's policy may require it of more; it never waives these. OUI's rule.
|
|
46
|
+
*/
|
|
47
|
+
export declare function requiresApproval(effect: EffectOrKind | undefined, destructive?: boolean): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Why a value is not a valid effect, or null. Checks the shape only: whether a
|
|
50
|
+
* route, container or operation it names exists is the generator's to check
|
|
51
|
+
* against the app.
|
|
52
|
+
*/
|
|
53
|
+
export declare function effectProblem(value: unknown): string | null;
|
|
54
|
+
//# sourceMappingURL=effect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effect.d.ts","sourceRoot":"","sources":["../src/effect.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,aAAa,EACnB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EACV,YAAY,EAGb,MAAM,mBAAmB,CAAC;AAE3B;;;;;;;;;;;;;;;;;GAiBG;AAEH,oFAAoF;AACpF,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAGvC,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAE1G;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,aAAa,CAAC;AAY7C,qDAAqD;AACrD,eAAO,MAAM,mBAAmB,EAAE,SAAS,gBAAgB,EAAqB,CAAC;AAEjF,8FAA8F;AAC9F,eAAO,MAAM,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,CAAqB,CAAC;AAErG;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,gBAAgB,CAAC;AAE3D,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,GAAG,gBAAgB,CAEjE;AAED,2HAA2H;AAC3H,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAE/E;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,OAAO,CAEjG;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAsC3D"}
|