libmodulor 0.20.0 → 0.22.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 (110) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +1 -1
  3. package/dist/esm/apps/Helper/src/lib/project.js +7 -7
  4. package/dist/esm/apps/Helper/src/ucds/CreateProjectUCD.d.ts +1 -0
  5. package/dist/esm/apps/Helper/src/ucds/CreateProjectUCD.js +20 -13
  6. package/dist/esm/dt/DataType.d.ts +2 -1
  7. package/dist/esm/dt/DataTypes.js +1 -0
  8. package/dist/esm/dt/Validation.js +1 -1
  9. package/dist/esm/dt/final/TGitSSHURL.d.ts +4 -3
  10. package/dist/esm/dt/final/TGitSSHURL.js +1 -1
  11. package/dist/esm/dt/final/TSSHPrivateKey.js +1 -3
  12. package/dist/esm/dt/final/TTransportType.d.ts +8 -0
  13. package/dist/esm/dt/final/TTransportType.js +16 -0
  14. package/dist/esm/dt/index.d.ts +1 -0
  15. package/dist/esm/dt/index.js +1 -0
  16. package/dist/esm/error/funcs.d.ts +2 -0
  17. package/dist/esm/error/funcs.js +19 -0
  18. package/dist/esm/error/index.d.ts +1 -0
  19. package/dist/esm/error/index.js +1 -0
  20. package/dist/esm/index.d.ts +2 -0
  21. package/dist/esm/index.js +2 -0
  22. package/dist/esm/std/HTTPAPICallExecutor.d.ts +16 -7
  23. package/dist/esm/std/HTTPAPICaller.d.ts +8 -1
  24. package/dist/esm/std/LLMManager.d.ts +20 -3
  25. package/dist/esm/std/impl/ConsoleLogger.js +2 -2
  26. package/dist/esm/std/impl/FakeClockManager.d.ts +6 -0
  27. package/dist/esm/std/impl/FakeClockManager.js +19 -0
  28. package/dist/esm/std/impl/FakeHTTPAPICallExecutor.js +19 -18
  29. package/dist/esm/std/impl/FakeLLMManager.d.ts +4 -0
  30. package/dist/esm/std/impl/FakeLLMManager.js +40 -0
  31. package/dist/esm/std/impl/FetchHTTPAPICallExecutor.js +1 -1
  32. package/dist/esm/std/impl/MistralAILLMManager.js +12 -0
  33. package/dist/esm/std/impl/NodeFormDataBuilder.js +3 -1
  34. package/dist/esm/std/impl/OllamaLLMManager.d.ts +7 -2
  35. package/dist/esm/std/impl/OllamaLLMManager.js +32 -5
  36. package/dist/esm/std/impl/OpenAILLMManager.js +9 -0
  37. package/dist/esm/std/impl/SimpleHTTPAPICaller.d.ts +7 -3
  38. package/dist/esm/std/impl/SimpleHTTPAPICaller.js +67 -16
  39. package/dist/esm/target/lib/cli/CommandExecutor.js +11 -3
  40. package/dist/esm/target/lib/react/UCPanel.d.ts +4 -2
  41. package/dist/esm/target/lib/react/UCPanel.js +2 -6
  42. package/dist/esm/target/lib/react/form.d.ts +5 -6
  43. package/dist/esm/target/lib/react/form.js +7 -10
  44. package/dist/esm/target/lib/react/useUC.d.ts +4 -4
  45. package/dist/esm/target/lib/server/ServerRequestHandler.d.ts +3 -2
  46. package/dist/esm/target/lib/server/ServerRequestHandler.js +2 -2
  47. package/dist/esm/target/lib/server-express/funcs.js +52 -1
  48. package/dist/esm/target/lib/server-hono/funcs.js +65 -2
  49. package/dist/esm/target/node-mcp-server/NodeLocalStdioMCPServerManager.js +1 -0
  50. package/dist/esm/target/react-native-pure/UCForm.d.ts +1 -1
  51. package/dist/esm/target/react-native-pure/UCForm.js +2 -2
  52. package/dist/esm/target/react-native-pure/UCFormField.d.ts +1 -1
  53. package/dist/esm/target/react-native-pure/UCFormField.js +3 -4
  54. package/dist/esm/target/react-native-pure/UCFormFieldControl.js +13 -7
  55. package/dist/esm/target/react-web-pure/UCForm.d.ts +1 -1
  56. package/dist/esm/target/react-web-pure/UCForm.js +2 -2
  57. package/dist/esm/target/react-web-pure/UCFormField.d.ts +1 -1
  58. package/dist/esm/target/react-web-pure/UCFormField.js +3 -4
  59. package/dist/esm/target/react-web-pure/UCFormFieldControl.js +7 -4
  60. package/dist/esm/testing/AppTester.d.ts +1 -1
  61. package/dist/esm/testing/AppTester.js +3 -2
  62. package/dist/esm/testing/impl/SimpleHTMLAppTestReportEmitter.js +1 -1
  63. package/dist/esm/testing/impl/TypeScriptLibUCDefASTParser.js +2 -2
  64. package/dist/esm/testing/impl/VitestAppTestSuiteEmitter.js +6 -3
  65. package/dist/esm/testing/uc-input.js +13 -12
  66. package/dist/esm/testing/workers/UCExecutor.js +41 -3
  67. package/dist/esm/uc/UC.d.ts +7 -7
  68. package/dist/esm/uc/UC.js +4 -3
  69. package/dist/esm/uc/UCInputField.d.ts +6 -3
  70. package/dist/esm/uc/UCInputField.js +39 -29
  71. package/dist/esm/uc/ext.d.ts +7 -1
  72. package/dist/esm/uc/impl/HTTPUCTransporter.d.ts +2 -2
  73. package/dist/esm/uc/impl/HTTPUCTransporter.js +3 -1
  74. package/dist/esm/uc/impl/SimpleUCManager.d.ts +3 -3
  75. package/dist/esm/uc/impl/SimpleUCManager.js +23 -4
  76. package/dist/esm/uc/index.d.ts +0 -1
  77. package/dist/esm/uc/index.js +0 -1
  78. package/dist/esm/uc/input-field.d.ts +2 -19
  79. package/dist/esm/uc/input-field.js +0 -19
  80. package/dist/esm/uc/input.d.ts +13 -7
  81. package/dist/esm/uc/lifecycle/client/SendClientMain.d.ts +1 -1
  82. package/dist/esm/uc/lifecycle/client/SendClientMain.js +5 -2
  83. package/dist/esm/uc/main.d.ts +8 -1
  84. package/dist/esm/uc/manager.d.ts +11 -2
  85. package/dist/esm/uc/output.d.ts +1 -0
  86. package/dist/esm/uc/output.js +10 -1
  87. package/dist/esm/uc/transporter.d.ts +7 -1
  88. package/dist/esm/uc/utils/rInput.js +4 -3
  89. package/dist/esm/uc/utils/rVal.d.ts +5 -5
  90. package/dist/esm/uc/utils/rVal.js +1 -12
  91. package/dist/esm/uc/value.d.ts +1 -2
  92. package/dist/esm/uc/workers/UCInputFilesProcessor.js +3 -3
  93. package/dist/esm/utils/async/types.d.ts +2 -0
  94. package/dist/esm/utils/async/types.js +1 -0
  95. package/dist/esm/utils/http/NDJSONStreamManager.d.ts +12 -0
  96. package/dist/esm/utils/http/NDJSONStreamManager.js +42 -0
  97. package/dist/esm/utils/http/SSEStreamManager.d.ts +12 -0
  98. package/dist/esm/utils/http/SSEStreamManager.js +57 -0
  99. package/dist/esm/utils/http/nd-json.d.ts +1 -0
  100. package/dist/esm/utils/http/nd-json.js +2 -0
  101. package/dist/esm/utils/http/sse.d.ts +14 -0
  102. package/dist/esm/utils/http/sse.js +24 -0
  103. package/dist/esm/utils/http/status.d.ts +4 -0
  104. package/dist/esm/utils/http/status.js +9 -0
  105. package/dist/esm/utils/index.d.ts +6 -0
  106. package/dist/esm/utils/index.js +4 -0
  107. package/dist/esm/utils/streams/types.d.ts +17 -0
  108. package/dist/esm/utils/streams/types.js +1 -0
  109. package/package.json +15 -15
  110. package/pnpm-workspace.yaml +1 -0
