@a2ui-sdk/react 0.0.3 → 0.1.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/README.md ADDED
@@ -0,0 +1,202 @@
1
+ # @a2ui-sdk/react
2
+
3
+ React implementation for rendering A2UI protocol. This package provides React components and hooks for integrating A2UI surfaces into your application.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @a2ui-sdk/react
9
+ ```
10
+
11
+ ### Peer Dependencies
12
+
13
+ - `react` ^19.0.0
14
+ - `react-dom` ^19.0.0
15
+
16
+ ## Usage
17
+
18
+ ### Basic Usage
19
+
20
+ ```tsx
21
+ import {
22
+ A2UIProvider,
23
+ A2UIRenderer,
24
+ type A2UIMessage,
25
+ type A2UIAction,
26
+ } from '@a2ui-sdk/react/0.9'
27
+
28
+ function App() {
29
+ const messages: A2UIMessage[] = [
30
+ // A2UI messages from your backend
31
+ ]
32
+
33
+ const handleAction = (action: A2UIAction) => {
34
+ console.log('Action:', action.name, action.context)
35
+ }
36
+
37
+ return (
38
+ <A2UIProvider messages={messages} onAction={handleAction}>
39
+ <A2UIRenderer />
40
+ </A2UIProvider>
41
+ )
42
+ }
43
+ ```
44
+
45
+ ### With Custom Components
46
+
47
+ You can override default components or add new ones via the `components` prop:
48
+
49
+ ```tsx
50
+ import { A2UIProvider, A2UIRenderer, useDataBinding } from '@a2ui-sdk/react/0.9'
51
+
52
+ // Custom component implementation
53
+ function MyCustomText({ text }: { text: DynamicString }) {
54
+ const resolvedText = useDataBinding(text)
55
+ return <span className="my-custom-style">{resolvedText}</span>
56
+ }
57
+
58
+ function App() {
59
+ const components = new Map([['Text', MyCustomText]])
60
+
61
+ return (
62
+ <A2UIProvider
63
+ messages={messages}
64
+ onAction={handleAction}
65
+ components={components}
66
+ >
67
+ <A2UIRenderer />
68
+ </A2UIProvider>
69
+ )
70
+ }
71
+ ```
72
+
73
+ ## Exports
74
+
75
+ ### v0.9 (Latest)
76
+
77
+ ```tsx
78
+ import {
79
+ // Components
80
+ A2UIProvider,
81
+ A2UIRenderer,
82
+ ComponentRenderer,
83
+
84
+ // Hooks
85
+ useDispatchAction,
86
+ useDataBinding,
87
+ useFormBinding,
88
+ useStringBinding,
89
+ useDataModel,
90
+ useValidation,
91
+ useSurfaceContext,
92
+ useScope,
93
+ useScopeBasePath,
94
+
95
+ // Types
96
+ type A2UIMessage,
97
+ type A2UIAction,
98
+ type A2UIProviderProps,
99
+ type A2UIRendererProps,
100
+ type ComponentsMap,
101
+ type Component,
102
+ type Action,
103
+ type DynamicValue,
104
+ type DynamicString,
105
+ type DynamicNumber,
106
+ type DynamicBoolean,
107
+ type DynamicStringList,
108
+ type ChildList,
109
+ type TemplateBinding,
110
+ type CheckRule,
111
+ type Checkable,
112
+ type ValidationResult,
113
+ type ScopeValue,
114
+ type DataModel,
115
+ } from '@a2ui-sdk/react/0.9'
116
+ ```
117
+
118
+ ### v0.8
119
+
120
+ ```tsx
121
+ import {
122
+ // Components
123
+ A2UIProvider,
124
+ A2UIRenderer,
125
+ ComponentRenderer,
126
+
127
+ // Hooks
128
+ useDispatchAction,
129
+ useDataBinding,
130
+ useFormBinding,
131
+ useSurfaceContext,
132
+ useDataModelContext,
133
+
134
+ // Types
135
+ type A2UIMessage,
136
+ type A2UIAction,
137
+ type A2UIProviderProps,
138
+ type A2UIRendererProps,
139
+ type ComponentsMap,
140
+ type Action,
141
+ type ValueSource,
142
+ } from '@a2ui-sdk/react/0.8'
143
+ ```
144
+
145
+ ### Namespace Import
146
+
147
+ ```tsx
148
+ import { v0_8, v0_9 } from '@a2ui-sdk/react'
149
+
150
+ // Use v0.9 API
151
+ const { A2UIProvider, A2UIRenderer } = v0_9
152
+ ```
153
+
154
+ ## Hooks
155
+
156
+ ### useDataBinding
157
+
158
+ Resolves a dynamic value from the data model:
159
+
160
+ ```tsx
161
+ const value = useDataBinding({ path: '/user/name' })
162
+ // Returns the value at /user/name in the data model
163
+ ```
164
+
165
+ ### useFormBinding
166
+
167
+ Two-way binding for form components:
168
+
169
+ ```tsx
170
+ const [value, setValue] = useFormBinding({ path: '/form/email' })
171
+ // value: current value
172
+ // setValue: update the data model
173
+ ```
174
+
175
+ ### useDispatchAction
176
+
177
+ Dispatch actions from custom components:
178
+
179
+ ```tsx
180
+ const dispatch = useDispatchAction()
181
+
182
+ const handleClick = () => {
183
+ dispatch({
184
+ name: 'submit',
185
+ context: { formId: 'contact' },
186
+ })
187
+ }
188
+ ```
189
+
190
+ ### useValidation
191
+
192
+ Validate form inputs against check rules:
193
+
194
+ ```tsx
195
+ const { valid, errors } = useValidation(checks)
196
+ // valid: boolean
197
+ // errors: string[] - list of failed validation messages
198
+ ```
199
+
200
+ ## License
201
+
202
+ Apache-2.0
@@ -2,7 +2,7 @@ import { jsx as t } from "react/jsx-runtime";
2
2
  import { memo as u } from "react";
3
3
  import { useDataModel as d } from "../../hooks/useDataBinding.js";
4
4
  import { cn as y } from "../../../lib/utils.js";
5
- import { getValueByPath as j } from "../../utils/pathUtils.js";
5
+ import { getValueByPath as j } from "@a2ui-sdk/utils/0.8";
6
6
  import { ComponentRenderer as r } from "../ComponentRenderer.js";
7
7
  const v = {
8
8
  start: "justify-start",
@@ -2,7 +2,7 @@ import { jsx as t } from "react/jsx-runtime";
2
2
  import { memo as d } from "react";
3
3
  import { useDataModel as x } from "../../hooks/useDataBinding.js";
4
4
  import { cn as u } from "../../../lib/utils.js";
5
- import { getValueByPath as v } from "../../utils/pathUtils.js";
5
+ import { getValueByPath as v } from "@a2ui-sdk/utils/0.8";
6
6
  import { ComponentRenderer as r } from "../ComponentRenderer.js";
7
7
  const L = {
8
8
  start: "items-start",
@@ -2,7 +2,7 @@ import { jsx as t } from "react/jsx-runtime";
2
2
  import { memo as l } from "react";
3
3
  import { useDataModel as u } from "../../hooks/useDataBinding.js";
4
4
  import { cn as y } from "../../../lib/utils.js";
5
- import { getValueByPath as j } from "../../utils/pathUtils.js";
5
+ import { getValueByPath as j } from "@a2ui-sdk/utils/0.8";
6
6
  import { ComponentRenderer as r } from "../ComponentRenderer.js";
7
7
  const v = {
8
8
  start: "justify-start",
@@ -1,7 +1,7 @@
1
1
  import { jsx as m } from "react/jsx-runtime";
2
2
  import { useContext as x, createContext as C, useCallback as p, useMemo as f } from "react";
3
3
  import { useDataModelContext as v } from "./DataModelContext.js";
4
- import { resolveActionContext as A } from "../utils/dataBinding.js";
4
+ import { resolveActionContext as A } from "@a2ui-sdk/utils/0.8";
5
5
  const s = C(null);
6
6
  function P({ onAction: t, children: c }) {
7
7
  const { getDataModel: o } = v(), e = p(
@@ -1,6 +1,6 @@
1
1
  import { jsx as C } from "react/jsx-runtime";
2
2
  import { createContext as P, useContext as f, useState as V, useCallback as a, useMemo as v } from "react";
3
- import { mergeAtPath as b, getValueByPath as y, setValueByPath as B } from "../utils/pathUtils.js";
3
+ import { mergeAtPath as b, getValueByPath as y, setValueByPath as B } from "@a2ui-sdk/utils/0.8";
4
4
  const g = P(
5
5
  null
6
6
  );
@@ -1,7 +1,7 @@
1
1
  import { useCallback as c } from "react";
2
2
  import { useSurfaceContext as I } from "../contexts/SurfaceContext.js";
3
3
  import { useDataModelContext as U } from "../contexts/DataModelContext.js";
4
- import { contentsToObject as b } from "../utils/dataBinding.js";
4
+ import { contentsToObject as b } from "@a2ui-sdk/utils/0.8";
5
5
  function g() {
6
6
  const { initSurface: n, updateSurface: d, deleteSurface: u, clearSurfaces: f } = I(), { updateDataModel: s, initDataModel: l, deleteDataModel: i, clearDataModels: p } = U(), o = c(
7
7
  (t) => {
@@ -1,6 +1,6 @@
1
1
  import { useMemo as i } from "react";
2
2
  import { useDataModelContext as l } from "../contexts/DataModelContext.js";
3
- import { resolveValue as m } from "../utils/dataBinding.js";
3
+ import { resolveValue as m } from "@a2ui-sdk/utils/0.8";
4
4
  function s(n, t, o) {
5
5
  const { getDataModel: e } = l();
6
6
  return i(() => {
@@ -2,7 +2,7 @@ import { jsx as r, Fragment as i } from "react/jsx-runtime";
2
2
  import { memo as f } from "react";
3
3
  import { ScopeProvider as p } from "../../contexts/ScopeContext.js";
4
4
  import { ComponentRenderer as s } from "../ComponentRenderer.js";
5
- import { resolvePath as $, getValueByPath as P } from "../../utils/pathUtils.js";
5
+ import { resolvePath as $, getValueByPath as P } from "@a2ui-sdk/utils/0.9";
6
6
  const b = f(function({
7
7
  surfaceId: l,
8
8
  template: c,
@@ -1,6 +1,6 @@
1
1
  import { jsx as d } from "react/jsx-runtime";
2
2
  import { createContext as x, useContext as p, useCallback as C, useMemo as f } from "react";
3
- import { resolveContext as v } from "../utils/dataBinding.js";
3
+ import { resolveContext as v } from "@a2ui-sdk/utils/0.9";
4
4
  const n = x(null);
5
5
  function b({ onAction: t, children: r }) {
6
6
  const e = C(
@@ -1,6 +1,6 @@
1
1
  import { jsx as P } from "react/jsx-runtime";
2
2
  import { createContext as b, useContext as A, useState as U, useCallback as a, useMemo as $ } from "react";
3
- import { setValueByPath as y } from "../utils/pathUtils.js";
3
+ import { setValueByPath as y } from "@a2ui-sdk/utils/0.9";
4
4
  const C = b(null);
5
5
  function z({ children: f }) {
6
6
  const [r, s] = U(/* @__PURE__ */ new Map()), i = a((e, n) => {
@@ -1,7 +1,7 @@
1
1
  import { useMemo as r, useCallback as D } from "react";
2
2
  import { useSurfaceContext as s } from "../contexts/SurfaceContext.js";
3
3
  import { useScope as g } from "../contexts/ScopeContext.js";
4
- import { resolveString as d, resolveValue as h, isPathBinding as c } from "../utils/dataBinding.js";
4
+ import { resolveString as d, resolveValue as h, isPathBinding as c } from "@a2ui-sdk/utils/0.9";
5
5
  function S(n, t, a) {
6
6
  const { getDataModel: e } = s(), { basePath: i } = g();
7
7
  return r(() => {
@@ -1,5 +1,5 @@
1
1
  import { CheckRule, ValidationResult } from '@a2ui-sdk/types/0.9';
2
- import { ValidationFunction } from '../utils/validation';
2
+ import { ValidationFunction } from '@a2ui-sdk/utils/0.9';
3
3
  /**
4
4
  * Hook for evaluating validation checks on a component.
5
5
  *
@@ -1,7 +1,7 @@
1
1
  import { useMemo as n } from "react";
2
2
  import { useSurfaceContext as i } from "../contexts/SurfaceContext.js";
3
3
  import { useScope as p } from "../contexts/ScopeContext.js";
4
- import { evaluateChecks as u } from "../utils/validation.js";
4
+ import { evaluateChecks as u } from "@a2ui-sdk/utils/0.9";
5
5
  function M(o, t, e) {
6
6
  const { getDataModel: r } = i(), { basePath: a } = p();
7
7
  return n(() => {
@@ -32,4 +32,3 @@ export { useDataBinding, useFormBinding, useStringBinding, useDataModel, } from
32
32
  export { useValidation } from './hooks/useValidation';
33
33
  export { useSurfaceContext } from './contexts/SurfaceContext';
34
34
  export { useScope, useScopeBasePath } from './contexts/ScopeContext';
35
- export { validationFunctions, evaluateChecks, evaluateCheckRule, type ValidationFunction, type EvaluationContext, } from './utils/validation';
package/dist/0.9/index.js CHANGED
@@ -1,26 +1,22 @@
1
1
  import { A2UIProvider as r } from "./contexts/A2UIProvider.js";
2
2
  import { A2UIRenderer as n } from "./A2UIRenderer.js";
3
- import { ComponentRenderer as i } from "./components/ComponentRenderer.js";
4
- import { useDispatchAction as p } from "./hooks/useDispatchAction.js";
5
- import { useDataBinding as m, useDataModel as f, useFormBinding as x, useStringBinding as d } from "./hooks/useDataBinding.js";
6
- import { useValidation as l } from "./hooks/useValidation.js";
7
- import { useSurfaceContext as h } from "./contexts/SurfaceContext.js";
8
- import { useScope as B, useScopeBasePath as C } from "./contexts/ScopeContext.js";
9
- import { evaluateCheckRule as A, evaluateChecks as D, validationFunctions as R } from "./utils/validation.js";
3
+ import { ComponentRenderer as p } from "./components/ComponentRenderer.js";
4
+ import { useDispatchAction as a } from "./hooks/useDispatchAction.js";
5
+ import { useDataBinding as u, useDataModel as f, useFormBinding as x, useStringBinding as d } from "./hooks/useDataBinding.js";
6
+ import { useValidation as g } from "./hooks/useValidation.js";
7
+ import { useSurfaceContext as S } from "./contexts/SurfaceContext.js";
8
+ import { useScope as D, useScopeBasePath as h } from "./contexts/ScopeContext.js";
10
9
  export {
11
10
  r as A2UIProvider,
12
11
  n as A2UIRenderer,
13
- i as ComponentRenderer,
14
- A as evaluateCheckRule,
15
- D as evaluateChecks,
16
- m as useDataBinding,
12
+ p as ComponentRenderer,
13
+ u as useDataBinding,
17
14
  f as useDataModel,
18
- p as useDispatchAction,
15
+ a as useDispatchAction,
19
16
  x as useFormBinding,
20
- B as useScope,
21
- C as useScopeBasePath,
17
+ D as useScope,
18
+ h as useScopeBasePath,
22
19
  d as useStringBinding,
23
- h as useSurfaceContext,
24
- l as useValidation,
25
- R as validationFunctions
20
+ S as useSurfaceContext,
21
+ g as useValidation
26
22
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a2ui-sdk/react",
3
- "version": "0.0.3",
3
+ "version": "0.1.0",
4
4
  "description": "A2UI SDK for React",
5
5
  "homepage": "https://easyops-cn.github.io/a2ui-sdk/",
6
6
  "repository": {
@@ -41,8 +41,8 @@
41
41
  "react-dom": "^19.0.0"
42
42
  },
43
43
  "devDependencies": {
44
- "@a2ui-sdk/types": "0.0.3",
45
- "@a2ui-sdk/utils": "0.0.3",
44
+ "@a2ui-sdk/types": "0.1.0",
45
+ "@a2ui-sdk/utils": "0.1.0",
46
46
  "@testing-library/dom": "^10.4.1",
47
47
  "@testing-library/jest-dom": "^6.9.1",
48
48
  "@testing-library/react": "^16.3.1",
@@ -1,95 +0,0 @@
1
- import { ValueSource, DataModel, DataEntry, DataModelValue } from '@a2ui-sdk/types/0.8';
2
- /**
3
- * Resolves a ValueSource to its actual value.
4
- *
5
- * @param source - The value source (literal or path reference)
6
- * @param dataModel - The data model for path lookups
7
- * @param defaultValue - Default value if source is undefined or path not found
8
- * @returns The resolved value
9
- *
10
- * @example
11
- * // Literal values
12
- * resolveValue({ literalString: "Hello" }, {}); // "Hello"
13
- * resolveValue({ literalNumber: 42 }, {}); // 42
14
- *
15
- * // Path references
16
- * const model = { user: { name: "John" } };
17
- * resolveValue({ path: "/user/name" }, model); // "John"
18
- * resolveValue({ path: "/user/age" }, model, 0); // 0 (default)
19
- */
20
- export declare function resolveValue<T = unknown>(source: ValueSource | undefined, dataModel: DataModel, defaultValue?: T): T;
21
- /**
22
- * Checks if a value source is a path reference.
23
- *
24
- * @param source - The value source to check
25
- * @returns True if the source is a path reference
26
- */
27
- export declare function isPathReference(source: ValueSource | undefined): source is {
28
- path: string;
29
- };
30
- /**
31
- * Gets the path from a value source, or undefined if it's not a path reference.
32
- *
33
- * @param source - The value source
34
- * @returns The path string or undefined
35
- */
36
- export declare function getPath(source: ValueSource | undefined): string | undefined;
37
- /**
38
- * Converts a DataEntry array to a plain object.
39
- * This is used for processing dataModelUpdate message contents.
40
- *
41
- * @param contents - Array of data entries from the server
42
- * @returns A plain object with the converted values
43
- *
44
- * @example
45
- * contentsToObject([
46
- * { key: "name", valueString: "John" },
47
- * { key: "age", valueNumber: 30 },
48
- * { key: "active", valueBoolean: true },
49
- * { key: "profile", valueMap: [
50
- * { key: "email", valueString: "john@example.com" }
51
- * ]}
52
- * ]);
53
- * // Returns: { name: "John", age: 30, active: true, profile: { email: "john@example.com" } }
54
- */
55
- export declare function contentsToObject(contents: DataEntry[]): Record<string, DataModelValue>;
56
- /**
57
- * Creates a literal string value source.
58
- *
59
- * @param value - The string value
60
- * @returns A ValueSource with literalString
61
- */
62
- export declare function literalString(value: string): ValueSource;
63
- /**
64
- * Creates a literal number value source.
65
- *
66
- * @param value - The number value
67
- * @returns A ValueSource with literalNumber
68
- */
69
- export declare function literalNumber(value: number): ValueSource;
70
- /**
71
- * Creates a literal boolean value source.
72
- *
73
- * @param value - The boolean value
74
- * @returns A ValueSource with literalBoolean
75
- */
76
- export declare function literalBoolean(value: boolean): ValueSource;
77
- /**
78
- * Creates a path reference value source.
79
- *
80
- * @param path - The data model path
81
- * @returns A ValueSource with path
82
- */
83
- export declare function pathRef(path: string): ValueSource;
84
- /**
85
- * Resolves action context items to a plain object.
86
- * This is used when dispatching actions to resolve all context values.
87
- *
88
- * @param context - Array of action context items
89
- * @param dataModel - The data model for path lookups
90
- * @returns A plain object with resolved context values
91
- */
92
- export declare function resolveActionContext(context: Array<{
93
- key: string;
94
- value: ValueSource;
95
- }> | undefined, dataModel: DataModel): Record<string, unknown>;
@@ -1,46 +0,0 @@
1
- import { getValueByPath as r } from "./pathUtils.js";
2
- function l(e, n, t) {
3
- if (e == null)
4
- return t;
5
- if ("literalString" in e)
6
- return e.literalString;
7
- if ("literalNumber" in e)
8
- return e.literalNumber;
9
- if ("literalBoolean" in e)
10
- return e.literalBoolean;
11
- if ("literalArray" in e)
12
- return e.literalArray;
13
- if ("path" in e) {
14
- const i = r(n, e.path);
15
- return i === void 0 ? t : i;
16
- }
17
- return t;
18
- }
19
- function a(e) {
20
- const n = {};
21
- for (const t of e) {
22
- const i = o(t.key);
23
- t.valueString !== void 0 ? n[i] = t.valueString : t.valueNumber !== void 0 ? n[i] = t.valueNumber : t.valueBoolean !== void 0 ? n[i] = t.valueBoolean : t.valueMap !== void 0 && (n[i] = a(t.valueMap));
24
- }
25
- return n;
26
- }
27
- function o(e) {
28
- if (e.includes("/")) {
29
- const n = e.split("/").filter(Boolean);
30
- return n[n.length - 1] || e;
31
- }
32
- return e;
33
- }
34
- function f(e, n) {
35
- if (!e)
36
- return {};
37
- const t = {};
38
- for (const i of e)
39
- t[i.key] = l(i.value, n);
40
- return t;
41
- }
42
- export {
43
- a as contentsToObject,
44
- f as resolveActionContext,
45
- l as resolveValue
46
- };
@@ -1,63 +0,0 @@
1
- import { DataModel, DataModelValue } from '@a2ui-sdk/types/0.8';
2
- /**
3
- * Gets a value from the data model by path.
4
- *
5
- * @param dataModel - The data model to read from
6
- * @param path - The path to the value (e.g., "/user/name")
7
- * @returns The value at the path, or undefined if not found
8
- *
9
- * @example
10
- * const model = { user: { name: "John" } };
11
- * getValueByPath(model, "/user/name"); // "John"
12
- * getValueByPath(model, "/user/age"); // undefined
13
- */
14
- export declare function getValueByPath(dataModel: DataModel, path: string): DataModelValue | undefined;
15
- /**
16
- * Sets a value in the data model by path, returning a new data model.
17
- * This function is immutable - it does not modify the original data model.
18
- *
19
- * @param dataModel - The data model to update
20
- * @param path - The path to set (e.g., "/user/name")
21
- * @param value - The value to set
22
- * @returns A new data model with the value set
23
- *
24
- * @example
25
- * const model = { user: { name: "John" } };
26
- * setValueByPath(model, "/user/name", "Jane");
27
- * // Returns: { user: { name: "Jane" } }
28
- */
29
- export declare function setValueByPath(dataModel: DataModel, path: string, value: unknown): DataModel;
30
- /**
31
- * Merges data into the data model at a given path.
32
- * This is used for dataModelUpdate messages where contents are merged.
33
- *
34
- * @param dataModel - The data model to update
35
- * @param path - The path to merge at (e.g., "/form")
36
- * @param data - The data to merge
37
- * @returns A new data model with the data merged
38
- */
39
- export declare function mergeAtPath(dataModel: DataModel, path: string, data: Record<string, unknown>): DataModel;
40
- /**
41
- * Normalizes a path to ensure it starts with "/" and has no trailing "/".
42
- *
43
- * @param path - The path to normalize
44
- * @returns The normalized path
45
- *
46
- * @example
47
- * normalizePath("user/name"); // "/user/name"
48
- * normalizePath("/user/name/"); // "/user/name"
49
- */
50
- export declare function normalizePath(path: string): string;
51
- /**
52
- * Joins two paths together.
53
- *
54
- * @param basePath - The base path
55
- * @param relativePath - The relative path to join
56
- * @returns The joined path
57
- *
58
- * @example
59
- * joinPaths("/user", "name"); // "/user/name"
60
- * joinPaths("/user", "/name"); // "/user/name"
61
- * joinPaths("/user/", "/name/"); // "/user/name"
62
- */
63
- export declare function joinPaths(basePath: string, relativePath: string): string;
@@ -1,44 +0,0 @@
1
- function l(e, t) {
2
- if (!t || t === "/")
3
- return e;
4
- const n = t.split("/").filter(Boolean);
5
- let r = e;
6
- for (const o of n) {
7
- if (r == null || typeof r != "object")
8
- return;
9
- r = r[o];
10
- }
11
- return r;
12
- }
13
- function g(e, t, n) {
14
- if (!t || t === "/")
15
- return typeof n == "object" && n !== null && !Array.isArray(n) ? { ...e, ...n } : e;
16
- const r = t.split("/").filter(Boolean);
17
- function o(u, s, i) {
18
- if (s.length === 0)
19
- return typeof i == "object" && i !== null && !Array.isArray(i) ? { ...u, ...i } : u;
20
- const [f, ...y] = s;
21
- if (y.length === 0)
22
- return {
23
- ...u,
24
- [f]: i
25
- };
26
- const c = u[f], A = typeof c == "object" && c !== null && !Array.isArray(c) ? c : {};
27
- return {
28
- ...u,
29
- [f]: o(A, y, i)
30
- };
31
- }
32
- return o(e, r, n);
33
- }
34
- function b(e, t, n) {
35
- if (!t || t === "/")
36
- return { ...e, ...n };
37
- const r = l(e, t), u = { ...typeof r == "object" && r !== null && !Array.isArray(r) ? r : {}, ...n };
38
- return g(e, t, u);
39
- }
40
- export {
41
- l as getValueByPath,
42
- b as mergeAtPath,
43
- g as setValueByPath
44
- };
@@ -1,126 +0,0 @@
1
- import { DynamicValue, DynamicString, DataModel, FormBindableValue } from '@a2ui-sdk/types/0.9';
2
- /**
3
- * Type guard to check if a value is a path binding.
4
- *
5
- * @param value - The value to check
6
- * @returns True if the value is a path binding object
7
- *
8
- * @example
9
- * isPathBinding({ path: "/user/name" }); // true
10
- * isPathBinding("literal"); // false
11
- * isPathBinding({ call: "required" }); // false
12
- */
13
- export declare function isPathBinding(value: FormBindableValue | undefined | null): value is {
14
- path: string;
15
- };
16
- /**
17
- * Type guard to check if a value is a function call.
18
- *
19
- * @param value - The value to check
20
- * @returns True if the value is a function call object
21
- */
22
- export declare function isFunctionCall(value: FormBindableValue | undefined | null): value is {
23
- call: string;
24
- args?: Record<string, DynamicValue>;
25
- };
26
- /**
27
- * Gets the path from a dynamic value, or undefined if it's not a path binding.
28
- *
29
- * @param value - The dynamic value
30
- * @returns The path string or undefined
31
- */
32
- export declare function getBindingPath(value: FormBindableValue | undefined | null): string | undefined;
33
- /**
34
- * Resolves a dynamic value to its actual value.
35
- *
36
- * Resolution order:
37
- * 1. If value is a path binding object → resolve from data model
38
- * 2. If value is a function call → return undefined (function calls not evaluated here)
39
- * 3. Otherwise → return literal value
40
- *
41
- * @param value - The dynamic value (literal, path binding, or function call)
42
- * @param dataModel - The data model for path lookups
43
- * @param basePath - Optional base path for relative path resolution
44
- * @param defaultValue - Default value if undefined or path not found
45
- * @returns The resolved value
46
- *
47
- * @example
48
- * // Literal values
49
- * resolveValue("Hello", {}); // "Hello"
50
- * resolveValue(42, {}); // 42
51
- * resolveValue(true, {}); // true
52
- *
53
- * // Path bindings
54
- * const model = { user: { name: "John" } };
55
- * resolveValue({ path: "/user/name" }, model); // "John"
56
- * resolveValue({ path: "name" }, model, "/user"); // "John" (relative)
57
- * resolveValue({ path: "/nonexistent" }, model, null, "default"); // "default"
58
- */
59
- export declare function resolveValue<T = unknown>(value: FormBindableValue | undefined | null, dataModel: DataModel, basePath?: string | null, defaultValue?: T): T;
60
- /**
61
- * Resolves a DynamicString value to a string.
62
- * This is a convenience wrapper for string values.
63
- *
64
- * Supports interpolation: if the string contains `${...}` expressions,
65
- * they will be replaced with values from the data model.
66
- *
67
- * @param value - The dynamic string value
68
- * @param dataModel - The data model for path lookups
69
- * @param basePath - Optional base path for relative path resolution
70
- * @param defaultValue - Default value if undefined or path not found
71
- * @returns The resolved string
72
- *
73
- * @example
74
- * // Simple string
75
- * resolveString("Hello", {}); // "Hello"
76
- *
77
- * // Path binding
78
- * resolveString({ path: "/user/name" }, { user: { name: "John" } }); // "John"
79
- *
80
- * // Interpolation
81
- * resolveString("Hello, ${/user/name}!", { user: { name: "John" } }); // "Hello, John!"
82
- */
83
- export declare function resolveString(value: DynamicString | undefined | null, dataModel: DataModel, basePath?: string | null, defaultValue?: string): string;
84
- /**
85
- * Resolves a dynamic number value.
86
- *
87
- * @param value - The dynamic number value
88
- * @param dataModel - The data model for path lookups
89
- * @param basePath - Optional base path for relative path resolution
90
- * @param defaultValue - Default value if undefined or path not found
91
- * @returns The resolved number
92
- */
93
- export declare function resolveNumber(value: number | {
94
- path: string;
95
- } | undefined | null, dataModel: DataModel, basePath?: string | null, defaultValue?: number): number;
96
- /**
97
- * Resolves a dynamic boolean value.
98
- *
99
- * @param value - The dynamic boolean value
100
- * @param dataModel - The data model for path lookups
101
- * @param basePath - Optional base path for relative path resolution
102
- * @param defaultValue - Default value if undefined or path not found
103
- * @returns The resolved boolean
104
- */
105
- export declare function resolveBoolean(value: boolean | {
106
- path: string;
107
- } | undefined | null, dataModel: DataModel, basePath?: string | null, defaultValue?: boolean): boolean;
108
- /**
109
- * Resolves action context values to a plain object.
110
- * All path bindings are resolved to their actual values.
111
- *
112
- * @param context - Object with dynamic values
113
- * @param dataModel - The data model for path lookups
114
- * @param basePath - Optional base path for relative path resolution
115
- * @returns A plain object with resolved context values
116
- *
117
- * @example
118
- * const context = {
119
- * name: { path: "/user/name" },
120
- * action: "submit",
121
- * count: 42
122
- * };
123
- * resolveContext(context, { user: { name: "John" } });
124
- * // Returns: { name: "John", action: "submit", count: 42 }
125
- */
126
- export declare function resolveContext(context: Record<string, DynamicValue> | undefined, dataModel: DataModel, basePath?: string | null): Record<string, unknown>;
@@ -1,41 +0,0 @@
1
- import { resolvePath as f, getValueByPath as c } from "./pathUtils.js";
2
- import { interpolate as y } from "@a2ui-sdk/utils/0.9";
3
- function e(r) {
4
- return r != null && typeof r == "object" && !Array.isArray(r) && "path" in r && typeof r.path == "string";
5
- }
6
- function p(r) {
7
- return r != null && typeof r == "object" && !Array.isArray(r) && "call" in r && typeof r.call == "string";
8
- }
9
- function g(r, i, o = null, t) {
10
- if (r == null)
11
- return t;
12
- if (e(r)) {
13
- const s = f(r.path, o), n = c(i, s);
14
- return n === void 0 ? t : n;
15
- }
16
- return p(r) ? t : r;
17
- }
18
- function l(r, i, o = null, t = "") {
19
- if (r == null)
20
- return t;
21
- if (e(r)) {
22
- const s = f(r.path, o), n = c(i, s);
23
- return n == null ? t : String(n);
24
- }
25
- return p(r) ? t : typeof r == "string" ? y(r, i, o) : String(r);
26
- }
27
- function m(r, i, o = null) {
28
- if (!r)
29
- return {};
30
- const t = {};
31
- for (const [s, n] of Object.entries(r))
32
- t[s] = g(n, i, o);
33
- return t;
34
- }
35
- export {
36
- p as isFunctionCall,
37
- e as isPathBinding,
38
- m as resolveContext,
39
- l as resolveString,
40
- g as resolveValue
41
- };
@@ -1,109 +0,0 @@
1
- import { DataModel } from '@a2ui-sdk/types/0.9';
2
- /**
3
- * Parses a JSON Pointer path into segments.
4
- *
5
- * @param path - The JSON Pointer path (e.g., "/user/name")
6
- * @returns Array of path segments
7
- *
8
- * @example
9
- * parseJsonPointer("/user/name"); // ["user", "name"]
10
- * parseJsonPointer("/items/0"); // ["items", "0"]
11
- * parseJsonPointer("/"); // []
12
- * parseJsonPointer("/a~1b"); // ["a/b"] (escaped slash)
13
- * parseJsonPointer("/m~0n"); // ["m~n"] (escaped tilde)
14
- */
15
- export declare function parseJsonPointer(path: string): string[];
16
- /**
17
- * Creates a JSON Pointer path from segments.
18
- *
19
- * @param segments - Array of path segments
20
- * @returns JSON Pointer path string
21
- *
22
- * @example
23
- * createJsonPointer(["user", "name"]); // "/user/name"
24
- * createJsonPointer(["a/b"]); // "/a~1b"
25
- * createJsonPointer([]); // "/"
26
- */
27
- export declare function createJsonPointer(segments: string[]): string;
28
- /**
29
- * Gets a value from the data model by JSON Pointer path.
30
- *
31
- * @param dataModel - The data model to read from
32
- * @param path - The JSON Pointer path (e.g., "/user/name")
33
- * @returns The value at the path, or undefined if not found
34
- *
35
- * @example
36
- * const model = { user: { name: "John" }, items: ["a", "b"] };
37
- * getValueByPath(model, "/user/name"); // "John"
38
- * getValueByPath(model, "/items/0"); // "a"
39
- * getValueByPath(model, "/nonexistent"); // undefined
40
- */
41
- export declare function getValueByPath(dataModel: DataModel, path: string): unknown;
42
- /**
43
- * Sets a value in the data model by JSON Pointer path, returning a new data model.
44
- * This function is immutable - it does not modify the original data model.
45
- *
46
- * @param dataModel - The data model to update
47
- * @param path - The JSON Pointer path (e.g., "/user/name")
48
- * @param value - The value to set (undefined to delete)
49
- * @returns A new data model with the value set
50
- *
51
- * @example
52
- * const model = { user: { name: "John" } };
53
- * setValueByPath(model, "/user/name", "Jane"); // { user: { name: "Jane" } }
54
- * setValueByPath(model, "/user/age", 30); // { user: { name: "John", age: 30 } }
55
- * setValueByPath(model, "/user/name", undefined); // { user: {} }
56
- */
57
- export declare function setValueByPath(dataModel: DataModel, path: string, value: unknown): DataModel;
58
- /**
59
- * Normalizes a path to ensure it starts with "/" and has no trailing "/".
60
- *
61
- * @param path - The path to normalize
62
- * @returns The normalized path
63
- *
64
- * @example
65
- * normalizePath("user/name"); // "/user/name"
66
- * normalizePath("/user/name/"); // "/user/name"
67
- */
68
- export declare function normalizePath(path: string): string;
69
- /**
70
- * Checks if a path is absolute (starts with "/").
71
- *
72
- * @param path - The path to check
73
- * @returns True if the path is absolute
74
- *
75
- * @example
76
- * isAbsolutePath("/user/name"); // true
77
- * isAbsolutePath("name"); // false
78
- * isAbsolutePath(""); // false
79
- */
80
- export declare function isAbsolutePath(path: string): boolean;
81
- /**
82
- * Resolves a path against a base path (scope).
83
- *
84
- * Absolute paths (starting with "/") are returned as-is.
85
- * Relative paths are resolved against the base path.
86
- *
87
- * @param path - The path to resolve
88
- * @param basePath - The base path (scope), or null for root scope
89
- * @returns The resolved absolute path
90
- *
91
- * @example
92
- * resolvePath("/user/name", "/items/0"); // "/user/name" (absolute)
93
- * resolvePath("name", "/items/0"); // "/items/0/name" (relative)
94
- * resolvePath("name", null); // "/name" (root scope)
95
- */
96
- export declare function resolvePath(path: string, basePath: string | null): string;
97
- /**
98
- * Joins two paths together.
99
- *
100
- * @param basePath - The base path
101
- * @param relativePath - The relative path to join
102
- * @returns The joined path
103
- *
104
- * @example
105
- * joinPaths("/user", "name"); // "/user/name"
106
- * joinPaths("/user", "/name"); // "/user/name"
107
- * joinPaths("/user/", "/name/"); // "/user/name"
108
- */
109
- export declare function joinPaths(basePath: string, relativePath: string): string;
@@ -1,74 +0,0 @@
1
- function y(t) {
2
- return !t || t === "/" ? [] : (t.startsWith("/") ? t.slice(1).split("/") : t.split("/")).filter((r) => r !== "").map((r) => r.replace(/~1/g, "/").replace(/~0/g, "~"));
3
- }
4
- function m(t, e) {
5
- if (!e || e === "/")
6
- return t;
7
- const r = y(e);
8
- let i = t;
9
- for (const f of r) {
10
- if (i == null)
11
- return;
12
- if (Array.isArray(i)) {
13
- const n = parseInt(f, 10);
14
- if (isNaN(n))
15
- return;
16
- i = i[n];
17
- } else if (typeof i == "object")
18
- i = i[f];
19
- else
20
- return;
21
- }
22
- return i;
23
- }
24
- function a(t, e, r) {
25
- if (!e || e === "/")
26
- return r === void 0 ? {} : typeof r == "object" && r !== null && !Array.isArray(r) ? r : t;
27
- const i = y(e), f = structuredClone(t);
28
- let n = f;
29
- for (let o = 0; o < i.length - 1; o++) {
30
- const l = i[o];
31
- if (Array.isArray(n)) {
32
- const s = parseInt(l, 10);
33
- if (isNaN(s))
34
- return f;
35
- (n[s] === null || n[s] === void 0) && (n[s] = {}), n = n[s];
36
- } else if (typeof n == "object" && n !== null) {
37
- const s = n;
38
- s[l] === null || s[l] === void 0 ? s[l] = {} : typeof s[l] != "object" && (s[l] = {}), n = s[l];
39
- } else
40
- return f;
41
- }
42
- const c = i[i.length - 1];
43
- if (Array.isArray(n)) {
44
- const o = parseInt(c, 10);
45
- isNaN(o) || (r === void 0 ? n.splice(o, 1) : n[o] = r);
46
- } else if (typeof n == "object" && n !== null) {
47
- const o = n;
48
- r === void 0 ? delete o[c] : o[c] = r;
49
- }
50
- return f;
51
- }
52
- function u(t) {
53
- let e = t.trim();
54
- return e.startsWith("/") || (e = "/" + e), e.length > 1 && e.endsWith("/") && (e = e.slice(0, -1)), e;
55
- }
56
- function g(t) {
57
- return t.startsWith("/");
58
- }
59
- function A(t, e) {
60
- return g(t) || e === null || e === "/" ? u(t) : d(e, t);
61
- }
62
- function d(t, e) {
63
- const r = u(t), i = e.trim().replace(/^\/+/, "").replace(/\/+$/, "");
64
- return i ? r === "/" ? "/" + i : r + "/" + i : r;
65
- }
66
- export {
67
- m as getValueByPath,
68
- g as isAbsolutePath,
69
- d as joinPaths,
70
- u as normalizePath,
71
- y as parseJsonPointer,
72
- A as resolvePath,
73
- a as setValueByPath
74
- };
@@ -1,49 +0,0 @@
1
- import { CheckRule, DynamicValue, DataModel, ValidationResult } from '@a2ui-sdk/types/0.9';
2
- /**
3
- * Type for a validation function.
4
- * Takes resolved arguments and returns a boolean.
5
- */
6
- export type ValidationFunction = (args: Record<string, unknown>) => boolean;
7
- /**
8
- * Built-in validation functions.
9
- */
10
- export declare const validationFunctions: Record<string, ValidationFunction>;
11
- /**
12
- * Context for evaluating expressions.
13
- */
14
- export interface EvaluationContext {
15
- dataModel: DataModel;
16
- basePath: string | null;
17
- functions?: Record<string, ValidationFunction>;
18
- }
19
- /**
20
- * Resolves function arguments from DynamicValue to actual values.
21
- */
22
- export declare function resolveArgs(args: Record<string, DynamicValue> | undefined, dataModel: DataModel, basePath: string | null): Record<string, unknown>;
23
- /**
24
- * Evaluates a function call.
25
- */
26
- export declare function evaluateFunctionCall(call: string, args: Record<string, DynamicValue> | undefined, context: EvaluationContext): boolean;
27
- /**
28
- * Evaluates a CheckRule (which is also a LogicExpression).
29
- *
30
- * @param rule - The check rule to evaluate
31
- * @param context - Evaluation context with data model and scope
32
- * @returns true if the check passes, false if it fails
33
- */
34
- export declare function evaluateCheckRule(rule: CheckRule, context: EvaluationContext): boolean;
35
- /**
36
- * Evaluates all checks for a component and returns validation result.
37
- *
38
- * @param checks - Array of check rules
39
- * @param dataModel - The data model for value resolution
40
- * @param basePath - The current scope base path (for relative paths)
41
- * @param functions - Optional custom validation functions
42
- * @returns ValidationResult with valid flag and error messages
43
- */
44
- export declare function evaluateChecks(checks: CheckRule[] | undefined, dataModel: DataModel, basePath: string | null, functions?: Record<string, ValidationFunction>): ValidationResult;
45
- /**
46
- * Extracts all paths referenced in a CheckRule for dependency tracking.
47
- * This is useful for knowing which data model paths affect validation.
48
- */
49
- export declare function extractCheckDependencies(checks: CheckRule[]): string[];
@@ -1,75 +0,0 @@
1
- import { resolveValue as l } from "./dataBinding.js";
2
- const a = {
3
- /**
4
- * Checks if a value is present (not null, undefined, or empty string).
5
- */
6
- required: ({ value: r }) => r == null ? !1 : typeof r == "string" ? r.trim().length > 0 : Array.isArray(r) ? r.length > 0 : !0,
7
- /**
8
- * Validates email format.
9
- */
10
- email: ({ value: r }) => typeof r != "string" ? !1 : /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(r),
11
- /**
12
- * Tests value against a regular expression pattern.
13
- */
14
- regex: ({ value: r, pattern: e }) => {
15
- if (typeof r != "string" || typeof e != "string") return !1;
16
- try {
17
- return new RegExp(e).test(r);
18
- } catch {
19
- return !1;
20
- }
21
- },
22
- /**
23
- * Validates string length within min/max bounds.
24
- */
25
- length: ({ value: r, min: e, max: n }) => {
26
- const s = String(r ?? "").length;
27
- return !(e != null && s < Number(e) || n != null && s > Number(n));
28
- },
29
- /**
30
- * Validates numeric value within min/max bounds.
31
- */
32
- numeric: ({ value: r, min: e, max: n }) => {
33
- const t = Number(r);
34
- return !(isNaN(t) || e != null && t < Number(e) || n != null && t > Number(n));
35
- }
36
- };
37
- function c(r, e, n) {
38
- if (!r) return {};
39
- const t = {};
40
- for (const [s, i] of Object.entries(r))
41
- t[s] = l(i, e, n, void 0);
42
- return t;
43
- }
44
- function g(r, e, n) {
45
- const { dataModel: t, basePath: s, functions: i = a } = n, o = i[r];
46
- if (!o)
47
- return console.warn(`[A2UI] Unknown validation function: ${r}`), !0;
48
- const u = c(e, t, s);
49
- return o(u);
50
- }
51
- function f(r, e) {
52
- return "and" in r && r.and ? r.and.every((n) => f(n, e)) : "or" in r && r.or ? r.or.some((n) => f(n, e)) : "not" in r && r.not ? !f(r.not, e) : "true" in r && r.true === !0 ? !0 : "false" in r && r.false === !1 ? !1 : "call" in r && r.call ? g(r.call, r.args, e) : !0;
53
- }
54
- function v(r, e, n, t) {
55
- if (!r || r.length === 0)
56
- return { valid: !0, errors: [] };
57
- const s = {
58
- dataModel: e,
59
- basePath: n,
60
- functions: t ?? a
61
- }, i = [];
62
- for (const o of r)
63
- !f(o, s) && o.message && i.push(o.message);
64
- return {
65
- valid: i.length === 0,
66
- errors: i
67
- };
68
- }
69
- export {
70
- f as evaluateCheckRule,
71
- v as evaluateChecks,
72
- g as evaluateFunctionCall,
73
- c as resolveArgs,
74
- a as validationFunctions
75
- };