@nan0web/ui 1.5.2 → 1.6.2
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 +36 -1
- package/package.json +3 -2
- package/src/ArchitectureMap/ArchitectureMap.js +111 -0
- package/src/ArchitectureMap/index.js +1 -0
- package/src/InterfaceTemplate/InterfaceTemplate.js +95 -0
- package/src/InterfaceTemplate/index.js +1 -0
- package/src/README.md.js +42 -1
- package/types/ArchitectureMap/ArchitectureMap.d.ts +70 -0
- package/types/ArchitectureMap/index.d.ts +1 -0
- package/types/InterfaceTemplate/InterfaceTemplate.d.ts +67 -0
- package/types/InterfaceTemplate/index.d.ts +1 -0
package/README.md
CHANGED
|
@@ -182,10 +182,30 @@ web components across platforms. It supports:
|
|
|
182
182
|
- **NaN0 Spec** — a concise YAML-based shorthand for declaring component variations.
|
|
183
183
|
- **OlmuiInspector** — unified UI for exploring component models and props.
|
|
184
184
|
- **Live Preview** — real-time rendering of component states.
|
|
185
|
-
- **i18n UI** — fully localized interface for global developers.
|
|
185
|
+
- **i18n UI** — fully localized interface (UK/EN) for global developers.
|
|
186
|
+
- **Theme Editor** — Bootstrap-like CSS variable system with live preview.
|
|
186
187
|
|
|
187
188
|
It follows the **Olmui** core pattern: *One Logic — Many UI* (same manifest powers both CLI and Web).
|
|
188
189
|
|
|
190
|
+
#### Theme Editor (CSS Variables)
|
|
191
|
+
|
|
192
|
+
Professional-grade theming with live preview. Supports:
|
|
193
|
+
|
|
194
|
+
- **Palette**: primary, secondary, success, warning, danger, info
|
|
195
|
+
- **Geometry**: border-radius (sm/md/lg/pill/circle), spacing (sm/md/lg)
|
|
196
|
+
- **Type-safe inputs**: `type="color"` for colors, number inputs for dimensions
|
|
197
|
+
|
|
198
|
+
#### Component Rendering Architecture
|
|
199
|
+
|
|
200
|
+
The IDE handles data transformation between YAML models and web components:
|
|
201
|
+
|
|
202
|
+
- **Table**: `rows[][] + columns[]` → `data[]` (array of objects)
|
|
203
|
+
- **Tree**: `data` → `items` mapping with 4-level taxonomy
|
|
204
|
+
- **Markdown**: Raw markdown → HTML via `_md2html()` converter
|
|
205
|
+
- **ProgressBar**: Tag alias (`ui-progress-bar` → `ui-progress`), variant colors
|
|
206
|
+
- **LangSelect**: `string[]` → `{code,title}[]` conversion
|
|
207
|
+
- **Hyphenated props**: Auto `camelCase` conversion (`show-label` → `showLabel`)
|
|
208
|
+
|
|
189
209
|
#### NaN0 Spec (YAML)
|
|
190
210
|
|
|
191
211
|
Concise format for defining variations:
|
|
@@ -197,6 +217,21 @@ How to define a component variation using NaN0 Spec?
|
|
|
197
217
|
$outline: true
|
|
198
218
|
```
|
|
199
219
|
|
|
220
|
+
#### Documentation Site
|
|
221
|
+
|
|
222
|
+
The IDE includes an auto-generated documentation site.
|
|
223
|
+
HTML pages are generated from `ide.html` template via `generate-pages.js`:
|
|
224
|
+
|
|
225
|
+
- Per-language pages (`/uk/Data/Table.html`, `/en/Feedback/Alert.html`)
|
|
226
|
+
- SEO-optimized with `<title>` and `<meta>` per component
|
|
227
|
+
- Category-based URL routing (`/Data/`, `/Feedback/`, `/Forms/`, `/Actions/`, `/System/`)
|
|
228
|
+
- i18n navbar with `data-i18n` attributes
|
|
229
|
+
|
|
230
|
+
How to run the documentation site?
|
|
231
|
+
```bash
|
|
232
|
+
npm run docs:dev
|
|
233
|
+
```
|
|
234
|
+
|
|
200
235
|
## Playground Demos
|
|
201
236
|
|
|
202
237
|
The library includes rich playground demos:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nan0web/ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.2",
|
|
4
4
|
"description": "NaN•Web UI. One application logic (algorithm) and many UI.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"types": "types/index.d.ts",
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
"test:release": "node --test \"releases/**/*.test.js\"",
|
|
23
23
|
"test:status": "nan0test status --hide-name",
|
|
24
24
|
"test:play": "node --test --test-timeout=3333 \"play/**/*.test.js\"",
|
|
25
|
-
"test:e2e": "playwright test",
|
|
25
|
+
"test:e2e": "playwright test --ignore-snapshots e2e/components.spec.js e2e/debug-label.spec.js",
|
|
26
|
+
"test:e2e:slow": "E2E_SLOW=1 playwright test e2e/visual.spec.js",
|
|
26
27
|
"test:all": "npm run test && npm run test:docs && npm run test:play && npm run test:e2e && npm run build && npm run knip",
|
|
27
28
|
"knip": "knip --production",
|
|
28
29
|
"precommit": "npm test",
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ArchitectureMap — a cross-package component readiness registry.
|
|
3
|
+
*
|
|
4
|
+
* Tracks which UI components are implemented in which packages
|
|
5
|
+
* (ui-lit, ui-cli, ui-react-bootstrap, etc.) and provides
|
|
6
|
+
* a programmatic readiness matrix.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* const map = new ArchitectureMap()
|
|
10
|
+
* map.register('ui-lit', ['Button', 'Input', 'Select'])
|
|
11
|
+
* map.register('ui-cli', ['Button', 'Input'])
|
|
12
|
+
* map.getMatrix()
|
|
13
|
+
* // → { Button: { 'ui-lit': true, 'ui-cli': true },
|
|
14
|
+
* // Input: { 'ui-lit': true, 'ui-cli': true },
|
|
15
|
+
* // Select: { 'ui-lit': true, 'ui-cli': false } }
|
|
16
|
+
* map.getReadiness('Button') // → true (in all packages)
|
|
17
|
+
* map.getReadiness('Select') // → false (missing from ui-cli)
|
|
18
|
+
*/
|
|
19
|
+
export default class ArchitectureMap {
|
|
20
|
+
/** @type {Map<string, Set<string>>} packageName → Set of component names */
|
|
21
|
+
#packages = new Map()
|
|
22
|
+
|
|
23
|
+
/** @type {Set<string>} all known component names */
|
|
24
|
+
#components = new Set()
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Register a package and its exported components.
|
|
28
|
+
*
|
|
29
|
+
* @param {string} packageName — e.g. 'ui-lit', 'ui-cli', 'ui-react-bootstrap'
|
|
30
|
+
* @param {string[]} componentsList — e.g. ['Button', 'Input', 'Select']
|
|
31
|
+
*/
|
|
32
|
+
register(packageName, componentsList = []) {
|
|
33
|
+
this.#packages.set(packageName, new Set(componentsList))
|
|
34
|
+
for (const name of componentsList) {
|
|
35
|
+
this.#components.add(name)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Get the list of all registered package names.
|
|
41
|
+
*
|
|
42
|
+
* @returns {string[]}
|
|
43
|
+
*/
|
|
44
|
+
getPackages() {
|
|
45
|
+
return [...this.#packages.keys()]
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Get all known component names (union of all packages).
|
|
50
|
+
*
|
|
51
|
+
* @returns {string[]}
|
|
52
|
+
*/
|
|
53
|
+
getComponents() {
|
|
54
|
+
return [...this.#components].sort()
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Build a readiness matrix: { componentName → { packageName → boolean } }.
|
|
59
|
+
*
|
|
60
|
+
* Every known component gets an entry for every registered package.
|
|
61
|
+
*
|
|
62
|
+
* @returns {Object<string, Object<string, boolean>>}
|
|
63
|
+
*/
|
|
64
|
+
getMatrix() {
|
|
65
|
+
const packages = this.getPackages()
|
|
66
|
+
/** @type {Object<string, Object<string, boolean>>} */
|
|
67
|
+
const matrix = {}
|
|
68
|
+
|
|
69
|
+
for (const comp of this.#components) {
|
|
70
|
+
matrix[comp] = {}
|
|
71
|
+
for (const pkg of packages) {
|
|
72
|
+
matrix[comp][pkg] = this.#packages.get(pkg)?.has(comp) ?? false
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return matrix
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Check if a component is implemented in ALL registered packages.
|
|
81
|
+
*
|
|
82
|
+
* @param {string} componentName
|
|
83
|
+
* @returns {boolean}
|
|
84
|
+
*/
|
|
85
|
+
getReadiness(componentName) {
|
|
86
|
+
if (this.#packages.size === 0) return false
|
|
87
|
+
for (const components of this.#packages.values()) {
|
|
88
|
+
if (!components.has(componentName)) return false
|
|
89
|
+
}
|
|
90
|
+
return true
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Get a summary: { total, ready, notReady, readyPercent }.
|
|
95
|
+
*
|
|
96
|
+
* @returns {{ total: number, ready: number, notReady: number, readyPercent: number }}
|
|
97
|
+
*/
|
|
98
|
+
getSummary() {
|
|
99
|
+
const components = this.getComponents()
|
|
100
|
+
const total = components.length
|
|
101
|
+
const ready = components.filter((c) => this.getReadiness(c)).length
|
|
102
|
+
return {
|
|
103
|
+
total,
|
|
104
|
+
ready,
|
|
105
|
+
notReady: total - ready,
|
|
106
|
+
readyPercent: total > 0 ? Math.round((ready / total) * 100) : 0,
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export { ArchitectureMap }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, ArchitectureMap } from './ArchitectureMap.js'
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* InterfaceTemplate — base class for defining new UI interfaces.
|
|
3
|
+
*
|
|
4
|
+
* Establishes the inheritance pattern for the "One Logic, Many UI" architecture.
|
|
5
|
+
* Each UI interface (CLI, Web, Mobile, Chat, Audio) extends this template
|
|
6
|
+
* and overrides the required methods.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* class CliInterface extends InterfaceTemplate {
|
|
10
|
+
* render(data) { return formatForTerminal(data) }
|
|
11
|
+
* async ask(prompt) { return readlinePrompt(prompt) }
|
|
12
|
+
* }
|
|
13
|
+
*
|
|
14
|
+
* @abstract
|
|
15
|
+
*/
|
|
16
|
+
export default class InterfaceTemplate {
|
|
17
|
+
/**
|
|
18
|
+
* List of methods that MUST be overridden by concrete implementations.
|
|
19
|
+
* Used for documentation and runtime validation.
|
|
20
|
+
*
|
|
21
|
+
* @type {string[]}
|
|
22
|
+
*/
|
|
23
|
+
static requiredMethods = ['render', 'ask']
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The name of this interface (e.g. 'cli', 'web', 'mobile').
|
|
27
|
+
* Override in subclass.
|
|
28
|
+
*
|
|
29
|
+
* @type {string}
|
|
30
|
+
*/
|
|
31
|
+
name = 'base'
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Render data to the user through the interface.
|
|
35
|
+
* Must be overridden by each concrete implementation.
|
|
36
|
+
*
|
|
37
|
+
* @param {any} [data] - data to render
|
|
38
|
+
* @returns {any} rendered output (string for CLI, DOM for web, etc.)
|
|
39
|
+
* @throws {Error} if not overridden
|
|
40
|
+
*/
|
|
41
|
+
render(data) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
`InterfaceTemplate.render() must be overridden by ${this.name || 'subclass'}. ` +
|
|
44
|
+
'This is the primary output method for the interface.',
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Request input from the user through the interface.
|
|
50
|
+
* Must be overridden by each concrete implementation.
|
|
51
|
+
*
|
|
52
|
+
* @param {string} prompt - question or label for the input
|
|
53
|
+
* @param {object} [options] - options (type, choices, default, etc.)
|
|
54
|
+
* @returns {Promise<any>} user's response
|
|
55
|
+
* @throws {Error} if not overridden
|
|
56
|
+
*/
|
|
57
|
+
async ask(prompt, options = {}) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
`InterfaceTemplate.ask() must be overridden by ${this.name || 'subclass'}. ` +
|
|
60
|
+
'This is the primary input method for the interface.',
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Validate that all required methods have been overridden.
|
|
66
|
+
* Call this in the subclass constructor to get early feedback.
|
|
67
|
+
*
|
|
68
|
+
* @returns {string[]} list of missing method overrides (empty = valid)
|
|
69
|
+
*/
|
|
70
|
+
validate() {
|
|
71
|
+
const missing = []
|
|
72
|
+
for (const method of InterfaceTemplate.requiredMethods) {
|
|
73
|
+
if (this[method] === InterfaceTemplate.prototype[method]) {
|
|
74
|
+
missing.push(method)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return missing
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Get interface capabilities info.
|
|
82
|
+
*
|
|
83
|
+
* @returns {{ name: string, requiredMethods: string[], isComplete: boolean }}
|
|
84
|
+
*/
|
|
85
|
+
info() {
|
|
86
|
+
const missing = this.validate()
|
|
87
|
+
return {
|
|
88
|
+
name: this.name,
|
|
89
|
+
requiredMethods: [...InterfaceTemplate.requiredMethods],
|
|
90
|
+
isComplete: missing.length === 0,
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export { InterfaceTemplate }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, InterfaceTemplate } from './InterfaceTemplate.js'
|
package/src/README.md.js
CHANGED
|
@@ -288,10 +288,30 @@ function testRender() {
|
|
|
288
288
|
* - **NaN0 Spec** — a concise YAML-based shorthand for declaring component variations.
|
|
289
289
|
* - **OlmuiInspector** — unified UI for exploring component models and props.
|
|
290
290
|
* - **Live Preview** — real-time rendering of component states.
|
|
291
|
-
* - **i18n UI** — fully localized interface for global developers.
|
|
291
|
+
* - **i18n UI** — fully localized interface (UK/EN) for global developers.
|
|
292
|
+
* - **Theme Editor** — Bootstrap-like CSS variable system with live preview.
|
|
292
293
|
*
|
|
293
294
|
* It follows the **Olmui** core pattern: *One Logic — Many UI* (same manifest powers both CLI and Web).
|
|
294
295
|
*
|
|
296
|
+
* #### Theme Editor (CSS Variables)
|
|
297
|
+
*
|
|
298
|
+
* Professional-grade theming with live preview. Supports:
|
|
299
|
+
*
|
|
300
|
+
* - **Palette**: primary, secondary, success, warning, danger, info
|
|
301
|
+
* - **Geometry**: border-radius (sm/md/lg/pill/circle), spacing (sm/md/lg)
|
|
302
|
+
* - **Type-safe inputs**: `type="color"` for colors, number inputs for dimensions
|
|
303
|
+
*
|
|
304
|
+
* #### Component Rendering Architecture
|
|
305
|
+
*
|
|
306
|
+
* The IDE handles data transformation between YAML models and web components:
|
|
307
|
+
*
|
|
308
|
+
* - **Table**: `rows[][] + columns[]` → `data[]` (array of objects)
|
|
309
|
+
* - **Tree**: `data` → `items` mapping with 4-level taxonomy
|
|
310
|
+
* - **Markdown**: Raw markdown → HTML via `_md2html()` converter
|
|
311
|
+
* - **ProgressBar**: Tag alias (`ui-progress-bar` → `ui-progress`), variant colors
|
|
312
|
+
* - **LangSelect**: `string[]` → `{code,title}[]` conversion
|
|
313
|
+
* - **Hyphenated props**: Auto `camelCase` conversion (`show-label` → `showLabel`)
|
|
314
|
+
*
|
|
295
315
|
* #### NaN0 Spec (YAML)
|
|
296
316
|
*
|
|
297
317
|
* Concise format for defining variations:
|
|
@@ -307,6 +327,27 @@ function testRender() {
|
|
|
307
327
|
assert.ok(pkg.name === '@nan0web/ui')
|
|
308
328
|
})
|
|
309
329
|
|
|
330
|
+
/**
|
|
331
|
+
* @docs
|
|
332
|
+
* #### Documentation Site
|
|
333
|
+
*
|
|
334
|
+
* The IDE includes an auto-generated documentation site.
|
|
335
|
+
* HTML pages are generated from `ide.html` template via `generate-pages.js`:
|
|
336
|
+
*
|
|
337
|
+
* - Per-language pages (`/uk/Data/Table.html`, `/en/Feedback/Alert.html`)
|
|
338
|
+
* - SEO-optimized with `<title>` and `<meta>` per component
|
|
339
|
+
* - Category-based URL routing (`/Data/`, `/Feedback/`, `/Forms/`, `/Actions/`, `/System/`)
|
|
340
|
+
* - i18n navbar with `data-i18n` attributes
|
|
341
|
+
*/
|
|
342
|
+
it('How to run the documentation site?', () => {
|
|
343
|
+
/**
|
|
344
|
+
* ```bash
|
|
345
|
+
* npm run docs:dev
|
|
346
|
+
* ```
|
|
347
|
+
*/
|
|
348
|
+
assert.ok(pkg.scripts?.['docs:dev'])
|
|
349
|
+
})
|
|
350
|
+
|
|
310
351
|
/**
|
|
311
352
|
* @docs
|
|
312
353
|
* ## Playground Demos
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ArchitectureMap — a cross-package component readiness registry.
|
|
3
|
+
*
|
|
4
|
+
* Tracks which UI components are implemented in which packages
|
|
5
|
+
* (ui-lit, ui-cli, ui-react-bootstrap, etc.) and provides
|
|
6
|
+
* a programmatic readiness matrix.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* const map = new ArchitectureMap()
|
|
10
|
+
* map.register('ui-lit', ['Button', 'Input', 'Select'])
|
|
11
|
+
* map.register('ui-cli', ['Button', 'Input'])
|
|
12
|
+
* map.getMatrix()
|
|
13
|
+
* // → { Button: { 'ui-lit': true, 'ui-cli': true },
|
|
14
|
+
* // Input: { 'ui-lit': true, 'ui-cli': true },
|
|
15
|
+
* // Select: { 'ui-lit': true, 'ui-cli': false } }
|
|
16
|
+
* map.getReadiness('Button') // → true (in all packages)
|
|
17
|
+
* map.getReadiness('Select') // → false (missing from ui-cli)
|
|
18
|
+
*/
|
|
19
|
+
export default class ArchitectureMap {
|
|
20
|
+
/**
|
|
21
|
+
* Register a package and its exported components.
|
|
22
|
+
*
|
|
23
|
+
* @param {string} packageName — e.g. 'ui-lit', 'ui-cli', 'ui-react-bootstrap'
|
|
24
|
+
* @param {string[]} componentsList — e.g. ['Button', 'Input', 'Select']
|
|
25
|
+
*/
|
|
26
|
+
register(packageName: string, componentsList?: string[]): void;
|
|
27
|
+
/**
|
|
28
|
+
* Get the list of all registered package names.
|
|
29
|
+
*
|
|
30
|
+
* @returns {string[]}
|
|
31
|
+
*/
|
|
32
|
+
getPackages(): string[];
|
|
33
|
+
/**
|
|
34
|
+
* Get all known component names (union of all packages).
|
|
35
|
+
*
|
|
36
|
+
* @returns {string[]}
|
|
37
|
+
*/
|
|
38
|
+
getComponents(): string[];
|
|
39
|
+
/**
|
|
40
|
+
* Build a readiness matrix: { componentName → { packageName → boolean } }.
|
|
41
|
+
*
|
|
42
|
+
* Every known component gets an entry for every registered package.
|
|
43
|
+
*
|
|
44
|
+
* @returns {Object<string, Object<string, boolean>>}
|
|
45
|
+
*/
|
|
46
|
+
getMatrix(): {
|
|
47
|
+
[x: string]: {
|
|
48
|
+
[x: string]: boolean;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Check if a component is implemented in ALL registered packages.
|
|
53
|
+
*
|
|
54
|
+
* @param {string} componentName
|
|
55
|
+
* @returns {boolean}
|
|
56
|
+
*/
|
|
57
|
+
getReadiness(componentName: string): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Get a summary: { total, ready, notReady, readyPercent }.
|
|
60
|
+
*
|
|
61
|
+
* @returns {{ total: number, ready: number, notReady: number, readyPercent: number }}
|
|
62
|
+
*/
|
|
63
|
+
getSummary(): {
|
|
64
|
+
total: number;
|
|
65
|
+
ready: number;
|
|
66
|
+
notReady: number;
|
|
67
|
+
readyPercent: number;
|
|
68
|
+
};
|
|
69
|
+
#private;
|
|
70
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, ArchitectureMap } from "./ArchitectureMap.js";
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* InterfaceTemplate — base class for defining new UI interfaces.
|
|
3
|
+
*
|
|
4
|
+
* Establishes the inheritance pattern for the "One Logic, Many UI" architecture.
|
|
5
|
+
* Each UI interface (CLI, Web, Mobile, Chat, Audio) extends this template
|
|
6
|
+
* and overrides the required methods.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* class CliInterface extends InterfaceTemplate {
|
|
10
|
+
* render(data) { return formatForTerminal(data) }
|
|
11
|
+
* async ask(prompt) { return readlinePrompt(prompt) }
|
|
12
|
+
* }
|
|
13
|
+
*
|
|
14
|
+
* @abstract
|
|
15
|
+
*/
|
|
16
|
+
export default class InterfaceTemplate {
|
|
17
|
+
/**
|
|
18
|
+
* List of methods that MUST be overridden by concrete implementations.
|
|
19
|
+
* Used for documentation and runtime validation.
|
|
20
|
+
*
|
|
21
|
+
* @type {string[]}
|
|
22
|
+
*/
|
|
23
|
+
static requiredMethods: string[];
|
|
24
|
+
/**
|
|
25
|
+
* The name of this interface (e.g. 'cli', 'web', 'mobile').
|
|
26
|
+
* Override in subclass.
|
|
27
|
+
*
|
|
28
|
+
* @type {string}
|
|
29
|
+
*/
|
|
30
|
+
name: string;
|
|
31
|
+
/**
|
|
32
|
+
* Render data to the user through the interface.
|
|
33
|
+
* Must be overridden by each concrete implementation.
|
|
34
|
+
*
|
|
35
|
+
* @param {any} [data] - data to render
|
|
36
|
+
* @returns {any} rendered output (string for CLI, DOM for web, etc.)
|
|
37
|
+
* @throws {Error} if not overridden
|
|
38
|
+
*/
|
|
39
|
+
render(data?: any): any;
|
|
40
|
+
/**
|
|
41
|
+
* Request input from the user through the interface.
|
|
42
|
+
* Must be overridden by each concrete implementation.
|
|
43
|
+
*
|
|
44
|
+
* @param {string} prompt - question or label for the input
|
|
45
|
+
* @param {object} [options] - options (type, choices, default, etc.)
|
|
46
|
+
* @returns {Promise<any>} user's response
|
|
47
|
+
* @throws {Error} if not overridden
|
|
48
|
+
*/
|
|
49
|
+
ask(prompt: string, options?: object): Promise<any>;
|
|
50
|
+
/**
|
|
51
|
+
* Validate that all required methods have been overridden.
|
|
52
|
+
* Call this in the subclass constructor to get early feedback.
|
|
53
|
+
*
|
|
54
|
+
* @returns {string[]} list of missing method overrides (empty = valid)
|
|
55
|
+
*/
|
|
56
|
+
validate(): string[];
|
|
57
|
+
/**
|
|
58
|
+
* Get interface capabilities info.
|
|
59
|
+
*
|
|
60
|
+
* @returns {{ name: string, requiredMethods: string[], isComplete: boolean }}
|
|
61
|
+
*/
|
|
62
|
+
info(): {
|
|
63
|
+
name: string;
|
|
64
|
+
requiredMethods: string[];
|
|
65
|
+
isComplete: boolean;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, InterfaceTemplate } from "./InterfaceTemplate.js";
|