@shwfed/config 2.7.6 → 2.7.8
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/mcp.mjs +165 -52
- package/dist/module.json +1 -1
- package/dist/preview/assets/badge-KAEXz3VO.js +1 -0
- package/dist/preview/assets/{config-C947O8za.js → config-BXx5syNf.js} +1 -1
- package/dist/preview/assets/{config-DhAntnE5.js → config-Bb9Yeh33.js} +1 -1
- package/dist/preview/assets/config-C-QRPeN1.js +1 -0
- package/dist/preview/assets/config-CkKx7sVR.js +1 -0
- package/dist/preview/assets/config-CtbYlZCL.js +1 -0
- package/dist/preview/assets/{config-Bl8L6943.js → config-DPlbFBRi.js} +1 -1
- package/dist/preview/assets/config-DbfJWa8K.js +1 -0
- package/dist/preview/assets/{config-DppExb4h.js → config-DbirfZyy.js} +1 -1
- package/dist/preview/assets/{config-B7hXY5FF.js → config-ZczGik30.js} +1 -1
- package/dist/preview/assets/definition.vue_vue_type_script_setup_true_lang-CQ6MUPKO.js +1 -0
- package/dist/preview/assets/{index-DiC1rvCq.js → index-Bv_aA34a.js} +1 -1
- package/dist/preview/assets/{index-B0PL01fm.css → index-C9P-6gZd.css} +1 -1
- package/dist/preview/assets/index-CJFU9znN.js +1 -0
- package/dist/preview/assets/index-DUOkekYu.js +680 -0
- package/dist/preview/assets/item-SC0WQMVu.js +1 -0
- package/dist/preview/assets/{runtime-DmV_M4B_.js → runtime-BPOf7Yqz.js} +1 -1
- package/dist/preview/assets/runtime-CC2caFS9.js +1 -0
- package/dist/preview/assets/runtime-CLaRFZzt.js +1 -0
- package/dist/preview/assets/runtime-Ckuz5Kxm.js +1 -0
- package/dist/preview/assets/{runtime-BQnHKogz.js → runtime-CnKlH0mi.js} +1 -1
- package/dist/preview/assets/runtime-DO0anKbw.js +1 -0
- package/dist/preview/assets/{runtime-kLWO8JbC.js → runtime-DcStOiOi.js} +1 -1
- package/dist/preview/assets/runtime-EVgYW6_7.js +1 -0
- package/dist/preview/assets/runtime-i32sR7d3.js +1 -0
- package/dist/preview/index.html +2 -2
- package/dist/runtime/components/actions/buttons/2026-04-21/com.shwfed.actions.button.navigation/runtime.vue +16 -2
- package/dist/runtime/components/block-layout-editor/index.vue +1 -4
- package/dist/runtime/components/config/blocks/2026-05-17/com.shwfed.block.chart.xy/config.vue +5 -0
- package/dist/runtime/components/config/blocks/2026-05-17/com.shwfed.block.chart.xy/runtime.vue +2 -2
- package/dist/runtime/components/config/blocks/2026-06-01/com.shwfed.block.animated.number/item.vue +2 -2
- package/dist/runtime/components/config/blocks/2026-06-01/com.shwfed.block.animated.number/schema.js +2 -2
- package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.card/badge.vue +3 -2
- package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.card/schema.js +2 -2
- package/dist/runtime/components/form/config.vue +24 -16
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.combobox.single.remote/runtime.vue +6 -5
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.combobox.single.remote/schema.js +2 -2
- package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/runtime.vue +3 -4
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/runtime.vue +3 -4
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/runtime.vue +3 -4
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.multi/runtime.vue +6 -5
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.multi/schema.js +2 -2
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.single/runtime.vue +6 -5
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.single/schema.js +2 -2
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/runtime.vue +3 -4
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/runtime.vue +3 -4
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/runtime.vue +3 -4
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/runtime.vue +3 -4
- package/dist/runtime/components/form/schema.d.ts +1 -1
- package/dist/runtime/components/form/schema.js +8 -3
- package/dist/runtime/components/form/utils/initial.d.ts +5 -4
- package/dist/runtime/components/form/utils/initial.js +2 -2
- package/dist/runtime/components/form/utils/schema-meta.d.ts +2 -0
- package/dist/runtime/components/form/utils/schema-meta.js +24 -0
- package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/runtime.vue +7 -6
- package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/schema.js +2 -2
- package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/runtime.vue +7 -6
- package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/schema.js +2 -2
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/runtime.vue +7 -6
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/schema.js +2 -2
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/runtime.vue +7 -6
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/schema.js +2 -2
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/runtime.vue +7 -6
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/schema.js +2 -2
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/runtime.vue +7 -6
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/schema.js +2 -2
- package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/runtime.vue +3 -4
- package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/schema.js +2 -2
- package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/runtime.vue +3 -4
- package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/schema.js +2 -2
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/runtime.vue +7 -6
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/schema.js +2 -2
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/runtime.vue +7 -6
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/schema.js +2 -2
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/runtime.vue +3 -4
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/schema.js +2 -2
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/runtime.vue +3 -4
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/schema.js +2 -2
- package/dist/runtime/components/table/config.vue +0 -36
- package/dist/runtime/components/table/index.vue +3 -4
- package/dist/runtime/components/table/schema.js +3 -3
- package/dist/runtime/components/ui/expression-editor/ExpressionEditor.d.vue.ts +4 -3
- package/dist/runtime/components/ui/expression-editor/ExpressionEditor.vue +135 -111
- package/dist/runtime/components/ui/expression-editor/ExpressionEditor.vue.d.ts +4 -3
- package/dist/runtime/share/expression.d.ts +36 -0
- package/dist/runtime/share/expression.js +38 -17
- package/dist/runtime/share/request.d.ts +29 -0
- package/dist/runtime/share/request.js +11 -0
- package/dist/runtime/vendor/cel-js/CLAUDE.md +3 -3
- package/dist/runtime/vendor/cel-js/PROMPT.md +44 -3
- package/dist/runtime/vendor/cel-js/lib/functions.js +2 -2
- package/dist/runtime/vendor/cel-js/lib/macros.js +66 -14
- package/dist/runtime/vendor/cel-js/lib/optional.js +52 -1
- package/package.json +1 -1
- package/dist/preview/assets/badge-C-IvPZBx.js +0 -1
- package/dist/preview/assets/config-DXlCQMVi.js +0 -1
- package/dist/preview/assets/config-Dj0rEZRq.js +0 -1
- package/dist/preview/assets/config-_aVQvlhc.js +0 -1
- package/dist/preview/assets/config-l01zamcS.js +0 -1
- package/dist/preview/assets/definition.vue_vue_type_script_setup_true_lang-BbuC0qEM.js +0 -1
- package/dist/preview/assets/index-BNaI1T0H.js +0 -680
- package/dist/preview/assets/index-BwoBmSxu.js +0 -1
- package/dist/preview/assets/item-GFiAkFW6.js +0 -1
- package/dist/preview/assets/runtime-5h5U6Ozr.js +0 -1
- package/dist/preview/assets/runtime-B6dXW6zW.js +0 -1
- package/dist/preview/assets/runtime-BEOIc4zU.js +0 -1
- package/dist/preview/assets/runtime-Bx7G-5dR.js +0 -1
- package/dist/preview/assets/runtime-TNDFpOlo.js +0 -1
- package/dist/preview/assets/runtime-g9hb36Vh.js +0 -1
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { Icon } from "@iconify/vue";
|
|
3
|
-
import { Effect } from "effect";
|
|
3
|
+
import { Effect, Option } from "effect";
|
|
4
4
|
import { Fetch } from "fx-fetch";
|
|
5
5
|
import { watchDebounced } from "@vueuse/core";
|
|
6
6
|
import { toast } from "vue-sonner";
|
|
7
7
|
import { computed, nextTick, ref, watch } from "vue";
|
|
8
8
|
import { useI18n } from "vue-i18n";
|
|
9
|
+
import { asRequest, fetchJsonOption } from "../../../../../share/request";
|
|
9
10
|
import { cel as _rawCel } from "../../../../../utils/cel";
|
|
10
11
|
import { celBindings, injectCELContext } from "../../../../../utils/cel-context";
|
|
11
12
|
import { getLocalizedText } from "../../../../../share/locale";
|
|
@@ -108,10 +109,10 @@ const requestSignature = computed(() => {
|
|
|
108
109
|
const expr = props.column.options.request;
|
|
109
110
|
if (!expr) return null;
|
|
110
111
|
try {
|
|
111
|
-
const
|
|
112
|
+
const req = asRequest(Effect.runSync(
|
|
112
113
|
$cel(expr, { row: row.value, index: rowIndex.value })
|
|
113
|
-
);
|
|
114
|
-
return JSON.stringify(
|
|
114
|
+
));
|
|
115
|
+
return Option.isSome(req) ? JSON.stringify(req.value.describe()) : null;
|
|
115
116
|
} catch {
|
|
116
117
|
return null;
|
|
117
118
|
}
|
|
@@ -126,8 +127,8 @@ async function fetchOptions() {
|
|
|
126
127
|
const expr = props.column.options.request;
|
|
127
128
|
remoteLoading.value = true;
|
|
128
129
|
const program = Effect.gen(function* () {
|
|
129
|
-
const
|
|
130
|
-
return
|
|
130
|
+
const json = yield* fetchJsonOption(yield* $cel(expr, { row: row.value, index: rowIndex.value }));
|
|
131
|
+
return Option.getOrNull(json);
|
|
131
132
|
});
|
|
132
133
|
try {
|
|
133
134
|
const result = await Effect.runPromise(Effect.provide(program, sharedFetchLayer));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Effect, Schema } from "effect";
|
|
2
2
|
import { getProperty } from "dot-prop";
|
|
3
|
-
import { Expression, LocaleMarkdown } from "../../../../../share/expression.js";
|
|
3
|
+
import { Expression, HttpRequestResult, LocaleMarkdown } from "../../../../../share/expression.js";
|
|
4
4
|
import { Locale } from "../../../../../share/locale.js";
|
|
5
5
|
import { Triggers } from "../../../../../share/event-bus.js";
|
|
6
6
|
import {
|
|
@@ -58,7 +58,7 @@ export function remoteOptionsSchema(configure) {
|
|
|
58
58
|
configure(env);
|
|
59
59
|
registerRowVariablesIfAbsent(env);
|
|
60
60
|
},
|
|
61
|
-
resultType:
|
|
61
|
+
resultType: HttpRequestResult
|
|
62
62
|
});
|
|
63
63
|
const CelOptions = Expression({
|
|
64
64
|
configure: (env) => {
|
|
@@ -6,6 +6,7 @@ import { useI18n } from "vue-i18n";
|
|
|
6
6
|
import { cel as _rawCel } from "../../../../../utils/cel";
|
|
7
7
|
import { celBindings, injectCELContext } from "../../../../../utils/cel-context";
|
|
8
8
|
import { getLocalizedText } from "../../../../../share/locale";
|
|
9
|
+
import { fetchJsonOption } from "../../../../../share/request";
|
|
9
10
|
import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput } from "../../../../ui/input-group";
|
|
10
11
|
import { Markdown } from "../../../../ui/markdown";
|
|
11
12
|
import { Popover, PopoverAnchor, PopoverContent, PopoverTrigger } from "../../../../ui/popover";
|
|
@@ -156,12 +157,10 @@ async function fetchTree() {
|
|
|
156
157
|
const effect = Effect.gen(function* () {
|
|
157
158
|
let jsonOpt = Option.none();
|
|
158
159
|
if (dataSource.request) {
|
|
159
|
-
|
|
160
|
+
jsonOpt = yield* fetchJsonOption(yield* $cel(dataSource.request, {
|
|
160
161
|
row: row.value,
|
|
161
162
|
index: rowIndex.value
|
|
162
|
-
});
|
|
163
|
-
const response = yield* builder.json();
|
|
164
|
-
jsonOpt = Option.some(response);
|
|
163
|
+
}));
|
|
165
164
|
}
|
|
166
165
|
const dataRaw = yield* $cel(dataSource.data, {
|
|
167
166
|
row: row.value,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Effect, Schema } from "effect";
|
|
2
2
|
import { getProperty } from "dot-prop";
|
|
3
3
|
import { Locale } from "../../../../../share/locale.js";
|
|
4
|
-
import { Expression, LocaleMarkdown } from "../../../../../share/expression.js";
|
|
4
|
+
import { Expression, HttpRequestResult, LocaleMarkdown } from "../../../../../share/expression.js";
|
|
5
5
|
import {
|
|
6
6
|
CelRowAccess,
|
|
7
7
|
derivedRowField,
|
|
@@ -37,7 +37,7 @@ export function schema(configure) {
|
|
|
37
37
|
};
|
|
38
38
|
const CelDataSourceRequest = Expression({
|
|
39
39
|
configure: dataSourceConfigure,
|
|
40
|
-
resultType:
|
|
40
|
+
resultType: HttpRequestResult
|
|
41
41
|
});
|
|
42
42
|
const CelDataSourceData = Expression({
|
|
43
43
|
configure: (env) => {
|
|
@@ -6,6 +6,7 @@ import { useI18n } from "vue-i18n";
|
|
|
6
6
|
import { cel as _rawCel } from "../../../../../utils/cel";
|
|
7
7
|
import { celBindings, injectCELContext } from "../../../../../utils/cel-context";
|
|
8
8
|
import { getLocalizedText } from "../../../../../share/locale";
|
|
9
|
+
import { fetchJsonOption } from "../../../../../share/request";
|
|
9
10
|
import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput } from "../../../../ui/input-group";
|
|
10
11
|
import { Markdown } from "../../../../ui/markdown";
|
|
11
12
|
import { Popover, PopoverAnchor, PopoverContent, PopoverTrigger } from "../../../../ui/popover";
|
|
@@ -159,12 +160,10 @@ async function fetchTree() {
|
|
|
159
160
|
const effect = Effect.gen(function* () {
|
|
160
161
|
let jsonOpt = Option.none();
|
|
161
162
|
if (dataSource.request) {
|
|
162
|
-
|
|
163
|
+
jsonOpt = yield* fetchJsonOption(yield* $cel(dataSource.request, {
|
|
163
164
|
row: row.value,
|
|
164
165
|
index: rowIndex.value
|
|
165
|
-
});
|
|
166
|
-
const response = yield* builder.json();
|
|
167
|
-
jsonOpt = Option.some(response);
|
|
166
|
+
}));
|
|
168
167
|
}
|
|
169
168
|
const dataRaw = yield* $cel(dataSource.data, {
|
|
170
169
|
row: row.value,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Effect, Schema } from "effect";
|
|
2
2
|
import { getProperty } from "dot-prop";
|
|
3
3
|
import { Locale } from "../../../../../share/locale.js";
|
|
4
|
-
import { Expression, LocaleMarkdown } from "../../../../../share/expression.js";
|
|
4
|
+
import { Expression, HttpRequestResult, LocaleMarkdown } from "../../../../../share/expression.js";
|
|
5
5
|
import {
|
|
6
6
|
CelRowAccess,
|
|
7
7
|
derivedRowField,
|
|
@@ -37,7 +37,7 @@ export function schema(configure) {
|
|
|
37
37
|
};
|
|
38
38
|
const CelDataSourceRequest = Expression({
|
|
39
39
|
configure: dataSourceConfigure,
|
|
40
|
-
resultType:
|
|
40
|
+
resultType: HttpRequestResult
|
|
41
41
|
});
|
|
42
42
|
const CelDataSourceData = Expression({
|
|
43
43
|
configure: (env) => {
|
|
@@ -1249,12 +1249,6 @@ const tableQueryValue = computed({
|
|
|
1249
1249
|
@update:model-value="(v) => updateGeneralOptionalString('rowKey', v)"
|
|
1250
1250
|
/>
|
|
1251
1251
|
</RowKeyCELContext>
|
|
1252
|
-
<p
|
|
1253
|
-
v-if="getError('rowKey')"
|
|
1254
|
-
class="text-xs text-red-500"
|
|
1255
|
-
>
|
|
1256
|
-
{{ getError("rowKey") }}
|
|
1257
|
-
</p>
|
|
1258
1252
|
</Field>
|
|
1259
1253
|
|
|
1260
1254
|
<!-- Host slot inside the general grid: a wrapping editor (e.g. the
|
|
@@ -1297,12 +1291,6 @@ const tableQueryValue = computed({
|
|
|
1297
1291
|
@update:model-value="(v) => updateDataSourceOptional('request', v)"
|
|
1298
1292
|
/>
|
|
1299
1293
|
</RequestCELContext>
|
|
1300
|
-
<p
|
|
1301
|
-
v-if="getError('dataSource.request')"
|
|
1302
|
-
class="text-xs text-red-500"
|
|
1303
|
-
>
|
|
1304
|
-
{{ getError("dataSource.request") }}
|
|
1305
|
-
</p>
|
|
1306
1294
|
</Field>
|
|
1307
1295
|
|
|
1308
1296
|
<div class="grid grid-cols-2 gap-x-6 gap-y-4">
|
|
@@ -1328,12 +1316,6 @@ const tableQueryValue = computed({
|
|
|
1328
1316
|
@update:model-value="(v) => setDataSourceField('data', v)"
|
|
1329
1317
|
/>
|
|
1330
1318
|
</JsonCELContext>
|
|
1331
|
-
<p
|
|
1332
|
-
v-if="getError('dataSource.data')"
|
|
1333
|
-
class="text-xs text-red-500"
|
|
1334
|
-
>
|
|
1335
|
-
{{ getError("dataSource.data") }}
|
|
1336
|
-
</p>
|
|
1337
1319
|
</Field>
|
|
1338
1320
|
<Field orientation="vertical">
|
|
1339
1321
|
<FieldLabel class="text-xs text-zinc-500">
|
|
@@ -1357,12 +1339,6 @@ const tableQueryValue = computed({
|
|
|
1357
1339
|
@update:model-value="(v) => updateDataSourceOptional('total', v)"
|
|
1358
1340
|
/>
|
|
1359
1341
|
</JsonCELContext>
|
|
1360
|
-
<p
|
|
1361
|
-
v-if="getError('dataSource.total')"
|
|
1362
|
-
class="text-xs text-red-500"
|
|
1363
|
-
>
|
|
1364
|
-
{{ getError("dataSource.total") }}
|
|
1365
|
-
</p>
|
|
1366
1342
|
</Field>
|
|
1367
1343
|
</div>
|
|
1368
1344
|
</div>
|
|
@@ -1515,12 +1491,6 @@ const tableQueryValue = computed({
|
|
|
1515
1491
|
@update:model-value="(v) => updateGeneralOptionalString('cellStyle', v)"
|
|
1516
1492
|
/>
|
|
1517
1493
|
</CellStyleCELContext>
|
|
1518
|
-
<p
|
|
1519
|
-
v-if="getError('cellStyle')"
|
|
1520
|
-
class="text-xs text-red-500"
|
|
1521
|
-
>
|
|
1522
|
-
{{ getError("cellStyle") }}
|
|
1523
|
-
</p>
|
|
1524
1494
|
</Field>
|
|
1525
1495
|
|
|
1526
1496
|
<Field orientation="vertical">
|
|
@@ -1543,12 +1513,6 @@ const tableQueryValue = computed({
|
|
|
1543
1513
|
class="min-h-20 font-mono text-xs"
|
|
1544
1514
|
@update:model-value="(v) => updateGeneralOptionalString('style', String(v))"
|
|
1545
1515
|
/>
|
|
1546
|
-
<p
|
|
1547
|
-
v-if="getError('style')"
|
|
1548
|
-
class="text-xs text-red-500"
|
|
1549
|
-
>
|
|
1550
|
-
{{ getError("style") }}
|
|
1551
|
-
</p>
|
|
1552
1516
|
</Field>
|
|
1553
1517
|
</div>
|
|
1554
1518
|
</div>
|
|
@@ -14,6 +14,7 @@ import { Effect, Fiber, Option } from "effect";
|
|
|
14
14
|
import { Fetch } from "fx-fetch";
|
|
15
15
|
import { Pagination } from "reka-ui/namespaced";
|
|
16
16
|
import { computed, h, onMounted, ref, toRaw, watch } from "vue";
|
|
17
|
+
import { fetchJsonOption } from "../../share/request";
|
|
17
18
|
import { useI18n } from "vue-i18n";
|
|
18
19
|
import { celBindings, provideCELContext, injectCELContext } from "../../utils/cel-context";
|
|
19
20
|
import TableRowProvider from "./row-provider.vue";
|
|
@@ -336,12 +337,10 @@ async function fetchDataSource() {
|
|
|
336
337
|
const effect = Effect.gen(function* () {
|
|
337
338
|
let jsonOpt = Option.none();
|
|
338
339
|
if (dataSource.request) {
|
|
339
|
-
|
|
340
|
+
jsonOpt = yield* fetchJsonOption(yield* $cel(
|
|
340
341
|
dataSource.request,
|
|
341
342
|
mergeCelContext({ pageIndex, pageSize })
|
|
342
|
-
);
|
|
343
|
-
const response = yield* builder.json();
|
|
344
|
-
jsonOpt = Option.some(response);
|
|
343
|
+
));
|
|
345
344
|
}
|
|
346
345
|
const nextRowsRaw = yield* $cel(
|
|
347
346
|
dataSource.data,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Schema } from "effect";
|
|
2
|
-
import { Expression } from "../../share/expression.js";
|
|
2
|
+
import { Expression, HttpRequestResult } from "../../share/expression.js";
|
|
3
3
|
import { Locale } from "../../share/locale.js";
|
|
4
4
|
import { md } from "../../share/markdown.js";
|
|
5
5
|
import { ActionSchemaFields } from "../actions/schema.js";
|
|
@@ -186,7 +186,7 @@ export function DataSource(configure, extras) {
|
|
|
186
186
|
configure(env);
|
|
187
187
|
extras?.request?.(env);
|
|
188
188
|
},
|
|
189
|
-
resultType:
|
|
189
|
+
resultType: HttpRequestResult
|
|
190
190
|
});
|
|
191
191
|
const CelRows = Expression({
|
|
192
192
|
configure: (env) => {
|
|
@@ -218,7 +218,7 @@ export function tableDataSource(configure) {
|
|
|
218
218
|
configure(env);
|
|
219
219
|
registerDataSourceRequestVars(env);
|
|
220
220
|
},
|
|
221
|
-
resultType:
|
|
221
|
+
resultType: HttpRequestResult
|
|
222
222
|
});
|
|
223
223
|
const CelRows = Expression({
|
|
224
224
|
configure: (env) => {
|
|
@@ -12,12 +12,13 @@ type __VLS_Props = {
|
|
|
12
12
|
placeholder?: string;
|
|
13
13
|
resultType?: string | string[];
|
|
14
14
|
extraVars?: Record<string, VarSpec>;
|
|
15
|
+
unlistedVarsAreDyn?: boolean;
|
|
15
16
|
};
|
|
16
|
-
declare var
|
|
17
|
+
declare var __VLS_13: {}, __VLS_129: {};
|
|
17
18
|
type __VLS_Slots = {} & {
|
|
18
|
-
leading?: (props: typeof
|
|
19
|
+
leading?: (props: typeof __VLS_13) => any;
|
|
19
20
|
} & {
|
|
20
|
-
trailing?: (props: typeof
|
|
21
|
+
trailing?: (props: typeof __VLS_129) => any;
|
|
21
22
|
};
|
|
22
23
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
23
24
|
"update:modelValue": (payload: string) => any;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { Icon } from "@iconify/vue";
|
|
3
3
|
import { computed, ref, useSlots, useTemplateRef, watch } from "vue";
|
|
4
|
+
import { buildCheckEnvironment, evaluateExpression } from "../../../share/expression";
|
|
4
5
|
import { injectCELContext, useScopeAncestry } from "../../../utils/cel-context";
|
|
5
6
|
import { Markdown } from "../markdown";
|
|
6
7
|
import CodeMirrorInput from "./CodeMirrorInput.vue";
|
|
@@ -17,7 +18,8 @@ const props = defineProps({
|
|
|
17
18
|
multiline: { type: Boolean, required: false },
|
|
18
19
|
placeholder: { type: String, required: false },
|
|
19
20
|
resultType: { type: [String, Array], required: false },
|
|
20
|
-
extraVars: { type: Object, required: false }
|
|
21
|
+
extraVars: { type: Object, required: false },
|
|
22
|
+
unlistedVarsAreDyn: { type: Boolean, required: false }
|
|
21
23
|
});
|
|
22
24
|
const emits = defineEmits(["update:modelValue"]);
|
|
23
25
|
const celContext = injectCELContext();
|
|
@@ -26,6 +28,20 @@ const varEntries = computed(() => buildVarEntries(celContext, props.extraVars));
|
|
|
26
28
|
const scopeEntries = computed(() => buildScopeEntries(scopeAncestry.value.slice(1)));
|
|
27
29
|
const scopeLookup = computed(() => buildScopeLookup(scopeAncestry.value));
|
|
28
30
|
const hasVars = computed(() => varEntries.value.length > 0 || scopeEntries.value.length > 0);
|
|
31
|
+
const checkEnvironment = computed(() => {
|
|
32
|
+
const vars = /* @__PURE__ */ new Map();
|
|
33
|
+
for (const [name, entry] of Object.entries(celContext)) vars.set(name, entry.type);
|
|
34
|
+
for (const [name, spec] of Object.entries(props.extraVars ?? {})) vars.set(name, spec.type);
|
|
35
|
+
return buildCheckEnvironment(
|
|
36
|
+
[...vars].map(([name, type]) => ({ name, type })),
|
|
37
|
+
{ unlistedVariablesAreDyn: props.unlistedVarsAreDyn }
|
|
38
|
+
);
|
|
39
|
+
});
|
|
40
|
+
const validationError = computed(() => {
|
|
41
|
+
const value = props.modelValue ?? props.defaultValue ?? "";
|
|
42
|
+
if (value.trim() === "") return null;
|
|
43
|
+
return evaluateExpression(checkEnvironment.value, value, props.resultType);
|
|
44
|
+
});
|
|
29
45
|
const open = ref(false);
|
|
30
46
|
const entries = ref([]);
|
|
31
47
|
const shownVars = computed(() => entries.value.filter((e) => e.group === "var"));
|
|
@@ -60,120 +76,128 @@ const addonAlign = computed(
|
|
|
60
76
|
</script>
|
|
61
77
|
|
|
62
78
|
<template>
|
|
63
|
-
<
|
|
64
|
-
<
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
<slot name="leading" />
|
|
69
|
-
</InputGroupAddon>
|
|
70
|
-
<CodeMirrorInput
|
|
71
|
-
ref="editor"
|
|
72
|
-
:model-value="props.modelValue"
|
|
73
|
-
:default-value="props.defaultValue"
|
|
74
|
-
:placeholder="props.placeholder"
|
|
75
|
-
:multiline="props.multiline"
|
|
76
|
-
:scope-lookup="scopeLookup"
|
|
77
|
-
:class="props.class"
|
|
78
|
-
@update:model-value="(v) => emits('update:modelValue', v)"
|
|
79
|
-
/>
|
|
80
|
-
<InputGroupAddon
|
|
81
|
-
v-if="showAddon"
|
|
82
|
-
:align="addonAlign"
|
|
83
|
-
class="justify-end gap-1.5"
|
|
84
|
-
>
|
|
85
|
-
<Popover
|
|
86
|
-
v-if="hasVars"
|
|
87
|
-
v-model:open="open"
|
|
79
|
+
<div class="flex flex-col gap-1.5">
|
|
80
|
+
<InputGroup>
|
|
81
|
+
<InputGroupAddon
|
|
82
|
+
v-if="$slots.leading"
|
|
83
|
+
align="inline-start"
|
|
88
84
|
>
|
|
89
|
-
<
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
85
|
+
<slot name="leading" />
|
|
86
|
+
</InputGroupAddon>
|
|
87
|
+
<CodeMirrorInput
|
|
88
|
+
ref="editor"
|
|
89
|
+
:model-value="props.modelValue"
|
|
90
|
+
:default-value="props.defaultValue"
|
|
91
|
+
:placeholder="props.placeholder"
|
|
92
|
+
:multiline="props.multiline"
|
|
93
|
+
:scope-lookup="scopeLookup"
|
|
94
|
+
:class="props.class"
|
|
95
|
+
@update:model-value="(v) => emits('update:modelValue', v)"
|
|
96
|
+
/>
|
|
97
|
+
<InputGroupAddon
|
|
98
|
+
v-if="showAddon"
|
|
99
|
+
:align="addonAlign"
|
|
100
|
+
class="justify-end gap-1.5"
|
|
101
|
+
>
|
|
102
|
+
<Popover
|
|
103
|
+
v-if="hasVars"
|
|
104
|
+
v-model:open="open"
|
|
101
105
|
>
|
|
102
|
-
<
|
|
103
|
-
<
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
106
|
+
<PopoverTrigger as-child>
|
|
107
|
+
<InputGroupButton
|
|
108
|
+
size="icon-xs"
|
|
109
|
+
aria-label="Inspect available variables"
|
|
110
|
+
>
|
|
111
|
+
<Icon icon="fluent:braces-variable-20-regular" />
|
|
112
|
+
</InputGroupButton>
|
|
113
|
+
</PopoverTrigger>
|
|
114
|
+
<PopoverContent
|
|
115
|
+
align="end"
|
|
116
|
+
:side-offset="6"
|
|
117
|
+
class="group/popover w-80 p-0 data-[side=top]:**:data-[slot=command-input-wrapper]:border-t data-[side=top]:**:data-[slot=command-input-wrapper]:border-b-0"
|
|
118
|
+
>
|
|
119
|
+
<Command class="rounded group-data-[side=top]/popover:flex-col-reverse">
|
|
120
|
+
<CommandInput placeholder="搜索可用变量" />
|
|
121
|
+
<CommandList class="max-h-48 overflow-y-auto">
|
|
122
|
+
<CommandEmpty>No variables.</CommandEmpty>
|
|
123
|
+
<CommandGroup>
|
|
124
|
+
<CommandItem
|
|
125
|
+
v-for="entry in shownVars"
|
|
126
|
+
:key="entry.id"
|
|
127
|
+
:value="entry.display"
|
|
128
|
+
class="cursor-pointer gap-2"
|
|
129
|
+
@select="insertVariable(entry.insert)"
|
|
130
|
+
@mouseenter="hoveredName = entry.id"
|
|
131
|
+
@focus="hoveredName = entry.id"
|
|
132
|
+
>
|
|
133
|
+
<Icon
|
|
134
|
+
icon="fluent:braces-variable-20-regular"
|
|
135
|
+
class="size-3.5 shrink-0 text-zinc-400"
|
|
136
|
+
/>
|
|
137
|
+
<span class="font-mono text-xs text-zinc-800">{{ entry.display }}</span>
|
|
138
|
+
<span class="flex-1 truncate text-xs text-zinc-500">{{ entry.label }}</span>
|
|
139
|
+
<span class="rounded bg-purple-100 px-1.5 py-0.5 font-mono text-[10px] leading-none text-purple-700 select-none">
|
|
140
|
+
{{ entry.type }}
|
|
141
|
+
</span>
|
|
142
|
+
</CommandItem>
|
|
143
|
+
</CommandGroup>
|
|
144
|
+
<CommandGroup
|
|
145
|
+
v-if="shownScopes.length > 0"
|
|
146
|
+
heading="跨层引用"
|
|
115
147
|
>
|
|
116
|
-
<
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
148
|
+
<CommandItem
|
|
149
|
+
v-for="entry in shownScopes"
|
|
150
|
+
:key="entry.id"
|
|
151
|
+
:value="`${entry.display} ${entry.id}`"
|
|
152
|
+
class="cursor-pointer gap-2"
|
|
153
|
+
@select="insertVariable(entry.insert)"
|
|
154
|
+
@mouseenter="hoveredName = entry.id"
|
|
155
|
+
@focus="hoveredName = entry.id"
|
|
156
|
+
>
|
|
157
|
+
<Icon
|
|
158
|
+
icon="fluent:link-20-regular"
|
|
159
|
+
class="size-3.5 shrink-0 text-zinc-400"
|
|
160
|
+
/>
|
|
161
|
+
<span class="flex-1 truncate text-xs text-zinc-700">{{ entry.display }}</span>
|
|
162
|
+
<span class="rounded bg-purple-100 px-1.5 py-0.5 font-mono text-[10px] leading-none text-purple-700 select-none">
|
|
163
|
+
{{ entry.type }}
|
|
164
|
+
</span>
|
|
165
|
+
</CommandItem>
|
|
166
|
+
</CommandGroup>
|
|
167
|
+
</CommandList>
|
|
168
|
+
<div
|
|
169
|
+
v-if="hoveredEntry"
|
|
170
|
+
class="border-t border-zinc-200 px-3 py-2 group-data-[side=top]/popover:border-t-0 group-data-[side=top]/popover:border-b"
|
|
130
171
|
>
|
|
131
|
-
<
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
class="cursor-pointer gap-2"
|
|
136
|
-
@select="insertVariable(entry.insert)"
|
|
137
|
-
@mouseenter="hoveredName = entry.id"
|
|
138
|
-
@focus="hoveredName = entry.id"
|
|
139
|
-
>
|
|
140
|
-
<Icon
|
|
141
|
-
icon="fluent:link-20-regular"
|
|
142
|
-
class="size-3.5 shrink-0 text-zinc-400"
|
|
143
|
-
/>
|
|
144
|
-
<span class="flex-1 truncate text-xs text-zinc-700">{{ entry.display }}</span>
|
|
145
|
-
<span class="rounded bg-purple-100 px-1.5 py-0.5 font-mono text-[10px] leading-none text-purple-700 select-none">
|
|
146
|
-
{{ entry.type }}
|
|
172
|
+
<div class="flex items-center gap-2">
|
|
173
|
+
<span class="text-xs font-medium text-zinc-700">{{ hoveredEntry.label }}</span>
|
|
174
|
+
<span class="ml-auto shrink-0 rounded bg-purple-100 px-1.5 py-0.5 font-mono text-[10px] leading-none text-purple-700 select-none">
|
|
175
|
+
{{ hoveredEntry.type }}
|
|
147
176
|
</span>
|
|
148
|
-
</
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
>
|
|
155
|
-
<div class="flex items-center gap-2">
|
|
156
|
-
<span class="text-xs font-medium text-zinc-700">{{ hoveredEntry.label }}</span>
|
|
157
|
-
<span class="ml-auto shrink-0 rounded bg-purple-100 px-1.5 py-0.5 font-mono text-[10px] leading-none text-purple-700 select-none">
|
|
158
|
-
{{ hoveredEntry.type }}
|
|
159
|
-
</span>
|
|
177
|
+
</div>
|
|
178
|
+
<Markdown
|
|
179
|
+
v-if="hoveredDescription"
|
|
180
|
+
:source="hoveredDescription"
|
|
181
|
+
class="prose prose-zinc prose-sm mt-1 text-xs"
|
|
182
|
+
/>
|
|
160
183
|
</div>
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
184
|
+
</Command>
|
|
185
|
+
</PopoverContent>
|
|
186
|
+
</Popover>
|
|
187
|
+
<span
|
|
188
|
+
v-if="resultTypeLabel"
|
|
189
|
+
class="rounded bg-purple-100 px-1.5 py-0.5 font-mono text-[10px] leading-none text-purple-700 select-none"
|
|
190
|
+
>
|
|
191
|
+
{{ resultTypeLabel }}
|
|
192
|
+
</span>
|
|
193
|
+
<slot name="trailing" />
|
|
194
|
+
</InputGroupAddon>
|
|
195
|
+
</InputGroup>
|
|
196
|
+
<p
|
|
197
|
+
v-if="validationError"
|
|
198
|
+
class="text-xs text-red-500"
|
|
199
|
+
>
|
|
200
|
+
{{ validationError }}
|
|
201
|
+
</p>
|
|
202
|
+
</div>
|
|
179
203
|
</template>
|
|
@@ -12,12 +12,13 @@ type __VLS_Props = {
|
|
|
12
12
|
placeholder?: string;
|
|
13
13
|
resultType?: string | string[];
|
|
14
14
|
extraVars?: Record<string, VarSpec>;
|
|
15
|
+
unlistedVarsAreDyn?: boolean;
|
|
15
16
|
};
|
|
16
|
-
declare var
|
|
17
|
+
declare var __VLS_13: {}, __VLS_129: {};
|
|
17
18
|
type __VLS_Slots = {} & {
|
|
18
|
-
leading?: (props: typeof
|
|
19
|
+
leading?: (props: typeof __VLS_13) => any;
|
|
19
20
|
} & {
|
|
20
|
-
trailing?: (props: typeof
|
|
21
|
+
trailing?: (props: typeof __VLS_129) => any;
|
|
21
22
|
};
|
|
22
23
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
23
24
|
"update:modelValue": (payload: string) => any;
|
|
@@ -2,6 +2,42 @@ import { Schema } from 'effect';
|
|
|
2
2
|
import { Environment } from '../vendor/cel-js/lib/index.js';
|
|
3
3
|
import { Locale } from './locale.js';
|
|
4
4
|
export type ResultType = string | string[] | ((type: string) => boolean);
|
|
5
|
+
/**
|
|
6
|
+
* Result-type matcher for a request expression. A request expression may now
|
|
7
|
+
* evaluate to `optional<HttpRequest>` — `None` means "no request, skip the
|
|
8
|
+
* fetch" — letting authors fetch conditionally (e.g. only when a `form_id` is
|
|
9
|
+
* present). For back-compat a bare `HttpRequest` still passes (always fetch).
|
|
10
|
+
* `dyn` and `optional<dyn>` are accepted too; the runtime normalizer
|
|
11
|
+
* (`asRequest`) treats any non-builder payload as `None` at dispatch time.
|
|
12
|
+
*
|
|
13
|
+
* Authors wrap both ternary branches in optionals, e.g.
|
|
14
|
+
* `form_id == "" ? optional.none() : optional.of(http.get(url))`, which the
|
|
15
|
+
* type-checker infers as `optional<HttpRequest>`.
|
|
16
|
+
*/
|
|
17
|
+
export declare const HttpRequestResult: ResultType;
|
|
18
|
+
/**
|
|
19
|
+
* Type-check `expression` against `env` and, if `resultType` is given, verify the
|
|
20
|
+
* inferred type satisfies it. Returns a Chinese error message, or `null` when the
|
|
21
|
+
* expression is valid. This is the single chokepoint both the schema validator
|
|
22
|
+
* (`Expression`'s filter) and the live `ExpressionEditor` call, so an inline
|
|
23
|
+
* verdict can never disagree with the save-time decode.
|
|
24
|
+
*/
|
|
25
|
+
export declare function evaluateExpression(env: Environment, expression: string, resultType?: ResultType): string | null;
|
|
26
|
+
/**
|
|
27
|
+
* Build a checking `Environment` from a flat list of `{ name, type }` variable
|
|
28
|
+
* specs — the projection an `ExpressionEditor` already holds via its injected CEL
|
|
29
|
+
* context plus `extraVars`. Functions/operators come free from the cloned
|
|
30
|
+
* `globalRegistry`; only variables are host-scoped, so this is all the editor
|
|
31
|
+
* needs to reproduce the schema's validation env. `__scopes__` is registered
|
|
32
|
+
* canonically here (and skipped from `vars`) exactly as `Expression` does, so
|
|
33
|
+
* cross-layer addressing type-checks in the editor too.
|
|
34
|
+
*/
|
|
35
|
+
export declare function buildCheckEnvironment(vars: Iterable<{
|
|
36
|
+
name: string;
|
|
37
|
+
type: string;
|
|
38
|
+
}>, options?: {
|
|
39
|
+
unlistedVariablesAreDyn?: boolean;
|
|
40
|
+
}): Environment;
|
|
5
41
|
export declare function Expression(options: {
|
|
6
42
|
configure: (env: Environment) => void;
|
|
7
43
|
resultType?: ResultType;
|