@shwfed/config 2.12.13 → 2.12.15
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/dist/module.json +1 -1
- package/dist/runtime/components/actions/buttons/2026-06-25/com.shwfed.actions.button.state.write/config.d.vue.ts +8 -0
- package/dist/runtime/components/actions/buttons/2026-06-25/com.shwfed.actions.button.state.write/config.vue +118 -25
- package/dist/runtime/components/actions/buttons/2026-06-25/com.shwfed.actions.button.state.write/config.vue.d.ts +8 -0
- package/dist/runtime/components/actions/buttons/2026-06-25/com.shwfed.actions.button.state.write/runtime.vue +48 -21
- package/dist/runtime/components/actions/buttons/2026-06-25/com.shwfed.actions.button.state.write/schema.d.ts +5 -0
- package/dist/runtime/components/actions/buttons/2026-06-25/com.shwfed.actions.button.state.write/schema.js +24 -1
- package/dist/runtime/components/config/use-editor.js +7 -0
- package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/config.d.vue.ts +18 -18
- package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/config.vue.d.ts +18 -18
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.d.vue.ts +18 -18
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.vue.d.ts +18 -18
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.d.vue.ts +18 -18
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.vue.d.ts +18 -18
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.d.vue.ts +18 -18
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.vue.d.ts +18 -18
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.d.vue.ts +18 -18
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.vue.d.ts +18 -18
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.d.vue.ts +18 -18
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.vue.d.ts +18 -18
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.d.vue.ts +18 -18
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.vue.d.ts +18 -18
- package/dist/runtime/components/sidebar/use-editor.js +7 -0
- package/dist/runtime/components/table/config.vue +10 -4
- package/dist/runtime/components/table/index.vue +6 -1
- package/dist/runtime/components/ui/expression-editor/ExpressionEditor.vue +21 -3
- package/dist/runtime/components/ui/expression-editor/index.d.ts +1 -0
- package/dist/runtime/components/ui/expression-editor/index.js +5 -0
- package/dist/runtime/components/ui/expression-editor/validity.d.ts +12 -0
- package/dist/runtime/components/ui/expression-editor/validity.js +27 -0
- package/dist/runtime/utils/cel-context.d.ts +15 -0
- package/dist/runtime/utils/cel-context.js +18 -1
- package/dist/runtime/vendor/cel-js/CLAUDE.md +1 -1
- package/dist/runtime/vendor/cel-js/PROMPT.md +15 -0
- package/dist/runtime/vendor/cel-js/lib/functions.js +28 -0
- package/package.json +1 -1
package/dist/module.json
CHANGED
|
@@ -13,6 +13,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
13
13
|
readonly target: string;
|
|
14
14
|
readonly operation: string;
|
|
15
15
|
}[] | undefined;
|
|
16
|
+
readonly requests?: readonly {
|
|
17
|
+
readonly id: string;
|
|
18
|
+
readonly request: string;
|
|
19
|
+
}[] | undefined;
|
|
16
20
|
readonly writes: readonly {
|
|
17
21
|
readonly path: string;
|
|
18
22
|
readonly value: string;
|
|
@@ -29,6 +33,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
29
33
|
readonly target: string;
|
|
30
34
|
readonly operation: string;
|
|
31
35
|
}[] | undefined;
|
|
36
|
+
readonly requests?: readonly {
|
|
37
|
+
readonly id: string;
|
|
38
|
+
readonly request: string;
|
|
39
|
+
}[] | undefined;
|
|
32
40
|
readonly writes: readonly {
|
|
33
41
|
readonly path: string;
|
|
34
42
|
readonly value: string;
|
|
@@ -8,6 +8,7 @@ import { Markdown } from "../../../../ui/markdown";
|
|
|
8
8
|
import { InputGroupButton } from "../../../../ui/input-group";
|
|
9
9
|
import { getStructFieldDescription, getStructFieldTitle } from "../../../schema";
|
|
10
10
|
import TriggersField from "../../../components/triggers-field.vue";
|
|
11
|
+
import TriggerRowScope from "../../../components/trigger-row-scope.vue";
|
|
11
12
|
import { schema } from "./schema";
|
|
12
13
|
defineOptions({ name: "ShwfedStateWriteActionConfig" });
|
|
13
14
|
const value = defineModel({ type: null, ...{ required: true } });
|
|
@@ -16,9 +17,33 @@ const actionSchema = schema(() => {
|
|
|
16
17
|
const fieldTitle = (f) => getStructFieldTitle(actionSchema, f) ?? f;
|
|
17
18
|
const fieldDescription = (f) => getStructFieldDescription(actionSchema, f);
|
|
18
19
|
const writes = computed(() => value.value.writes ?? []);
|
|
20
|
+
const requests = computed(() => value.value.requests ?? []);
|
|
21
|
+
const roster = computed(
|
|
22
|
+
() => requests.value.map((r, i) => ({
|
|
23
|
+
id: r.id,
|
|
24
|
+
label: `\u7B2C ${i + 1} \u6B65`,
|
|
25
|
+
valid: true,
|
|
26
|
+
description: "HTTP \u54CD\u5E94"
|
|
27
|
+
}))
|
|
28
|
+
);
|
|
19
29
|
function patchWrites(next) {
|
|
20
30
|
value.value = { ...value.value, writes: next };
|
|
21
31
|
}
|
|
32
|
+
function patchRequests(next) {
|
|
33
|
+
const draft = { ...value.value };
|
|
34
|
+
if (next.length === 0) Reflect.deleteProperty(draft, "requests");
|
|
35
|
+
else draft.requests = next;
|
|
36
|
+
value.value = draft;
|
|
37
|
+
}
|
|
38
|
+
function updateRequestRow(index, patch) {
|
|
39
|
+
patchRequests(requests.value.map((r, i) => i === index ? { ...r, ...patch } : r));
|
|
40
|
+
}
|
|
41
|
+
function addRequestRow() {
|
|
42
|
+
patchRequests([...requests.value, { id: crypto.randomUUID(), request: "" }]);
|
|
43
|
+
}
|
|
44
|
+
function removeRequestRow(index) {
|
|
45
|
+
patchRequests(requests.value.filter((_, i) => i !== index));
|
|
46
|
+
}
|
|
22
47
|
function updateRow(index, patch) {
|
|
23
48
|
patchWrites(writes.value.map((w, i) => i === index ? { ...w, ...patch } : w));
|
|
24
49
|
}
|
|
@@ -41,40 +66,37 @@ function updateTriggers(next) {
|
|
|
41
66
|
<Field orientation="vertical">
|
|
42
67
|
<FieldLabel class="text-xs text-zinc-500">
|
|
43
68
|
<template
|
|
44
|
-
v-if="fieldDescription('
|
|
69
|
+
v-if="fieldDescription('requests')"
|
|
45
70
|
#tooltip
|
|
46
71
|
>
|
|
47
72
|
<Markdown
|
|
48
|
-
:source="fieldDescription('
|
|
73
|
+
:source="fieldDescription('requests')"
|
|
49
74
|
block
|
|
50
75
|
class="prose prose-sm prose-zinc"
|
|
51
76
|
/>
|
|
52
77
|
</template>
|
|
53
|
-
{{ fieldTitle("
|
|
78
|
+
{{ fieldTitle("requests") }}
|
|
54
79
|
</FieldLabel>
|
|
55
80
|
|
|
56
81
|
<div class="flex flex-col gap-3">
|
|
57
|
-
<!-- One
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
the `trailing` slot.
|
|
82
|
+
<!-- One「写入前」request per line: a static「第 N 步」marker notched into
|
|
83
|
+
the editor's `leading` slot (its response is referenced positionally
|
|
84
|
+
as `steps["<id>"]`), the request expression in the editor, and a
|
|
85
|
+
destructive delete in the `trailing` slot. Outside `TriggerRowScope`
|
|
86
|
+
so the request expressions keep the base scope (no `steps`). -->
|
|
61
87
|
<ExpressionEditor
|
|
62
|
-
v-for="(row, index) in
|
|
63
|
-
:key="
|
|
64
|
-
:model-value="row.
|
|
65
|
-
|
|
66
|
-
|
|
88
|
+
v-for="(row, index) in requests"
|
|
89
|
+
:key="row.id"
|
|
90
|
+
:model-value="row.request"
|
|
91
|
+
result-type="HttpRequest"
|
|
92
|
+
placeholder="请求,如 http.get('/api/rate')"
|
|
93
|
+
@update:model-value="(v) => updateRequestRow(index, { request: v })"
|
|
67
94
|
>
|
|
68
95
|
<template #leading>
|
|
69
|
-
<
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
placeholder="路径"
|
|
74
|
-
class="w-44 min-w-0 border-r border-zinc-200 bg-transparent pr-3 font-mono text-sm text-zinc-700 outline-none placeholder:text-zinc-300"
|
|
75
|
-
:aria-label="`\u5199\u5165\u8DEF\u5F84 ${index + 1}`"
|
|
76
|
-
@input="updateRow(index, { path: $event.target.value })"
|
|
77
|
-
>
|
|
96
|
+
<span
|
|
97
|
+
data-slot="state-write-request-step"
|
|
98
|
+
class="w-16 shrink-0 border-r border-zinc-200 pr-3 font-mono text-xs whitespace-nowrap text-zinc-500 select-none"
|
|
99
|
+
>第 {{ index + 1 }} 步</span>
|
|
78
100
|
</template>
|
|
79
101
|
<template #trailing>
|
|
80
102
|
<InputGroupButton
|
|
@@ -84,8 +106,8 @@ function updateTriggers(next) {
|
|
|
84
106
|
>
|
|
85
107
|
<button
|
|
86
108
|
type="button"
|
|
87
|
-
:aria-label="`\u79FB\u9664\
|
|
88
|
-
@click="
|
|
109
|
+
:aria-label="`\u79FB\u9664\u8BF7\u6C42 ${index + 1}`"
|
|
110
|
+
@click="removeRequestRow(index)"
|
|
89
111
|
>
|
|
90
112
|
<Icon icon="fluent:delete-20-regular" />
|
|
91
113
|
</button>
|
|
@@ -96,14 +118,85 @@ function updateTriggers(next) {
|
|
|
96
118
|
<Button
|
|
97
119
|
type="button"
|
|
98
120
|
class="justify-center"
|
|
99
|
-
@click="
|
|
121
|
+
@click="addRequestRow"
|
|
100
122
|
>
|
|
101
123
|
<Icon icon="fluent:add-20-regular" />
|
|
102
|
-
<span
|
|
124
|
+
<span>添加请求</span>
|
|
103
125
|
</Button>
|
|
104
126
|
</div>
|
|
105
127
|
</Field>
|
|
106
128
|
|
|
129
|
+
<Field orientation="vertical">
|
|
130
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
131
|
+
<template
|
|
132
|
+
v-if="fieldDescription('writes')"
|
|
133
|
+
#tooltip
|
|
134
|
+
>
|
|
135
|
+
<Markdown
|
|
136
|
+
:source="fieldDescription('writes')"
|
|
137
|
+
block
|
|
138
|
+
class="prose prose-sm prose-zinc"
|
|
139
|
+
/>
|
|
140
|
+
</template>
|
|
141
|
+
{{ fieldTitle("writes") }}
|
|
142
|
+
</FieldLabel>
|
|
143
|
+
|
|
144
|
+
<!-- Advertise the「写入前」requests as the step roster to the value
|
|
145
|
+
editors only: they get the「第 N 步」picker chips + `steps` inline
|
|
146
|
+
validation, while the request editors above keep the base scope. -->
|
|
147
|
+
<TriggerRowScope :roster="roster">
|
|
148
|
+
<div class="flex flex-col gap-3">
|
|
149
|
+
<!-- One write item, on a single line: a monofont binding path notched
|
|
150
|
+
into the editor's `leading` slot, the value expression in the
|
|
151
|
+
editor itself (its own `{x}` badge), and a destructive delete in
|
|
152
|
+
the `trailing` slot. Reuses the ExpressionEditor's own InputGroup. -->
|
|
153
|
+
<ExpressionEditor
|
|
154
|
+
v-for="(row, index) in writes"
|
|
155
|
+
:key="index"
|
|
156
|
+
:model-value="row.value"
|
|
157
|
+
placeholder="值,如 selected[?0].?exchangeRate"
|
|
158
|
+
@update:model-value="(v) => updateRow(index, { value: v })"
|
|
159
|
+
>
|
|
160
|
+
<template #leading>
|
|
161
|
+
<input
|
|
162
|
+
type="text"
|
|
163
|
+
data-slot="state-write-path"
|
|
164
|
+
:value="row.path"
|
|
165
|
+
placeholder="路径"
|
|
166
|
+
class="w-44 min-w-0 border-r border-zinc-200 bg-transparent pr-3 font-mono text-sm text-zinc-700 outline-none placeholder:text-zinc-300"
|
|
167
|
+
:aria-label="`\u5199\u5165\u8DEF\u5F84 ${index + 1}`"
|
|
168
|
+
@input="updateRow(index, { path: $event.target.value })"
|
|
169
|
+
>
|
|
170
|
+
</template>
|
|
171
|
+
<template #trailing>
|
|
172
|
+
<InputGroupButton
|
|
173
|
+
variant="destructive"
|
|
174
|
+
size="icon-xs"
|
|
175
|
+
as-child
|
|
176
|
+
>
|
|
177
|
+
<button
|
|
178
|
+
type="button"
|
|
179
|
+
:aria-label="`\u79FB\u9664\u5199\u5165\u9879 ${index + 1}`"
|
|
180
|
+
@click="removeRow(index)"
|
|
181
|
+
>
|
|
182
|
+
<Icon icon="fluent:delete-20-regular" />
|
|
183
|
+
</button>
|
|
184
|
+
</InputGroupButton>
|
|
185
|
+
</template>
|
|
186
|
+
</ExpressionEditor>
|
|
187
|
+
|
|
188
|
+
<Button
|
|
189
|
+
type="button"
|
|
190
|
+
class="justify-center"
|
|
191
|
+
@click="addRow"
|
|
192
|
+
>
|
|
193
|
+
<Icon icon="fluent:add-20-regular" />
|
|
194
|
+
<span>添加写入项</span>
|
|
195
|
+
</Button>
|
|
196
|
+
</div>
|
|
197
|
+
</TriggerRowScope>
|
|
198
|
+
</Field>
|
|
199
|
+
|
|
107
200
|
<Field orientation="vertical">
|
|
108
201
|
<FieldLabel class="text-xs text-zinc-500">
|
|
109
202
|
<template
|
|
@@ -13,6 +13,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
13
13
|
readonly target: string;
|
|
14
14
|
readonly operation: string;
|
|
15
15
|
}[] | undefined;
|
|
16
|
+
readonly requests?: readonly {
|
|
17
|
+
readonly id: string;
|
|
18
|
+
readonly request: string;
|
|
19
|
+
}[] | undefined;
|
|
16
20
|
readonly writes: readonly {
|
|
17
21
|
readonly path: string;
|
|
18
22
|
readonly value: string;
|
|
@@ -29,6 +33,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
29
33
|
readonly target: string;
|
|
30
34
|
readonly operation: string;
|
|
31
35
|
}[] | undefined;
|
|
36
|
+
readonly requests?: readonly {
|
|
37
|
+
readonly id: string;
|
|
38
|
+
readonly request: string;
|
|
39
|
+
}[] | undefined;
|
|
32
40
|
readonly writes: readonly {
|
|
33
41
|
readonly path: string;
|
|
34
42
|
readonly value: string;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { Effect } from "effect";
|
|
2
|
+
import { Effect, Option } from "effect";
|
|
3
|
+
import { Fetch } from "fx-fetch";
|
|
3
4
|
import { createDefu } from "defu";
|
|
4
5
|
import { cel as _rawCel } from "../../../../../utils/cel";
|
|
5
6
|
import { celBindings, injectCELContext } from "../../../../../utils/cel-context";
|
|
6
7
|
import { dispatchTriggers, useEventChannel } from "../../../../../share/event-bus";
|
|
8
|
+
import { asRequest } from "../../../../../share/request";
|
|
7
9
|
import { useFormState } from "../../../../form/utils/state";
|
|
8
10
|
import ShwfedActionDefinition from "../../../components/definition.vue";
|
|
9
11
|
defineOptions({ name: "ShwfedStateWriteActionRuntime" });
|
|
@@ -31,27 +33,52 @@ function mergeAtPath(current, next) {
|
|
|
31
33
|
}
|
|
32
34
|
return next;
|
|
33
35
|
}
|
|
34
|
-
const effect = Effect.suspend(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
|
|
36
|
+
const effect = Effect.suspend(() => {
|
|
37
|
+
const steps = {};
|
|
38
|
+
return Effect.forEach(
|
|
39
|
+
// 写入前: issue each request in list order against the base scope (no
|
|
40
|
+
// `steps` — requests can't reference each other). `asRequest` maps the
|
|
41
|
+
// evaluated value to `Some(builder)` / `None` (author opted out → skip the
|
|
42
|
+
// fetch, leaving `steps["<id>"]` unset). A failed `.json()` short-circuits
|
|
43
|
+
// the whole click before any write runs — the effect fails and the action
|
|
44
|
+
// runner absorbs it, exactly as a failing `value` expression does.
|
|
45
|
+
props.config.requests ?? [],
|
|
46
|
+
(request) => Effect.flatMap($cel(request.request), (evaluated) => {
|
|
47
|
+
const builder = asRequest(evaluated);
|
|
48
|
+
if (Option.isNone(builder)) return Effect.void;
|
|
49
|
+
return Effect.map(builder.value.json(), (json) => {
|
|
50
|
+
steps[request.id] = json;
|
|
51
|
+
});
|
|
52
|
+
}),
|
|
53
|
+
{ discard: true }
|
|
54
|
+
).pipe(
|
|
55
|
+
Effect.flatMap(
|
|
56
|
+
() => (
|
|
57
|
+
// Evaluate every row's `value` in list order. A row with a blank `path` is
|
|
58
|
+
// skipped (a half-authored row writes nowhere) but its value is never
|
|
59
|
+
// evaluated — `Effect.forEach` keeps the click sequential and short-circuits
|
|
60
|
+
// on the first failing expression, matching the old map-eval-then-write.
|
|
61
|
+
Effect.forEach(
|
|
62
|
+
props.config.writes ?? [],
|
|
63
|
+
(write) => {
|
|
64
|
+
const path = write.path?.trim() ?? "";
|
|
65
|
+
if (path.length === 0) return Effect.void;
|
|
66
|
+
return Effect.map($cel(write.value, { steps }), (result) => {
|
|
67
|
+
const merged = mergeAtPath(formState.getAt(path), result);
|
|
68
|
+
formState.setAt(path, merged);
|
|
69
|
+
});
|
|
70
|
+
},
|
|
71
|
+
{ discard: true }
|
|
72
|
+
)
|
|
73
|
+
)
|
|
51
74
|
),
|
|
52
|
-
() => dispatchTriggers(channel, props.config.onSuccess, $cel)
|
|
53
|
-
|
|
54
|
-
|
|
75
|
+
Effect.flatMap(() => dispatchTriggers(channel, props.config.onSuccess, $cel)),
|
|
76
|
+
// The request builders need a `Fetch` layer; `ShwfedActionDefinition` runs
|
|
77
|
+
// the effect with no requirements channel, so provide it here — same layer
|
|
78
|
+
// the request op/button use.
|
|
79
|
+
Effect.provide(Fetch.layer)
|
|
80
|
+
);
|
|
81
|
+
});
|
|
55
82
|
</script>
|
|
56
83
|
|
|
57
84
|
<template>
|
|
@@ -9,6 +9,10 @@ export declare const metadata: {
|
|
|
9
9
|
export declare function schema(configure: (env: Environment) => void): Schema.Struct<{
|
|
10
10
|
type: Schema.Literal<["com.shwfed.actions.button.state.write"]>;
|
|
11
11
|
compatibilityDate: Schema.Literal<["2026-06-25"]>;
|
|
12
|
+
requests: Schema.optional<Schema.Array$<Schema.Struct<{
|
|
13
|
+
id: Schema.refine<string, typeof Schema.String>;
|
|
14
|
+
request: Schema.Schema<string, string, never>;
|
|
15
|
+
}>>>;
|
|
12
16
|
writes: Schema.Array$<Schema.Struct<{
|
|
13
17
|
path: Schema.SchemaClass<string, string, never>;
|
|
14
18
|
value: Schema.Schema<string, string, never>;
|
|
@@ -23,3 +27,4 @@ export declare function schema(configure: (env: Environment) => void): Schema.St
|
|
|
23
27
|
}>;
|
|
24
28
|
export type Value = Schema.Schema.Type<ReturnType<typeof schema>>;
|
|
25
29
|
export type WriteValue = Value['writes'][number];
|
|
30
|
+
export type RequestValue = NonNullable<Value['requests']>[number];
|
|
@@ -2,6 +2,7 @@ import { Schema } from "effect";
|
|
|
2
2
|
import { Expression } from "../../../../../share/expression.js";
|
|
3
3
|
import { Triggers } from "../../../../../share/event-bus.js";
|
|
4
4
|
import { md } from "../../../../../share/markdown.js";
|
|
5
|
+
import { registerStepsVariableIfAbsent } from "../../../../operations/utils/step-vars.js";
|
|
5
6
|
export const type = "com.shwfed.actions.button.state.write";
|
|
6
7
|
export const compatibilityDate = "2026-06-25";
|
|
7
8
|
export const metadata = {
|
|
@@ -9,19 +10,41 @@ export const metadata = {
|
|
|
9
10
|
icon: "fluent:document-edit-20-regular"
|
|
10
11
|
};
|
|
11
12
|
export function schema(configure) {
|
|
13
|
+
const withSteps = (env) => {
|
|
14
|
+
configure(env);
|
|
15
|
+
registerStepsVariableIfAbsent(env);
|
|
16
|
+
};
|
|
12
17
|
const Write = Schema.Struct({
|
|
13
18
|
path: Schema.String.annotations({
|
|
14
19
|
title: "\u8DEF\u5F84",
|
|
15
20
|
description: "\u5199\u5165\u7684\u7ED1\u5B9A\u8DEF\u5F84\uFF0C\u5982 `dataJson.cus_currency`"
|
|
16
21
|
}),
|
|
17
|
-
value: Expression({ configure }).annotations({
|
|
22
|
+
value: Expression({ configure: withSteps }).annotations({
|
|
18
23
|
title: "\u503C",
|
|
19
24
|
description: "\u70B9\u51FB\u540E\u6C42\u503C\uFF0C\u7ED3\u679C\u5199\u5165\u8BE5\u8DEF\u5F84"
|
|
20
25
|
})
|
|
21
26
|
});
|
|
27
|
+
const Request = Schema.Struct({
|
|
28
|
+
id: Schema.UUID.annotations({
|
|
29
|
+
title: "ID",
|
|
30
|
+
description: '\u8BF7\u6C42\u6807\u8BC6\uFF0C\u5199\u5165\u503C\u7ECF `steps["<id>"]` \u5F15\u7528'
|
|
31
|
+
}),
|
|
32
|
+
request: Expression({ configure, resultType: "HttpRequest" }).annotations({
|
|
33
|
+
title: "\u8BF7\u6C42",
|
|
34
|
+
description: "\u6784\u9020\u4E00\u4E2A\u8BF7\u6C42\uFF0C\u670D\u52A1\u5668\u987B\u8FD4\u56DE JSON \u54CD\u5E94\uFF1B\u7ED3\u679C\u6309\u300C\u7B2C N \u6B65\u300D\u5B58\u5165 `steps`"
|
|
35
|
+
})
|
|
36
|
+
});
|
|
22
37
|
return Schema.Struct({
|
|
23
38
|
type: Schema.Literal(type),
|
|
24
39
|
compatibilityDate: Schema.Literal(compatibilityDate),
|
|
40
|
+
requests: Schema.optional(Schema.Array(Request).annotations({
|
|
41
|
+
title: "\u5199\u5165\u524D",
|
|
42
|
+
description: md`
|
|
43
|
+
点击后先按列表顺序发起这些请求,其响应可在「写入值」中经
|
|
44
|
+
\`steps["<第 N 步>"]\` 引用。任一请求失败(网络错误 / 非 2xx / 不可解析)
|
|
45
|
+
则中止,不进行任何写入。
|
|
46
|
+
`
|
|
47
|
+
})),
|
|
25
48
|
writes: Schema.Array(Write).annotations({
|
|
26
49
|
title: "\u5199\u5165\u503C",
|
|
27
50
|
description: md`
|
|
@@ -6,6 +6,7 @@ import { readClip, reidFragment, writeClip } from "../../share/clipboard.js";
|
|
|
6
6
|
import { PageConfig } from "./schema.js";
|
|
7
7
|
import { BLOCKS, findBlock } from "./utils/resolve.js";
|
|
8
8
|
import { formatValidationError } from "./utils/validation-error.js";
|
|
9
|
+
import { createExpressionValidityRegistry, provideExpressionValidity } from "../ui/expression-editor/index.js";
|
|
9
10
|
function deepClone(value) {
|
|
10
11
|
return JSON.parse(JSON.stringify(value));
|
|
11
12
|
}
|
|
@@ -373,10 +374,16 @@ export function useConfigEditor(model, options = {}) {
|
|
|
373
374
|
pushBlock(blockId);
|
|
374
375
|
}
|
|
375
376
|
const validationError = ref(null);
|
|
377
|
+
const validityRegistry = createExpressionValidityRegistry();
|
|
378
|
+
provideExpressionValidity(validityRegistry);
|
|
376
379
|
function confirm() {
|
|
377
380
|
const schema = PageConfig(configure);
|
|
378
381
|
try {
|
|
379
382
|
const decoded = Schema.decodeUnknownSync(schema)(draft.value);
|
|
383
|
+
if (!validityRegistry.allValid()) {
|
|
384
|
+
validationError.value = "\u5B58\u5728\u65E0\u6548\u7684\u8DE8\u5C42\u4F5C\u7528\u57DF\u5F15\u7528\uFF0C\u8BF7\u4FEE\u6B63\u6807\u7EA2\u7684\u8868\u8FBE\u5F0F\u540E\u518D\u4FDD\u5B58";
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
380
387
|
validationError.value = null;
|
|
381
388
|
model.value = decoded;
|
|
382
389
|
baseline.value = deepClone(decoded);
|
|
@@ -56,15 +56,6 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
56
56
|
readonly message: string;
|
|
57
57
|
}[]];
|
|
58
58
|
readonly cascade: "independent" | "cascade-down" | "cascade-both";
|
|
59
|
-
readonly nodeTooltip?: readonly [{
|
|
60
|
-
readonly locale: "zh";
|
|
61
|
-
readonly message: string;
|
|
62
|
-
}, ...{
|
|
63
|
-
readonly locale: "en" | "ja" | "ko";
|
|
64
|
-
readonly message: string;
|
|
65
|
-
}[]] | undefined;
|
|
66
|
-
readonly nodeSelectable?: string | undefined;
|
|
67
|
-
readonly expandAll: boolean;
|
|
68
59
|
readonly validations?: readonly {
|
|
69
60
|
readonly message: readonly [{
|
|
70
61
|
readonly locale: "zh";
|
|
@@ -76,6 +67,15 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
76
67
|
readonly warning?: boolean | undefined;
|
|
77
68
|
readonly when: string;
|
|
78
69
|
}[] | undefined;
|
|
70
|
+
readonly nodeTooltip?: readonly [{
|
|
71
|
+
readonly locale: "zh";
|
|
72
|
+
readonly message: string;
|
|
73
|
+
}, ...{
|
|
74
|
+
readonly locale: "en" | "ja" | "ko";
|
|
75
|
+
readonly message: string;
|
|
76
|
+
}[]] | undefined;
|
|
77
|
+
readonly nodeSelectable?: string | undefined;
|
|
78
|
+
readonly expandAll: boolean;
|
|
79
79
|
}) => any;
|
|
80
80
|
}, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
|
|
81
81
|
"onUpdate:modelValue"?: ((value: {
|
|
@@ -131,15 +131,6 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
131
131
|
readonly message: string;
|
|
132
132
|
}[]];
|
|
133
133
|
readonly cascade: "independent" | "cascade-down" | "cascade-both";
|
|
134
|
-
readonly nodeTooltip?: readonly [{
|
|
135
|
-
readonly locale: "zh";
|
|
136
|
-
readonly message: string;
|
|
137
|
-
}, ...{
|
|
138
|
-
readonly locale: "en" | "ja" | "ko";
|
|
139
|
-
readonly message: string;
|
|
140
|
-
}[]] | undefined;
|
|
141
|
-
readonly nodeSelectable?: string | undefined;
|
|
142
|
-
readonly expandAll: boolean;
|
|
143
134
|
readonly validations?: readonly {
|
|
144
135
|
readonly message: readonly [{
|
|
145
136
|
readonly locale: "zh";
|
|
@@ -151,6 +142,15 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
151
142
|
readonly warning?: boolean | undefined;
|
|
152
143
|
readonly when: string;
|
|
153
144
|
}[] | undefined;
|
|
145
|
+
readonly nodeTooltip?: readonly [{
|
|
146
|
+
readonly locale: "zh";
|
|
147
|
+
readonly message: string;
|
|
148
|
+
}, ...{
|
|
149
|
+
readonly locale: "en" | "ja" | "ko";
|
|
150
|
+
readonly message: string;
|
|
151
|
+
}[]] | undefined;
|
|
152
|
+
readonly nodeSelectable?: string | undefined;
|
|
153
|
+
readonly expandAll: boolean;
|
|
154
154
|
}) => any) | undefined;
|
|
155
155
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
156
156
|
declare const _default: typeof __VLS_export;
|
|
@@ -56,15 +56,6 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
56
56
|
readonly message: string;
|
|
57
57
|
}[]];
|
|
58
58
|
readonly cascade: "independent" | "cascade-down" | "cascade-both";
|
|
59
|
-
readonly nodeTooltip?: readonly [{
|
|
60
|
-
readonly locale: "zh";
|
|
61
|
-
readonly message: string;
|
|
62
|
-
}, ...{
|
|
63
|
-
readonly locale: "en" | "ja" | "ko";
|
|
64
|
-
readonly message: string;
|
|
65
|
-
}[]] | undefined;
|
|
66
|
-
readonly nodeSelectable?: string | undefined;
|
|
67
|
-
readonly expandAll: boolean;
|
|
68
59
|
readonly validations?: readonly {
|
|
69
60
|
readonly message: readonly [{
|
|
70
61
|
readonly locale: "zh";
|
|
@@ -76,6 +67,15 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
76
67
|
readonly warning?: boolean | undefined;
|
|
77
68
|
readonly when: string;
|
|
78
69
|
}[] | undefined;
|
|
70
|
+
readonly nodeTooltip?: readonly [{
|
|
71
|
+
readonly locale: "zh";
|
|
72
|
+
readonly message: string;
|
|
73
|
+
}, ...{
|
|
74
|
+
readonly locale: "en" | "ja" | "ko";
|
|
75
|
+
readonly message: string;
|
|
76
|
+
}[]] | undefined;
|
|
77
|
+
readonly nodeSelectable?: string | undefined;
|
|
78
|
+
readonly expandAll: boolean;
|
|
79
79
|
}) => any;
|
|
80
80
|
}, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
|
|
81
81
|
"onUpdate:modelValue"?: ((value: {
|
|
@@ -131,15 +131,6 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
131
131
|
readonly message: string;
|
|
132
132
|
}[]];
|
|
133
133
|
readonly cascade: "independent" | "cascade-down" | "cascade-both";
|
|
134
|
-
readonly nodeTooltip?: readonly [{
|
|
135
|
-
readonly locale: "zh";
|
|
136
|
-
readonly message: string;
|
|
137
|
-
}, ...{
|
|
138
|
-
readonly locale: "en" | "ja" | "ko";
|
|
139
|
-
readonly message: string;
|
|
140
|
-
}[]] | undefined;
|
|
141
|
-
readonly nodeSelectable?: string | undefined;
|
|
142
|
-
readonly expandAll: boolean;
|
|
143
134
|
readonly validations?: readonly {
|
|
144
135
|
readonly message: readonly [{
|
|
145
136
|
readonly locale: "zh";
|
|
@@ -151,6 +142,15 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
151
142
|
readonly warning?: boolean | undefined;
|
|
152
143
|
readonly when: string;
|
|
153
144
|
}[] | undefined;
|
|
145
|
+
readonly nodeTooltip?: readonly [{
|
|
146
|
+
readonly locale: "zh";
|
|
147
|
+
readonly message: string;
|
|
148
|
+
}, ...{
|
|
149
|
+
readonly locale: "en" | "ja" | "ko";
|
|
150
|
+
readonly message: string;
|
|
151
|
+
}[]] | undefined;
|
|
152
|
+
readonly nodeSelectable?: string | undefined;
|
|
153
|
+
readonly expandAll: boolean;
|
|
154
154
|
}) => any) | undefined;
|
|
155
155
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
156
156
|
declare const _default: typeof __VLS_export;
|
|
@@ -53,15 +53,6 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
53
53
|
readonly message: string;
|
|
54
54
|
}[]];
|
|
55
55
|
readonly cascade: "independent" | "cascade-down" | "cascade-both";
|
|
56
|
-
readonly nodeTooltip?: readonly [{
|
|
57
|
-
readonly locale: "zh";
|
|
58
|
-
readonly message: string;
|
|
59
|
-
}, ...{
|
|
60
|
-
readonly locale: "en" | "ja" | "ko";
|
|
61
|
-
readonly message: string;
|
|
62
|
-
}[]] | undefined;
|
|
63
|
-
readonly nodeSelectable?: string | undefined;
|
|
64
|
-
readonly expandAll: boolean;
|
|
65
56
|
readonly validations?: readonly {
|
|
66
57
|
readonly message: readonly [{
|
|
67
58
|
readonly locale: "zh";
|
|
@@ -73,6 +64,15 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
73
64
|
readonly warning?: boolean | undefined;
|
|
74
65
|
readonly when: string;
|
|
75
66
|
}[] | undefined;
|
|
67
|
+
readonly nodeTooltip?: readonly [{
|
|
68
|
+
readonly locale: "zh";
|
|
69
|
+
readonly message: string;
|
|
70
|
+
}, ...{
|
|
71
|
+
readonly locale: "en" | "ja" | "ko";
|
|
72
|
+
readonly message: string;
|
|
73
|
+
}[]] | undefined;
|
|
74
|
+
readonly nodeSelectable?: string | undefined;
|
|
75
|
+
readonly expandAll: boolean;
|
|
76
76
|
}) => any;
|
|
77
77
|
}, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
|
|
78
78
|
"onUpdate:modelValue"?: ((value: {
|
|
@@ -125,15 +125,6 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
125
125
|
readonly message: string;
|
|
126
126
|
}[]];
|
|
127
127
|
readonly cascade: "independent" | "cascade-down" | "cascade-both";
|
|
128
|
-
readonly nodeTooltip?: readonly [{
|
|
129
|
-
readonly locale: "zh";
|
|
130
|
-
readonly message: string;
|
|
131
|
-
}, ...{
|
|
132
|
-
readonly locale: "en" | "ja" | "ko";
|
|
133
|
-
readonly message: string;
|
|
134
|
-
}[]] | undefined;
|
|
135
|
-
readonly nodeSelectable?: string | undefined;
|
|
136
|
-
readonly expandAll: boolean;
|
|
137
128
|
readonly validations?: readonly {
|
|
138
129
|
readonly message: readonly [{
|
|
139
130
|
readonly locale: "zh";
|
|
@@ -145,6 +136,15 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
145
136
|
readonly warning?: boolean | undefined;
|
|
146
137
|
readonly when: string;
|
|
147
138
|
}[] | undefined;
|
|
139
|
+
readonly nodeTooltip?: readonly [{
|
|
140
|
+
readonly locale: "zh";
|
|
141
|
+
readonly message: string;
|
|
142
|
+
}, ...{
|
|
143
|
+
readonly locale: "en" | "ja" | "ko";
|
|
144
|
+
readonly message: string;
|
|
145
|
+
}[]] | undefined;
|
|
146
|
+
readonly nodeSelectable?: string | undefined;
|
|
147
|
+
readonly expandAll: boolean;
|
|
148
148
|
}) => any) | undefined;
|
|
149
149
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
150
150
|
declare const _default: typeof __VLS_export;
|