@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.
- package/README.md +18 -20
- package/package.json +15 -16
- package/src/App/Command/DepsCommand.js +29 -0
- package/src/App/Core/UI.js +1 -50
- package/src/App/Core/Widget.js +4 -6
- package/src/App/User/Command/Message.js +2 -43
- package/src/App/User/Command/index.js +2 -8
- package/src/App/User/UserApp.js +31 -11
- package/src/README.md.js +33 -33
- package/src/StdIn.js +12 -13
- package/src/View/View.js +7 -7
- package/src/core/Form/Form.js +8 -6
- package/src/core/Form/Input.js +13 -13
- package/src/core/Form/Message.js +6 -5
- package/src/core/InputAdapter.js +2 -2
- package/src/core/Message/Message.js +109 -19
- package/src/core/Message/OutputMessage.js +7 -7
- package/src/core/Message/index.js +3 -4
- package/src/core/Stream.js +11 -10
- package/src/core/UiAdapter.js +216 -0
- package/src/core/index.js +10 -7
- package/src/index.js +4 -4
- package/types/App/Command/DepsCommand.d.ts +16 -0
- package/types/App/Core/UI.d.ts +2 -13
- package/types/App/Core/Widget.d.ts +6 -7
- package/types/App/User/Command/Message.d.ts +2 -29
- package/types/App/User/Command/index.d.ts +2 -4
- package/types/App/User/UserApp.d.ts +14 -7
- package/types/StdIn.d.ts +13 -13
- package/types/View/View.d.ts +6 -6
- package/types/core/Form/Form.d.ts +2 -5
- package/types/core/Form/Input.d.ts +4 -4
- package/types/core/Form/Message.d.ts +5 -10
- package/types/core/Intent.d.ts +91 -0
- package/types/core/Message/Message.d.ts +58 -15
- package/types/core/Message/OutputMessage.d.ts +3 -3
- package/types/core/Message/index.d.ts +3 -4
- package/types/core/Stream.d.ts +4 -4
- package/types/core/UiAdapter.d.ts +122 -0
- package/types/core/index.d.ts +6 -5
- package/types/index.d.ts +4 -4
- package/src/App/User/Command/Options.js +0 -48
- 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
|
-
|
|
8
|
-
export {
|
|
9
|
-
|
|
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
|
-
|
|
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
|
|
33
|
-
export { default as
|
|
34
|
-
export { default as
|
|
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
|
+
}
|
package/types/App/Core/UI.d.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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 {
|
|
20
|
-
* @returns {Promise<
|
|
17
|
+
* @param {UiMessage} input - instance of UiMessage or similar
|
|
18
|
+
* @returns {Promise<UiMessage | null>} instance of UiMessage or null
|
|
21
19
|
*/
|
|
22
|
-
ask(input:
|
|
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
|
|
38
|
+
import { UiMessage } from "../../core/index.js";
|
|
40
39
|
import { StreamEntry } from "@nan0web/db";
|
|
@@ -1,29 +1,2 @@
|
|
|
1
|
-
export default
|
|
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,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
|
-
|
|
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 {
|
|
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:
|
|
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 {
|
|
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:
|
|
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
|
|
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
|
-
|
|
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 {
|
|
19
|
+
* @param {UiMessage[]} [props.stream=[]] - Initial input stream
|
|
21
20
|
*/
|
|
22
21
|
constructor(props?: {
|
|
23
22
|
processor?: Processor | undefined;
|
|
24
|
-
stream?:
|
|
23
|
+
stream?: UiMessage[] | undefined;
|
|
25
24
|
});
|
|
26
|
-
/** @type {
|
|
27
|
-
stream:
|
|
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<
|
|
42
|
+
* @returns {Promise<UiMessage>} Next input message
|
|
44
43
|
*/
|
|
45
|
-
read(): Promise<
|
|
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
|
|
54
|
-
* @param {
|
|
55
|
-
* @returns {
|
|
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:
|
|
56
|
+
decode(message: UiMessage | string[] | any): UiMessage;
|
|
58
57
|
}
|
|
59
58
|
import EventProcessor from "@nan0web/event/oop";
|
|
60
|
-
import
|
|
59
|
+
import { UiMessage } from "./core/index.js";
|
|
61
60
|
declare class Processor extends EventProcessor {
|
|
62
61
|
}
|
|
62
|
+
export {};
|
package/types/View/View.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @typedef {Object} ComponentFn
|
|
3
3
|
* @property {string} name
|
|
4
|
-
* @property {(input:
|
|
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 {
|
|
100
|
-
* @returns {Promise<
|
|
99
|
+
* @param {UiMessage} input
|
|
100
|
+
* @returns {Promise<UiMessage | null>}
|
|
101
101
|
*/
|
|
102
|
-
ask(input:
|
|
102
|
+
ask(input: UiMessage): Promise<UiMessage | null>;
|
|
103
103
|
}
|
|
104
104
|
export type ComponentFn = {
|
|
105
105
|
name: string;
|
|
106
|
-
ask: (input:
|
|
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
|
|
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 {
|
|
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 {
|
|
18
|
-
* @property {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
|
|
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
|
|
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
|
|
2
|
+
* FormMessage – specialized UiMessage for forms.
|
|
3
|
+
* It carries form-specific data and schema for validation.
|
|
3
4
|
*
|
|
4
5
|
* @class FormMessage
|
|
5
|
-
* @extends
|
|
6
|
+
* @extends UiMessage
|
|
6
7
|
*/
|
|
7
|
-
export default class FormMessage extends
|
|
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
|
|
29
|
+
import UiMessage from "../Message/Message.js";
|