@nan0web/ui 1.12.2 → 3.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 (160) hide show
  1. package/README.md +18 -355
  2. package/package.json +36 -22
  3. package/src/Component/index.js +1 -5
  4. package/src/Model/Element.js +183 -0
  5. package/src/Model/index.js +2 -2
  6. package/src/Theme/AppTheme.js +19 -0
  7. package/src/Theme/CustomTheme.js +32 -0
  8. package/src/Theme/DarkLightTheme.js +34 -0
  9. package/src/Theme/Theme.js +25 -0
  10. package/src/Theme/atoms/Avatar.js +20 -0
  11. package/src/Theme/atoms/Badge.js +28 -0
  12. package/src/Theme/atoms/Button.js +88 -0
  13. package/src/Theme/atoms/Checkbox.js +26 -0
  14. package/src/Theme/atoms/Input.js +28 -0
  15. package/src/Theme/atoms/Radio.js +26 -0
  16. package/src/Theme/atoms/Select.js +16 -0
  17. package/src/Theme/atoms/TextArea.js +17 -0
  18. package/src/Theme/atoms/Typography.js +26 -0
  19. package/src/Theme/atoms/index.js +11 -0
  20. package/src/Theme/createTheme.js +22 -0
  21. package/src/Theme/index.js +20 -0
  22. package/src/Theme/molecules/Card.js +24 -0
  23. package/src/Theme/molecules/index.js +3 -0
  24. package/src/Theme/organisms/Modal.js +24 -0
  25. package/src/Theme/organisms/index.js +3 -0
  26. package/src/Theme/presets/HighContrastTheme.js +65 -0
  27. package/src/Theme/presets/NightTheme.js +66 -0
  28. package/src/Theme/presets/index.js +4 -0
  29. package/src/Theme/tokens.js +115 -0
  30. package/src/core/InputAdapter.js +1 -2
  31. package/src/core/Intent.js +22 -8
  32. package/src/core/Message/Message.js +3 -0
  33. package/src/core/OutputAdapter.js +9 -13
  34. package/src/core/index.js +7 -4
  35. package/src/core/resolvePositionalArgs.js +51 -0
  36. package/src/domain/Content.js +5 -5
  37. package/src/domain/Document.js +1 -1
  38. package/src/domain/HeroModel.js +1 -1
  39. package/src/domain/ModelAsApp.js +310 -20
  40. package/src/domain/ModelAsApp.story.js +117 -0
  41. package/src/domain/app/GalleryCommand.js +9 -8
  42. package/src/domain/app/{GalleryRenderIntent.js → GalleryRenderCommand.js} +20 -20
  43. package/src/domain/app/IntentAuditor.js +53 -0
  44. package/src/domain/app/JsIntentAuditor.js +145 -0
  45. package/src/domain/app/PyIntentAuditor.js +144 -0
  46. package/src/domain/app/SnapshotAuditor.js +82 -86
  47. package/src/domain/app/SnapshotRunner.js +1 -1
  48. package/src/domain/app/UIApp.js +12 -21
  49. package/src/domain/components/ShellModel.js +2 -2
  50. package/src/index.js +38 -10
  51. package/src/inspect.js +4 -0
  52. package/src/testing/SnapshotRunner.js +2 -1
  53. package/src/utils/format.js +21 -0
  54. package/src/utils/processI18n.js +27 -0
  55. package/src/utils/resolveContext.js +79 -0
  56. package/types/Component/index.d.ts +1 -5
  57. package/types/Model/Element.d.ts +87 -0
  58. package/types/Model/index.d.ts +2 -2
  59. package/types/Theme/AppTheme.d.ts +14 -0
  60. package/types/Theme/CustomTheme.d.ts +21 -0
  61. package/types/Theme/DarkLightTheme.d.ts +16 -0
  62. package/types/Theme/Theme.d.ts +18 -0
  63. package/types/Theme/atoms/Avatar.d.ts +14 -0
  64. package/types/Theme/atoms/Badge.d.ts +22 -0
  65. package/types/Theme/atoms/Button.d.ts +144 -0
  66. package/types/Theme/atoms/Checkbox.d.ts +20 -0
  67. package/types/Theme/atoms/Input.d.ts +22 -0
  68. package/types/Theme/atoms/Radio.d.ts +20 -0
  69. package/types/Theme/atoms/Select.d.ts +15 -0
  70. package/types/Theme/atoms/TextArea.d.ts +17 -0
  71. package/types/Theme/atoms/Typography.d.ts +47 -0
  72. package/types/Theme/atoms/index.d.ts +10 -0
  73. package/types/Theme/createTheme.d.ts +7 -0
  74. package/types/Theme/index.d.ts +10 -0
  75. package/types/Theme/molecules/Card.d.ts +18 -0
  76. package/types/Theme/molecules/index.d.ts +2 -0
  77. package/types/Theme/organisms/Modal.d.ts +18 -0
  78. package/types/Theme/organisms/index.d.ts +2 -0
  79. package/types/Theme/presets/HighContrastTheme.d.ts +2 -0
  80. package/types/Theme/presets/NightTheme.d.ts +2 -0
  81. package/types/Theme/presets/index.d.ts +3 -0
  82. package/types/Theme/tokens.d.ts +119 -0
  83. package/types/core/Intent.d.ts +10 -7
  84. package/types/core/Message/Message.d.ts +3 -0
  85. package/types/core/OutputAdapter.d.ts +2 -4
  86. package/types/core/index.d.ts +5 -2
  87. package/types/core/resolvePositionalArgs.d.ts +24 -0
  88. package/types/docs/README.md.d.ts +1 -0
  89. package/types/domain/Content.d.ts +2 -2
  90. package/types/domain/Document.d.ts +4 -3
  91. package/types/domain/FooterModel.d.ts +2 -1
  92. package/types/domain/HeroModel.d.ts +2 -2
  93. package/types/domain/ModelAsApp.d.ts +49 -5
  94. package/types/domain/ModelAsApp.story.d.ts +1 -0
  95. package/types/domain/app/GalleryCommand.d.ts +6 -37
  96. package/types/domain/app/GalleryRenderCommand.d.ts +27 -0
  97. package/types/domain/app/IntentAuditor.d.ts +23 -0
  98. package/types/domain/app/JsIntentAuditor.d.ts +22 -0
  99. package/types/domain/app/PyIntentAuditor.d.ts +22 -0
  100. package/types/domain/app/SnapshotAuditor.d.ts +34 -25
  101. package/types/domain/app/SnapshotRunner.d.ts +2 -2
  102. package/types/domain/app/UIApp.d.ts +14 -11
  103. package/types/domain/components/ShellModel.d.ts +1 -5
  104. package/types/index.d.ts +10 -10
  105. package/types/inspect.d.ts +4 -0
  106. package/types/testing/verifySnapshot.d.ts +1 -1
  107. package/types/utils/format.d.ts +5 -0
  108. package/types/utils/processI18n.d.ts +8 -0
  109. package/types/utils/resolveContext.d.ts +21 -0
  110. package/src/App/Command/DepsCommand.js +0 -24
  111. package/src/App/Core/CoreApp.js +0 -125
  112. package/src/App/Core/UI.js +0 -63
  113. package/src/App/Core/Widget.js +0 -61
  114. package/src/App/Core/index.js +0 -11
  115. package/src/App/Scenario.js +0 -45
  116. package/src/App/User/Command/Message.js +0 -3
  117. package/src/App/User/Command/index.js +0 -5
  118. package/src/App/User/UserApp.js +0 -85
  119. package/src/App/User/UserUI.js +0 -20
  120. package/src/App/User/index.js +0 -9
  121. package/src/App/index.js +0 -14
  122. package/src/Component/Process/Input.js +0 -63
  123. package/src/Component/Process/Process.js +0 -24
  124. package/src/Component/Process/index.js +0 -5
  125. package/src/Component/Welcome/Input.js +0 -48
  126. package/src/Component/Welcome/Welcome.js +0 -22
  127. package/src/Component/Welcome/index.js +0 -5
  128. package/src/Frame/Frame.js +0 -608
  129. package/src/Frame/Props.js +0 -96
  130. package/src/StdIn.js +0 -100
  131. package/src/StdOut.js +0 -95
  132. package/src/View/RenderOptions.js +0 -48
  133. package/src/View/View.js +0 -306
  134. package/src/core/Message/index.js +0 -6
  135. package/types/App/Command/DepsCommand.d.ts +0 -14
  136. package/types/App/Core/CoreApp.d.ts +0 -70
  137. package/types/App/Core/UI.d.ts +0 -38
  138. package/types/App/Core/Widget.d.ts +0 -39
  139. package/types/App/Core/index.d.ts +0 -10
  140. package/types/App/Scenario.d.ts +0 -26
  141. package/types/App/User/Command/Message.d.ts +0 -2
  142. package/types/App/User/Command/index.d.ts +0 -3
  143. package/types/App/User/UserApp.d.ts +0 -41
  144. package/types/App/User/UserUI.d.ts +0 -9
  145. package/types/App/User/index.d.ts +0 -8
  146. package/types/App/index.d.ts +0 -12
  147. package/types/Component/Process/Input.d.ts +0 -48
  148. package/types/Component/Process/Process.d.ts +0 -13
  149. package/types/Component/Process/index.d.ts +0 -4
  150. package/types/Component/Welcome/Input.d.ts +0 -34
  151. package/types/Component/Welcome/Welcome.d.ts +0 -13
  152. package/types/Component/Welcome/index.d.ts +0 -4
  153. package/types/Frame/Frame.d.ts +0 -186
  154. package/types/Frame/Props.d.ts +0 -77
  155. package/types/StdIn.d.ts +0 -62
  156. package/types/StdOut.d.ts +0 -52
  157. package/types/View/RenderOptions.d.ts +0 -29
  158. package/types/View/View.d.ts +0 -124
  159. package/types/core/Message/index.d.ts +0 -4
  160. package/types/domain/app/GalleryRenderIntent.d.ts +0 -31
