@nan0web/ui 1.0.3 → 1.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.
Files changed (43) hide show
  1. package/README.md +18 -20
  2. package/package.json +15 -16
  3. package/src/App/Command/DepsCommand.js +29 -0
  4. package/src/App/Core/UI.js +1 -50
  5. package/src/App/Core/Widget.js +4 -6
  6. package/src/App/User/Command/Message.js +2 -43
  7. package/src/App/User/Command/index.js +2 -8
  8. package/src/App/User/UserApp.js +31 -11
  9. package/src/README.md.js +33 -33
  10. package/src/StdIn.js +12 -13
  11. package/src/View/View.js +7 -7
  12. package/src/core/Form/Form.js +8 -6
  13. package/src/core/Form/Input.js +13 -13
  14. package/src/core/Form/Message.js +6 -5
  15. package/src/core/InputAdapter.js +2 -2
  16. package/src/core/Message/Message.js +109 -19
  17. package/src/core/Message/OutputMessage.js +7 -7
  18. package/src/core/Message/index.js +3 -4
  19. package/src/core/Stream.js +11 -10
  20. package/src/core/UiAdapter.js +216 -0
  21. package/src/core/index.js +10 -7
  22. package/src/index.js +4 -4
  23. package/types/App/Command/DepsCommand.d.ts +16 -0
  24. package/types/App/Core/UI.d.ts +2 -13
  25. package/types/App/Core/Widget.d.ts +6 -7
  26. package/types/App/User/Command/Message.d.ts +2 -29
  27. package/types/App/User/Command/index.d.ts +2 -4
  28. package/types/App/User/UserApp.d.ts +14 -7
  29. package/types/StdIn.d.ts +13 -13
  30. package/types/View/View.d.ts +6 -6
  31. package/types/core/Form/Form.d.ts +2 -5
  32. package/types/core/Form/Input.d.ts +4 -4
  33. package/types/core/Form/Message.d.ts +5 -10
  34. package/types/core/Intent.d.ts +91 -0
  35. package/types/core/Message/Message.d.ts +58 -15
  36. package/types/core/Message/OutputMessage.d.ts +3 -3
  37. package/types/core/Message/index.d.ts +3 -4
  38. package/types/core/Stream.d.ts +4 -4
  39. package/types/core/UiAdapter.d.ts +122 -0
  40. package/types/core/index.d.ts +6 -5
  41. package/types/index.d.ts +4 -4
  42. package/src/App/User/Command/Options.js +0 -48
  43. package/src/core/Message/InputMessage.js +0 -119
