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.
- package/CHANGELOG.md +32 -0
- package/README.md +1 -1
- package/dist/esm/apps/Helper/src/lib/project.js +7 -7
- package/dist/esm/apps/Helper/src/ucds/CreateProjectUCD.d.ts +1 -0
- package/dist/esm/apps/Helper/src/ucds/CreateProjectUCD.js +20 -13
- package/dist/esm/dt/DataType.d.ts +2 -1
- package/dist/esm/dt/DataTypes.js +1 -0
- package/dist/esm/dt/Validation.js +1 -1
- package/dist/esm/dt/final/TGitSSHURL.d.ts +4 -3
- package/dist/esm/dt/final/TGitSSHURL.js +1 -1
- package/dist/esm/dt/final/TSSHPrivateKey.js +1 -3
- package/dist/esm/dt/final/TTransportType.d.ts +8 -0
- package/dist/esm/dt/final/TTransportType.js +16 -0
- package/dist/esm/dt/index.d.ts +1 -0
- package/dist/esm/dt/index.js +1 -0
- package/dist/esm/error/funcs.d.ts +2 -0
- package/dist/esm/error/funcs.js +19 -0
- package/dist/esm/error/index.d.ts +1 -0
- package/dist/esm/error/index.js +1 -0
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/std/HTTPAPICallExecutor.d.ts +16 -7
- package/dist/esm/std/HTTPAPICaller.d.ts +8 -1
- package/dist/esm/std/LLMManager.d.ts +20 -3
- package/dist/esm/std/impl/ConsoleLogger.js +2 -2
- package/dist/esm/std/impl/FakeClockManager.d.ts +6 -0
- package/dist/esm/std/impl/FakeClockManager.js +19 -0
- package/dist/esm/std/impl/FakeHTTPAPICallExecutor.js +19 -18
- package/dist/esm/std/impl/FakeLLMManager.d.ts +4 -0
- package/dist/esm/std/impl/FakeLLMManager.js +40 -0
- package/dist/esm/std/impl/FetchHTTPAPICallExecutor.js +1 -1
- package/dist/esm/std/impl/MistralAILLMManager.js +12 -0
- package/dist/esm/std/impl/NodeFormDataBuilder.js +3 -1
- package/dist/esm/std/impl/OllamaLLMManager.d.ts +7 -2
- package/dist/esm/std/impl/OllamaLLMManager.js +32 -5
- package/dist/esm/std/impl/OpenAILLMManager.js +9 -0
- package/dist/esm/std/impl/SimpleHTTPAPICaller.d.ts +7 -3
- package/dist/esm/std/impl/SimpleHTTPAPICaller.js +67 -16
- package/dist/esm/target/lib/cli/CommandExecutor.js +11 -3
- package/dist/esm/target/lib/react/UCPanel.d.ts +4 -2
- package/dist/esm/target/lib/react/UCPanel.js +2 -6
- package/dist/esm/target/lib/react/form.d.ts +5 -6
- package/dist/esm/target/lib/react/form.js +7 -10
- package/dist/esm/target/lib/react/useUC.d.ts +4 -4
- package/dist/esm/target/lib/server/ServerRequestHandler.d.ts +3 -2
- package/dist/esm/target/lib/server/ServerRequestHandler.js +2 -2
- package/dist/esm/target/lib/server-express/funcs.js +52 -1
- package/dist/esm/target/lib/server-hono/funcs.js +65 -2
- package/dist/esm/target/node-mcp-server/NodeLocalStdioMCPServerManager.js +1 -0
- package/dist/esm/target/react-native-pure/UCForm.d.ts +1 -1
- package/dist/esm/target/react-native-pure/UCForm.js +2 -2
- package/dist/esm/target/react-native-pure/UCFormField.d.ts +1 -1
- package/dist/esm/target/react-native-pure/UCFormField.js +3 -4
- package/dist/esm/target/react-native-pure/UCFormFieldControl.js +13 -7
- package/dist/esm/target/react-web-pure/UCForm.d.ts +1 -1
- package/dist/esm/target/react-web-pure/UCForm.js +2 -2
- package/dist/esm/target/react-web-pure/UCFormField.d.ts +1 -1
- package/dist/esm/target/react-web-pure/UCFormField.js +3 -4
- package/dist/esm/target/react-web-pure/UCFormFieldControl.js +7 -4
- package/dist/esm/testing/AppTester.d.ts +1 -1
- package/dist/esm/testing/AppTester.js +3 -2
- package/dist/esm/testing/impl/SimpleHTMLAppTestReportEmitter.js +1 -1
- package/dist/esm/testing/impl/TypeScriptLibUCDefASTParser.js +2 -2
- package/dist/esm/testing/impl/VitestAppTestSuiteEmitter.js +6 -3
- package/dist/esm/testing/uc-input.js +13 -12
- package/dist/esm/testing/workers/UCExecutor.js +41 -3
- package/dist/esm/uc/UC.d.ts +7 -7
- package/dist/esm/uc/UC.js +4 -3
- package/dist/esm/uc/UCInputField.d.ts +6 -3
- package/dist/esm/uc/UCInputField.js +39 -29
- package/dist/esm/uc/ext.d.ts +7 -1
- package/dist/esm/uc/impl/HTTPUCTransporter.d.ts +2 -2
- package/dist/esm/uc/impl/HTTPUCTransporter.js +3 -1
- package/dist/esm/uc/impl/SimpleUCManager.d.ts +3 -3
- package/dist/esm/uc/impl/SimpleUCManager.js +23 -4
- package/dist/esm/uc/index.d.ts +0 -1
- package/dist/esm/uc/index.js +0 -1
- package/dist/esm/uc/input-field.d.ts +2 -19
- package/dist/esm/uc/input-field.js +0 -19
- package/dist/esm/uc/input.d.ts +13 -7
- package/dist/esm/uc/lifecycle/client/SendClientMain.d.ts +1 -1
- package/dist/esm/uc/lifecycle/client/SendClientMain.js +5 -2
- package/dist/esm/uc/main.d.ts +8 -1
- package/dist/esm/uc/manager.d.ts +11 -2
- package/dist/esm/uc/output.d.ts +1 -0
- package/dist/esm/uc/output.js +10 -1
- package/dist/esm/uc/transporter.d.ts +7 -1
- package/dist/esm/uc/utils/rInput.js +4 -3
- package/dist/esm/uc/utils/rVal.d.ts +5 -5
- package/dist/esm/uc/utils/rVal.js +1 -12
- package/dist/esm/uc/value.d.ts +1 -2
- package/dist/esm/uc/workers/UCInputFilesProcessor.js +3 -3
- package/dist/esm/utils/async/types.d.ts +2 -0
- package/dist/esm/utils/async/types.js +1 -0
- package/dist/esm/utils/http/NDJSONStreamManager.d.ts +12 -0
- package/dist/esm/utils/http/NDJSONStreamManager.js +42 -0
- package/dist/esm/utils/http/SSEStreamManager.d.ts +12 -0
- package/dist/esm/utils/http/SSEStreamManager.js +57 -0
- package/dist/esm/utils/http/nd-json.d.ts +1 -0
- package/dist/esm/utils/http/nd-json.js +2 -0
- package/dist/esm/utils/http/sse.d.ts +14 -0
- package/dist/esm/utils/http/sse.js +24 -0
- package/dist/esm/utils/http/status.d.ts +4 -0
- package/dist/esm/utils/http/status.js +9 -0
- package/dist/esm/utils/index.d.ts +6 -0
- package/dist/esm/utils/index.js +4 -0
- package/dist/esm/utils/streams/types.d.ts +17 -0
- package/dist/esm/utils/streams/types.js +1 -0
- package/package.json +15 -15
- 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.
|
|
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,
|
|
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,
|
|
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
|
|
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,
|
|
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,
|
|
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 = (
|
|
16
|
-
setErrMsg(validateFormField(i18nManager, f
|
|
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 {
|
|
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
|
-
|
|
34
|
+
f.setVal(valueArr);
|
|
35
|
+
onChangeBase();
|
|
36
|
+
setInternalValue(valueArr);
|
|
35
37
|
}
|
|
36
38
|
else {
|
|
37
|
-
|
|
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
|
-
|
|
46
|
+
f.clear();
|
|
47
|
+
onChangeBase();
|
|
44
48
|
setInternalValue(null);
|
|
45
49
|
return;
|
|
46
50
|
}
|
|
47
|
-
|
|
51
|
+
f.setVal(value);
|
|
52
|
+
onChangeBase();
|
|
48
53
|
setInternalValue(value);
|
|
49
54
|
};
|
|
50
55
|
const onValueChange = (value) => {
|
|
51
|
-
|
|
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,
|
|
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,
|
|
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
|
|
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,
|
|
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,
|
|
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 = (
|
|
15
|
-
setErrMsg(validateFormField(i18nManager, f
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
45
|
+
f.setVal(valueArr);
|
|
46
|
+
onChangeBase();
|
|
45
47
|
}
|
|
46
48
|
else {
|
|
47
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
|
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-
|
|
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-
|
|
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(
|
|
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
|
|
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 {
|
|
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
|
|
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'],
|
|
44
|
-
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
|
-
|
|
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
|
-
|
|
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-
|
|
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-
|
|
139
|
+
// @ts-expect-error
|
|
102
140
|
input[k] = this.derandomizeInputFile(v);
|
|
103
141
|
}
|
|
104
142
|
}
|
package/dist/esm/uc/UC.d.ts
CHANGED
|
@@ -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<
|
|
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:
|
|
23
|
+
fill(input: UCInputPartial<I>): this;
|
|
24
24
|
hasInputField(key: UCFieldKey): boolean;
|
|
25
25
|
hasMediaInInput(): boolean;
|
|
26
26
|
hasOutputParts(): boolean;
|
|
27
|
-
inputField<
|
|
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<
|
|
36
|
-
reqVal0<
|
|
37
|
-
rValArr<
|
|
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 {
|
|
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
|
-
|
|
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 {
|
|
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
|
-
*
|
|
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
|
-
|
|
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;
|