@@ -0,0 +1,22 @@
1
+ /**
2
+ * JsIntentAuditor — Specialized auditor for JS/TS output hygiene.
3
+ */
4
+ export class JsIntentAuditor extends AuditorModel {
5
+ /** @type {string[]} Directories to ignore during scanning */
6
+ static IGNORE_DIRS: string[];
7
+ /**
8
+ * Checks if a directory or file should be ignored.
9
+ * @param {string} name
10
+ * @returns {boolean}
11
+ */
12
+ static isIgnored(name: string): boolean;
13
+ /**
14
+ * Inspects file content for console.* or process.* writes.
15
+ * @param {string} content Content of the file.
16
+ * @param {import('@nan0web/i18n').TFunction} t Translate function.
17
+ * @returns {string[]} List of error messages.
18
+ */
19
+ static inspectFileContent(content: string, t: import("@nan0web/i18n").TFunction): string[];
20
+ }
21
+ export default JsIntentAuditor;
22
+ import { AuditorModel } from '@nan0web/inspect/domain/AuditorModel';
@@ -0,0 +1,22 @@
1
+ /**
2
+ * PyIntentAuditor — Specialized auditor for Python output hygiene.
3
+ */
4
+ export class PyIntentAuditor extends AuditorModel {
5
+ /** @type {string[]} Directories to ignore during scanning */
6
+ static IGNORE_DIRS: string[];
7
+ /**
8
+ * Checks if a directory or file should be ignored.
9
+ * @param {string} name
10
+ * @returns {boolean}
11
+ */
12
+ static isIgnored(name: string): boolean;
13
+ /**
14
+ * Inspects Python file content for print or sys.stdout/stderr writes.
15
+ * @param {string} content Content of the file.
16
+ * @param {import('@nan0web/i18n').TFunction} t Translate function.
17
+ * @returns {string[]} List of error messages.
18
+ */
19
+ static inspectFileContent(content: string, t: import("@nan0web/i18n").TFunction): string[];
20
+ }
21
+ export default PyIntentAuditor;
22
+ import { AuditorModel } from '@nan0web/inspect/domain/AuditorModel';
@@ -1,25 +1,33 @@
1
1
  /**
2
2
  * SnapshotAuditor — Zero-Hallucination Snapshot Validation (Model-as-Schema v2).
3
3
  * Parses snapshots without evaluating the app logic and detects artifacts.
4
- *
5
- * @extends {AuditorModel}
6
4
  */