@@ -0,0 +1,216 @@
1
+ import EventProcessor from "@nan0web/event/oop"
2
+ import CancelError from "./Error/CancelError.js"
3
+ import UIMessage from "./Message/Message.js"
4
+ import UIForm from "./Form/Form.js"
5
+ import FormInput from "./Form/Input.js"
6
+ import OutputAdapter from "./OutputAdapter.js"
7
+ import OutputMessage from "./Message/OutputMessage.js"
8
+
9
+ /**
10
+ * Unified UI Adapter that handles both input and output operations.
11
+ * It manages user interactions and rendering of messages, forms, and progress.
12
+ *
13
+ * @class UiAdapter
14
+ * @extends EventProcessor
15
+ *
16
+ * @example
17
+ * const adapter = new UiAdapter()
18
+ * adapter.output = new View()
19
+ *
20
+ * const result = await adapter.requireInput(new LoginMessage())
21
+ * console.log(result) // { username: "user", password: "pass" }
22
+ */
23
+ export default class UiAdapter extends EventProcessor {
24
+ static CancelError = CancelError
25
+ /** @returns {typeof CancelError} */
26
+ get CancelError() {
27
+ return /** @type {typeof UiAdapter} */ (this.constructor).CancelError
28
+ }
29
+
30
+ /** @type {OutputAdapter | null} Output interface for rendering */
31
+ output = null
32
+
33
+ /**
34
+ * Starts listening for input and emits an `input` event.
35
+ *
36
+ * @returns {void}
37
+ */
38
+ start() {
39
+ this.emit('input', UIMessage.from({ body: "Adapter started" }))
40
+ }
41
+
42
+ /**
43
+ * Stops listening for input and output streams.
44
+ * Default implementation does nothing; override in subclasses to perform cleanup.
45
+ *
46
+ * @returns {void}
47
+ */
48
+ stop() {
49
+ // Default implementation – does nothing
50
+ }
51
+
52
+ /**
53
+ * Checks whether the adapter is ready to receive input.
54
+ *
55
+ * @returns {boolean} Always true in base class; override for specific checks.
56
+ */
57
+ isReady() {
58
+ return true
59
+ }
60
+
61
+ /**
62
+ * Helper to ask a question.
63
+ * Must be implemented by subclasses.
64
+ *
65
+ * @param {string} question - Question to ask the user.
66
+ * @returns {Promise<string>} User's response.
67
+ * @throws {Error} If not implemented in subclass.
68
+ */
69
+ async ask(question) {
70
+ throw new Error('ask() method must be implemented in subclass')
71
+ }
72
+
73
+ /**
74
+ * Generic selection prompt.
75
+ * Must be implemented by subclasses.
76
+ *
77
+ * @param {object} config - Selection configuration.
78
+ * @param {string[]} [config.options=[]] - List of options to choose from.
79
+ * @returns {Promise<{ index: number, value: string | null }>} Selected option.
80
+ * @throws {Error} If not implemented in subclass.
81
+ */
82
+ async select(config) {
83
+ throw new Error('select() method must be implemented in subclass')
84
+ }
85
+
86
+ /**
87
+ * Process a UIForm and return its result.
88
+ *
89
+ * This default implementation follows an **agnostic UI** approach:
90
+ * it simply returns the form instance (with optional initial state merged)
91
+ * without UI interaction. Concrete adapters (CLI, Web, etc.) can override
92
+ * this method to render the form, collect user input and return a richer
93
+ * result object (`{ form, cancelled }`).
94
+ *
95
+ * @param {UIForm} form - The UIForm instance to process.
96
+ * @param {object} [initialState={}] - Pre‑filled values for the form.
97
+ * @returns {Promise<{ form: UIForm, cancelled?: boolean }>} Form processing result.
98
+ */
99
+ async processForm(form, initialState = {}) {
100
+ // Merge any provided initial state into the form's internal state.
101
+ if (initialState && typeof initialState === 'object') {
102
+ form.state = { ...form.state, ...initialState }
103
+ }
104
+ // In the agnostic baseline we do not perform any interactive I/O.
105
+ // Sub‑classes may provide a UI (render, ask, etc.) and return
106
+ // `{ form, cancelled: true/false, ... }`.
107
+ return { form }
108
+ }
109
+
110
+ /**
111
+ * Ensures a message's body is fully and validly filled.
112
+ * Generates a form from the message's static Body schema,
113
+ * then iteratively collects input until all fields are valid or cancelled.
114
+ *
115
+ * @template {UIMessage} T
116
+ * @param {T} msg - Message instance needing input.
117
+ * @returns {Promise<T['body']>} Updated and validated message body.
118
+ *
119
+ * @example
120
+ * const body = await adapter.requireInput(new LoginMessage({ body: { username: "user" } }))
121
+ * // → prompts for password, returns { username: "user", password: "..." }
122
+ */
123
+ async requireInput(msg) {
124
+ if (!msg) {
125
+ throw new Error("Message instance is required")
126
+ }
127
+ if (!(msg instanceof UIMessage)) {
128
+ throw new TypeError("Message must be an instance of UIMessage")
129
+ }
130
+ /** @type {Map<string,string>} */
131
+ let errors = msg.validate()
132
+ while (errors.size > 0) {
133
+ const form = generateForm(
134
+ /** @type {any} */(msg.constructor).Body,
135
+ { initialState: msg.body }
136
+ )
137
+
138
+ const formResult = await this.processForm ? this.processForm(form, msg.body) : {} // Assume method exists or handle differently, but error indicates missing method; perhaps remove if not used
139
+ if (formResult.cancelled) {
140
+ throw new CancelError("User cancelled form")
141
+ }
142
+
143
+ const updatedBody = { ...msg.body, ...formResult.form.state }
144
+ const updatedErrors = msg.validate(updatedBody)
145
+
146
+ if (updatedErrors.size > 0) {
147
+ if (this.output) {
148
+ this.output.render(new OutputMessage({
149
+ type: "Alert",
150
+ variant: "error",
151
+ body: Array.from(updatedErrors.values()).join("\n")
152
+ }))
153
+ }
154
+ errors = updatedErrors
155
+ continue
156
+ }
157
+ msg.body = updatedBody
158
+ break
159
+ }
160
+ return msg.body
161
+ }
162
+
163
+ /**
164
+ * Renders a message to the user interface.
165
+ * Must be implemented by subclasses.
166
+ *
167
+ * @param {UIMessage} message - Message to render.
168
+ * @emits rendered
169
+ * @throws {Error} If not implemented in subclass.
170
+ */
171
+ render(message) {
172
+ throw new Error("render() must be implemented by subclass")
173
+ this.emit("rendered", message)
174
+ }
175
+ }
176
+
177
+ /**
178
+ * Generates a UIForm from a static Body schema.
179
+ *
180
+ * @param {Function} BodyClass - Class defining field schema.
181
+ * @param {Object} [options={}] - Generation options.
182
+ * @param {Object} [options.initialState={}] - Pre-filled form values.
183
+ * @param {Function} [options.t] - Optional translation function.
184
+ * @returns {UIForm} Form instance ready for input.
185
+ */
186
+ export function generateForm(BodyClass, options = {}) {
187
+ const { initialState = {}, t = v => v } = options
188
+ const fields = []
189
+
190
+ for (const [name, schema] of Object.entries(BodyClass)) {
191
+ if (typeof schema !== "object" || schema === null || !name || !schema.help) continue
192
+
193
+ const label = t(schema.help) || name
194
+ const placeholder = t(schema.placeholder || schema.defaultValue || "")
195
+ const isRequired = !!schema.required
196
+
197
+ fields.push(
198
+ new FormInput({
199
+ name,
200
+ label,
201
+ type: schema.type || FormInput.TYPES.TEXT,
202
+ required: isRequired,
203
+ placeholder,
204
+ options: schema.options ? schema.options.map(o => String(o)) : [],
205
+ validation: schema.validate
206
+ ? (value) => {
207
+ const res = schema.validate(value)
208
+ return res === true ? true : typeof res === "string" ? res : `Invalid ${name}`
209
+ }
210
+ : () => true,
211
+ }),
212
+ )
213
+ }
214
+
215
+ return new UIForm({ fields })
216
+ }
package/src/core/index.js CHANGED
@@ -1,15 +1,18 @@
1
- // export default App
2
-
3
1
  export { default as InputAdapter } from "./InputAdapter.js"