@@ -3,14 +3,60 @@ import { deleteCookie, getCookie, setCookie } from 'hono/cookie';
3
3
  import { logger } from 'hono/logger';
4
4
  import { secureHeaders } from 'hono/secure-headers';
5
5
  import { NotFoundError } from '../../../error/index.js';
6
- import { fromFormData } from '../../../utils/index.js';
6
+ import { fmtSingleDataMsg, fmtSSEError, fromFormData, isError, SSE_HEADERS, } from '../../../utils/index.js';
7
7
  export function buildHandler(appManifest, ucd, contract, serverRequestHandler, ucManager, beforeExec) {
8
8
  const { envelope } = contract;
9
9
  const handler = async (c) => {
10
10
  await beforeExec?.(c);
11
+ const transportType = ucd.ext?.http?.transportType ?? 'standard';
12
+ let execOpts;
13
+ let stream;
14
+ let controller;
15
+ switch (transportType) {
16
+ case 'standard':
17
+ // Nothing to do
18
+ break;
19
+ case 'stream': {
20
+ stream = new ReadableStream({
21
+ start: (ctrl) => {
22
+ controller = ctrl;
23
+ let closed = false;
24
+ const close = () => {
25
+ if (closed) {
26
+ return;
27
+ }
28
+ ctrl.close();
29
+ closed = true;
30
+ };
31
+ execOpts = {
32
+ stream: {
33
+ onClose: async () => { },
34
+ onData: async (output) => {
35
+ if (!output || closed) {
36
+ return;
37
+ }
38
+ ctrl.enqueue(fmtSingleDataMsg(output));
39
+ },
40
+ onDone: async () => {
41
+ close();
42
+ },
43
+ },
44
+ };
45
+ c.req.raw.signal.addEventListener('abort', async () => {
46
+ close();
47
+ await execOpts?.stream?.onClose();
48
+ });
49
+ },
50
+ });
51
+ break;
52
+ }
53
+ default:
54
+ ((_) => { })(transportType);
55
+ }
11
56
  const { body, status } = await serverRequestHandler.exec({
12
57
  appManifest,
13
58
  envelope,
59
+ execOpts,
14
60
  req: toReq(c),
15
61
  res: toRes(c),
16
62
  ucd,
@@ -19,6 +65,23 @@ export function buildHandler(appManifest, ucd, contract, serverRequestHandler, u
19
65
  if (!body) {
20
66
  return c.newResponse(null, status);
21
67
  }
68
+ switch (transportType) {
69
+ case 'standard':
70
+ return c.json(body, status);
71
+ case 'stream': {
72
+ if (isError(status)) {
73
+ controller?.enqueue(fmtSSEError({
74
+ message: body.message,
75
+ status,
76
+ }));
77
+ }
78
+ return new Response(stream, {
79
+ headers: SSE_HEADERS,
80
+ });
81
+ }
82
+ default:
83
+ ((_) => { })(transportType);
84
+ }
22
85
  return c.json(body, status);
23
86
  };
24
87
  return handler;
@@ -50,7 +113,7 @@ export function toReq(c) {
50
113
  return {
51
114
  bodyFromFormData: async () => fromFormData(await c.req.formData()),
52
115
  bodyFromJSON: () => c.req.json(),
53
- bodyFromQueryParams: async () => c.req.queries(),
116
+ bodyFromQueryParams: async () => c.req.query(),
54
117
  bodyRaw: c.req.raw,
55
118
  cookie: async (name) => getCookie(c, name),
56
119
  header: async (name) => c.req.header(name),
@@ -125,6 +125,7 @@ let NodeLocalStdioMCPServerManager = class NodeLocalStdioMCPServerManager {
125
125
  def: ucd,
126
126
  });
127
127
  if (args) {
128
+ // biome-ignore lint/suspicious/noExplicitAny: can be anything
128
129
  uc.fill(args);
129
130
  }
130
131
  const confirmed = await this.ucManager.confirmClient(uc);
@@ -1,4 +1,4 @@
1
1
  import type { ReactElement } from 'react';
2
2
  import type { UCInput, UCOPIBase } from '../../uc/index.js';
3
3
  import type { UCFormProps } from '../lib/react/form.js';
4
- export declare function UCForm<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>({ disabled, execState, onChange, onSubmit, uc, }: UCFormProps<I, OPI0, OPI1>): ReactElement;
4
+ export declare function UCForm<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>({ disabled, execState, onSubmit, uc, }: UCFormProps<I, OPI0, OPI1>): ReactElement;
@@ -3,10 +3,10 @@ import { View } from 'react-native';
3
3
  import { useStyleContext } from '../lib/react/StyleContextProvider.js';
4
4
  import { UCFormField } from './UCFormField.js';
5
5
  import { UCFormSubmitControl } from './UCFormSubmitControl.js';
6
- export function UCForm({ disabled, execState, onChange, onSubmit, uc, }) {
6
+ export function UCForm({ disabled, execState, onSubmit, uc, }) {
7
7
  const { form } = useStyleContext();
8
8
  const onPress = async () => {
9
9
  await onSubmit();
10
10
  };
11
- return (_jsxs(View, { style: form?.style, children: [uc.inputFieldsForForm().map((f) => (_jsx(UCFormField, { disabled: disabled, execState: execState, f: f, onChange: onChange }, f.key))), _jsx(UCFormSubmitControl, { disabled: disabled, execState: execState, onPress: onPress, uc: uc })] }));
11
+ return (_jsxs(View, { style: form?.style, children: [uc.inputFieldsForForm().map((f) => (_jsx(UCFormField, { disabled: disabled, execState: execState, f: f }, f.key))), _jsx(UCFormSubmitControl, { disabled: disabled, execState: execState, onPress: onPress, uc: uc })] }));
12
12
  }
@@ -1,4 +1,4 @@
1
1
  import { type ReactElement } from 'react';
2
2
  import type { DataType } from '../../dt/index.js';
3
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;
4
+ export declare function UCFormField<T extends DataType>({ disabled, execState, f, only, }: UCFormFieldProps<T>): ReactElement;
@@ -8,13 +8,12 @@ import { UCFormFieldControl } from './UCFormFieldControl.js';
8
8
  import { UCFormFieldDesc } from './UCFormFieldDesc.js';
9
9
  import { UCFormFieldErr } from './UCFormFieldErr.js';
10
10
  import { UCFormFieldLabel } from './UCFormFieldLabel.js';
11
- export function UCFormField({ disabled, execState, f, onChange: onChangeBase, only, }) {
11
+ export function UCFormField({ disabled, execState, f, only, }) {
12
12
  const { i18nManager } = useDIContext();
13
13
  const { formField } = useStyleContext();
14
14
  const [errMsg, setErrMsg] = useState(null);
15
- const onChange = (f, op, v) => {
16
- setErrMsg(validateFormField(i18nManager, f, v));
17
- onChangeBase(f, op, v);
15
+ const onChange = () => {
16
+ setErrMsg(validateFormField(i18nManager, f));
18
17
  };
19
18
  const elements = only ?? UC_FORM_FIELD_ELEMENTS;
20
19
  return (_jsxs(View, { style: formField?.style, children: [elements.includes('label') && _jsx(UCFormFieldLabel, { f: f }), elements.includes('control') && (_jsx(UCFormFieldControl, { disabled: disabled, execState: execState, f: f, onChange: onChange })), elements.includes('err') && errMsg && (_jsx(UCFormFieldErr, { errMsg: errMsg })), elements.includes('desc') && _jsx(UCFormFieldDesc, { f: f })] }));
@@ -2,7 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useEffect, useState } from 'react';
3
3
  import { FlatList, Pressable, StyleSheet, Switch, Text, TextInput, } from 'react-native';
4
4
  import { TBoolean } from '../../dt/index.js';
5
- import { UCInputFieldChangeOperator, ucifRepeatability, } from '../../uc/index.js';
5
+ import { ucifRepeatability } from '../../uc/index.js';
6
6
  import { isBlank } from '../../utils/index.js';
7
7
  import { styleDef, useStyleContext, } from '../lib/react/StyleContextProvider.js';
8
8
  import { rnInputDef } from '../lib/rn/input.js';
@@ -31,24 +31,30 @@ export function UCFormFieldControl({ disabled, errMsg = null, execState, f, onCh
31
31
  const valueArr = value
32
32
  .split(MULTIPLE_VALUES_SEPARATOR)
33
33
  .map((v) => v.trim());
34
- onChangeBase(f, UCInputFieldChangeOperator.SET, valueArr);
34
+ f.setVal(valueArr);
35
+ onChangeBase();
36
+ setInternalValue(valueArr);
35
37
  }
36
38
  else {
37
- onChangeBase(f, UCInputFieldChangeOperator.SET, value);
39
+ f.setVal(value);
40
+ onChangeBase();
41
+ setInternalValue(value);
38
42
  }
39
- setInternalValue(value);
40
43
  };
41
44
  const onSelect = (value) => {
42
45
  if (internalValue === value) {
43
- onChangeBase(f, UCInputFieldChangeOperator.RESET, null);
46
+ f.clear();
47
+ onChangeBase();
44
48
  setInternalValue(null);
45
49
  return;
46
50
  }
47
- onChangeBase(f, UCInputFieldChangeOperator.SET, value);
51
+ f.setVal(value);
52
+ onChangeBase();
48
53
  setInternalValue(value);
49
54
  };
50
55
  const onValueChange = (value) => {
51
- onChangeBase(f, UCInputFieldChangeOperator.SET, value);
56
+ f.setVal(value);
57
+ onChangeBase();
52
58
  setInternalValue(value);
53
59
  };
54
60
  const attrs = rnInputDef(f, disabled, errMsg);
@@ -1,4 +1,4 @@
1
1
  import { type ReactElement } from 'react';
2
2
  import type { UCInput, UCOPIBase } from '../../uc/index.js';
3
3
  import type { UCFormProps } from '../lib/react/form.js';
4
- export declare function UCForm<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>({ clearAfterExec, disabled, execState, onChange, onSubmit: onSubmitBase, uc, }: UCFormProps<I, OPI0, OPI1>): ReactElement;
4
+ export declare function UCForm<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>({ clearAfterExec, disabled, execState, onSubmit: onSubmitBase, uc, }: UCFormProps<I, OPI0, OPI1>): ReactElement;
@@ -3,7 +3,7 @@ import { useRef } from 'react';
3
3
  import { useStyleContext } from '../lib/react/StyleContextProvider.js';
4
4
  import { UCFormField } from './UCFormField.js';
5
5
  import { UCFormSubmitControl } from './UCFormSubmitControl.js';
6
- export function UCForm({ clearAfterExec, disabled, execState, onChange, onSubmit: onSubmitBase, uc, }) {
6
+ export function UCForm({ clearAfterExec, disabled, execState, onSubmit: onSubmitBase, uc, }) {
7
7
  const { form } = useStyleContext();
8
8
  const formRef = useRef(null);
9
9
  const onSubmit = async (e) => {
@@ -13,5 +13,5 @@ export function UCForm({ clearAfterExec, disabled, execState, onChange, onSubmit
13
13
  formRef.current?.reset();
14
14
  }
15
15
  };
16
- return (_jsxs("form", { className: form?.className, onSubmit: onSubmit, ref: formRef, style: form?.style, children: [uc.inputFieldsForForm().map((f) => (_jsx(UCFormField, { disabled: disabled, execState: execState, f: f, onChange: onChange }, f.key))), _jsx(UCFormSubmitControl, { disabled: disabled, execState: execState, uc: uc })] }));
16
+ return (_jsxs("form", { className: form?.className, onSubmit: onSubmit, ref: formRef, style: form?.style, children: [uc.inputFieldsForForm().map((f) => (_jsx(UCFormField, { disabled: disabled, execState: execState, f: f }, f.key))), _jsx(UCFormSubmitControl, { disabled: disabled, execState: execState, uc: uc })] }));
17
17
  }
@@ -1,4 +1,4 @@
1
1
  import { type ReactElement } from 'react';
2
2
  import type { DataType } from '../../dt/index.js';
3
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;
4
+ export declare function UCFormField<T extends DataType>({ disabled, execState, f, only, }: UCFormFieldProps<T>): ReactElement;
@@ -7,13 +7,12 @@ import { UCFormFieldControl } from './UCFormFieldControl.js';
7
7
  import { UCFormFieldDesc } from './UCFormFieldDesc.js';
8
8
  import { UCFormFieldErr } from './UCFormFieldErr.js';
9
9
  import { UCFormFieldLabel } from './UCFormFieldLabel.js';
10
- export function UCFormField({ disabled, execState, f, onChange: onChangeBase, only, }) {
10
+ export function UCFormField({ disabled, execState, f, only, }) {
11
11
  const { i18nManager } = useDIContext();
12
12
  const { formField } = useStyleContext();
13
13
  const [errMsg, setErrMsg] = useState(null);
14
- const onChange = (f, op, v) => {
15
- setErrMsg(validateFormField(i18nManager, f, v));
16
- onChangeBase(f, op, v);
14
+ const onChange = () => {
15
+ setErrMsg(validateFormField(i18nManager, f));
17
16
  };
18
17
  const elements = only ?? UC_FORM_FIELD_ELEMENTS;
19
18
  return (_jsxs("div", { className: formField?.className, style: formField?.style, children: [elements.includes('label') && _jsx(UCFormFieldLabel, { f: f }), elements.includes('control') && (_jsx(UCFormFieldControl, { disabled: disabled, execState: execState, f: f, onChange: onChange })), elements.includes('err') && errMsg && (_jsx(UCFormFieldErr, { errMsg: errMsg })), elements.includes('desc') && _jsx(UCFormFieldDesc, { f: f })] }));
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { TBoolean } from '../../dt/index.js';
3
- import { UCInputFieldChangeOperator, ucifRepeatability, } from '../../uc/index.js';
3
+ import { ucifRepeatability } from '../../uc/index.js';
4
4
  import { styleDef, useStyleContext, } from '../lib/react/StyleContextProvider.js';
5
5
  import { htmlInputDef } from '../lib/web/input.js';
6
6
  const CHECKED_FIELD_TYPES = ['checkbox', 'radio'];
@@ -27,7 +27,8 @@ export function UCFormFieldControl({ disabled, errMsg = null, execState, f, onCh
27
27
  if (target.localName === 'select' && !value) {
28
28
  // Prevent the value from being '' when we set/unset the select
29
29
  // Otherwise it sets '' as value and prevents the form for being valid
30
- onChangeBase(f, UCInputFieldChangeOperator.RESET, value);
30
+ f.clear();
31
+ onChangeBase();
31
32
  return;
32
33
  }
33
34
  if (CHECKED_FIELD_TYPES.includes(type) && 'checked' in target) {
@@ -41,10 +42,12 @@ export function UCFormFieldControl({ disabled, errMsg = null, execState, f, onCh
41
42
  const valueArr = value
42
43
  .split(MULTIPLE_VALUES_SEPARATOR)
43
44
  .map((v) => v.trim());
44
- onChangeBase(f, UCInputFieldChangeOperator.SET, valueArr);
45
+ f.setVal(valueArr);
46
+ onChangeBase();
45
47
  }
46
48
  else {
47
- onChangeBase(f, UCInputFieldChangeOperator.SET, value);
49
+ f.setVal(value);
50
+ onChangeBase();
48
51
  }
49
52
  };
50
53
  const defaultChecked = attrs.internal?.checked;
@@ -62,7 +62,7 @@ export declare class AppTester {
62
62
  checkUCDSources(): Promise<void>;
63
63
  checkUC(ucdRef: AppTesterUCDRef): Promise<void>;
64
64
  execFlow(flow: AppTesterFlow): Promise<AppTesterFlowExecOutput>;
65
- execMonkeyTest<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(ucd: UCDef<I, OPI0, OPI1>, input: I): Promise<UCExecutorExecOutput<I, OPI0, OPI1>>;
65
+ execMonkeyTest<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(ucd: UCDef<I, OPI0, OPI1>, input: NonNullable<I>): Promise<UCExecutorExecOutput<I, OPI0, OPI1>>;
66
66
  execUC<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(input: Omit<UCExecutorInput<I, OPI0, OPI1>, 'appManifest'>, flow?: AppTesterFlow): Promise<AppTestSuiteTestResult<I, OPI0, OPI1>>;
67
67
  finalize(): Promise<void>;
68
68
  getCtx(): AppTesterCtx;
@@ -13,7 +13,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
13
13
  import { inject, injectable } from 'inversify';
14
14
  import { I18nEN } from '../i18n/locales/en.js';
15
15
  import { I18nFR } from '../i18n/locales/fr.js';
16
- import { FAKE_USER_ADMIN, UCBuilder, UCInputFieldChangeOperator, ucHTTPContract, } from '../uc/index.js';
16
+ import { FAKE_USER_ADMIN, UCBuilder, ucHTTPContract, } from '../uc/index.js';
17
17
  // We inject directly the implementation because we'll generate all the reports and not only the one that is bound to the interface.
18
18
  // We can plan a setting à la Vitest where we specify the types of reports to generate though.
19
19
  import { SimpleHTMLAppTestReportEmitter } from './impl/SimpleHTMLAppTestReportEmitter.js';
@@ -137,7 +137,8 @@ let AppTester = class AppTester {
137
137
  if (inputOverride) {
138
138
  const inputOverrides = inputOverride(output);
139
139
  for (const [k, v] of Object.entries(inputOverrides)) {
140
- uc.inputField(k).setValue(UCInputFieldChangeOperator.SET, v);
140
+ // @ts-expect-error
141
+ uc.inputField(k).setVal(v);
141
142
  }
142
143
  }
143
144
  };
@@ -140,7 +140,7 @@ const template = (appPath, testResults, testSummary) => `<!DOCTYPE html>
140
140
  const search = new URLSearchParams(window.location.search);
141
141
  const status = search.get('status');
142
142
  if (status) {
143
- document.querySelectorAll(\`table tbody tr:not(.\${status\})\`).forEach((n) => n.remove());
143
+ document.querySelectorAll(\`table tbody tr:not(.\${status})\`).forEach((n) => n.remove());
144
144
  }
145
145
  </script>
146
146
  </table>
@@ -92,9 +92,9 @@ let TypeScriptLibUCDefASTParser = class TypeScriptLibUCDefASTParser {
92
92
  target)],
93
93
  };
94
94
  this.compilerOptions.incremental = false; // Otherwise it triggers the following error : Option '--incremental' can only be specified using tsconfig, emitting to single file or when option '--tsBuildInfoFile' is specified.
95
- // @ts-ignore
95
+ // @ts-expect-error
96
96
  this.compilerOptions.jsx = undefined; // Otherwise it triggers the following error since TS 5.5 : jsx is a string value; tsconfig JSON must be parsed with parseJsonSourceFileConfigFileContent or getParsedCommandLineOfConfigFile before passing to createProgram
97
- // @ts-ignore
97
+ // @ts-expect-error
98
98
  this.compilerOptions.lib = undefined; // Otherwise it triggers errors saying it does not find them
99
99
  }
100
100
  getTypeFields(node) {
@@ -186,7 +186,7 @@ describe('Run', async () => {
186
186
  expect(out).toSatisfy(assertion);
187
187
  } else {
188
188
  expect({ out, sideEffects }).toMatchSnapshot(
189
- \`hash = \${hash\}\`,
189
+ \`hash = \${hash}\`,
190
190
  );
191
191
  }
192
192
  },
@@ -209,7 +209,10 @@ describe('Run', async () => {
209
209
  }
210
210
 
211
211
  public async run(_m: Model, _r: RealSystem): Promise<void> {
212
- const out = await runner.execMonkeyTest(ucd, this.input);
212
+ const out = await runner.execMonkeyTest(
213
+ ucd,
214
+ this.input,
215
+ );
213
216
 
214
217
  if (out.err !== null) {
215
218
  if (!(out.err instanceof CustomError)) {
@@ -220,7 +223,7 @@ describe('Run', async () => {
220
223
  }
221
224
 
222
225
  public toString(): string {
223
- return \`\${ucd.metadata.name\}(\${JSON.stringify(this.input)\})\`;
226
+ return \`\${ucd.metadata.name}(\${JSON.stringify(this.input)})\`;
224
227
  }
225
228
  }
226
229
 
@@ -1,5 +1,5 @@
1
1
  import { TFile } from '../dt/index.js';
2
- import { UCInputFieldChangeOperator, ucifIsMandatory, ucifMustBeFilledManually, ucifRepeatability, } from '../uc/index.js';
2
+ import { ucifIsMandatory, ucifMustBeFilledManually, ucifRepeatability, } from '../uc/index.js';
3
3
  export const DEFAULT_UC_INPUT_FILLERS = [
4
4
  'ALL_WITH_EXAMPLES',
5
5
  'ONLY_MANDATORY_WITH_EXAMPLES',
@@ -36,19 +36,20 @@ export function onlySetProgrammaticallyWithExamples(uc) {
36
36
  // biome-ignore lint/suspicious/noExplicitAny: can be anything
37
37
  function fillWithExample(f) {
38
38
  const { type } = f.def;
39
- let val = type.getExamples()?.[0] ?? type.example();
40
39
  if (type instanceof TFile) {
41
- const file = val;
40
+ const example = type.getExamples()?.[0] ?? type.example();
42
41
  // TODO : Consider building a real file with real data (e.g. image, pdf, txt, etc.)
43
- val = new File(['01010101010101010101010101010101'], file.path, {
44
- type: file.type,
42
+ const val = new File(['01010101010101010101010101010101'], example.path, {
43
+ type: example.type,
45
44
  });
45
+ const [isRepeatable] = ucifRepeatability(f.def);
46
+ if (isRepeatable) {
47
+ f.addVal(val);
48
+ }
49
+ else {
50
+ f.setVal(val);
51
+ }
52
+ return;
46
53
  }
47
- const [isRepeatable] = ucifRepeatability(f.def);
48
- if (isRepeatable) {
49
- f.setValue(UCInputFieldChangeOperator.ADD, val);
50
- }
51
- else {
52
- f.setValue(UCInputFieldChangeOperator.SET, val);
53
- }
54
+ f.fillWithExample();
54
55
  }
@@ -13,6 +13,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
13
13
  var UCExecutor_1;
14
14
  import { inject, injectable } from 'inversify';
15
15
  import { rInput, UCBuilder, } from '../../uc/index.js';
16
+ const ERR_CLIENT_EXPECTED_UCOR = (name) => `${name} client is expected to return an ucor`;
16
17
  const ERR_CLIENT_EXPECTED_OUTPUT = (name) => `${name} client is expected to return an output but returned nothing`;
17
18
  const ERR_CLIENT_UNEXPECTED_OUTPUT = (name) => `${name} client is expected to return nothing but returned an output`;
18
19
  let UCExecutor = class UCExecutor {
@@ -70,7 +71,44 @@ let UCExecutor = class UCExecutor {
70
71
  out.io.i = input;
71
72
  out.hash = this.cryptoManager.hash(UCExecutor_1.HASH_ALG, [name, JSON.stringify(args), JSON.stringify(input)].join(UCExecutor_1.HASH_SEP), UCExecutor_1.HASH_BTT_ENCODING);
72
73
  try {
73
- const ucor = await this.ucManager.execClient(uc);
74
+ let ucor;
75
+ const transportType = ucd.ext?.http?.transportType ?? 'standard';
76
+ switch (transportType) {
77
+ case 'standard':
78
+ ucor = await this.ucManager.execClient(uc);
79
+ break;
80
+ case 'stream': {
81
+ try {
82
+ let abort;
83
+ await this.ucManager.execClient(uc, {
84
+ registerAbort: (func) => {
85
+ abort = func;
86
+ },
87
+ stream: {
88
+ onClose: async () => { },
89
+ onData: async (ucor2) => {
90
+ if (!ucor) {
91
+ ucor = ucor2;
92
+ abort();
93
+ }
94
+ },
95
+ onDone: async () => { },
96
+ },
97
+ });
98
+ }
99
+ catch (err) {
100
+ if (err.name !== 'AbortError') {
101
+ throw err;
102
+ }
103
+ }
104
+ break;
105
+ }
106
+ default:
107
+ ((_) => { })(transportType);
108
+ }
109
+ if (!ucor) {
110
+ throw new Error(ERR_CLIENT_EXPECTED_UCOR(name));
111
+ }
74
112
  const output = ucor.output();
75
113
  if (uc.hasOutputParts() && !output) {
76
114
  throw new Error(ERR_CLIENT_EXPECTED_OUTPUT(name));
@@ -92,13 +130,13 @@ let UCExecutor = class UCExecutor {
92
130
  if (Array.isArray(v)) {
93
131
  v.forEach((vv, idx) => {
94
132
  if (vv instanceof File) {
95
- // @ts-ignore
133
+ // @ts-expect-error
96
134
  input[k][idx] = this.derandomizeInputFile(vv);
97
135
  }
98
136
  });
99
137
  }
100
138
  else if (v instanceof File) {
101
- // @ts-ignore
139
+ // @ts-expect-error
102
140
  input[k] = this.derandomizeInputFile(v);
103
141
  }
104
142
  }
@@ -2,7 +2,7 @@ import type { AppManifest } from '../app/index.js';
2
2
  import { type DataType, Validation } from '../dt/index.js';
3
3
  import type { UCAuth } from './auth.js';
4
4
  import type { UCDef, UCFieldKey } from './def.js';
5
- import type { UCInput } from './input.js';
5
+ import type { UCInput, UCInputKey, UCInputKeyDataType, UCInputPartial } from './input.js';
6
6
  import type { UCOPIBase } from './opi.js';
7
7
  import { UCInputField } from './UCInputField.js';
8
8
  import type { reqVal0, rVal0, rValArr } from './utils/rVal.js';
@@ -16,15 +16,15 @@ export declare class UC<I extends UCInput | undefined = undefined, OPI0 extends
16
16
  appManifest: AppManifest;
17
17
  def: UCDef<I, OPI0, OPI1>;
18
18
  auth: UCAuth | null;
19
- inputFields: UCInputField<any>[];
19
+ inputFields: UCInputField<DataType>[];
20
20
  constructor(appManifest: AppManifest, def: UCDef<I, OPI0, OPI1>, auth: UCAuth | null);
21
21
  clear(): void;
22
22
  clearSensitiveInputFields(): void;
23
- fill(input: Partial<I>): this;
23
+ fill(input: UCInputPartial<I>): this;
24
24
  hasInputField(key: UCFieldKey): boolean;
25
25
  hasMediaInInput(): boolean;
26
26
  hasOutputParts(): boolean;
27
- inputField<T extends DataType>(key: keyof NonNullable<I>): UCInputField<T>;
27
+ inputField<K extends UCInputKey<I>>(key: K): UCInputField<UCInputKeyDataType<I, K>>;
28
28
  inputFieldsForForm(): UCInputField<any>[];
29
29
  inputFieldsOrdered(): UCInputField<any>[];
30
30
  inputFieldsInsensitive(): UCInputField<any>[];
@@ -32,8 +32,8 @@ export declare class UC<I extends UCInput | undefined = undefined, OPI0 extends
32
32
  needsInputFilling(): boolean;
33
33
  needsOutputDisplay(): boolean;
34
34
  operatesOnAggregate(): boolean;
35
- rVal0<T extends DataType>(key: keyof I): ReturnType<typeof rVal0<T>>;
36
- reqVal0<T extends DataType>(key: keyof I): ReturnType<typeof reqVal0<T>>;
37
- rValArr<T extends DataType>(key: keyof I): ReturnType<typeof rValArr<T>>;
35
+ rVal0<K extends UCInputKey<I>>(key: K): ReturnType<typeof rVal0<UCInputKeyDataType<I, K>>>;
36
+ reqVal0<K extends UCInputKey<I>>(key: K): ReturnType<typeof reqVal0<UCInputKeyDataType<I, K>>>;
37
+ rValArr<K extends UCInputKey<I>>(key: K): ReturnType<typeof rValArr<UCInputKeyDataType<I, K>>>;
38
38
  validate(): [UCInputField<any> | null, Validation] | null;
39
39
  }
package/dist/esm/uc/UC.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { TFile, Validation } from '../dt/index.js';
2
2
  import { isBlank } from '../utils/index.js';
3
- import { UCInputFieldChangeOperator, ucifIsMandatory, ucifIsSensitive, ucifMustBeFilledManually, } from './input-field.js';
3
+ import { ucifIsMandatory, ucifIsSensitive, ucifMustBeFilledManually, } from './input-field.js';
4
4
  import { AggregateInputDef } from './io/input/AggregateInput.js';
5
5
  import { ListInputDef } from './io/input/ListInput.js';
6
6
  import { UCInputField } from './UCInputField.js';
@@ -8,7 +8,6 @@ export class UC {
8
8
  appManifest;
9
9
  def;
10
10
  auth;
11
- // biome-ignore lint/suspicious/noExplicitAny: can be anything
12
11
  inputFields;
13
12
  constructor(appManifest, def, auth) {
14
13
  this.appManifest = appManifest;
@@ -40,7 +39,8 @@ export class UC {
40
39
  }
41
40
  fill(input) {
42
41
  for (const f of this.inputFields) {
43
- f.setValue(UCInputFieldChangeOperator.SET, input[f.key]);
42
+ const val = input[f.key];
43
+ f.setVal(val);
44
44
  }
45
45
  return this;
46
46
  }
@@ -58,6 +58,7 @@ export class UC {
58
58
  if (!field) {
59
59
  throw new Error(`Input field ${key.toString()} does not exist`);
60
60
  }
61
+ // @ts-expect-error
61
62
  return field;
62
63
  }
63
64
  // biome-ignore lint/suspicious/noExplicitAny: can be anything
@@ -1,6 +1,6 @@
1
1
  import { type DataType, Validation } from '../dt/index.js';
2
2
  import type { UCFieldKey, UCWording } from './def.js';
3
- import { UCInputFieldChangeOperator, type UCInputFieldDef, type UCInputFieldValue } from './input-field.js';
3
+ import { type UCInputFieldDef, type UCInputFieldValue } from './input-field.js';
4
4
  import { type reqVal0, rVal0, rValArr } from './utils/rVal.js';
5
5
  export declare class UCInputField<T extends DataType> {
6
6
  key: UCFieldKey;
@@ -13,7 +13,9 @@ export declare class UCInputField<T extends DataType> {
13
13
  private dynamicWording;
14
14
  private value;
15
15
  constructor(key: UCFieldKey, def: UCInputFieldDef<T>);
16
+ addVal(value: UCInputFieldValue<T>): void;
16
17
  clear(): void;
18
+ fillWithExample(): void;
17
19
  getDynamicWording(): Partial<UCWording> | undefined;
18
20
  getValue(): UCInputFieldValue<T>;
19
21
  /**
@@ -35,14 +37,15 @@ export declare class UCInputField<T extends DataType> {
35
37
  */
36
38
  reqVal0(): ReturnType<typeof reqVal0<T>>;
37
39
  /**
38
- * Require the value as an array
40
+ * Read the value as an array
39
41
  *
40
42
  * Unlink the standalone {@link rValArr}, it returns the default value in an array if present.
41
43
  *
42
44
  * @returns
43
45
  */
44
46
  rValArr(): ReturnType<typeof rValArr<T>>;
45
- setValue(op: UCInputFieldChangeOperator, value: UCInputFieldValue<T>): void;
47
+ rmVal(value: UCInputFieldValue<T>): void;
48
+ setVal(value: UCInputFieldValue<T>): void;
46
49
  updateDef(def: UCInputFieldDef<T>): void;
47
50
  updateDynamicWording(dynamicWording: Partial<UCWording> | undefined): void;
48
51
  updateType(type: UCInputFieldDef<T>['type']): void;