7
- export class SnapshotAuditor {
8
- static alias: string;
9
- static dir: {
10
- type: string;
11
- help: string;
12
- positional: boolean;
13
- default: string;
14
- };
5
+ export class SnapshotAuditor extends AuditorModel {
15
6
  static data: {
16
7
  type: string;
17
8
  help: string;
18
9
  default: string;
19
10
  };
20
- /** @type {Object<string, string>} Messages for UI */
21
11
  static UI: {
22
- [x: string]: string;
12
+ title: string;
13
+ description: string;
14
+ icon: string;
15
+ starting: string;
16
+ noSnapshots: string;
17
+ doneSuccess: string;
18
+ doneErrors: string;
19
+ auditPassed: string;
20
+ auditFailed: string;
21
+ errorDb: string;
22
+ errorGlitch: string;
23
+ errorShort: string;
24
+ errorSyntax: string;
25
+ errorArtifact: string;
26
+ errorRouting: string;
27
+ errorUntranslated: string;
28
+ errorEnglishLeak: string;
29
+ errorEmptyRender: string;
30
+ errorForeignLeak: string;
23
31
  };
24
32
  /** @type {string[]} Common UI components that can be empty in render */
25
33
  static EXEMPT_EMPTY: string[];
@@ -31,6 +39,14 @@ export class SnapshotAuditor {
31
39
  static SUSPICIOUS_FILENAME: RegExp;
32
40
  /** @type {number} Minimum filename length */
33
41
  static MIN_FILENAME_LENGTH: number;
42
+ /** @type {string[]} Directories to ignore during scanning */
43
+ static IGNORE_DIRS: string[];
44
+ /**
45
+ * Checks if a directory or file should be ignored.
46
+ * @param {string} name
47
+ * @returns {boolean}
48
+ */
49
+ static isIgnored(name: string): boolean;
34
50
  /**
35
51
  * Extracts all valid words from an object into a Set.
36
52
  * @param {any} obj Node to extract from.
@@ -53,7 +69,7 @@ export class SnapshotAuditor {
53
69
  * @param {Record<string, Set<string>>} [dictionaries=undefined] Loaded dictionaries for mutual exclusion check.
54
70
  * @returns {{ score: number, errors: string[] }}
55
71
  */
56
- static inspectText(content: string, locale: string, filename: string, t: any, dictionaries?: Record<string, Set<string>>): {
72
+ static inspectText(content: string, locale: string, filename: string, t: import("@nan0web/i18n").TFunction, dictionaries?: Record<string, Set<string>>): {
57
73
  score: number;
58
74
  errors: string[];
59
75
  };
@@ -66,7 +82,7 @@ export class SnapshotAuditor {
66
82
  static checkNode(node: any, path: string, context: {
67
83
  locale: string;
68
84
  errors: string[];
69
- t: any;
85
+ t: import("@nan0web/i18n").TFunction;
70
86
  dictionaries?: Record<string, Set<string>>;
71
87
  }): void;
72
88
  /**
@@ -78,22 +94,15 @@ export class SnapshotAuditor {
78
94
  static checkString(str: string, path: string, context: {
79
95
  locale: string;
80
96
  errors: string[];
81
- t: any;
97
+ t: import("@nan0web/i18n").TFunction;
82
98
  dictionaries?: Record<string, Set<string>>;
83
99
  }): void;
84
100
  /**
85
101
  * @param {Partial<SnapshotAuditor> | Record<string, any>} [data={}]
86
- * @param {Partial<import('@nan0web/types').ModelOptions>} [options={}]
102
+ * @param {Partial<import('@nan0web/ui').ModelAsAppOptions>} [options={}]
87
103
  */
88
- constructor(data?: Partial<SnapshotAuditor> | Record<string, any>, options?: Partial<import("@nan0web/types").ModelOptions>);
89
- /** @type {import('@nan0web/types').ModelOptions} */
90
- options: import("@nan0web/types").ModelOptions;
91
- /** @type {string} Target directory to audit */ dir: string;
104
+ constructor(data?: Partial<SnapshotAuditor> | Record<string, any>, options?: Partial<import("@nan0web/ui").ModelAsAppOptions>);
92
105
  /** @type {string} Directory to scan for dictionaries */ data: string;
93
- /**
94
- * Run the snapshot audit inside the target directory.
95
- * @returns {AsyncGenerator<import('@nan0web/ui').Intent, any, any>}
96
- */
97
- run(): AsyncGenerator<import("@nan0web/ui").Intent, any, any>;
98
106
  }
99
107
  export default SnapshotAuditor;
108
+ import { AuditorModel } from '@nan0web/inspect/domain/AuditorModel';
@@ -26,9 +26,9 @@ export class SnapshotRunner extends Model {
26
26
  };
27
27
  /**
28
28
  * @param {Partial<SnapshotRunner> | Record<string, any>} [data={}]
29
- * @param {import('@nan0web/types').ModelOptions} [options={}]
29
+ * @param {Partial<import('@nan0web/types').ModelOptions>} [options={}]
30
30
  */
31
- constructor(data?: Partial<SnapshotRunner> | Record<string, any>, options?: import("@nan0web/types").ModelOptions);
31
+ constructor(data?: Partial<SnapshotRunner> | Record<string, any>, options?: Partial<import("@nan0web/types").ModelOptions>);
32
32
  /** @type {string} Directory containing snapshots */ snapshotsDir: string;
33
33
  /** @type {string} Root data directory */ data: string;
34
34
  /** @type {(compName: string) => string} */ getCategory: (compName: string) => string;
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @property {string[]} _positionals
3
+ * @property {string} command Type of command to run
4
+ * @property {boolean} help Show help message
5
+ */
1
6
  export class UIApp extends ModelAsApp {
2
7
  static command: {
3
8
  type: string;
@@ -10,19 +15,12 @@ export class UIApp extends ModelAsApp {
10
15
  helpText: string;
11
16
  unknownCommand: string;
12
17
  };
13
- static help: {
14
- help: string;
15
- default: boolean;
16
- };
17
18
  /**
18
19
  * @param {Partial<UIApp> | Record<string, any>} [data={}]
19
- * @param {import('@nan0web/types').ModelOptions} [options={}]
20
+ * @param {Partial<import('@nan0web/types').ModelOptions>} [options={}]
20
21
  */
21
- constructor(data?: Partial<UIApp> | Record<string, any>, options?: import("@nan0web/types").ModelOptions);
22
- /** @type {string[]} */ _positionals: string[];
23
- /** @type {string} Type of command to run */ command: string;
24
- /** @type {boolean} Show help message */ help: boolean;
25
- run(): AsyncGenerator<import("../../core/Intent.js").ShowIntent | import("../../core/Intent.js").RenderIntent | (import("../../core/Intent.js").AskIntent & {
22
+ constructor(data?: Partial<UIApp> | Record<string, any>, options?: Partial<import("@nan0web/types").ModelOptions>);
23
+ run(): AsyncGenerator<import("../../core/Intent.js").ShowIntent | (import("../../core/Intent.js").AskIntent & {
26
24
  $value?: any;
27
25
  $success?: boolean;
28
26
  $files?: Record<string, string>;
@@ -37,6 +35,11 @@ export class UIApp extends ModelAsApp {
37
35
  $success?: boolean;
38
36
  $files?: Record<string, string>;
39
37
  $message?: string;
38
+ }) | (import("../../core/Intent.js").RenderIntent & {
39
+ $value?: any;
40
+ $success?: boolean;
41
+ $files?: Record<string, string>;
42
+ $message?: string;
40
43
  }) | (import("../../core/Intent.js").AgentIntent & {
41
44
  $value?: any;
42
45
  $success?: boolean;
@@ -47,7 +50,7 @@ export class UIApp extends ModelAsApp {
47
50
  $success?: boolean;
48
51
  $files?: Record<string, string>;
49
52
  $message?: string;
50
- }), any, any>;
53
+ }), import("../../core/Intent.js").ResultIntent, any>;
51
54
  }
52
55
  export default UIApp;
53
56
  import { ModelAsApp } from '../ModelAsApp.js';
@@ -46,11 +46,7 @@ export class ShellModel extends Model {
46
46
  /** @type {string} */ index: string;
47
47
  /** @type {string} */ locale: string;
48
48
  /** @type {string} */ port: string;
49
- run(): AsyncGenerator<import("../../core/Intent.js").AskIntent | {
50
- type: string;
51
- level: any;
52
- message: any;
53
- }, any, unknown>;
49
+ run(): AsyncGenerator<import("../../core/Intent.js").AskIntent | import("../../core/Intent.js").LogIntent, any, unknown>;
54
50
  #private;
55
51
  }
56
52
  import { Model } from '@nan0web/types';
package/types/index.d.ts CHANGED
@@ -1,3 +1,6 @@
1
+ export { default as Element } from "./Model/Element.js";
2
+ export { resolveContext } from "./utils/resolveContext.js";
3
+ export { processI18n } from "./utils/processI18n.js";
1
4
  export { format } from "./format.js";
2
5
  export { default as Navigation } from "./domain/Navigation.js";
3
6
  export { default as FormMessage } from "./core/Form/Message.js";
@@ -7,8 +10,9 @@ export { default as OutputAdapter } from "./core/OutputAdapter.js";
7
10
  export { default as OutputMessage } from "./core/Message/OutputMessage.js";
8
11
  export { default as UiForm } from "./core/Form/Form.js";
9
12
  export { default as UiMessage } from "./core/Message/Message.js";
10
- export { default as UiStream } from "./core/Stream.js";
11
13
  export { default as UiAdapter } from "./core/UiAdapter.js";
14
+ export { resolvePositionalArgs } from "./core/resolvePositionalArgs.js";
15
+ export { tokens } from "./Theme/tokens.js";
12
16
  export * from "./core/Intent.js";
13
17
  export * from "./domain/index.js";
14
18
  export { IntentErrorModel } from "./core/IntentErrorModel.js";
@@ -32,15 +36,11 @@ export type AbortResponse = import("./core/Intent.js").AbortResponse;
32
36
  export type ShowData = import("./core/Intent.js").ShowData;
33
37
  export type AskOptions = import("./core/InputAdapter.js").AskOptions;
34
38
  export type ModelAsAppOptions = import("./domain/index.js").ModelAsAppOptions;
35
- import Frame from './Frame/Frame.js';
36
- import FrameProps from './Frame/Props.js';
37
39
  import Locale from './Locale.js';
38
- import StdIn from './StdIn.js';
39
- import StdOut from './StdOut.js';
40
- import View from './View/View.js';
41
- import RenderOptions from './View/RenderOptions.js';
42
- import Model from './Model/index.js';
40
+ import { Model } from '@nan0web/types';
41
+ import Models from './Model/index.js';
43
42
  import Component from './Component/index.js';
44
- import App from './App/index.js';
45
- export { Frame, FrameProps, Locale, StdIn, StdOut, View, RenderOptions, Model, Component, App };
43
+ export { Locale, Model, Models, Component };
44
+ export { default as Theme, getUserTheme, CustomTheme, DarkLightTheme, NightTheme, createTheme } from "./Theme/index.js";
46
45
  export { default as Error, CancelError } from "./core/Error/index.js";
46
+ export { runFlow, flow, Prompt, Stream, Alert, Toast, Badge, Text, Table, Input, Select, Confirm, Multiselect, Mask, Password, Spinner, Progress, default as Flow } from "./core/Flow.js";
@@ -1,2 +1,6 @@
1
1
  export * from "./testing/SnapshotRunner.js";
2
2
  export * from "./testing/verifySnapshot.js";
3
+ export { SnapshotAuditor } from "./domain/app/SnapshotAuditor.js";
4
+ export { IntentAuditor } from "./domain/app/IntentAuditor.js";
5
+ export { JsIntentAuditor } from "./domain/app/JsIntentAuditor.js";
6
+ export { PyIntentAuditor } from "./domain/app/PyIntentAuditor.js";
@@ -10,5 +10,5 @@ export function verifySnapshot({ name, data, fs, path }: {
10
10
  name: string;
11
11
  data: Array<any>;
12
12
  fs?: typeof import("node:fs/promises") | undefined;
13
- path?: import("path").PlatformPath | undefined;
13
+ path?: typeof import("node:path") | undefined;
14
14
  }): Promise<void>;
@@ -0,0 +1,5 @@
1
+ export namespace format {
2
+ function currency(value: any, currency?: string, locale?: string): string;
3
+ function rate(value: any, locale?: string): string;
4
+ function number(value: any, locale?: string): string;
5
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Обробляє i18n та замінює змінні в тексті.
3
+ * @param {any} input - Вміст для обробки.
4
+ * @param {Function} [t] - Функція перекладу.
5
+ * @param {Object} [data] - Дані для підстановки.
6
+ * @returns {any}
7
+ */
8
+ export function processI18n(input: any, t?: Function, data?: any): any;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Resolves context-aware values in strings and objects.
3
+ * Supports:
4
+ * - References: `data:currencies`, `action:save`, `fn:calculate,100,USD,UAH`
5
+ * - Templates: `{{user.name}}`, `{{currencies[0]}}`
6
+ * - Scalars: numbers, booleans, etc. (passthrough)
7
+ *
8
+ * @param {Object} context - Application context (data, actions, functions)
9
+ * @param {*} value - Raw value to resolve
10
+ * @returns {*} Resolved value
11
+ */
12
+ export function resolveContext(context: any, value: any): any;
13
+ /**
14
+ * Resolves a context value or returns undefined if resolution fails.
15
+ * Used internally by renderers to safely resolve props.
16
+ *
17
+ * @param {Object} ctx - Context with data, actions and functions
18
+ * @param {string} value - String value to resolve
19
+ * @returns {*} Resolved value or undefined
20
+ */
21
+ export function resolveContextValue(ctx: any, value: string): any;
@@ -1,24 +0,0 @@
1
- import UiMessage from '../../core/Message/Message.js'
2
-
3
- class DepsCommandBody {
4
- static fix = {
5
- help: 'Fix dependencies',
6
- defaultValue: false,
7
- }
8
- constructor(input = {}) {
9
- const { fix = DepsCommandBody.fix.defaultValue } = input
10
- this.fix = !!fix
11
- }
12
- }
13
-
14
- export class DepsCommand extends UiMessage {
15
- static Body = DepsCommandBody
16
- constructor(input = {}) {
17
- const { body = new DepsCommandBody() } = UiMessage.parseBody(input, DepsCommandBody)
18
- super(input)
19
- /** @type {DepsCommandBody} */
20
- this.body = body
21
- }
22
- }
23
-
24
- export default DepsCommand
@@ -1,125 +0,0 @@
1
- import { Message } from '@nan0web/co'
2
- import { typeOf } from '@nan0web/types'
3
- import UI from './UI.js'
4
-
5
- /** @typedef {Function} CommandFn */
6
-
7
- /**
8
- * Abstract base class for all apps.
9
- * Each app processes input commands and produces output.
10
- */
11
- export default class CoreApp {
12
- /** @type {string} App name */
13
- name
14
-
15
- /** @type {Map<string, CommandFn>} Registered command handlers */
16
- commands
17
-
18
- /** @type {Record<string, any>} App state */
19
- state
20
-
21
- /** @type {Message} Starting command parsed from argv */
22
- startCommand
23
-
24
- /**
25
- * Creates a new CoreApp instance.
26
- * @param {object} props - CoreApp properties
27
- * @param {string} [props.name="CoreApp"] - App name
28
- * @param {object} [props.state={}] - Initial state object
29
- * @param {Message} [props.startCommand=new Message()] - Command line arguments to parse
30
- */
31
- constructor(props = {}) {
32
- const { name = 'CoreApp', state = {}, startCommand = new Message() } = props
33
- this.name = String(name)
34
- this.state = state
35
- this.commands = new Map()
36
- // @deprecated @todo fix the argv by moving to ui-cli.
37
- this.startCommand = Message.from(startCommand ?? {})
38
- }
39
-
40
- /**
41
- * Sets app state.
42
- * @param {string|object} state - State key or object with multiple keys
43
- * @param {any} [value] - State value if state is a string key
44
- * @returns {object} Updated state
45
- */
46
- set(state, value) {
47
- if ('string' === typeof state) {
48
- this.state[state] = value
49
- } else {
50
- Object.assign(this.state, state)
51
- }
52
- // @todo save state
53
- return this.state
54
- }
55
-
56
- /**
57
- * Register a command handler.
58
- * @param {string} commandName - Name of the command to register
59
- * @param {Function} handler - async function or sync function that accepts params and returns output
60
- */
61
- registerCommand(commandName, handler) {
62
- if (!typeOf(Function)(handler)) {
63
- throw new TypeError('Handler must be a function')
64
- }
65
- this.commands.set(commandName, handler)
66
- }
67
-
68
- /**
69
- * Returns a string representation of the app.
70
- * @returns {string} String representation including name and state
71
- */
72
- toString() {
73
- return `${this.constructor.name}(name=${this.name}, state=${JSON.stringify(this.state)})`
74
- }
75
-
76
- /**
77
- * Process a command message.
78
- * @param {Message} msg - Command to process
79
- * @param {UI} ui - UI instance to use for rendering
80
- * @returns {Promise<any>} Output of the command
81
- * @throws {Error} If the command is not registered
82
- */
83
- async processCommand(msg, ui) {
84
- const handler = this.commands.get(msg.constructor.name)
85
- if (!handler) {
86
- throw new Error(
87
- [
88
- 'Unknown command',
89
- ': ',
90
- msg.constructor.name,
91
- '\n',
92
- 'Available commands',
93
- ': ',
94
- [...this.commands.keys()].join(', '),
95
- ].join(''),
96
- )
97
- }
98
- return await handler.apply(this, [msg, ui])
99
- }
100
-
101
- /**
102
- * Process an array of command messages sequentially.
103
- * @param {Message[]} Messages - Array of commands to process
104
- * @param {UI} ui - UI instance to use for rendering
105
- * @returns {Promise<any[]>} Array of command outputs
106
- */
107
- async processCommands(Messages, ui) {
108
- const results = []
109
- for (const cmdMsg of Messages) {
110
- const result = await this.processCommand(cmdMsg, ui)
111
- results.push(result)
112
- }
113
- return results
114
- }
115
-
116
- /**
117
- * Select a command to run. Must be implemented by subclasses.
118
- * @param {UI} ui - UI instance for interaction
119
- * @returns {Promise<string>} Command name to execute
120
- * @throws {Error} Always thrown as this method must be implemented by subclasses
121
- */
122
- async selectCommand(ui) {
123
- throw new Error('Not implemented, must be implemented by subclass')
124
- }
125
- }
@@ -1,63 +0,0 @@
1
- import { Message } from '@nan0web/co'
2
- import View from '../../View/View.js'
3
- import CoreApp from './CoreApp.js'
4
- import Widget from './Widget.js'
5
-
6
- /** @typedef {import("../../View/View.js").ComponentFn} ComponentFn */
7
-
8
- /**
9
- * Abstract UI class to connect apps and widgets.
10
- * Supports input/output data typed classes and views.
11
- */
12
- export default class UI extends Widget {
13
- /** @type {CoreApp} The app instance connected to this UI */
14
- app
15
-
16
- /**
17
- * Creates a new UI instance.
18
- * @param {CoreApp} app - The app to connect to this UI
19
- * @param {View} [view] - View instance for rendering (default: new View())
20
- */
21
- constructor(app, view = new View()) {
22
- super(view)
23
- this.app = app
24
- }
25
-
26
- /**
27
- * Convert raw input to Message array.
28
- * Must be implemented by subclasses.
29
- * @param {any} rawInput - Raw input to convert
30
- * @returns {Message[]} Array of command messages
31
- * @throws {Error} Always thrown as this method must be implemented by subclasses
32
- */
33
- convertInput(rawInput) {
34
- throw new Error('convertInput must be implemented by subclass')
35
- }
36
-
37
- /**
38
- * Sets up event handlers for UI process events.
39
- * @param {ComponentFn} UIProcess - Process view component
40
- */
41
- show(UIProcess) {
42
- if (!UIProcess) return
43
- const onStart = () => {
44
- // this.view.render(UIProcess)
45
- }
46
- const onData = () => {}
47
- const onEnd = () => {}
48
-
49
- this.on('start', onStart)
50
- this.on('data', onData)
51
- this.on('end', onEnd)
52
- }
53
-
54
- /**
55
- * Output results to the interface.
56
- * @param {any[]} results - Results to output
57
- */
58
- output(results) {
59
- results.forEach((result) => {
60
- this.view.info(JSON.stringify(result))
61
- })
62
- }
63
- }
@@ -1,61 +0,0 @@
1
- import EventProcessor from '@nan0web/event/oop'
2
- import View from '../../View/View.js'
3
- import { StreamEntry } from '@nan0web/db'
4
- import { UiMessage } from '../../core/index.js'
5
-
6
- /** @typedef {import("./UI.js").ComponentFn} ComponentFn */
7
-
8
- /**
9
- * Abstract Widget class.
10
- * Widget is a view with ability to input data in a specific format.
11
- * Input and output data are typed classes.
12
- */
13
- export default class Widget extends EventProcessor {
14
- /** @type {View} The view associated with this widget */
15
- view
16
-
17
- /**
18
- * Creates a new Widget instance.
19
- * @param {View} [view] - View instance (default: new View())
20
- */
21
- constructor(view = new View()) {
22
- super()
23
- this.view = view
24
- }
25
-
26
- /**
27
- * Ask user for input data of specific class.
28
- * @param {UiMessage} input - instance of UiMessage or similar
29
- * @returns {Promise<UiMessage | null>} instance of UiMessage or null
30
- */
31
- async ask(input) {
32
- return await this.view.ask(input)
33
- }
34
-
35
- /**
36
- * @param {AsyncGenerator<StreamEntry>} stream
37
- * @returns {Promise<void>}
38
- */
39
- async read(stream) {
40
- for await (const entry of stream) {
41
- this.view.progress(true)(entry)
42
- }
43
- }
44
-
45
- /**
46
- * Render output data using a view function.
47
- * @param {Function|string} viewFnOrName - View function or registered view name
48
- * @param {object} outputData - Typed output data instance
49
- * @returns {any} Rendered output
50
- * @throws {Error} If view component is not found when using string name
51
- */
52
- render(viewFnOrName, outputData) {
53
- /** @type {Function | ComponentFn | undefined} */
54
- const viewFn = typeof viewFnOrName === 'string' ? this.view.get(viewFnOrName) : viewFnOrName
55
-
56
- if (!viewFn) {
57
- throw new Error(['View component not found', ': ', viewFnOrName].join(''))
58
- }
59
- return this.view.render(viewFn)(outputData)
60
- }
61
- }
@@ -1,11 +0,0 @@
1
- import CoreApp from './CoreApp.js'
2
- import UI from './UI.js'
3
- import Widget from './Widget.js'
4
-
5
- export { CoreApp, UI }
6
-
7
- export default {
8
- App: CoreApp,
9
- UI,
10
- Widget,
11
- }
@@ -1,45 +0,0 @@
1
- import App from './index.js'
2
- import UI from './Core/UI.js'
3
-
4
- /** @typedef {import("./Core/CoreApp.js").default} CoreApp */
5
-
6
- /**
7
- * Abstract Scenario class to test app logic.
8
- * Scenarios run input commands and verify output.
9
- */
10
- export default class Scenario {
11
- /** @type {CoreApp} The app to run scenarios against */
12
- app
13
-
14
- /**
15
- * Creates a new Scenario instance.
16
- * @param {CoreApp} app - App instance to run scenarios against
17
- * @param {UI} ui - User interface
18
- * @throws {TypeError} If app is not an App.Core.App instance
19
- */
20
- constructor(app, ui) {
21
- if (!(app instanceof App.Core.App)) {
22
- throw new TypeError('Scenario requires a App.Core.App instance')
23
- }
24
- this.app = app
25
- this.ui = ui
26
- }
27
-
28
- /**
29
- * Run scenario with input commands and expected output.
30
- * @param {Array<any[]>} inputCommands - Array of command arrays
31
- * @param {Array<any>} expectedOutputs - Expected outputs for each command
32
- * @returns {Promise<boolean>} True if all outputs match expected
33
- */
34
- async run(inputCommands, expectedOutputs) {
35
- const commandMessages = inputCommands.map((arr) => App.Command.Message.parse(arr))
36
- const outputs = await this.app.processCommands(commandMessages, this.ui)
37
- if (outputs.length !== expectedOutputs.length) return false
38
- for (let i = 0; i < outputs.length; i++) {
39
- if (JSON.stringify(outputs[i]) !== JSON.stringify(expectedOutputs[i])) {
40
- return false
41
- }
42
- }
43
- return true
44
- }
45
- }
@@ -1,3 +0,0 @@
1
- import UiMessage from '../../../core/Message/Message.js'
2
-
3
- export default UiMessage
@@ -1,5 +0,0 @@
1
- import CommandMessage from './Message.js'
2
-
3
- export { CommandMessage }
4
-
5
- export default CommandMessage