4
2
  export { default as OutputAdapter } from "./OutputAdapter.js"
5
- export { default as UIStream } from "./Stream.js"
6
3
 
7
- export { default as UIMessage } from "./Message/Message.js"
8
- export { default as InputMessage } from "./Message/InputMessage.js"
9
- export { default as OutputMessage } from "./Message/OutputMessage.js"
4
+ import UIStream from "./Stream.js"
5
+ export { UIStream, UIStream as UiStream }
6
+ import StreamEntry from "./StreamEntry.js"
7
+ export { StreamEntry, StreamEntry as UiStreamEntry }
10
8
 
9
+ export { default as UiMessage } from "./Message/Message.js"
11
10
  export { default as FormMessage } from "./Form/Message.js"
12
11
  export { default as FormInput } from "./Form/Input.js"
13
- export { default as UIForm } from "./Form/Form.js"
12
+
13
+ import UIForm from "./Form/Form.js"
14
+ export { UIForm, UIForm as UiForm }
14
15
 
15
16
  export { default as Error, CancelError } from "./Error/index.js"
17
+
18
+ export { default as UiAdapter } from "./UiAdapter.js"
package/src/index.js CHANGED
@@ -26,10 +26,10 @@ export {
26
26
  export { default as FormMessage } from "./core/Form/Message.js"
27
27
  export { default as FormInput } from "./core/Form/Input.js"
28
28
  export { default as InputAdapter } from "./core/InputAdapter.js"
29
- export { default as InputMessage } from "./core/Message/InputMessage.js"
30
29
  export { default as OutputAdapter } from "./core/OutputAdapter.js"
31
30
  export { default as OutputMessage } from "./core/Message/OutputMessage.js"
32
- export { default as UIForm } from "./core/Form/Form.js"
33
- export { default as UIMessage } from "./core/Message/Message.js"
34
- export { default as UIStream } from "./core/Stream.js"
31
+ export { default as UiForm } from "./core/Form/Form.js"
32
+ export { default as UiMessage } from "./core/Message/Message.js"
33
+ export { default as UiStream } from "./core/Stream.js"
35
34
  export { default as Error, CancelError } from "./core/Error/index.js"
35
+ export { default as UiAdapter } from "./core/UiAdapter.js"
@@ -0,0 +1,16 @@
1
+ export class DepsCommand extends UiMessage {
2
+ static Body: typeof DepsCommandBody;
3
+ constructor(input?: {});
4
+ /** @type {DepsCommandBody} */
5
+ body: DepsCommandBody;
6
+ }
7
+ export default DepsCommand;
8
+ import UiMessage from "../../core/Message/Message.js";
9
+ declare class DepsCommandBody {
10
+ static fix: {
11
+ help: string;
12
+ defaultValue: boolean;
13
+ };
14
+ constructor(input?: {});
15
+ fix: boolean;
16
+ }
@@ -1,11 +1,9 @@
1
- export default UI;
2
- export type ComponentFn = import("../../View/View.js").ComponentFn;
3
1
  /** @typedef {import("../../View/View.js").ComponentFn} ComponentFn */
4
2
  /**
5
3
  * Abstract UI class to connect apps and widgets.
6
4
  * Supports input/output data typed classes and views.
7
5
  */
8
- declare class UI extends Widget {
6
+ export default class UI extends Widget {
9
7
  /**
10
8
  * Creates a new UI instance.
11
9
  * @param {CoreApp} app - The app to connect to this UI
@@ -22,16 +20,6 @@ declare class UI extends Widget {
22
20
  * @throws {Error} Always thrown as this method must be implemented by subclasses
23
21
  */
24
22
  convertInput(rawInput: any): Message[];
25
- /**
26
- * Process input, run commands on app, and output results.
27
- * Supports progress callback.
28
- * @emits {start} Emitted when processing begins
29
- * @emits {data} Emitted for each command being processed
30
- * @emits {end} Emitted when all commands have been processed
31
- * @param {any} rawInput - Raw input to process
32
- * @returns {Promise<any[]>} Results of command processing
33
- */
34
- process(rawInput: any): Promise<any[]>;
35
23
  /**
36
24
  * Sets up event handlers for UI process events.
37
25
  * @param {ComponentFn} UIProcess - Process view component
@@ -43,6 +31,7 @@ declare class UI extends Widget {
43
31
  */
44
32
  output(results: any[]): void;
45
33
  }
34
+ export type ComponentFn = import("../../View/View.js").ComponentFn;
46
35
  import Widget from "./Widget.js";
47
36
  import CoreApp from "./CoreApp.js";
48
37
  import { Message } from "@nan0web/co";
@@ -1,12 +1,10 @@
1
- export default Widget;
2
- export type ComponentFn = import("./UI.js").ComponentFn;
3
1
  /** @typedef {import("./UI.js").ComponentFn} ComponentFn */
4
2
  /**
5
3
  * Abstract Widget class.
6
4
  * Widget is a view with ability to input data in a specific format.
7
5
  * Input and output data are typed classes.
8
6
  */
9
- declare class Widget extends EventProcessor {
7
+ export default class Widget extends EventProcessor {
10
8
  /**
11
9
  * Creates a new Widget instance.
12
10
  * @param {View} [view] - View instance (default: new View())
@@ -16,10 +14,10 @@ declare class Widget extends EventProcessor {
16
14
  view: View;
17
15
  /**
18
16
  * Ask user for input data of specific class.
19
- * @param {InputMessage} input - instance of InputMessage or similar
20
- * @returns {Promise<InputMessage | null>} instance of InputMessage or null
17
+ * @param {UiMessage} input - instance of UiMessage or similar
18
+ * @returns {Promise<UiMessage | null>} instance of UiMessage or null
21
19
  */
22
- ask(input: InputMessage): Promise<InputMessage | null>;
20
+ ask(input: UiMessage): Promise<UiMessage | null>;
23
21
  /**
24
22
  * @param {AsyncGenerator<StreamEntry>} stream
25
23
  * @returns {Promise<void>}
@@ -34,7 +32,8 @@ declare class Widget extends EventProcessor {
34
32
  */
35
33
  render(viewFnOrName: Function | string, outputData: object): any;
36
34
  }
35
+ export type ComponentFn = import("./UI.js").ComponentFn;
37
36
  import EventProcessor from "@nan0web/event/oop";
38
37
  import View from "../../View/View.js";
39
- import InputMessage from "../../core/Message/InputMessage.js";
38
+ import { UiMessage } from "../../core/index.js";
40
39
  import { StreamEntry } from "@nan0web/db";
@@ -1,29 +1,2 @@
1
- export default UserAppCommandMessage;
2
- /**
3
- * Extends Command.Message to include user-specific command options.
4
- */
5
- declare class UserAppCommandMessage {
6
- /**
7
- * Parses an array of strings into a UserAppCommandMessage.
8
- * @param {string[] | string} value - Arguments to parse
9
- * @returns {UserAppCommandMessage} Parsed command message
10
- */
11
- static parse(value?: string[] | string): UserAppCommandMessage;
12
- /**
13
- * Creates a new UserAppCommandMessage instance.
14
- * @param {object} props - Command message properties
15
- * @param {string[]} [props.args=[]] - Command arguments
16
- * @param {Partial<UserAppCommandOptions>} [props.opts={}] - User-specific options
17
- */
18
- constructor(props?: {
19
- args?: string[] | undefined;
20
- opts?: Partial<UserAppCommandOptions> | undefined;
21
- });
22
- /**
23
- * @param {Partial<UserAppCommandOptions>} value
24
- */
25
- set opts(value: Partial<UserAppCommandOptions>);
26
- /** @returns {UserAppCommandOptions} */
27
- get opts(): UserAppCommandOptions;
28
- }
29
- import UserAppCommandOptions from "./Options.js";
1
+ export default UiMessage;
2
+ import UiMessage from "../../../core/Message/Message.js";
@@ -1,5 +1,3 @@
1
- declare const _default: any;
2
- export default _default;
1
+ export { CommandMessage };
2
+ export default CommandMessage;
3
3
  import CommandMessage from "./Message.js";
4
- import CommandOptions from "./Options.js";
5
- export { CommandMessage, CommandOptions };
@@ -1,34 +1,41 @@
1
- export default UserApp;
2
1
  /**
3
2
  * UserApp requires user name and shows Welcome view.
4
3
  * If user.name is provided in command input, ignores user input.
5
4
  * User can change user data to see another Welcome view.
6
5
  */
7
- declare class UserApp extends CoreApp {
6
+ export default class UserApp extends CoreApp {
8
7
  /**
9
8
  * Creates a new UserApp instance.
10
9
  * @param {Partial<CoreApp>} [props={}] - UserApp properties
11
10
  */
12
11
  constructor(props?: Partial<CoreApp>);
12
+ /**
13
+ * Handle deps command with async generator for stream processing.
14
+ * @param {DepsCommand} cmd - Command message with deps parameters
15
+ * @param {UserUI} ui - UI instance
16
+ * @returns {Promise<Object>} Command output
17
+ */
18
+ handleDeps(cmd: DepsCommand, ui: UserUI): Promise<any>;
13
19
  /**
14
20
  * Set user data from params.
15
- * @param {Message} cmd - Command message with user data
21
+ * @param {UserAppCommandMessage} cmd - Command message with user data
16
22
  * @param {UserUI} ui - UI instance
17
23
  * @returns {Promise<{ message: string }>} Welcome message
18
24
  */
19
- setUser(cmd: Message, ui: UserUI): Promise<{
25
+ setUser(cmd: UserAppCommandMessage, ui: UserUI): Promise<{
20
26
  message: string;
21
27
  }>;
22
28
  /**
23
29
  * Show welcome message for current user.
24
- * @param {Message} cmd - Command message
30
+ * @param {UserAppCommandMessage} cmd - Command message
25
31
  * @param {UserUI} ui - UI instance
26
32
  * @returns {Promise<string[][]>} Welcome view output
27
33
  */
28
- welcome(cmd: Message, ui: UserUI): Promise<string[][]>;
34
+ welcome(cmd: UserAppCommandMessage, ui: UserUI): Promise<string[][]>;
29
35
  user: User | undefined;
30
36
  }
31
37
  import CoreApp from "../Core/CoreApp.js";
32
- import { Message } from "@nan0web/co";
38
+ import DepsCommand from "./Command/Message.js";
33
39
  import UserUI from "./UserUI.js";
40
+ import UserAppCommandMessage from "./Command/Message.js";
34
41
  import User from "../../Model/User/User.js";
package/types/StdIn.d.ts CHANGED
@@ -1,8 +1,7 @@
1
- export default StdIn;
2
1
  /**
3
2
  * Handles standard input stream with message buffering.
4
3
  */
5
- declare class StdIn extends EventProcessor {
4
+ export default class StdIn extends EventProcessor {
6
5
  /** @type {number} Read interval in milliseconds */
7
6
  static READ_INTERVAL: number;
8
7
  /** @type {string[]} Messages to ignore */
@@ -17,14 +16,14 @@ declare class StdIn extends EventProcessor {
17
16
  * Creates a new StdIn instance.
18
17
  * @param {object} props - StdIn properties
19
18
  * @param {Processor} [props.processor] - Input processor
20
- * @param {InputMessage[]} [props.stream=[]] - Initial input stream
19
+ * @param {UiMessage[]} [props.stream=[]] - Initial input stream
21
20
  */
22
21
  constructor(props?: {
23
22
  processor?: Processor | undefined;
24
- stream?: InputMessage[] | undefined;
23
+ stream?: UiMessage[] | undefined;
25
24
  });
26
- /** @type {InputMessage[]} Input message buffer */
27
- stream: InputMessage[];
25
+ /** @type {UiMessage[]} Input message buffer */
26
+ stream: UiMessage[];
28
27
  /** @type {Processor} Input processor */
29
28
  processor: Processor;
30
29
  /**
@@ -40,9 +39,9 @@ declare class StdIn extends EventProcessor {
40
39
  /**
41
40
  * Reads a message from the input stream.
42
41
  * Waits until messages are available if stream is empty.
43
- * @returns {Promise<InputMessage>} Next input message
42
+ * @returns {Promise<UiMessage>} Next input message
44
43
  */
45
- read(): Promise<InputMessage>;
44
+ read(): Promise<UiMessage>;
46
45
  /**
47
46
  * Writes a message to the input stream.
48
47
  * @param {string} message - Message to write
@@ -50,13 +49,14 @@ declare class StdIn extends EventProcessor {
50
49
  */
51
50
  write(message: string): boolean;
52
51
  /**
53
- * Decodes a message into an InputMessage instance.
54
- * @param {InputMessage | string[] | any} message - Message to decode
55
- * @returns {InputMessage} Decoded input message
52
+ * Decodes a message into an UiMessage instance.
53
+ * @param {UiMessage | string[] | any} message - Message to decode
54
+ * @returns {UiMessage} Decoded input message
56
55
  */
57
- decode(message: InputMessage | string[] | any): InputMessage;
56
+ decode(message: UiMessage | string[] | any): UiMessage;
58
57
  }
59
58
  import EventProcessor from "@nan0web/event/oop";
60
- import InputMessage from "./core/Message/InputMessage.js";
59
+ import { UiMessage } from "./core/index.js";
61
60
  declare class Processor extends EventProcessor {
62
61
  }
62
+ export {};
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @typedef {Object} ComponentFn
3
3
  * @property {string} name
4
- * @property {(input: InputMessage) => Promise<any>} ask
4
+ * @property {(input: UiMessage) => Promise<any>} ask
5
5
  * @property {Function} bind
6
6
  */
7
7
  export default class View {
@@ -96,14 +96,14 @@ export default class View {
96
96
  */
97
97
  get(name: string): ComponentFn | undefined;
98
98
  /**
99
- * @param {InputMessage} input
100
- * @returns {Promise<InputMessage | null>}
99
+ * @param {UiMessage} input
100
+ * @returns {Promise<UiMessage | null>}
101
101
  */
102
- ask(input: InputMessage): Promise<InputMessage | null>;
102
+ ask(input: UiMessage): Promise<UiMessage | null>;
103
103
  }
104
104
  export type ComponentFn = {
105
105
  name: string;
106
- ask: (input: InputMessage) => Promise<any>;
106
+ ask: (input: UiMessage) => Promise<any>;
107
107
  bind: Function;
108
108
  };
109
109
  import StdIn from "../StdIn.js";
@@ -112,4 +112,4 @@ import Frame from "../Frame/Frame.js";
112
112
  import Locale from "../Locale.js";
113
113
  import { FrameRenderMethod } from "../Frame/Frame.js";
114
114
  import RenderOptions from "./RenderOptions.js";
115
- import InputMessage from "../core/Message/InputMessage.js";
115
+ import UiMessage from "../core/Message/Message.js";
@@ -89,12 +89,9 @@ export default class UIForm extends FormMessage {
89
89
  /**
90
90
  * Validates the entire form.
91
91
  *
92
- * @returns {{isValid: boolean, errors: Object}} Validation result.
92
+ * @returns {Map<string, string>} Map of validation errors, empty if valid.
93
93
  */
94
- validate(): {
95
- isValid: boolean;
96
- errors: any;
97
- };
94
+ validate(): Map<string, string>;
98
95
  /**
99
96
  * Validates a single field.
100
97
  *
@@ -14,8 +14,8 @@
14
14
  * @property {string} type - Input type (text, email, number, select, etc.).
15
15
  * @property {boolean} required - Whether the field is required.
16
16
  * @property {string} placeholder - Placeholder text.
17
- * @property {Array<string>} options - Select options (if type is 'select').
18
- * @property {Function|null} validation - Custom validation function.
17
+ * @property {InputOptions} options - Select options (if type is 'select').
18
+ * @property {Function} validation - Custom validation function.
19
19
  * @property {*} defaultValue - Default value.
20
20
  */
21
21
  export default class FormInput {
@@ -45,7 +45,7 @@ export default class FormInput {
45
45
  * @param {boolean} [props.required=false] - Is required.
46
46
  * @param {string} [props.placeholder=''] - Placeholder.
47
47
  * @param {InputOptions} [props.options=[]] - Select options or async function to retrieve data with the search and page.
48
- * @param {Function} [props.validation=null] - Custom validation.
48
+ * @param {Function} [props.validation] - Custom validation.
49
49
  * @param {*} [props.defaultValue=null] - Default value.
50
50
  */
51
51
  constructor(props: {
@@ -64,7 +64,7 @@ export default class FormInput {
64
64
  /** @type {boolean} */ required: boolean;
65
65
  /** @type {string} */ placeholder: string;
66
66
  /** @type {InputOptions} */ options: InputOptions;
67
- /** @type {Function|null} */ validation: Function | null;
67
+ /** @type {Function} */ validation: Function;
68
68
  /** @type {*} */ defaultValue: any;
69
69
  requireValidType(): void;
70
70
  /**
@@ -1,16 +1,11 @@
1
1
  /**
2
- * FormMessage – specialized InputMessage for forms.
2
+ * FormMessage – specialized UiMessage for forms.
3
+ * It carries form-specific data and schema for validation.
3
4
  *
4
5
  * @class FormMessage
5
- * @extends InputMessage
6
+ * @extends UiMessage
6
7
  */
7
- export default class FormMessage extends InputMessage {
8
- /**
9
- * Creates a FormMessage.
10
- *
11
- * @param {Object} [input={}] - Message properties.
12
- */
13
- constructor(input?: any);
8
+ export default class FormMessage extends UiMessage {
14
9
  data: any;
15
10
  schema: any;
16
11
  /**
@@ -31,4 +26,4 @@ export default class FormMessage extends InputMessage {
31
26
  errors: any;
32
27
  };
33
28
  }
34
- import InputMessage from "../Message/InputMessage.js";
29
+ import UiMessage from "../Message/Message.js";