libmodulor 0.4.0 → 0.6.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 (246) hide show
  1. package/.github/dependabot.yml +19 -0
  2. package/CHANGELOG.md +35 -1
  3. package/README.md +10 -4
  4. package/dist/esm/app/workers/AppSrcFilePathBuilder.d.ts +16 -0
  5. package/dist/esm/app/workers/AppSrcFilePathBuilder.js +6 -4
  6. package/dist/esm/apps/Helper/index.js +1 -0
  7. package/dist/esm/apps/Helper/src/i18n.js +4 -0
  8. package/dist/esm/apps/Helper/src/lib/project.d.ts +2 -0
  9. package/dist/esm/apps/Helper/src/lib/project.js +120 -0
  10. package/dist/esm/apps/Helper/src/manifest.d.ts +5 -0
  11. package/dist/esm/apps/Helper/src/manifest.js +5 -0
  12. package/dist/esm/apps/Helper/src/ucds/CreateProjectUCD.d.ts +15 -0
  13. package/dist/esm/apps/Helper/src/ucds/CreateProjectUCD.js +118 -0
  14. package/dist/esm/apps/Helper/src/ucds/GenerateAppsTestsUCD.js +3 -2
  15. package/dist/esm/bundlers/vite/StripUCDLifecycleServerPlugin.js +3 -0
  16. package/dist/esm/convention.d.ts +1 -0
  17. package/dist/esm/convention.js +17 -4
  18. package/dist/esm/dt/Validation.d.ts +8 -0
  19. package/dist/esm/dt/Validation.js +8 -0
  20. package/dist/esm/dt/base/TBase.d.ts +2 -1
  21. package/dist/esm/dt/base/TBoolean.js +2 -0
  22. package/dist/esm/dt/base/TInt.js +3 -0
  23. package/dist/esm/dt/base/TNumber.js +2 -0
  24. package/dist/esm/dt/base/TObject.d.ts +15 -0
  25. package/dist/esm/dt/base/TObject.js +14 -0
  26. package/dist/esm/dt/base/TString.js +1 -1
  27. package/dist/esm/dt/final/TAmount.js +1 -0
  28. package/dist/esm/dt/final/TCountryISO3166Alpha2.js +1 -0
  29. package/dist/esm/dt/final/TCurrencyISO4217.js +1 -0
  30. package/dist/esm/dt/final/TDateTimeFormat.js +1 -0
  31. package/dist/esm/dt/final/TEmail.js +2 -0
  32. package/dist/esm/dt/final/TEmoji.js +4 -0
  33. package/dist/esm/dt/final/TFile.js +3 -0
  34. package/dist/esm/dt/final/THostAddress.js +2 -0
  35. package/dist/esm/dt/final/TIPv6.js +1 -0
  36. package/dist/esm/dt/final/TJWT.js +8 -0
  37. package/dist/esm/dt/final/TPercentage.js +5 -0
  38. package/dist/esm/dt/final/TSQLQuery.js +1 -0
  39. package/dist/esm/dt/final/TSSHPrivateKey.js +3 -1
  40. package/dist/esm/dt/final/TSemVerVersion.js +1 -0
  41. package/dist/esm/dt/final/TShellCommand.js +1 -0
  42. package/dist/esm/dt/final/TURL.js +2 -0
  43. package/dist/esm/dt/final/TUUID.js +1 -0
  44. package/dist/esm/dt/final/TYesNo.js +1 -1
  45. package/dist/esm/dt/index.d.ts +1 -1
  46. package/dist/esm/i18n/WordingManager.d.ts +16 -0
  47. package/dist/esm/i18n/types.d.ts +5 -0
  48. package/dist/esm/icon/Icon.d.ts +7 -0
  49. package/dist/esm/index.d.ts +3 -0
  50. package/dist/esm/index.js +4 -0
  51. package/dist/esm/index.node.d.ts +1 -0
  52. package/dist/esm/index.node.js +1 -0
  53. package/dist/esm/index.react.d.ts +1 -1
  54. package/dist/esm/product/manifest.d.ts +15 -0
  55. package/dist/esm/products/Helper/container.js +4 -0
  56. package/dist/esm/products/Helper/index.js +5 -0
  57. package/dist/esm/products/Helper/manifest.d.ts +6 -1
  58. package/dist/esm/std/BufferManager.d.ts +18 -0
  59. package/dist/esm/std/ClockManager.d.ts +5 -0
  60. package/dist/esm/std/EnvironmentManager.d.ts +10 -0
  61. package/dist/esm/std/HTTPAPICaller.d.ts +6 -0
  62. package/dist/esm/std/I18nManager.d.ts +26 -0
  63. package/dist/esm/std/JWTManager.d.ts +26 -0
  64. package/dist/esm/std/JobManager.d.ts +6 -0
  65. package/dist/esm/std/LLMManager.d.ts +25 -0
  66. package/dist/esm/std/LLMManager.js +1 -0
  67. package/dist/esm/std/PromptManager.d.ts +8 -0
  68. package/dist/esm/std/SettingsManager.d.ts +19 -0
  69. package/dist/esm/std/SettingsManager.js +9 -0
  70. package/dist/esm/std/ShellCommandExecutor.d.ts +19 -0
  71. package/dist/esm/std/ShellCommandExecutor.js +1 -0
  72. package/dist/esm/std/impl/ConsoleLogger.js +7 -1
  73. package/dist/esm/std/impl/FakeEmailManager.js +1 -0
  74. package/dist/esm/std/impl/FakeJobManager.js +1 -0
  75. package/dist/esm/std/impl/FetchHTTPAPICallExecutor.d.ts +9 -0
  76. package/dist/esm/std/impl/FetchHTTPAPICallExecutor.js +11 -0
  77. package/dist/esm/std/impl/MistralAILLMManager.d.ts +17 -0
  78. package/dist/esm/std/impl/MistralAILLMManager.js +56 -0
  79. package/dist/esm/std/impl/NodeCryptoManager.js +6 -1
  80. package/dist/esm/std/impl/NodeDeterministicCryptoManager.d.ts +14 -0
  81. package/dist/esm/std/impl/NodeDeterministicCryptoManager.js +17 -3
  82. package/dist/esm/std/impl/NodeFSManager.js +10 -0
  83. package/dist/esm/std/impl/NodeHTTPAPICallExecutorAgentBuilder.js +2 -0
  84. package/dist/esm/std/impl/NodePromptManager.js +3 -0
  85. package/dist/esm/std/impl/NodeSpawnShellCommandExecutor.d.ts +4 -0
  86. package/dist/esm/std/impl/NodeSpawnShellCommandExecutor.js +41 -0
  87. package/dist/esm/std/impl/OllamaLLMManager.d.ts +20 -0
  88. package/dist/esm/std/impl/OllamaLLMManager.js +56 -0
  89. package/dist/esm/std/impl/OpenAILLMManager.d.ts +17 -0
  90. package/dist/esm/std/impl/OpenAILLMManager.js +51 -0
  91. package/dist/esm/std/impl/SimpleHTTPAPICaller.js +14 -0
  92. package/dist/esm/std/impl/SimpleMapI18nManager.js +4 -2
  93. package/dist/esm/std/impl/StdDateClockManager.js +3 -0
  94. package/dist/esm/std/impl/UCDataStoreExternalResourceManager.js +3 -0
  95. package/dist/esm/std/impl/WebCryptoManager.js +9 -0
  96. package/dist/esm/std/index.d.ts +2 -0
  97. package/dist/esm/std/index.js +2 -0
  98. package/dist/esm/target/lib/cli/renderer.js +3 -0
  99. package/dist/esm/target/lib/client/consts.d.ts +3 -0
  100. package/dist/esm/target/lib/client/consts.js +3 -0
  101. package/dist/esm/target/lib/mcp-server/MCPServerBooter.js +1 -0
  102. package/dist/esm/target/lib/react/UCContainer.js +1 -0
  103. package/dist/esm/target/lib/react/UCPanel.js +4 -0
  104. package/dist/esm/target/lib/react/form.d.ts +26 -2
  105. package/dist/esm/target/lib/react/form.js +18 -1
  106. package/dist/esm/target/lib/react/useUC.d.ts +8 -0
  107. package/dist/esm/target/lib/react/useUC.js +22 -0
  108. package/dist/esm/target/lib/react/useUCOR.d.ts +15 -0
  109. package/dist/esm/target/lib/react/useUCOR.js +45 -0
  110. package/dist/esm/target/lib/rn/input.d.ts +7 -0
  111. package/dist/esm/target/lib/rn/input.js +2 -0
  112. package/dist/esm/target/lib/server/AuthenticationChecker.js +2 -1
  113. package/dist/esm/target/lib/server/BasicAuthenticationChecker.js +1 -0
  114. package/dist/esm/target/lib/server/CSPDirectivesBuilder.js +13 -0
  115. package/dist/esm/target/lib/server/CustomerFacingErrorBuilder.js +3 -0
  116. package/dist/esm/target/lib/server/PrivateApiKeyAuthenticationChecker.js +1 -0
  117. package/dist/esm/target/lib/server/PublicApiKeyChecker.js +1 -1
  118. package/dist/esm/target/lib/server/RequestChecker.js +5 -4
  119. package/dist/esm/target/lib/server/RequestHandler.d.ts +5 -0
  120. package/dist/esm/target/lib/server/RequestLogger.js +5 -0
  121. package/dist/esm/target/lib/server/ServerManager.d.ts +19 -0
  122. package/dist/esm/target/lib/server/consts.d.ts +3 -0
  123. package/dist/esm/target/lib/server/consts.js +3 -0
  124. package/dist/esm/target/lib/web/input.d.ts +21 -0
  125. package/dist/esm/target/lib/web/input.js +4 -0
  126. package/dist/esm/target/node-core-cli/NodeCoreCLIManager.js +2 -2
  127. package/dist/esm/target/node-express-server/NodeExpressServerManager.js +5 -0
  128. package/dist/esm/target/node-express-server/lib/AuthCookieCreator.js +1 -1
  129. package/dist/esm/target/node-express-server/middlewares/AuthenticationCheckerMiddlewareBuilder.js +1 -0
  130. package/dist/esm/target/node-express-server/middlewares/PublicApiKeyCheckerMiddlewareBuilder.js +1 -0
  131. package/dist/esm/target/node-express-server/middlewares/RequestCheckerMiddlewareBuilder.js +1 -0
  132. package/dist/esm/target/node-express-server/middlewares/RequestHandlerMiddlewareBuilder.js +8 -0
  133. package/dist/esm/target/node-express-server/middlewares/RequestLoggerMiddlewareBuilder.js +1 -0
  134. package/dist/esm/target/node-mcp-server/NodeLocalStdioMCPServerManager.d.ts +10 -0
  135. package/dist/esm/target/node-mcp-server/NodeLocalStdioMCPServerManager.js +14 -0
  136. package/dist/esm/target/react-native-pure/UCForm.js +2 -2
  137. package/dist/esm/target/react-native-pure/UCFormField.d.ts +2 -9
  138. package/dist/esm/target/react-native-pure/UCFormField.js +9 -20
  139. package/dist/esm/target/react-native-pure/UCFormFieldControl.d.ts +3 -10
  140. package/dist/esm/target/react-native-pure/UCFormFieldControl.js +9 -8
  141. package/dist/esm/target/react-native-pure/UCFormFieldDesc.d.ts +2 -5
  142. package/dist/esm/target/react-native-pure/UCFormFieldDesc.js +2 -2
  143. package/dist/esm/target/react-native-pure/UCFormFieldErr.d.ts +2 -6
  144. package/dist/esm/target/react-native-pure/UCFormFieldLabel.d.ts +2 -5
  145. package/dist/esm/target/react-native-pure/UCFormFieldLabel.js +2 -2
  146. package/dist/esm/target/react-native-pure/UCFormSubmitControl.d.ts +2 -7
  147. package/dist/esm/target/react-native-pure/UCFormSubmitControl.js +1 -1
  148. package/dist/esm/target/react-web-pure/UCForm.js +1 -1
  149. package/dist/esm/target/react-web-pure/UCFormField.d.ts +2 -9
  150. package/dist/esm/target/react-web-pure/UCFormField.js +9 -20
  151. package/dist/esm/target/react-web-pure/UCFormFieldControl.d.ts +3 -10
  152. package/dist/esm/target/react-web-pure/UCFormFieldControl.js +20 -5
  153. package/dist/esm/target/react-web-pure/UCFormFieldDesc.d.ts +2 -5
  154. package/dist/esm/target/react-web-pure/UCFormFieldDesc.js +2 -2
  155. package/dist/esm/target/react-web-pure/UCFormFieldErr.d.ts +2 -6
  156. package/dist/esm/target/react-web-pure/UCFormFieldLabel.d.ts +2 -5
  157. package/dist/esm/target/react-web-pure/UCFormFieldLabel.js +3 -3
  158. package/dist/esm/target/react-web-pure/UCFormSubmitControl.d.ts +2 -4
  159. package/dist/esm/target/react-web-pure/UCFormSubmitControl.js +1 -1
  160. package/dist/esm/testing/AppTester.d.ts +4 -0
  161. package/dist/esm/testing/AppTester.js +16 -0
  162. package/dist/esm/testing/AppTesterConfigurator.d.ts +68 -0
  163. package/dist/esm/testing/UCDataStoreTester.d.ts +9 -0
  164. package/dist/esm/testing/UCDataStoreTester.js +13 -0
  165. package/dist/esm/testing/impl/SimpleAppDocsEmitter.js +22 -2
  166. package/dist/esm/testing/impl/SimpleAppTesterConfigurator.js +1 -0
  167. package/dist/esm/testing/impl/SimpleHTMLAppTestReportEmitter.js +9 -3
  168. package/dist/esm/testing/impl/TypeScriptLibUCDefASTParser.js +12 -4
  169. package/dist/esm/testing/impl/VitestAppTestSuiteEmitter.js +6 -0
  170. package/dist/esm/testing/opts.d.ts +38 -0
  171. package/dist/esm/testing/opts.js +1 -1
  172. package/dist/esm/testing/uc-input.js +2 -0
  173. package/dist/esm/testing/workers/AppTesterCtxInitializer.js +7 -0
  174. package/dist/esm/testing/workers/UCExecutor.js +1 -0
  175. package/dist/esm/testing/workers/checkers/AppIndexChecker.js +1 -0
  176. package/dist/esm/testing/workers/checkers/UCDefSourcesChecker.js +4 -0
  177. package/dist/esm/uc/UC.js +19 -1
  178. package/dist/esm/uc/UCInputField.d.ts +28 -0
  179. package/dist/esm/uc/UCInputField.js +42 -0
  180. package/dist/esm/uc/data.d.ts +3 -0
  181. package/dist/esm/uc/def.d.ts +7 -0
  182. package/dist/esm/uc/exec.d.ts +39 -0
  183. package/dist/esm/uc/exec.js +29 -0
  184. package/dist/esm/uc/ext.d.ts +30 -1
  185. package/dist/esm/uc/helpers/UCOutputBuilder.js +5 -0
  186. package/dist/esm/uc/helpers/UCOutputReader.js +3 -1
  187. package/dist/esm/uc/impl/HTTPUCTransporter.js +4 -0
  188. package/dist/esm/uc/impl/InMemoryUCDataStore.js +7 -0
  189. package/dist/esm/uc/impl/KnexUCDataStore.d.ts +4 -0
  190. package/dist/esm/uc/impl/KnexUCDataStore.js +14 -0
  191. package/dist/esm/uc/impl/SimpleUCManager.js +6 -0
  192. package/dist/esm/uc/input-field.d.ts +60 -0
  193. package/dist/esm/uc/input-field.js +33 -0
  194. package/dist/esm/uc/input.d.ts +24 -0
  195. package/dist/esm/uc/lifecycle/client/IdleClientMain.js +1 -0
  196. package/dist/esm/uc/lifecycle/server/IdleServerMain.js +2 -0
  197. package/dist/esm/uc/manager.d.ts +11 -0
  198. package/dist/esm/uc/metadata.d.ts +10 -0
  199. package/dist/esm/uc/opi-layout.d.ts +3 -0
  200. package/dist/esm/uc/opi.d.ts +8 -0
  201. package/dist/esm/uc/output-field.d.ts +9 -0
  202. package/dist/esm/uc/output-part.d.ts +22 -0
  203. package/dist/esm/uc/output.d.ts +3 -0
  204. package/dist/esm/uc/policies/RoleRegularUCPolicy.js +1 -0
  205. package/dist/esm/uc/policies/funcs.js +1 -0
  206. package/dist/esm/uc/policy.d.ts +22 -0
  207. package/dist/esm/uc/sec.d.ts +9 -0
  208. package/dist/esm/uc/server.d.ts +10 -0
  209. package/dist/esm/uc/settings.d.ts +25 -0
  210. package/dist/esm/uc/side-effect.d.ts +16 -0
  211. package/dist/esm/uc/side-effect.js +16 -0
  212. package/dist/esm/uc/utils/rInput.d.ts +12 -0
  213. package/dist/esm/uc/utils/rInput.js +2 -0
  214. package/dist/esm/uc/utils/rVal.d.ts +25 -0
  215. package/dist/esm/uc/utils/rVal.js +27 -0
  216. package/dist/esm/uc/utils/recIs.d.ts +9 -0
  217. package/dist/esm/uc/utils/recIs.js +12 -1
  218. package/dist/esm/uc/utils/stripUCDLifecycleServer.d.ts +13 -0
  219. package/dist/esm/uc/utils/stripUCDLifecycleServer.js +17 -0
  220. package/dist/esm/uc/utils/ucifcoIsForArray.d.ts +6 -0
  221. package/dist/esm/uc/utils/ucifcoIsForArray.js +6 -0
  222. package/dist/esm/uc/workers/SimpleAggregateFinder.d.ts +12 -0
  223. package/dist/esm/uc/workers/SimpleAggregateFinder.js +12 -0
  224. package/dist/esm/uc/workers/UCBuilder.d.ts +7 -0
  225. package/dist/esm/uc/workers/UCBuilder.js +7 -0
  226. package/dist/esm/uc/workers/UCExecChecker.js +2 -0
  227. package/dist/esm/uc/workers/UCInputFilesProcessor.js +10 -4
  228. package/dist/esm/uc/workers/UCOutputFilesProcessor.js +6 -2
  229. package/dist/esm/utils/async/sleep.d.ts +10 -0
  230. package/dist/esm/utils/async/sleep.js +10 -0
  231. package/dist/esm/utils/http/appendData.js +5 -1
  232. package/dist/esm/utils/ioc/ContainerPrinter.js +2 -0
  233. package/dist/esm/utils/ioc/bindCommon.js +4 -0
  234. package/dist/esm/utils/ioc/bindNodeCLI.js +2 -0
  235. package/dist/esm/utils/ioc/bindNodeCore.js +1 -0
  236. package/dist/esm/utils/ioc/bindProduct.js +2 -0
  237. package/dist/esm/utils/ioc/bindRN.js +1 -0
  238. package/dist/esm/utils/ioc/bindServer.js +1 -0
  239. package/dist/esm/utils/ioc/bindWeb.js +2 -0
  240. package/dist/esm/utils/ioc/container.js +6 -0
  241. package/dist/esm/utils/numbers/units.js +3 -0
  242. package/dist/esm/utils/types/funcs.d.ts +35 -0
  243. package/dist/esm/utils/types/funcs.js +35 -0
  244. package/dist/esm/utils/types/utility-types.d.ts +17 -0
  245. package/dist/esm/utils/types/utility-types.js +1 -0
  246. package/package.json +13 -14
