@nan0web/ui 1.1.0 → 1.3.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 +19 -14
- package/package.json +6 -4
- package/src/App/Command/DepsCommand.js +5 -9
- package/src/App/Core/CoreApp.js +18 -17
- package/src/App/Core/UI.js +11 -15
- package/src/App/Core/Widget.js +6 -10
- package/src/App/Core/index.js +3 -3
- package/src/App/Scenario.js +4 -4
- package/src/App/User/Command/Message.js +1 -1
- package/src/App/User/Command/index.js +1 -1
- package/src/App/User/UserApp.js +28 -21
- package/src/App/User/UserUI.js +2 -2
- package/src/App/User/index.js +2 -2
- package/src/App/index.js +5 -10
- package/src/Component/Process/Input.js +10 -17
- package/src/Component/Process/Process.js +3 -5
- package/src/Component/Process/index.js +2 -2
- package/src/Component/SortableList/SortableList.js +100 -0
- package/src/Component/SortableList/index.js +3 -0
- package/src/Component/Welcome/Input.js +2 -4
- package/src/Component/Welcome/Welcome.js +5 -9
- package/src/Component/Welcome/index.js +2 -2
- package/src/Component/index.js +5 -3
- package/src/Frame/Frame.js +163 -146
- package/src/Frame/Props.js +20 -20
- package/src/Locale.js +17 -18
- package/src/Model/User/User.js +3 -6
- package/src/Model/index.js +1 -1
- package/src/README.md.js +84 -94
- package/src/StdIn.js +8 -12
- package/src/StdOut.js +23 -27
- package/src/View/RenderOptions.js +1 -1
- package/src/View/View.js +40 -36
- package/src/core/Error/CancelError.js +2 -2
- package/src/core/Error/index.js +3 -5
- package/src/core/Flow.js +347 -0
- package/src/core/Form/Form.js +35 -33
- package/src/core/Form/Input.js +21 -6
- package/src/core/Form/Message.js +3 -6
- package/src/core/Form/index.js +4 -8
- package/src/core/InputAdapter.js +4 -6
- package/src/core/Message/Message.js +9 -12
- package/src/core/Message/OutputMessage.js +19 -17
- package/src/core/Message/index.js +2 -2
- package/src/core/OutputAdapter.js +12 -10
- package/src/core/Stream.js +1 -1
- package/src/core/StreamEntry.js +2 -2
- package/src/core/UiAdapter.js +31 -30
- package/src/core/index.js +33 -10
- package/src/functions.js +8 -15
- package/src/index.js +21 -32
- package/types/App/Command/DepsCommand.d.ts +1 -1
- package/types/App/Command/Options.d.ts +37 -40
- package/types/App/Command/index.d.ts +6 -6
- package/types/App/Core/CoreApp.d.ts +2 -2
- package/types/App/Core/UI.d.ts +4 -4
- package/types/App/Core/Widget.d.ts +4 -4
- package/types/App/Core/index.d.ts +3 -3
- package/types/App/Scenario.d.ts +1 -1
- package/types/App/User/Command/Message.d.ts +1 -1
- package/types/App/User/Command/Options.d.ts +29 -29
- package/types/App/User/Command/index.d.ts +1 -1
- package/types/App/User/UserApp.d.ts +5 -5
- package/types/App/User/index.d.ts +2 -2
- package/types/App/index.d.ts +4 -4
- package/types/Component/Process/Process.d.ts +2 -2
- package/types/Component/Process/index.d.ts +2 -2
- package/types/Component/SortableList/SortableList.d.ts +58 -0
- package/types/Component/SortableList/index.d.ts +2 -0
- package/types/Component/Welcome/Input.d.ts +1 -1
- package/types/Component/Welcome/Welcome.d.ts +1 -1
- package/types/Component/Welcome/index.d.ts +2 -2
- package/types/Component/index.d.ts +5 -3
- package/types/Frame/Frame.d.ts +1 -1
- package/types/Frame/Props.d.ts +1 -1
- package/types/Model/index.d.ts +1 -1
- package/types/StdIn.d.ts +2 -2
- package/types/StdOut.d.ts +1 -1
- package/types/View/View.d.ts +7 -7
- package/types/core/Error/index.d.ts +1 -1
- package/types/core/Flow.d.ts +320 -0
- package/types/core/Form/Form.d.ts +2 -2
- package/types/core/Form/Input.d.ts +11 -0
- package/types/core/Form/Message.d.ts +1 -1
- package/types/core/Form/index.d.ts +3 -3
- package/types/core/InputAdapter.d.ts +2 -2
- package/types/core/Intent.d.ts +65 -68
- package/types/core/Message/InputMessage.d.ts +65 -65
- package/types/core/Message/Message.d.ts +1 -1
- package/types/core/Message/OutputMessage.d.ts +1 -1
- package/types/core/Message/index.d.ts +2 -2
- package/types/core/Stream.d.ts +1 -1
- package/types/core/UiAdapter.d.ts +5 -5
- package/types/core/index.d.ts +4 -3
- package/types/index.d.ts +10 -10
package/src/core/Form/Input.js
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* @property {string} placeholder - Placeholder text.
|
|
19
19
|
* @property {InputOptions} options - Select options (if type is 'select').
|
|
20
20
|
* @property {Function} validation - Custom validation function.
|
|
21
|
+
* @property {string} mask - Mask pattern (e.g. '###-###').
|
|
21
22
|
* @property {*} defaultValue - Default value.
|
|
22
23
|
*/
|
|
23
24
|
export default class FormInput {
|
|
@@ -28,6 +29,7 @@ export default class FormInput {
|
|
|
28
29
|
/** @type {string} */ placeholder = ''
|
|
29
30
|
/** @type {InputOptions} */ options = []
|
|
30
31
|
/** @type {Function} */ validation = () => true
|
|
32
|
+
/** @type {string} */ mask = ''
|
|
31
33
|
/** @type {*} */ defaultValue = null
|
|
32
34
|
|
|
33
35
|
/**
|
|
@@ -40,6 +42,13 @@ export default class FormInput {
|
|
|
40
42
|
SELECT: 'select',
|
|
41
43
|
CHECKBOX: 'checkbox',
|
|
42
44
|
TEXTAREA: 'textarea',
|
|
45
|
+
PASSWORD: 'password',
|
|
46
|
+
SECRET: 'secret',
|
|
47
|
+
MASK: 'mask',
|
|
48
|
+
CONFIRM: 'confirm',
|
|
49
|
+
TOGGLE: 'toggle',
|
|
50
|
+
MULTISELECT: 'multiselect',
|
|
51
|
+
AUTOCOMPLETE: 'autocomplete',
|
|
43
52
|
}
|
|
44
53
|
|
|
45
54
|
/**
|
|
@@ -53,6 +62,7 @@ export default class FormInput {
|
|
|
53
62
|
* @param {string} [props.placeholder=''] - Placeholder.
|
|
54
63
|
* @param {InputOptions} [props.options=[]] - Select options or async function to retrieve data with the search and page.
|
|
55
64
|
* @param {Function} [props.validation] - Custom validation.
|
|
65
|
+
* @param {string} [props.mask=''] - Mask pattern.
|
|
56
66
|
* @param {*} [props.defaultValue=null] - Default value.
|
|
57
67
|
*/
|
|
58
68
|
constructor(props) {
|
|
@@ -64,6 +74,7 @@ export default class FormInput {
|
|
|
64
74
|
placeholder = this.placeholder,
|
|
65
75
|
options = [],
|
|
66
76
|
validation = this.validation,
|
|
77
|
+
mask = '',
|
|
67
78
|
defaultValue = this.defaultValue,
|
|
68
79
|
} = props
|
|
69
80
|
|
|
@@ -78,6 +89,7 @@ export default class FormInput {
|
|
|
78
89
|
this.placeholder = String(placeholder)
|
|
79
90
|
this.options = options
|
|
80
91
|
this.validation = validation
|
|
92
|
+
this.mask = String(mask)
|
|
81
93
|
this.defaultValue = defaultValue
|
|
82
94
|
|
|
83
95
|
this.requireValidType()
|
|
@@ -85,12 +97,14 @@ export default class FormInput {
|
|
|
85
97
|
|
|
86
98
|
requireValidType() {
|
|
87
99
|
if (!Object.values(FormInput.TYPES).includes(this.type)) {
|
|
88
|
-
throw new TypeError(
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
100
|
+
throw new TypeError(
|
|
101
|
+
[
|
|
102
|
+
'FormInput.type is invalid!',
|
|
103
|
+
['Provided', this.type].join(': '),
|
|
104
|
+
'Available types:',
|
|
105
|
+
...Object.values(FormInput.TYPES).map((t) => ` - ${t}`),
|
|
106
|
+
].join('\n'),
|
|
107
|
+
)
|
|
94
108
|
}
|
|
95
109
|
}
|
|
96
110
|
|
|
@@ -107,6 +121,7 @@ export default class FormInput {
|
|
|
107
121
|
required: this.required,
|
|
108
122
|
placeholder: this.placeholder,
|
|
109
123
|
options: this.options,
|
|
124
|
+
mask: this.mask,
|
|
110
125
|
defaultValue: this.defaultValue,
|
|
111
126
|
}
|
|
112
127
|
}
|
package/src/core/Form/Message.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import UiMessage from
|
|
1
|
+
import UiMessage from '../Message/Message.js'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* FormMessage – specialized UiMessage for forms.
|
|
@@ -15,10 +15,7 @@ export default class FormMessage extends UiMessage {
|
|
|
15
15
|
*/
|
|
16
16
|
constructor(input = {}) {
|
|
17
17
|
super(input)
|
|
18
|
-
const {
|
|
19
|
-
data = {},
|
|
20
|
-
schema = {},
|
|
21
|
-
} = input
|
|
18
|
+
const { data = {}, schema = {} } = input
|
|
22
19
|
|
|
23
20
|
// Store data and schema for easy access
|
|
24
21
|
this.data = data
|
|
@@ -81,4 +78,4 @@ export default class FormMessage extends UiMessage {
|
|
|
81
78
|
|
|
82
79
|
return { isValid: Object.keys(errors).length === 0, errors }
|
|
83
80
|
}
|
|
84
|
-
}
|
|
81
|
+
}
|
package/src/core/Form/index.js
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
import FormInput from
|
|
2
|
-
import FormMessage from
|
|
3
|
-
import Form from
|
|
1
|
+
import FormInput from './Input.js'
|
|
2
|
+
import FormMessage from './Message.js'
|
|
3
|
+
import Form from './Form.js'
|
|
4
4
|
|
|
5
|
-
export {
|
|
6
|
-
FormInput,
|
|
7
|
-
FormMessage,
|
|
8
|
-
Form,
|
|
9
|
-
}
|
|
5
|
+
export { FormInput, FormMessage, Form }
|
|
10
6
|
|
|
11
7
|
export default Form
|
package/src/core/InputAdapter.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import Event from
|
|
2
|
-
import CancelError from
|
|
3
|
-
import UiMessage from
|
|
1
|
+
import Event from '@nan0web/event/oop'
|
|
2
|
+
import CancelError from './Error/CancelError.js'
|
|
3
|
+
import UiMessage from './Message/Message.js'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Abstract input adapter for UI implementations.
|
|
@@ -20,9 +20,7 @@ export default class InputAdapter extends Event {
|
|
|
20
20
|
* @returns {void}
|
|
21
21
|
*/
|
|
22
22
|
start() {
|
|
23
|
-
this.emit('input',
|
|
24
|
-
UiMessage.from({ body: "Adapter started" })
|
|
25
|
-
)
|
|
23
|
+
this.emit('input', UiMessage.from({ body: 'Adapter started' }))
|
|
26
24
|
}
|
|
27
25
|
|
|
28
26
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Message } from
|
|
1
|
+
import { Message } from '@nan0web/co'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @typedef {Object} MessageBodySchema
|
|
@@ -40,13 +40,13 @@ export default class UiMessage extends Message {
|
|
|
40
40
|
SUCCESS: 'success',
|
|
41
41
|
WARNING: 'warning',
|
|
42
42
|
COMMAND: 'command',
|
|
43
|
-
NAVIGATION: 'navigation'
|
|
43
|
+
NAVIGATION: 'navigation',
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
/** @type {string} */
|
|
47
|
-
type =
|
|
47
|
+
type = ''
|
|
48
48
|
/** @type {string} */
|
|
49
|
-
id =
|
|
49
|
+
id = ''
|
|
50
50
|
|
|
51
51
|
/**
|
|
52
52
|
* Creates a UiMessage.
|
|
@@ -56,10 +56,7 @@ export default class UiMessage extends Message {
|
|
|
56
56
|
constructor(input = {}) {
|
|
57
57
|
super(input)
|
|
58
58
|
|
|
59
|
-
const {
|
|
60
|
-
type = this.type,
|
|
61
|
-
id = this.id,
|
|
62
|
-
} = input
|
|
59
|
+
const { type = this.type, id = this.id } = input
|
|
63
60
|
this.id = id || `ui-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
|
|
64
61
|
this.type = String(type)
|
|
65
62
|
|
|
@@ -96,7 +93,7 @@ export default class UiMessage extends Message {
|
|
|
96
93
|
for (const [field, schema] of entries) {
|
|
97
94
|
const value = body[field]
|
|
98
95
|
const fn = schema?.validate
|
|
99
|
-
if (
|
|
96
|
+
if ('function' === typeof fn) {
|
|
100
97
|
const ok = fn.apply(body, [value])
|
|
101
98
|
if (ok !== true) {
|
|
102
99
|
result.set(field, String(ok))
|
|
@@ -105,7 +102,7 @@ export default class UiMessage extends Message {
|
|
|
105
102
|
}
|
|
106
103
|
const required = schema?.required ?? false
|
|
107
104
|
if (required && !value) {
|
|
108
|
-
result.set(field,
|
|
105
|
+
result.set(field, 'Required')
|
|
109
106
|
continue
|
|
110
107
|
}
|
|
111
108
|
if (schema?.pattern && schema.pattern instanceof RegExp) {
|
|
@@ -116,10 +113,10 @@ export default class UiMessage extends Message {
|
|
|
116
113
|
}
|
|
117
114
|
if (schema?.options) {
|
|
118
115
|
if (!Array.isArray(schema.options)) {
|
|
119
|
-
throw new Error(
|
|
116
|
+
throw new Error('Schema options must be an array of possible values')
|
|
120
117
|
}
|
|
121
118
|
if (!schema.options.includes(value)) {
|
|
122
|
-
result.set(field,
|
|
119
|
+
result.set(field, 'Enumeration must have one value')
|
|
123
120
|
continue
|
|
124
121
|
}
|
|
125
122
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import UiMessage from
|
|
1
|
+
import UiMessage from './Message.js'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* OutputMessage – message sent from the system to the UI.
|
|
@@ -11,7 +11,7 @@ export default class OutputMessage extends UiMessage {
|
|
|
11
11
|
LOW: 0,
|
|
12
12
|
NORMAL: 1,
|
|
13
13
|
HIGH: 2,
|
|
14
|
-
CRITICAL: 3
|
|
14
|
+
CRITICAL: 3,
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
/** @type {string[]} */
|
|
@@ -36,19 +36,19 @@ export default class OutputMessage extends UiMessage {
|
|
|
36
36
|
body = [],
|
|
37
37
|
meta = {},
|
|
38
38
|
error = null,
|
|
39
|
-
priority = OutputMessage.PRIORITY.NORMAL
|
|
39
|
+
priority = OutputMessage.PRIORITY.NORMAL,
|
|
40
40
|
} = input
|
|
41
41
|
|
|
42
|
-
const contentSource = 'body' in input ? body :
|
|
43
|
-
'content' in input ? content : []
|
|
42
|
+
const contentSource = 'body' in input ? body : 'content' in input ? content : []
|
|
44
43
|
|
|
45
|
-
this.body = Array.isArray(contentSource)
|
|
46
|
-
contentSource
|
|
47
|
-
|
|
44
|
+
this.body = Array.isArray(contentSource)
|
|
45
|
+
? contentSource
|
|
46
|
+
: contentSource
|
|
47
|
+
? [String(contentSource)]
|
|
48
|
+
: []
|
|
48
49
|
|
|
49
50
|
this.meta = meta
|
|
50
|
-
this.error = error instanceof Error ? error :
|
|
51
|
-
error ? new Error(String(error)) : null
|
|
51
|
+
this.error = error instanceof Error ? error : error ? new Error(String(error)) : null
|
|
52
52
|
this.priority = Number(priority)
|
|
53
53
|
|
|
54
54
|
if (!this.type && this.error) {
|
|
@@ -91,7 +91,7 @@ export default class OutputMessage extends UiMessage {
|
|
|
91
91
|
let combinedError = this.error
|
|
92
92
|
let combinedPriority = this.priority
|
|
93
93
|
|
|
94
|
-
messages.forEach(msg => {
|
|
94
|
+
messages.forEach((msg) => {
|
|
95
95
|
if (msg instanceof OutputMessage) {
|
|
96
96
|
combinedContent.push(...msg.content)
|
|
97
97
|
combinedMeta = { ...combinedMeta, ...msg.meta }
|
|
@@ -105,7 +105,7 @@ export default class OutputMessage extends UiMessage {
|
|
|
105
105
|
meta: combinedMeta,
|
|
106
106
|
error: combinedError,
|
|
107
107
|
priority: combinedPriority,
|
|
108
|
-
type: this.type
|
|
108
|
+
type: this.type,
|
|
109
109
|
})
|
|
110
110
|
}
|
|
111
111
|
|
|
@@ -122,11 +122,13 @@ export default class OutputMessage extends UiMessage {
|
|
|
122
122
|
type: this.type,
|
|
123
123
|
id: this.id,
|
|
124
124
|
time: this.time.toISOString(),
|
|
125
|
-
error: this.error
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
125
|
+
error: this.error
|
|
126
|
+
? {
|
|
127
|
+
message: this.error.message,
|
|
128
|
+
stack: this.error.stack,
|
|
129
|
+
}
|
|
130
|
+
: null,
|
|
131
|
+
priority: this.priority,
|
|
130
132
|
}
|
|
131
133
|
}
|
|
132
134
|
|
|
@@ -16,7 +16,7 @@ class OutputAdapter extends Event {
|
|
|
16
16
|
* @throws {Error} If not overridden by a subclass.
|
|
17
17
|
*/
|
|
18
18
|
render(message) {
|
|
19
|
-
throw new Error(
|
|
19
|
+
throw new Error('render() must be implemented by subclass')
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
/**
|
|
@@ -27,14 +27,16 @@ class OutputAdapter extends Event {
|
|
|
27
27
|
* @returns {void}
|
|
28
28
|
*/
|
|
29
29
|
progress(progress, metadata = {}) {
|
|
30
|
-
this.render(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
30
|
+
this.render(
|
|
31
|
+
OutputMessage.from({
|
|
32
|
+
content: [],
|
|
33
|
+
metadata: {
|
|
34
|
+
...metadata,
|
|
35
|
+
progress,
|
|
36
|
+
elementType: 'progress',
|
|
37
|
+
},
|
|
38
|
+
}),
|
|
39
|
+
)
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
/**
|
|
@@ -47,4 +49,4 @@ class OutputAdapter extends Event {
|
|
|
47
49
|
}
|
|
48
50
|
}
|
|
49
51
|
|
|
50
|
-
export default OutputAdapter
|
|
52
|
+
export default OutputAdapter
|
package/src/core/Stream.js
CHANGED
package/src/core/StreamEntry.js
CHANGED
|
@@ -24,7 +24,7 @@ export default class StreamEntry {
|
|
|
24
24
|
* Error message associated with the stream entry.
|
|
25
25
|
* @type {string}
|
|
26
26
|
*/
|
|
27
|
-
error =
|
|
27
|
+
error = ''
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Creates a new StreamEntry instance.
|
|
@@ -56,4 +56,4 @@ export default class StreamEntry {
|
|
|
56
56
|
if (input instanceof StreamEntry) return input
|
|
57
57
|
return new StreamEntry(input)
|
|
58
58
|
}
|
|
59
|
-
}
|
|
59
|
+
}
|
package/src/core/UiAdapter.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import EventProcessor from
|
|
2
|
-
import CancelError from
|
|
3
|
-
import UIMessage from
|
|
4
|
-
import UIForm from
|
|
5
|
-
import FormInput from
|
|
6
|
-
import OutputAdapter from
|
|
7
|
-
import OutputMessage from
|
|
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
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Unified UI Adapter that handles both input and output operations.
|
|
@@ -36,7 +36,7 @@ export default class UiAdapter extends EventProcessor {
|
|
|
36
36
|
* @returns {void}
|
|
37
37
|
*/
|
|
38
38
|
start() {
|
|
39
|
-
this.emit('input', UIMessage.from({ body:
|
|
39
|
+
this.emit('input', UIMessage.from({ body: 'Adapter started' }))
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
/**
|
|
@@ -122,22 +122,21 @@ export default class UiAdapter extends EventProcessor {
|
|
|
122
122
|
*/
|
|
123
123
|
async requireInput(msg) {
|
|
124
124
|
if (!msg) {
|
|
125
|
-
throw new Error(
|
|
125
|
+
throw new Error('Message instance is required')
|
|
126
126
|
}
|
|
127
127
|
if (!(msg instanceof UIMessage)) {
|
|
128
|
-
throw new TypeError(
|
|
128
|
+
throw new TypeError('Message must be an instance of UIMessage')
|
|
129
129
|
}
|
|
130
130
|
/** @type {Map<string,string>} */
|
|
131
131
|
let errors = msg.validate()
|
|
132
132
|
while (errors.size > 0) {
|
|
133
|
-
const form = generateForm(
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
)
|
|
133
|
+
const form = generateForm(/** @type {any} */ (msg.constructor).Body, {
|
|
134
|
+
initialState: msg.body,
|
|
135
|
+
})
|
|
137
136
|
|
|
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
|
|
137
|
+
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
138
|
if (formResult.cancelled) {
|
|
140
|
-
throw new CancelError(
|
|
139
|
+
throw new CancelError('User cancelled form')
|
|
141
140
|
}
|
|
142
141
|
|
|
143
142
|
const updatedBody = { ...msg.body, ...formResult.form.state }
|
|
@@ -145,11 +144,13 @@ export default class UiAdapter extends EventProcessor {
|
|
|
145
144
|
|
|
146
145
|
if (updatedErrors.size > 0) {
|
|
147
146
|
if (this.output) {
|
|
148
|
-
this.output.render(
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
147
|
+
this.output.render(
|
|
148
|
+
new OutputMessage({
|
|
149
|
+
type: 'Alert',
|
|
150
|
+
variant: 'error',
|
|
151
|
+
body: Array.from(updatedErrors.values()).join('\n'),
|
|
152
|
+
}),
|
|
153
|
+
)
|
|
153
154
|
}
|
|
154
155
|
errors = updatedErrors
|
|
155
156
|
continue
|
|
@@ -169,8 +170,8 @@ export default class UiAdapter extends EventProcessor {
|
|
|
169
170
|
* @throws {Error} If not implemented in subclass.
|
|
170
171
|
*/
|
|
171
172
|
render(message) {
|
|
172
|
-
throw new Error(
|
|
173
|
-
this.emit(
|
|
173
|
+
throw new Error('render() must be implemented by subclass')
|
|
174
|
+
this.emit('rendered', message)
|
|
174
175
|
}
|
|
175
176
|
}
|
|
176
177
|
|
|
@@ -184,14 +185,14 @@ export default class UiAdapter extends EventProcessor {
|
|
|
184
185
|
* @returns {UIForm} Form instance ready for input.
|
|
185
186
|
*/
|
|
186
187
|
export function generateForm(BodyClass, options = {}) {
|
|
187
|
-
const { initialState = {}, t = v => v } = options
|
|
188
|
+
const { initialState = {}, t = (v) => v } = options
|
|
188
189
|
const fields = []
|
|
189
190
|
|
|
190
191
|
for (const [name, schema] of Object.entries(BodyClass)) {
|
|
191
|
-
if (typeof schema !==
|
|
192
|
+
if (typeof schema !== 'object' || schema === null || !name || !schema.help) continue
|
|
192
193
|
|
|
193
194
|
const label = t(schema.help) || name
|
|
194
|
-
const placeholder = t(schema.placeholder || schema.defaultValue ||
|
|
195
|
+
const placeholder = t(schema.placeholder || schema.defaultValue || '')
|
|
195
196
|
const isRequired = !!schema.required
|
|
196
197
|
|
|
197
198
|
fields.push(
|
|
@@ -201,12 +202,12 @@ export function generateForm(BodyClass, options = {}) {
|
|
|
201
202
|
type: schema.type || FormInput.TYPES.TEXT,
|
|
202
203
|
required: isRequired,
|
|
203
204
|
placeholder,
|
|
204
|
-
options: schema.options ? schema.options.map(o => String(o)) : [],
|
|
205
|
+
options: schema.options ? schema.options.map((o) => String(o)) : [],
|
|
205
206
|
validation: schema.validate
|
|
206
207
|
? (value) => {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
208
|
+
const res = schema.validate(value)
|
|
209
|
+
return res === true ? true : typeof res === 'string' ? res : `Invalid ${name}`
|
|
210
|
+
}
|
|
210
211
|
: () => true,
|
|
211
212
|
}),
|
|
212
213
|
)
|
package/src/core/index.js
CHANGED
|
@@ -1,18 +1,41 @@
|
|
|
1
|
-
export { default as InputAdapter } from
|
|
2
|
-
export { default as OutputAdapter } from
|
|
1
|
+
export { default as InputAdapter } from './InputAdapter.js'
|
|
2
|
+
export { default as OutputAdapter } from './OutputAdapter.js'
|
|
3
3
|
|
|
4
|
-
import UIStream from
|
|
4
|
+
import UIStream from './Stream.js'
|
|
5
5
|
export { UIStream, UIStream as UiStream }
|
|
6
|
-
import StreamEntry from
|
|
6
|
+
import StreamEntry from './StreamEntry.js'
|
|
7
7
|
export { StreamEntry, StreamEntry as UiStreamEntry }
|
|
8
8
|
|
|
9
|
-
export { default as UiMessage } from
|
|
10
|
-
export { default as FormMessage } from
|
|
11
|
-
export { default as FormInput } from
|
|
9
|
+
export { default as UiMessage } from './Message/Message.js'
|
|
10
|
+
export { default as FormMessage } from './Form/Message.js'
|
|
11
|
+
export { default as FormInput } from './Form/Input.js'
|
|
12
12
|
|
|
13
|
-
import UIForm from
|
|
13
|
+
import UIForm from './Form/Form.js'
|
|
14
14
|
export { UIForm, UIForm as UiForm }
|
|
15
15
|
|
|
16
|
-
export { default as Error, CancelError } from
|
|
16
|
+
export { default as Error, CancelError } from './Error/index.js'
|
|
17
17
|
|
|
18
|
-
export { default as UiAdapter } from
|
|
18
|
+
export { default as UiAdapter } from './UiAdapter.js'
|
|
19
|
+
|
|
20
|
+
// Flow — Yield-Based Universal UI Architecture
|
|
21
|
+
export {
|
|
22
|
+
runFlow,
|
|
23
|
+
flow,
|
|
24
|
+
View,
|
|
25
|
+
Prompt,
|
|
26
|
+
Stream,
|
|
27
|
+
Alert,
|
|
28
|
+
Toast,
|
|
29
|
+
Badge,
|
|
30
|
+
Text,
|
|
31
|
+
Table,
|
|
32
|
+
Input,
|
|
33
|
+
Select,
|
|
34
|
+
Confirm,
|
|
35
|
+
Multiselect,
|
|
36
|
+
Mask,
|
|
37
|
+
Password,
|
|
38
|
+
Spinner,
|
|
39
|
+
Progress,
|
|
40
|
+
} from './Flow.js'
|
|
41
|
+
export { default as Flow } from './Flow.js'
|
package/src/functions.js
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
import { empty } from
|
|
1
|
+
import { empty } from '@nan0web/types'
|
|
2
2
|
|
|
3
3
|
export const spaces = (options = {}) => {
|
|
4
4
|
const { cols = [], padding = 1, aligns = [] } = options
|
|
5
|
-
return (row) =>
|
|
5
|
+
return (row) =>
|
|
6
6
|
row.map((str, i) => {
|
|
7
|
-
const pad =
|
|
8
|
-
return aligns[i] ===
|
|
7
|
+
const pad = ' '.repeat(cols[i] - str.length + padding)
|
|
8
|
+
return aligns[i] === 'r' ? pad + str : str + pad
|
|
9
9
|
})
|
|
10
|
-
)
|
|
11
10
|
}
|
|
12
11
|
|
|
13
12
|
export const weight = (arr) => {
|
|
14
|
-
return (Fn = v => v) => {
|
|
13
|
+
return (Fn = (v) => v) => {
|
|
15
14
|
const cols = []
|
|
16
|
-
arr.forEach(m => {
|
|
15
|
+
arr.forEach((m) => {
|
|
17
16
|
Fn(m).forEach((str, i) => {
|
|
18
17
|
if (undefined === cols[i]) cols[i] = 0
|
|
19
18
|
cols[i] = Math.max(str.length, cols[i])
|
|
@@ -23,16 +22,10 @@ export const weight = (arr) => {
|
|
|
23
22
|
}
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
|
|
27
25
|
export const table = (options = {}) => {
|
|
28
|
-
const {
|
|
29
|
-
Fn = v => v,
|
|
30
|
-
cols = [],
|
|
31
|
-
padding = 1,
|
|
32
|
-
aligns = []
|
|
33
|
-
} = options
|
|
26
|
+
const { Fn = (v) => v, cols = [], padding = 1, aligns = [] } = options
|
|
34
27
|
return (arr) => {
|
|
35
28
|
const options = { cols: empty(cols) ? weight(arr)(Fn) : cols, padding, aligns }
|
|
36
|
-
return arr.map(row => spaces(options)(row))
|
|
29
|
+
return arr.map((row) => spaces(options)(row))
|
|
37
30
|
}
|
|
38
31
|
}
|
package/src/index.js
CHANGED
|
@@ -1,35 +1,24 @@
|
|
|
1
|
-
import Frame from
|
|
2
|
-
import Locale from
|
|
3
|
-
import StdIn from
|
|
4
|
-
import StdOut from
|
|
5
|
-
import View from
|
|
6
|
-
import RenderOptions from
|
|
7
|
-
import FrameProps from
|
|
8
|
-
import Model from
|
|
9
|
-
import Component from
|
|
10
|
-
import App from
|
|
1
|
+
import Frame from './Frame/Frame.js'
|
|
2
|
+
import Locale from './Locale.js'
|
|
3
|
+
import StdIn from './StdIn.js'
|
|
4
|
+
import StdOut from './StdOut.js'
|
|
5
|
+
import View from './View/View.js'
|
|
6
|
+
import RenderOptions from './View/RenderOptions.js'
|
|
7
|
+
import FrameProps from './Frame/Props.js'
|
|
8
|
+
import Model from './Model/index.js'
|
|
9
|
+
import Component from './Component/index.js'
|
|
10
|
+
import App from './App/index.js'
|
|
11
11
|
|
|
12
|
-
export {
|
|
13
|
-
Frame,
|
|
14
|
-
FrameProps,
|
|
15
|
-
Locale,
|
|
16
|
-
StdIn,
|
|
17
|
-
StdOut,
|
|
18
|
-
View,
|
|
19
|
-
RenderOptions,
|
|
20
|
-
Model,
|
|
21
|
-
Component,
|
|
22
|
-
App,
|
|
23
|
-
}
|
|
12
|
+
export { Frame, FrameProps, Locale, StdIn, StdOut, View, RenderOptions, Model, Component, App }
|
|
24
13
|
|
|
25
14
|
// export default App
|
|
26
|
-
export { default as FormMessage } from
|
|
27
|
-
export { default as FormInput } from
|
|
28
|
-
export { default as InputAdapter } from
|
|
29
|
-
export { default as OutputAdapter } from
|
|
30
|
-
export { default as OutputMessage } from
|
|
31
|
-
export { default as UiForm } from
|
|
32
|
-
export { default as UiMessage } from
|
|
33
|
-
export { default as UiStream } from
|
|
34
|
-
export { default as Error, CancelError } from
|
|
35
|
-
export { default as UiAdapter } from
|
|
15
|
+
export { default as FormMessage } from './core/Form/Message.js'
|
|
16
|
+
export { default as FormInput } from './core/Form/Input.js'
|
|
17
|
+
export { default as InputAdapter } from './core/InputAdapter.js'
|
|
18
|
+
export { default as OutputAdapter } from './core/OutputAdapter.js'
|
|
19
|
+
export { default as OutputMessage } from './core/Message/OutputMessage.js'
|
|
20
|
+
export { default as UiForm } from './core/Form/Form.js'
|
|
21
|
+
export { default as UiMessage } from './core/Message/Message.js'
|
|
22
|
+
export { default as UiStream } from './core/Stream.js'
|
|
23
|
+
export { default as Error, CancelError } from './core/Error/index.js'
|
|
24
|
+
export { default as UiAdapter } from './core/UiAdapter.js'
|
|
@@ -5,7 +5,7 @@ export class DepsCommand extends UiMessage {
|
|
|
5
5
|
body: DepsCommandBody;
|
|
6
6
|
}
|
|
7
7
|
export default DepsCommand;
|
|
8
|
-
import UiMessage from
|
|
8
|
+
import UiMessage from '../../core/Message/Message.js';
|
|
9
9
|
declare class DepsCommandBody {
|
|
10
10
|
static fix: {
|
|
11
11
|
help: string;
|