@@ -31,9 +31,28 @@ export interface ServerManagerSettings extends ServerManagerAuthSettings, Settin
31
31
  }
32
32
  export interface ServerManager extends Initializable {
33
33
  overrideUCManager(ucManager: UCManager): void;
34
+ /**
35
+ * Mount the use case as an endpoint
36
+ * @param appManifest
37
+ * @param ucd
38
+ * @param contract
39
+ */
34
40
  mount<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(appManifest: AppManifest, ucd: UCDef<I, OPI0, OPI1>, contract: UCHTTPContract): Promise<void>;
41
+ /**
42
+ * Mount the static directory at `/`
43
+ * @param dirPath
44
+ */
35
45
  mountStaticDir(dirPath: DirPath): Promise<void>;
46
+ /**
47
+ * Start listening on the specific host and port
48
+ */
36
49
  start(): Promise<void>;
50
+ /**
51
+ * Stop listening
52
+ */
37
53
  stop(): Promise<void>;
54
+ /**
55
+ * Warm up with things that must be done after the routes have been defined (e.g. error middleware, etc.)
56
+ */
38
57
  warmUp(): Promise<void>;
39
58
  }
@@ -1,2 +1,5 @@
1
1
  import type { ServerManagerSettings } from './ServerManager.js';
2
+ /**
3
+ * @see TARGET_DEFAULT_SERVER_CLIENT_MANAGER_SETTINGS
4
+ */
2
5
  export declare const TARGET_DEFAULT_SERVER_MANAGER_SETTINGS: ServerManagerSettings;
@@ -1,3 +1,6 @@
1
+ /**
2
+ * @see TARGET_DEFAULT_SERVER_CLIENT_MANAGER_SETTINGS
3
+ */
1
4
  export const TARGET_DEFAULT_SERVER_MANAGER_SETTINGS = {
2
5
  server_basic_auth_entries: {},
3
6
  server_binding_host: 'localhost',
@@ -1,9 +1,30 @@
1
1
  import { type DataType, type ErrorMessage, type HTMLInputType } from '../../../dt/index.js';
2
2
  import { type UCExecState, type UCInputField } from '../../../uc/index.js';
3
3
  export interface HTMLInputDef {
4
+ /**
5
+ * Internal types that are not part of the W3C spec
6
+ *
7
+ * @see node_modules/@types/react/index.d.ts#InputHTMLAttributes
8
+ */
4
9
  internal?: {
10
+ /**
11
+ * When a fiels is `multiline`, you should probably render a `<textarea />` in place of an `<input />`.
12
+ */
5
13
  multiline?: boolean | undefined;
6
14
  };
15
+ /**
16
+ * Fields that are part of the W3C spec
17
+ *
18
+ * These are safe to destructure directly in an `<input />` component.
19
+ *
20
+ * Note that they come with their camel case form, à la React.
21
+ * The reason is that it's easier to transform this to the original spec (`maxLength` => `maxlength`) vs doing the opposite (`maxlength` > `maxLength`).
22
+ * In the first case, we can simply call `.toLowerCase()` on the keys, while in the second, we'd need a dedicated function that "camel-cases" a string.
23
+ *
24
+ * @example `<input {...attrs.spec} />`
25
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attributes
26
+ * @see node_modules/@types/react/index.d.ts `InputHTMLAttributes`
27
+ */
7
28
  spec?: {
8
29
  'aria-errormessage'?: string | undefined;
9
30
  'aria-invalid'?: boolean | undefined;
@@ -6,6 +6,7 @@ export function htmlInputDef(field, execState, errMsg) {
6
6
  spec: {},
7
7
  };
8
8
  if (!def.internal || !def.spec) {
9
+ // Just a guard to safely type the rest of the function without using !
9
10
  return def;
10
11
  }
11
12
  const { key, def: fDef } = field;
@@ -13,11 +14,14 @@ export function htmlInputDef(field, execState, errMsg) {
13
14
  def.spec.disabled = ucIsDisabled(execState);
14
15
  def.spec.id = ucifId(key);
15
16
  def.spec.name = key;
17
+ // Testing the types by usage probability to make the if/else evaluation stop ideally earlier
16
18
  if (fType instanceof TString) {
17
19
  const constraints = fType.getConstraints();
18
20
  if (constraints) {
19
21
  def.spec.maxLength = constraints.maxLength;
20
22
  def.spec.minLength = constraints.minLength;
23
+ // https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/pattern
24
+ // > No forward slashes should be specified around the pattern text
21
25
  def.spec.pattern = constraints.format?.regexp?.source;
22
26
  }
23
27
  def.internal.multiline = fType.isPotentiallyLong();
@@ -57,7 +57,7 @@ let NodeCoreCLIManager = class NodeCoreCLIManager {
57
57
  }
58
58
  parseArgsConfig(uc) {
59
59
  const config = {
60
- allowPositionals: true,
60
+ allowPositionals: true, // For the command name
61
61
  strict: true,
62
62
  };
63
63
  if (uc.inputFields.length === 0) {
@@ -68,7 +68,7 @@ let NodeCoreCLIManager = class NodeCoreCLIManager {
68
68
  const { def } = f;
69
69
  let defaultValue = def.type.getDefaultValue();
70
70
  if (typeof defaultValue === 'number') {
71
- defaultValue = defaultValue.toString();
71
+ defaultValue = defaultValue.toString(); // parseArgs does not accept numbers as default value
72
72
  }
73
73
  const [isRepeatable, _max] = ucifRepeatability(def);
74
74
  const type = def.type instanceof TBoolean ? 'boolean' : 'string';
@@ -77,6 +77,8 @@ let NodeExpressServerManager = class NodeExpressServerManager {
77
77
  async init() {
78
78
  this.runtime = express();
79
79
  this.runtime.use(this.helmetMB.exec({}));
80
+ // TODO : Add FileStorageManager (Local, S3, FSBucket)
81
+ // Right now, the files are only stored locally. We need more flexibility. Maybe we can also install https://imgproxy.net.
80
82
  this.runtime.use(fileUpload({
81
83
  createParentPath: true,
82
84
  debug: this.s().logger_level === 'trace',
@@ -125,6 +127,8 @@ let NodeExpressServerManager = class NodeExpressServerManager {
125
127
  if (!this.server?.listening) {
126
128
  return;
127
129
  }
130
+ // As stated in the docs of `close`, only awaiting `.close` is not enough to make sure all the connections are closed.
131
+ // Hence the wrapping in a promise, where the callback is called when the 'close' event is emitted.
128
132
  return new Promise((resolve, reject) => {
129
133
  if (!this.server) {
130
134
  return resolve();
@@ -138,6 +142,7 @@ let NodeExpressServerManager = class NodeExpressServerManager {
138
142
  });
139
143
  }
140
144
  async warmUp() {
145
+ // Always at the "almost" last position to handle all the errors (from other middlewares and request handlers)
141
146
  this.runtime.use(this.errorMB.exec({}));
142
147
  }
143
148
  async createServer() {
@@ -35,7 +35,7 @@ let AuthCookieCreator = class AuthCookieCreator {
35
35
  httpOnly: this.s().server_cookies_http_only,
36
36
  sameSite: this.s().server_cookies_same_site,
37
37
  secure: this.s().server_cookies_secure,
38
- signed: false,
38
+ signed: false, // Not signing to keep it simple and btw, the JWT is already signed
39
39
  },
40
40
  val: jwt,
41
41
  };
@@ -51,6 +51,7 @@ let AuthenticationCheckerMiddlewareBuilder = class AuthenticationCheckerMiddlewa
51
51
  nextFn();
52
52
  }
53
53
  catch (err) {
54
+ // Always catch otherwise it breaks the middleware chain and hangs forever
54
55
  nextFn(err);
55
56
  }
56
57
  };
@@ -35,6 +35,7 @@ let PublicApiKeyCheckerMiddlewareBuilder = class PublicApiKeyCheckerMiddlewareBu
35
35
  nextFn();
36
36
  }
37
37
  catch (err) {
38
+ // Always catch otherwise it breaks the middleware chain and hangs forever
38
39
  nextFn(err);
39
40
  }
40
41
  };
@@ -28,6 +28,7 @@ let RequestCheckerMiddlewareBuilder = class RequestCheckerMiddlewareBuilder {
28
28
  nextFn();
29
29
  }
30
30
  catch (err) {
31
+ // Always catch otherwise it breaks the middleware chain and hangs forever
31
32
  nextFn(err);
32
33
  }
33
34
  };
@@ -49,6 +49,8 @@ let RequestHandlerMiddlewareBuilder = class RequestHandlerMiddlewareBuilder {
49
49
  if (ucor.canItem00()) {
50
50
  item = ucor.item00().item;
51
51
  }
52
+ // Be careful with this, as some are incompatible.
53
+ // For instance, if there is a REDIRECT and then a CLEAR_AUTH, the latter won't be executed as we return after the redirect.
52
54
  for (const se of sideEffects) {
53
55
  const { type } = se;
54
56
  switch (type) {
@@ -74,6 +76,7 @@ let RequestHandlerMiddlewareBuilder = class RequestHandlerMiddlewareBuilder {
74
76
  res.send(output && transform ? transform(output) : output);
75
77
  }
76
78
  catch (err) {
79
+ // Always catch otherwise it breaks the middleware chain and hangs forever
77
80
  nextFn(err);
78
81
  }
79
82
  };
@@ -82,6 +85,7 @@ let RequestHandlerMiddlewareBuilder = class RequestHandlerMiddlewareBuilder {
82
85
  switch (envelope) {
83
86
  case 'form-data': {
84
87
  const input = req.body;
88
+ // files is present when using express-fileupload
85
89
  if ('files' in req && req.files) {
86
90
  for (const [field, value] of Object.entries(req.files)) {
87
91
  input[field] = Array.isArray(value)
@@ -89,6 +93,8 @@ let RequestHandlerMiddlewareBuilder = class RequestHandlerMiddlewareBuilder {
89
93
  : this.toFile(value);
90
94
  }
91
95
  }
96
+ // TODO : Change this ugly code
97
+ // When a field has multiple values, they key is `field[]` and not `field`
92
98
  const sanitized = {};
93
99
  for (const [k, v] of Object.entries(input)) {
94
100
  const sanitizedKey = k.split('[')[0];
@@ -96,6 +102,8 @@ let RequestHandlerMiddlewareBuilder = class RequestHandlerMiddlewareBuilder {
96
102
  continue;
97
103
  }
98
104
  sanitized[sanitizedKey] = v;
105
+ // For some reason, when there is only one value, it is received as scalar and not as an array
106
+ // Even if there is only one, we want an array
99
107
  if (k.includes('[') && !Array.isArray(v)) {
100
108
  sanitized[sanitizedKey] = [v];
101
109
  }
@@ -31,6 +31,7 @@ let RequestLoggerMiddlewareBuilder = class RequestLoggerMiddlewareBuilder {
31
31
  }
32
32
  catch (err) {
33
33
  this.logger.error(err);
34
+ // Continue as usual : the user shouldn't be impacted if we have issues logging the requests
34
35
  nextFn();
35
36
  }
36
37
  };
@@ -7,6 +7,16 @@ import type { Configurable, LoggerSettings, SettingsManager } from '../../std/in
7
7
  import { UCBuilder, type UCDef, type UCHTTPContract, type UCInput, type UCManager, type UCOPIBase } from '../../uc/index.js';
8
8
  import type { ServerManager } from '../lib/server/ServerManager.js';
9
9
  type S = Pick<LoggerSettings, 'logger_level'>;
10
+ /**
11
+ * A simple MCP Server implementation
12
+ *
13
+ * Although it implements {@link ServerManager}, this implementation is not necessarily a "server".
14
+ * Indeed, it uses a local `Transport` so it must be considered the same as a {@link NodeCoreCLIManager}.
15
+ * Therefore, it calls `execClient` and not `execServer`.
16
+ * This way, Claude AI, or any other client is just a wrapper on top of it.
17
+ *
18
+ * @alpha This implementation still has lots of TODOs and has not been tested in real conditions. It needs to be stabilized before usage.
19
+ */
10
20
  export declare class NodeLocalStdioMCPServerManager implements Configurable<S>, ServerManager {
11
21
  private productManifest;
12
22
  private settingsManager;
@@ -17,6 +17,16 @@ import { inject, injectable } from 'inversify';
17
17
  import { WordingManager } from '../../i18n/index.js';
18
18
  import { UCBuilder, ucMountingPoint, ucifIsMandatory, } from '../../uc/index.js';
19
19
  import { propertyType, resError, resObj } from './funcs.js';
20
+ /**
21
+ * A simple MCP Server implementation
22
+ *
23
+ * Although it implements {@link ServerManager}, this implementation is not necessarily a "server".
24
+ * Indeed, it uses a local `Transport` so it must be considered the same as a {@link NodeCoreCLIManager}.
25
+ * Therefore, it calls `execClient` and not `execServer`.
26
+ * This way, Claude AI, or any other client is just a wrapper on top of it.
27
+ *
28
+ * @alpha This implementation still has lots of TODOs and has not been tested in real conditions. It needs to be stabilized before usage.
29
+ */
20
30
  let NodeLocalStdioMCPServerManager = class NodeLocalStdioMCPServerManager {
21
31
  productManifest;
22
32
  settingsManager;
@@ -55,6 +65,9 @@ let NodeLocalStdioMCPServerManager = class NodeLocalStdioMCPServerManager {
55
65
  });
56
66
  if (this.s().logger_level !== 'error') {
57
67
  const message = 'Set the logging_level to "error" as MCP does not want the server to log to stdout (see https://modelcontextprotocol.io/docs/tools/debugging#implementing-logging)';
68
+ // Depending on the `Logger` implementation, this.logger.error() might not write to stderr (e.g. can write to a file).
69
+ // That's why we explicitly write to stdout by calling console.error().
70
+ // biome-ignore lint/suspicious/noConsole: we want it
58
71
  console.error(new Error(message));
59
72
  }
60
73
  }
@@ -112,6 +125,7 @@ let NodeLocalStdioMCPServerManager = class NodeLocalStdioMCPServerManager {
112
125
  }
113
126
  async execRequest(request) {
114
127
  const { name, arguments: args } = request.params;
128
+ // TODO : Check authentication in some way (see if MCP handles it)
115
129
  const auth = null;
116
130
  try {
117
131
  const route = this.tools.get(name);
@@ -1,13 +1,13 @@
1
1
  import React, {} from 'react';
2
2
  import { View } from 'react-native';
3
3
  import { UCFormField } from './UCFormField.js';
4
- import { UCFormSubmitControl, } from './UCFormSubmitControl.js';
4
+ import { UCFormSubmitControl } from './UCFormSubmitControl.js';
5
5
  export function UCForm({ disabled, execState, onChange, onSubmit, uc, }) {
6
6
  const onPress = async () => {
7
7
  await onSubmit();
8
8
  };
9
9
  return (React.createElement(View, null,
10
10
  uc.inputFieldsForForm().map((f) => (React.createElement(View, { key: f.key },
11
- React.createElement(UCFormField, { disabled: disabled, execState: execState, field: f, onChange: onChange })))),
11
+ React.createElement(UCFormField, { disabled: disabled, execState: execState, f: f, onChange: onChange })))),
12
12
  React.createElement(UCFormSubmitControl, { execState: execState, disabled: disabled, onPress: onPress, uc: uc })));
13
13
  }
@@ -1,11 +1,4 @@
1
1
  import { type ReactElement } from 'react';
2
2
  import type { DataType } from '../../dt/index.js';
3
- import { type Props as FormFieldControlProps } from './UCFormFieldControl.js';
4
- import { type Props as FormFieldLabelProps } from './UCFormFieldLabel.js';
5
- declare const ELEMENTS: readonly ["control", "desc", "err", "label"];
6
- type Element = (typeof ELEMENTS)[number];
7
- type Props<T extends DataType> = FormFieldControlProps<T> & FormFieldLabelProps<T> & {
8
- only?: Element[];
9
- };
10
- export declare function UCFormField<T extends DataType>({ disabled, execState, field, onChange: onChangeBase, only, }: Props<T>): ReactElement;
11
- export {};
3
+ import { type UCFormFieldProps } from '../lib/react/form.js';
4
+ export declare function UCFormField<T extends DataType>({ disabled, execState, f, onChange: onChangeBase, only, }: UCFormFieldProps<T>): ReactElement;
@@ -1,32 +1,21 @@
1
1
  import React, { useState } from 'react';
2
2
  import { useDIContext } from '../lib/react/DIContextProvider.js';
3
- import { UCFormFieldControl, } from './UCFormFieldControl.js';
3
+ import { UC_FORM_FIELD_ELEMENTS, validateFormField, } from '../lib/react/form.js';
4
+ import { UCFormFieldControl } from './UCFormFieldControl.js';
4
5
  import { UCFormFieldDesc } from './UCFormFieldDesc.js';
5
6
  import { UCFormFieldErr } from './UCFormFieldErr.js';
6
- import { UCFormFieldLabel, } from './UCFormFieldLabel.js';
7
- const ELEMENTS = ['control', 'desc', 'err', 'label'];
8
- export function UCFormField({ disabled, execState, field, onChange: onChangeBase, only, }) {
7
+ import { UCFormFieldLabel } from './UCFormFieldLabel.js';
8
+ export function UCFormField({ disabled, execState, f, onChange: onChangeBase, only, }) {
9
9
  const { i18nManager } = useDIContext();
10
- const { type } = field.def;
11
10
  const [errMsg, setErrMsg] = useState(null);
12
- const elements = only ?? ELEMENTS;
13
11
  const onChange = (f, op, v) => {
14
- setErrMsg(null);
15
- const vArr = Array.isArray(v) ? v : [v];
16
- for (const vv of vArr) {
17
- const validation = type.assign(vv).validate();
18
- const violation = validation.get();
19
- if (violation) {
20
- const [key, expected] = violation;
21
- setErrMsg(i18nManager.t(key, { vars: { expected } }));
22
- break;
23
- }
24
- }
12
+ setErrMsg(validateFormField(i18nManager, f, v));
25
13
  onChangeBase(f, op, v);
26
14
  };
15
+ const elements = only ?? UC_FORM_FIELD_ELEMENTS;
27
16
  return (React.createElement(React.Fragment, null,
28
- elements.includes('label') && React.createElement(UCFormFieldLabel, { field: field }),
29
- elements.includes('control') && (React.createElement(UCFormFieldControl, { disabled: disabled, execState: execState, field: field, onChange: onChange })),
17
+ elements.includes('label') && React.createElement(UCFormFieldLabel, { f: f }),
18
+ elements.includes('control') && (React.createElement(UCFormFieldControl, { disabled: disabled, execState: execState, f: f, onChange: onChange })),
30
19
  elements.includes('err') && errMsg && (React.createElement(UCFormFieldErr, { errMsg: errMsg })),
31
- elements.includes('desc') && React.createElement(UCFormFieldDesc, { field: field })));
20
+ elements.includes('desc') && React.createElement(UCFormFieldDesc, { f: f })));
32
21
  }
@@ -1,11 +1,4 @@
1
1
  import { type ReactElement } from 'react';
2
- import type { DataType, ErrorMessage } from '../../dt/index.js';
3
- import { type UCInputField } from '../../uc/index.js';
4
- import type { UCFormFieldControlOnChange } from '../lib/react/form.js';
5
- import type { UCPanelState } from '../lib/react/panel.js';
6
- export type Props<T extends DataType> = UCPanelState & {
7
- errMsg?: ErrorMessage | null;
8
- field: UCInputField<T>;
9
- onChange: UCFormFieldControlOnChange<T>;
10
- };
11
- export declare function UCFormFieldControl<T extends DataType>({ errMsg, execState, field, onChange: onChangeBase, }: Props<T>): ReactElement;
2
+ import type { DataType } from '../../dt/index.js';
3
+ import type { UCFormFieldControlProps } from '../lib/react/form.js';
4
+ export declare function UCFormFieldControl<T extends DataType>({ errMsg, execState, f, onChange: onChangeBase, }: UCFormFieldControlProps<T>): ReactElement;
@@ -4,22 +4,23 @@ import { UCInputFieldChangeOperator, ucifRepeatability, } from '../../uc/index.j
4
4
  import { isBlank } from '../../utils/index.js';
5
5
  import { rnInputDef } from '../lib/rn/input.js';
6
6
  const MULTIPLE_VALUES_SEPARATOR = ',';
7
- export function UCFormFieldControl({ errMsg = null, execState, field, onChange: onChangeBase, }) {
8
- const [internalValue, setInternalValue] = useState(field.getValue());
7
+ export function UCFormFieldControl({ errMsg = null, execState, f, onChange: onChangeBase, }) {
8
+ const [internalValue, setInternalValue] = useState(f.getValue());
9
+ // biome-ignore lint/correctness/useExhaustiveDependencies: false positive : It is actually necessary (only `field` does not trigger the effect)
9
10
  useEffect(() => {
10
- setInternalValue(field.getValue());
11
- }, [field.getValue()]);
12
- const attrs = rnInputDef(field, execState, errMsg);
11
+ setInternalValue(f.getValue());
12
+ }, [f.getValue()]);
13
+ const attrs = rnInputDef(f, execState, errMsg);
13
14
  const onChangeText = (value) => {
14
- const [isRepeatable] = ucifRepeatability(field.def);
15
+ const [isRepeatable] = ucifRepeatability(f.def);
15
16
  if (isRepeatable && typeof value === 'string') {
16
17
  const valueArr = value
17
18
  .split(MULTIPLE_VALUES_SEPARATOR)
18
19
  .map((v) => v.trim());
19
- onChangeBase(field, UCInputFieldChangeOperator.SET, valueArr);
20
+ onChangeBase(f, UCInputFieldChangeOperator.SET, valueArr);
20
21
  }
21
22
  else {
22
- onChangeBase(field, UCInputFieldChangeOperator.SET, value);
23
+ onChangeBase(f, UCInputFieldChangeOperator.SET, value);
23
24
  }
24
25
  setInternalValue(value);
25
26
  };
@@ -1,7 +1,4 @@
1
1
  import { type ReactElement } from 'react';
2
2
  import type { DataType } from '../../dt/index.js';
3
- import type { UCInputField } from '../../uc/index.js';
4
- export interface Props<T extends DataType> {
5
- field: UCInputField<T>;
6
- }
7
- export declare function UCFormFieldDesc<T extends DataType>({ field, }: Props<T>): ReactElement | null;
3
+ import type { UCFormFieldDescProps } from '../lib/react/form.js';
4
+ export declare function UCFormFieldDesc<T extends DataType>({ f, }: UCFormFieldDescProps<T>): ReactElement | null;
@@ -1,9 +1,9 @@
1
1
  import React, {} from 'react';
2
2
  import { Text } from 'react-native';
3
3
  import { useDIContext } from '../lib/react/DIContextProvider.js';
4
- export function UCFormFieldDesc({ field, }) {
4
+ export function UCFormFieldDesc({ f, }) {
5
5
  const { wordingManager } = useDIContext();
6
- const { desc } = wordingManager.ucif(field);
6
+ const { desc } = wordingManager.ucif(f);
7
7
  if (!desc) {
8
8
  return null;
9
9
  }
@@ -1,7 +1,3 @@
1
1
  import { type ReactElement } from 'react';
2
- import type { ErrorMessage } from '../../dt/index.js';
3
- interface Props {
4
- errMsg: ErrorMessage;
5
- }
6
- export declare function UCFormFieldErr({ errMsg }: Props): ReactElement;
7
- export {};
2
+ import type { UCFormFieldErrProps } from '../lib/react/form.js';
3
+ export declare function UCFormFieldErr({ errMsg }: UCFormFieldErrProps): ReactElement;
@@ -1,7 +1,4 @@
1
1
  import { type ReactElement } from 'react';
2
2
  import type { DataType } from '../../dt/index.js';
3
- import type { UCInputField } from '../../uc/index.js';
4
- export interface Props<T extends DataType> {
5
- field: UCInputField<T>;
6
- }
7
- export declare function UCFormFieldLabel<T extends DataType>({ field, }: Props<T>): ReactElement;
3
+ import type { UCFormFieldLabelProps } from '../lib/react/form.js';
4
+ export declare function UCFormFieldLabel<T extends DataType>({ f, }: UCFormFieldLabelProps<T>): ReactElement;
@@ -1,8 +1,8 @@
1
1
  import React, {} from 'react';
2
2
  import { Text } from 'react-native';
3
3
  import { useDIContext } from '../lib/react/DIContextProvider.js';
4
- export function UCFormFieldLabel({ field, }) {
4
+ export function UCFormFieldLabel({ f, }) {
5
5
  const { wordingManager } = useDIContext();
6
- const { label } = wordingManager.ucif(field);
6
+ const { label } = wordingManager.ucif(f);
7
7
  return React.createElement(Text, null, label);
8
8
  }
@@ -1,9 +1,4 @@
1
1
  import { type ReactElement } from 'react';
2
2
  import type { UCInput, UCOPIBase } from '../../uc/index.js';
3
- import type { UCPanelCtx } from '../lib/react/panel.js';
4
- export type UCFormSubmitOnPress = () => Promise<void>;
5
- type Props<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> = UCPanelCtx<I, OPI0, OPI1> & {
6
- onPress?: UCFormSubmitOnPress;
7
- };
8
- export declare function UCFormSubmitControl<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>({ execState, disabled, onPress, uc }: Props<I, OPI0, OPI1>): ReactElement;
9
- export {};
3
+ import type { UCFormSubmitControlProps } from '../lib/react/form.js';
4
+ export declare function UCFormSubmitControl<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>({ execState, disabled, onPress, uc, }: UCFormSubmitControlProps<I, OPI0, OPI1>): ReactElement;
@@ -1,7 +1,7 @@
1
1
  import React, {} from 'react';
2
2
  import { Pressable, Text } from 'react-native';
3
3
  import { useDIContext } from '../lib/react/DIContextProvider.js';
4
- export function UCFormSubmitControl({ execState, disabled, onPress, uc }) {
4
+ export function UCFormSubmitControl({ execState, disabled, onPress, uc, }) {
5
5
  const { wordingManager } = useDIContext();
6
6
  return (React.createElement(Pressable, { onPress: onPress, disabled: disabled },
7
7
  React.createElement(Text, null, wordingManager.ucISubmit(uc.def, execState))));
@@ -12,6 +12,6 @@ export function UCForm({ clearAfterExec, disabled, execState, onChange, onSubmit
12
12
  };
13
13
  return (React.createElement("form", { onSubmit: onSubmit, ref: formRef },
14
14
  uc.inputFieldsForForm().map((f) => (React.createElement("div", { key: f.key },
15
- React.createElement(UCFormField, { disabled: disabled, execState: execState, field: f, onChange: onChange })))),
15
+ React.createElement(UCFormField, { disabled: disabled, execState: execState, f: f, onChange: onChange })))),
16
16
  React.createElement(UCFormSubmitControl, { execState: execState, disabled: disabled, uc: uc })));
17
17
  }
@@ -1,11 +1,4 @@
1
1
  import { type ReactElement } from 'react';
2
2
  import type { DataType } from '../../dt/index.js';
3
- import { type Props as FormFieldControlProps } from './UCFormFieldControl.js';
4
- import { type Props as FormFieldLabelProps } from './UCFormFieldLabel.js';
5
- declare const ELEMENTS: readonly ["control", "desc", "err", "label"];
6
- type Element = (typeof ELEMENTS)[number];
7
- type Props<T extends DataType> = FormFieldControlProps<T> & FormFieldLabelProps<T> & {
8
- only?: Element[];
9
- };
10
- export declare function UCFormField<T extends DataType>({ disabled, execState, field, onChange: onChangeBase, only, }: Props<T>): ReactElement;
11
- export {};
3
+ import { type UCFormFieldProps } from '../lib/react/form.js';
4
+ export declare function UCFormField<T extends DataType>({ disabled, execState, f, onChange: onChangeBase, only, }: UCFormFieldProps<T>): ReactElement;
@@ -1,32 +1,21 @@
1
1
  import React, { useState } from 'react';
2
2
  import { useDIContext } from '../lib/react/DIContextProvider.js';
3
- import { UCFormFieldControl, } from './UCFormFieldControl.js';
3
+ import { UC_FORM_FIELD_ELEMENTS, validateFormField, } from '../lib/react/form.js';
4
+ import { UCFormFieldControl } from './UCFormFieldControl.js';
4
5
  import { UCFormFieldDesc } from './UCFormFieldDesc.js';
5
6
  import { UCFormFieldErr } from './UCFormFieldErr.js';
6
- import { UCFormFieldLabel, } from './UCFormFieldLabel.js';
7
- const ELEMENTS = ['control', 'desc', 'err', 'label'];
8
- export function UCFormField({ disabled, execState, field, onChange: onChangeBase, only, }) {
7
+ import { UCFormFieldLabel } from './UCFormFieldLabel.js';
8
+ export function UCFormField({ disabled, execState, f, onChange: onChangeBase, only, }) {
9
9
  const { i18nManager } = useDIContext();
10
- const { type } = field.def;
11
10
  const [errMsg, setErrMsg] = useState(null);
12
- const elements = only ?? ELEMENTS;
13
11
  const onChange = (f, op, v) => {
14
- setErrMsg(null);
15
- const vArr = Array.isArray(v) ? v : [v];
16
- for (const vv of vArr) {
17
- const validation = type.assign(vv).validate();
18
- const violation = validation.get();
19
- if (violation) {
20
- const [key, expected] = violation;
21
- setErrMsg(i18nManager.t(key, { vars: { expected } }));
22
- break;
23
- }
24
- }
12
+ setErrMsg(validateFormField(i18nManager, f, v));
25
13
  onChangeBase(f, op, v);
26
14
  };
15
+ const elements = only ?? UC_FORM_FIELD_ELEMENTS;
27
16
  return (React.createElement(React.Fragment, null,
28
- elements.includes('label') && React.createElement(UCFormFieldLabel, { field: field }),
29
- elements.includes('control') && (React.createElement(UCFormFieldControl, { disabled: disabled, execState: execState, field: field, onChange: onChange })),
17
+ elements.includes('label') && React.createElement(UCFormFieldLabel, { f: f }),
18
+ elements.includes('control') && (React.createElement(UCFormFieldControl, { disabled: disabled, execState: execState, f: f, onChange: onChange })),
30
19
  elements.includes('err') && errMsg && (React.createElement(UCFormFieldErr, { errMsg: errMsg })),
31
- elements.includes('desc') && React.createElement(UCFormFieldDesc, { field: field })));
20
+ elements.includes('desc') && React.createElement(UCFormFieldDesc, { f: f })));
32
21
  }
@@ -1,11 +1,4 @@
1
1
  import { type ReactElement } from 'react';
2
- import type { DataType, ErrorMessage } from '../../dt/index.js';
3
- import { type UCInputField } from '../../uc/index.js';
4
- import type { UCFormFieldControlOnChange } from '../lib/react/form.js';
5
- import type { UCPanelState } from '../lib/react/panel.js';
6
- export type Props<T extends DataType> = UCPanelState & {
7
- errMsg?: ErrorMessage | null;
8
- field: UCInputField<T>;
9
- onChange: UCFormFieldControlOnChange<T>;
10
- };
11
- export declare function UCFormFieldControl<T extends DataType>({ errMsg, execState, field, onChange: onChangeBase, }: Props<T>): ReactElement;
2
+ import type { DataType } from '../../dt/index.js';
3
+ import type { UCFormFieldControlProps } from '../lib/react/form.js';
4
+ export declare function UCFormFieldControl<T extends DataType>({ errMsg, execState, f, onChange: onChangeBase, }: UCFormFieldControlProps<T>): ReactElement;