@shwfed/config 2.12.1 → 2.12.3
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/module.mjs +10 -0
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/config.d.vue.ts +68 -68
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/config.vue.d.ts +68 -68
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/runtime.d.vue.ts +68 -68
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/runtime.vue.d.ts +68 -68
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/schema.d.ts +34 -34
- package/dist/runtime/components/form/config.vue +17 -6
- package/dist/runtime/components/form/fields/2026-04-24/com.shwfed.form.field.combobox.single/config.d.vue.ts +2 -2
- package/dist/runtime/components/form/fields/2026-04-24/com.shwfed.form.field.combobox.single/config.vue.d.ts +2 -2
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.daterange/config.d.vue.ts +6 -6
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.daterange/config.vue.d.ts +6 -6
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetimerange/config.d.vue.ts +8 -8
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetimerange/config.vue.d.ts +8 -8
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.timerange/config.d.vue.ts +2 -2
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.timerange/config.vue.d.ts +2 -2
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.combobox.single.remote/config.d.vue.ts +2 -2
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.combobox.single.remote/config.vue.d.ts +2 -2
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/row.vue +8 -1
- package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/config.d.vue.ts +24 -24
- package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/config.vue.d.ts +24 -24
- package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.monthrange/config.d.vue.ts +6 -6
- package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.monthrange/config.vue.d.ts +6 -6
- package/dist/runtime/components/form/fields/2026-05-25/com.shwfed.form.field.combobox.multi/config.d.vue.ts +2 -2
- package/dist/runtime/components/form/fields/2026-05-25/com.shwfed.form.field.combobox.multi/config.vue.d.ts +2 -2
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.d.vue.ts +24 -24
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.vue.d.ts +24 -24
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.d.vue.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.vue.d.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.multi/config.d.vue.ts +32 -32
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.multi/config.vue.d.ts +32 -32
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.multi/runtime.vue +10 -2
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.single/config.d.vue.ts +32 -32
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.single/config.vue.d.ts +32 -32
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.single/runtime.vue +10 -2
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.d.vue.ts +24 -24
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.vue.d.ts +24 -24
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/runtime.vue +19 -1
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.d.vue.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.vue.d.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/runtime.vue +19 -1
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.d.vue.ts +24 -24
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.vue.d.ts +24 -24
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/runtime.vue +20 -1
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.d.vue.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.vue.d.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/runtime.vue +20 -1
- package/dist/runtime/components/form/fields/2026-06-14/com.shwfed.form.field.combobox.multi/config.d.vue.ts +32 -32
- package/dist/runtime/components/form/fields/2026-06-14/com.shwfed.form.field.combobox.multi/config.vue.d.ts +32 -32
- package/dist/runtime/components/form/fields/2026-06-14/com.shwfed.form.field.combobox.multi/runtime.vue +10 -2
- package/dist/runtime/components/form/fields/2026-06-14/com.shwfed.form.field.combobox.single/config.d.vue.ts +32 -32
- package/dist/runtime/components/form/fields/2026-06-14/com.shwfed.form.field.combobox.single/config.vue.d.ts +32 -32
- package/dist/runtime/components/form/fields/2026-06-14/com.shwfed.form.field.combobox.single/runtime.vue +10 -2
- package/dist/runtime/components/form/index.vue +6 -3
- package/dist/runtime/components/form/utils/form-vars.js +2 -1
- package/dist/runtime/components/head.d.vue.ts +13 -0
- package/dist/runtime/components/head.vue +69 -0
- package/dist/runtime/components/head.vue.d.ts +13 -0
- package/dist/runtime/components/sidebar/config.d.vue.ts +7 -0
- package/dist/runtime/components/sidebar/config.vue +302 -0
- package/dist/runtime/components/sidebar/config.vue.d.ts +7 -0
- package/dist/runtime/components/sidebar/favorites.d.ts +18 -0
- package/dist/runtime/components/sidebar/favorites.js +20 -0
- package/dist/runtime/components/sidebar/footer.d.vue.ts +11 -0
- package/dist/runtime/components/sidebar/footer.vue +49 -0
- package/dist/runtime/components/sidebar/footer.vue.d.ts +11 -0
- package/dist/runtime/components/sidebar/index.d.vue.ts +50 -0
- package/dist/runtime/components/sidebar/index.vue +100 -0
- package/dist/runtime/components/sidebar/index.vue.d.ts +50 -0
- package/dist/runtime/components/sidebar/node.d.vue.ts +9 -0
- package/dist/runtime/components/sidebar/node.vue +102 -0
- package/dist/runtime/components/sidebar/node.vue.d.ts +9 -0
- package/dist/runtime/components/sidebar/schema.d.ts +72 -0
- package/dist/runtime/components/sidebar/schema.js +84 -0
- package/dist/runtime/components/sidebar/tree.d.vue.ts +10 -0
- package/dist/runtime/components/sidebar/tree.vue +260 -0
- package/dist/runtime/components/sidebar/tree.vue.d.ts +10 -0
- package/dist/runtime/components/sidebar/types.d.ts +19 -0
- package/dist/runtime/components/sidebar/types.js +0 -0
- package/dist/runtime/components/sidebar/use-editor.d.ts +18 -0
- package/dist/runtime/components/sidebar/use-editor.js +43 -0
- package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/config.d.vue.ts +36 -36
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/config.vue.d.ts +36 -36
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.d.vue.ts +40 -40
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.vue.d.ts +40 -40
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/config.d.vue.ts +36 -36
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/config.vue.d.ts +36 -36
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.d.vue.ts +40 -40
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.vue.d.ts +40 -40
- package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/config.d.vue.ts +4 -4
- package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +4 -4
- package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/config.d.vue.ts +26 -26
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/config.vue.d.ts +26 -26
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/config.d.vue.ts +26 -26
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/config.vue.d.ts +26 -26
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/config.d.vue.ts +4 -4
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +4 -4
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/config.d.vue.ts +26 -26
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/config.vue.d.ts +26 -26
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/config.d.vue.ts +26 -26
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/config.vue.d.ts +26 -26
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/config.d.vue.ts +4 -4
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +4 -4
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/schema.d.ts +68 -68
- package/dist/runtime/components/ui/date-picker/DatePickerInput.d.vue.ts +1 -1
- package/dist/runtime/components/ui/date-picker/DatePickerInput.vue.d.ts +1 -1
- package/dist/runtime/components/ui/date-picker/DatePickerTimeInput.d.vue.ts +1 -1
- package/dist/runtime/components/ui/date-picker/DatePickerTimeInput.vue.d.ts +1 -1
- package/dist/runtime/components/ui/date-range-picker/DateRangePickerInput.d.vue.ts +1 -1
- package/dist/runtime/components/ui/date-range-picker/DateRangePickerInput.vue.d.ts +1 -1
- package/dist/runtime/components/ui/date-range-picker/DateRangePickerTimeInput.d.vue.ts +2 -2
- package/dist/runtime/components/ui/date-range-picker/DateRangePickerTimeInput.vue.d.ts +2 -2
- package/dist/runtime/components/ui/expression-editor/CodeMirrorInput.d.vue.ts +1 -0
- package/dist/runtime/components/ui/expression-editor/CodeMirrorInput.vue +8 -0
- package/dist/runtime/components/ui/expression-editor/CodeMirrorInput.vue.d.ts +1 -0
- package/dist/runtime/components/ui/expression-editor/ExpressionEditor.d.vue.ts +3 -2
- package/dist/runtime/components/ui/expression-editor/ExpressionEditor.vue +51 -9
- package/dist/runtime/components/ui/expression-editor/ExpressionEditor.vue.d.ts +3 -2
- package/dist/runtime/components/ui/expression-editor/option-chip-extension.d.ts +4 -0
- package/dist/runtime/components/ui/expression-editor/option-chip-extension.js +119 -0
- package/dist/runtime/components/ui/expression-editor/option-refs.d.ts +6 -0
- package/dist/runtime/components/ui/expression-editor/option-refs.js +24 -0
- package/dist/runtime/components/ui/expression-editor/picker-entries.d.ts +2 -1
- package/dist/runtime/components/ui/expression-editor/picker-entries.js +12 -2
- package/dist/runtime/utils/cel-context.d.ts +1 -0
- package/dist/runtime/utils/cel-context.js +1 -0
- package/dist/runtime/utils/selections-registry.d.ts +40 -6
- package/dist/runtime/utils/selections-registry.js +19 -4
- package/dist/runtime/vendor/cel-js/CLAUDE.md +2 -0
- package/dist/runtime/vendor/cel-js/PROMPT.md +2 -0
- package/dist/runtime/vendor/cel-js/lib/functions.js +33 -0
- package/package.json +1 -1
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { Facet, RangeSetBuilder } from "@codemirror/state";
|
|
2
|
+
import {
|
|
3
|
+
Decoration,
|
|
4
|
+
EditorView,
|
|
5
|
+
ViewPlugin,
|
|
6
|
+
WidgetType
|
|
7
|
+
} from "@codemirror/view";
|
|
8
|
+
import { scanOptionRefs } from "./option-refs.js";
|
|
9
|
+
export const optionLookupFacet = Facet.define({
|
|
10
|
+
combine: (values) => values.length > 0 ? values[values.length - 1] : /* @__PURE__ */ new Map()
|
|
11
|
+
});
|
|
12
|
+
class OptionChipWidget extends WidgetType {
|
|
13
|
+
constructor(id, name) {
|
|
14
|
+
super();
|
|
15
|
+
this.id = id;
|
|
16
|
+
this.name = name;
|
|
17
|
+
}
|
|
18
|
+
eq(other) {
|
|
19
|
+
return other.id === this.id && other.name === this.name;
|
|
20
|
+
}
|
|
21
|
+
toDOM() {
|
|
22
|
+
const chip = document.createElement("span");
|
|
23
|
+
chip.className = "cm-option-chip";
|
|
24
|
+
chip.setAttribute("data-option-id", this.id);
|
|
25
|
+
const tag = document.createElement("span");
|
|
26
|
+
tag.className = "cm-option-chip-tag";
|
|
27
|
+
tag.textContent = "\u5168\u90E8\u9009\u9879";
|
|
28
|
+
chip.appendChild(tag);
|
|
29
|
+
const text = document.createElement("span");
|
|
30
|
+
text.className = "cm-option-chip-label";
|
|
31
|
+
if (this.name !== null) {
|
|
32
|
+
text.textContent = this.name;
|
|
33
|
+
chip.title = `\u5168\u90E8\u9009\u9879 \xB7 ${this.name}`;
|
|
34
|
+
} else {
|
|
35
|
+
chip.classList.add("cm-option-chip-dangling");
|
|
36
|
+
const short = this.id.length > 8 ? `${this.id.slice(0, 8)}\u2026` : this.id;
|
|
37
|
+
text.textContent = short;
|
|
38
|
+
chip.title = `\u672A\u77E5\u5B57\u6BB5 ${this.id}`;
|
|
39
|
+
}
|
|
40
|
+
chip.appendChild(text);
|
|
41
|
+
return chip;
|
|
42
|
+
}
|
|
43
|
+
ignoreEvent() {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function buildChips(view) {
|
|
48
|
+
const lookup = view.state.facet(optionLookupFacet);
|
|
49
|
+
const builder = new RangeSetBuilder();
|
|
50
|
+
for (const ref of scanOptionRefs(view.state.doc.toString())) {
|
|
51
|
+
const name = lookup.get(ref.id) ?? null;
|
|
52
|
+
builder.add(
|
|
53
|
+
ref.from,
|
|
54
|
+
ref.to,
|
|
55
|
+
Decoration.replace({ widget: new OptionChipWidget(ref.id, name) })
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
return builder.finish();
|
|
59
|
+
}
|
|
60
|
+
const chipPlugin = ViewPlugin.fromClass(
|
|
61
|
+
class {
|
|
62
|
+
decorations;
|
|
63
|
+
constructor(view) {
|
|
64
|
+
this.decorations = buildChips(view);
|
|
65
|
+
}
|
|
66
|
+
update(update) {
|
|
67
|
+
if (update.docChanged || update.viewportChanged || update.startState.facet(optionLookupFacet) !== update.state.facet(optionLookupFacet)) {
|
|
68
|
+
this.decorations = buildChips(update.view);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
decorations: (plugin) => plugin.decorations,
|
|
74
|
+
// Atomic so the caret steps over a chip and Backspace removes the whole
|
|
75
|
+
// `options["id"]` at once — matching the selection chip's delete-as-unit feel.
|
|
76
|
+
provide: (plugin) => EditorView.atomicRanges.of((view) => view.plugin(plugin)?.decorations ?? Decoration.none)
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
const chipTheme = EditorView.theme({
|
|
80
|
+
".cm-option-chip": {
|
|
81
|
+
display: "inline-flex",
|
|
82
|
+
alignItems: "center",
|
|
83
|
+
gap: "0.25rem",
|
|
84
|
+
margin: "0 1px",
|
|
85
|
+
padding: "0.125rem 0.25rem",
|
|
86
|
+
borderRadius: "0.25rem",
|
|
87
|
+
background: "#fffbeb",
|
|
88
|
+
border: "1px solid #fde68a",
|
|
89
|
+
color: "#b45309",
|
|
90
|
+
fontFamily: "ui-sans-serif, system-ui, sans-serif",
|
|
91
|
+
verticalAlign: "baseline",
|
|
92
|
+
cursor: "default",
|
|
93
|
+
whiteSpace: "nowrap"
|
|
94
|
+
},
|
|
95
|
+
".cm-option-chip-dangling": {
|
|
96
|
+
background: "#fef2f2",
|
|
97
|
+
borderColor: "#fecaca",
|
|
98
|
+
color: "#b91c1c"
|
|
99
|
+
},
|
|
100
|
+
".cm-option-chip-tag": {
|
|
101
|
+
borderRadius: "0.125rem",
|
|
102
|
+
background: "#fef3c7",
|
|
103
|
+
padding: "0.05rem 0.2rem",
|
|
104
|
+
fontSize: "9px",
|
|
105
|
+
lineHeight: "1",
|
|
106
|
+
color: "#d97706"
|
|
107
|
+
},
|
|
108
|
+
".cm-option-chip-dangling .cm-option-chip-tag": {
|
|
109
|
+
background: "#fee2e2",
|
|
110
|
+
color: "#b91c1c"
|
|
111
|
+
},
|
|
112
|
+
".cm-option-chip-label": {
|
|
113
|
+
fontSize: "0.75rem",
|
|
114
|
+
lineHeight: "1.1"
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
export function optionChips() {
|
|
118
|
+
return [chipPlugin, chipTheme];
|
|
119
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { OPTIONS_VAR } from "../../../utils/cel-context.js";
|
|
2
|
+
const OPTION_REF_RE = new RegExp(
|
|
3
|
+
`(?<![\\w$.])${OPTIONS_VAR}\\[\\??("(?:[^"\\\\]|\\\\.)*")\\]`,
|
|
4
|
+
"g"
|
|
5
|
+
);
|
|
6
|
+
export function scanOptionRefs(text) {
|
|
7
|
+
const out = [];
|
|
8
|
+
OPTION_REF_RE.lastIndex = 0;
|
|
9
|
+
let match;
|
|
10
|
+
while ((match = OPTION_REF_RE.exec(text)) !== null) {
|
|
11
|
+
let id;
|
|
12
|
+
try {
|
|
13
|
+
id = JSON.parse(match[1]);
|
|
14
|
+
} catch {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
out.push({
|
|
18
|
+
from: match.index,
|
|
19
|
+
to: match.index + match[0].length,
|
|
20
|
+
id
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
return out;
|
|
24
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type ScopeAncestor, type SelectionFieldRef, type StepRef } from '../../../utils/cel-context.js';
|
|
2
2
|
export type PickEntry = {
|
|
3
3
|
id: string;
|
|
4
|
-
group: 'var' | 'scope' | 'selection' | 'step';
|
|
4
|
+
group: 'var' | 'scope' | 'selection' | 'option' | 'step';
|
|
5
5
|
insert: string;
|
|
6
6
|
display: string;
|
|
7
7
|
label: string;
|
|
@@ -15,6 +15,7 @@ export type PickVarMeta = {
|
|
|
15
15
|
};
|
|
16
16
|
export declare function buildVarEntries(celContext: Record<string, PickVarMeta>, extraVars?: Record<string, PickVarMeta>): PickEntry[];
|
|
17
17
|
export declare function buildSelectionEntries(roster: ReadonlyArray<SelectionFieldRef>): PickEntry[];
|
|
18
|
+
export declare function buildOptionEntries(roster: ReadonlyArray<SelectionFieldRef>): PickEntry[];
|
|
18
19
|
export declare function buildStepEntries(roster: ReadonlyArray<StepRef>): PickEntry[];
|
|
19
20
|
export declare function selectShadowedScopes(ancestry: ReadonlyArray<ScopeAncestor>): ScopeAncestor[];
|
|
20
21
|
export declare function buildScopeEntries(ancestry: ReadonlyArray<ScopeAncestor>): PickEntry[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { SCOPE_ADDRESS_VAR, SELECTIONS_VAR, STEPS_VAR } from "../../../utils/cel-context.js";
|
|
1
|
+
import { OPTIONS_VAR, SCOPE_ADDRESS_VAR, SELECTIONS_VAR, STEPS_VAR } from "../../../utils/cel-context.js";
|
|
2
2
|
import { scopeOrigin } from "./scope-refs.js";
|
|
3
|
-
const SUPPRESSED_VARS = /* @__PURE__ */ new Set([SCOPE_ADDRESS_VAR, SELECTIONS_VAR, STEPS_VAR]);
|
|
3
|
+
const SUPPRESSED_VARS = /* @__PURE__ */ new Set([SCOPE_ADDRESS_VAR, SELECTIONS_VAR, OPTIONS_VAR, STEPS_VAR]);
|
|
4
4
|
export function buildVarEntries(celContext, extraVars) {
|
|
5
5
|
const out = [];
|
|
6
6
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -25,6 +25,16 @@ export function buildSelectionEntries(roster) {
|
|
|
25
25
|
type: "dyn"
|
|
26
26
|
}));
|
|
27
27
|
}
|
|
28
|
+
export function buildOptionEntries(roster) {
|
|
29
|
+
return roster.map((field) => ({
|
|
30
|
+
id: `option:${field.id}`,
|
|
31
|
+
group: "option",
|
|
32
|
+
insert: `${OPTIONS_VAR}[?${JSON.stringify(field.id)}]`,
|
|
33
|
+
display: field.name,
|
|
34
|
+
label: "\u5168\u90E8\u9009\u9879",
|
|
35
|
+
type: "dyn"
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
28
38
|
export function buildStepEntries(roster) {
|
|
29
39
|
return roster.filter((step) => step.valid).map((step) => ({
|
|
30
40
|
id: `step:${step.id}`,
|
|
@@ -8,6 +8,7 @@ export type CELVar = {
|
|
|
8
8
|
export type CELContext = Record<string, CELVar>;
|
|
9
9
|
export declare const SCOPE_ADDRESS_VAR = "__scopes__";
|
|
10
10
|
export declare const SELECTIONS_VAR = "selections";
|
|
11
|
+
export declare const OPTIONS_VAR = "options";
|
|
11
12
|
export declare const STEPS_VAR = "steps";
|
|
12
13
|
export type ScopeAccessor = Record<string, () => unknown>;
|
|
13
14
|
export declare function provideCELContext(context: CELContext): void;
|
|
@@ -2,6 +2,7 @@ import { computed, inject, provide, shallowRef } from "vue";
|
|
|
2
2
|
import { injectLocal, provideLocal } from "@vueuse/core";
|
|
3
3
|
export const SCOPE_ADDRESS_VAR = "__scopes__";
|
|
4
4
|
export const SELECTIONS_VAR = "selections";
|
|
5
|
+
export const OPTIONS_VAR = "options";
|
|
5
6
|
export const STEPS_VAR = "steps";
|
|
6
7
|
const CEL_CONTEXT_KEY = Symbol("cel-context");
|
|
7
8
|
export function provideCELContext(context) {
|
|
@@ -38,17 +38,38 @@ export type SelectionsRegistry = {
|
|
|
38
38
|
clear: (uuid: string) => void;
|
|
39
39
|
};
|
|
40
40
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
41
|
+
* The `options` channel is the exact same registry shape — a `uuid → value` map
|
|
42
|
+
* with the identical shallowRef + map-replace + identity-dedup discipline — but
|
|
43
|
+
* carries a field's WHOLE loaded option list (`options["<uuid>"]` → `[opt, …]`)
|
|
44
|
+
* rather than its selected option. A field owns both channels: `selections`
|
|
45
|
+
* publishes the picked option(s), `options` publishes every option it loaded.
|
|
46
|
+
* Kept under a separate injection key so the two maps are independent providers
|
|
47
|
+
* on the one host (the form root provides both). `OptionsRegistry` is a plain
|
|
48
|
+
* alias of `SelectionsRegistry` — the recursion-safety invariant is identical,
|
|
49
|
+
* so they must share the one implementation, never a drifting copy.
|
|
50
|
+
*/
|
|
51
|
+
export type OptionsRegistry = SelectionsRegistry;
|
|
52
|
+
/**
|
|
53
|
+
* Create the selections registry and provide it to descendants. The returned
|
|
54
|
+
* `entries` ref is what the host overlays as the `selections` CEL thunk.
|
|
44
55
|
*/
|
|
45
56
|
export declare function provideSelectionsRegistry(): SelectionsRegistry;
|
|
46
57
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
|
|
58
|
+
* Create the options registry and provide it to descendants. The returned
|
|
59
|
+
* `entries` ref is what the host overlays as the `options` CEL thunk.
|
|
60
|
+
*/
|
|
61
|
+
export declare function provideOptionsRegistry(): OptionsRegistry;
|
|
62
|
+
/**
|
|
63
|
+
* Inject the nearest selections registry, or `undefined` when there's no
|
|
64
|
+
* providing host (an uncontrolled field, a unit test). Callers must tolerate the
|
|
65
|
+
* absent case — publishing is best-effort.
|
|
50
66
|
*/
|
|
51
67
|
export declare function useSelectionsRegistry(): SelectionsRegistry | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* Inject the nearest options registry, or `undefined` when there's no providing
|
|
70
|
+
* host. Best-effort, same contract as `useSelectionsRegistry`.
|
|
71
|
+
*/
|
|
72
|
+
export declare function useOptionsRegistry(): OptionsRegistry | undefined;
|
|
52
73
|
/**
|
|
53
74
|
* Wire a selection field's publish lifecycle to the nearest registry. Call once
|
|
54
75
|
* in setup; it injects the host registry (tolerating absence), watches the
|
|
@@ -75,3 +96,16 @@ export declare function publishSelection<T>(key: string, resolved: () => T | und
|
|
|
75
96
|
identity: (value: T) => string;
|
|
76
97
|
raw: (value: T) => unknown;
|
|
77
98
|
}): void;
|
|
99
|
+
/**
|
|
100
|
+
* Wire a selection field's OPTIONS-list publish lifecycle to the nearest options
|
|
101
|
+
* registry. Same contract and de-dup discipline as `publishSelection` — the
|
|
102
|
+
* recursion hazard is identical (`celBindings` reads the `options` map on every
|
|
103
|
+
* `$cel` pass, and remote records are re-copied each pass), so `resolved` must
|
|
104
|
+
* return the whole loaded list, `identity` must project it to the STABLE joined
|
|
105
|
+
* option keys (never the payload), and `raw` projects it to the array stored for
|
|
106
|
+
* siblings to read. An empty list resolves to `undefined` → the entry clears.
|
|
107
|
+
*/
|
|
108
|
+
export declare function publishOptions<T>(key: string, resolved: () => T | undefined, project: {
|
|
109
|
+
identity: (value: T) => string;
|
|
110
|
+
raw: (value: T) => unknown;
|
|
111
|
+
}): void;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { inject, onUnmounted, provide, shallowRef, watch } from "vue";
|
|
2
2
|
const SELECTIONS_KEY = Symbol("shwfed-selections");
|
|
3
|
+
const OPTIONS_KEY = Symbol("shwfed-options");
|
|
3
4
|
function sameSelection(a, b) {
|
|
4
5
|
if (Object.is(a, b)) return true;
|
|
5
6
|
if (Array.isArray(a) && Array.isArray(b)) {
|
|
@@ -8,7 +9,7 @@ function sameSelection(a, b) {
|
|
|
8
9
|
}
|
|
9
10
|
return false;
|
|
10
11
|
}
|
|
11
|
-
|
|
12
|
+
function createRegistry(key) {
|
|
12
13
|
const entries = shallowRef({});
|
|
13
14
|
const registry = {
|
|
14
15
|
entries,
|
|
@@ -19,18 +20,29 @@ export function provideSelectionsRegistry() {
|
|
|
19
20
|
clear: (uuid) => {
|
|
20
21
|
if (!(uuid in entries.value)) return;
|
|
21
22
|
entries.value = Object.fromEntries(
|
|
22
|
-
Object.entries(entries.value).filter(([
|
|
23
|
+
Object.entries(entries.value).filter(([key2]) => key2 !== uuid)
|
|
23
24
|
);
|
|
24
25
|
}
|
|
25
26
|
};
|
|
26
|
-
provide(
|
|
27
|
+
provide(key, registry);
|
|
27
28
|
return registry;
|
|
28
29
|
}
|
|
30
|
+
export function provideSelectionsRegistry() {
|
|
31
|
+
return createRegistry(SELECTIONS_KEY);
|
|
32
|
+
}
|
|
33
|
+
export function provideOptionsRegistry() {
|
|
34
|
+
return createRegistry(OPTIONS_KEY);
|
|
35
|
+
}
|
|
29
36
|
export function useSelectionsRegistry() {
|
|
30
37
|
return inject(SELECTIONS_KEY, void 0);
|
|
31
38
|
}
|
|
39
|
+
export function useOptionsRegistry() {
|
|
40
|
+
return inject(OPTIONS_KEY, void 0);
|
|
41
|
+
}
|
|
32
42
|
export function publishSelection(key, resolved, project) {
|
|
33
|
-
|
|
43
|
+
publishTo(useSelectionsRegistry(), key, resolved, project);
|
|
44
|
+
}
|
|
45
|
+
function publishTo(registry, key, resolved, project) {
|
|
34
46
|
const NONE = "\0:none";
|
|
35
47
|
let last = "\0:init";
|
|
36
48
|
watch(
|
|
@@ -47,3 +59,6 @@ export function publishSelection(key, resolved, project) {
|
|
|
47
59
|
);
|
|
48
60
|
onUnmounted(() => registry?.clear(key));
|
|
49
61
|
}
|
|
62
|
+
export function publishOptions(key, resolved, project) {
|
|
63
|
+
publishTo(useOptionsRegistry(), key, resolved, project);
|
|
64
|
+
}
|
|
@@ -18,6 +18,8 @@ A `list.enumerate(): list<map<string, dyn>>` receiver method has been added (not
|
|
|
18
18
|
|
|
19
19
|
A `list.slice(number)` / `list.slice(number, number)` receiver pair has been added (not from upstream, in `functions.ts` beside `list.enumerate()`) — delegates straight to JS `Array.prototype.slice`, so negative indices count from the end (`list.slice(0, -1)` drops the last element) and out-of-range bounds clamp rather than throw. End is exclusive. Fills the gap left by CEL's `list[i]`, which has no negative indexing. Both overloads return `list<dyn>`.
|
|
20
20
|
|
|
21
|
+
A `string.replace(string, string): string` / `string.replace(string, string, number): string` receiver pair has been added (in `functions.ts` beside `string.trim()`), matching the CEL strings-extension `replace`. The two-arg form delegates to JS `String.prototype.replaceAll` (so all non-overlapping occurrences are replaced; an empty `from` interleaves `to`). The three-arg form takes a limit and mirrors Go's `strings.Replace` via the `replaceLimited` helper: `limit < 0` replaces all, `0` replaces none, otherwise the first `limit` occurrences (`"foo".replace("", "_", 2) == "_f_oo"`).
|
|
22
|
+
|
|
21
23
|
`evaluate` now returns `Effect<T, ParseError | EvaluationError | TypeError>` instead of a plain value. The entire evaluation pipeline is Effect-based — every AST node's `evaluate` function returns an Effect, and sub-expressions are composed via `Effect.gen` / `yield*`. Promise-based async handling has been removed. User-registered functions may return `Effect` values, which are automatically flatMapped into the evaluation pipeline. Import `Effect` from `effect` and use `Effect.runSync` or `Effect.runPromise` to execute the returned Effect.
|
|
22
24
|
|
|
23
25
|
The `homogeneousAggregateLiterals` and `enableOptionalTypes` environment options have been removed. Aggregate data structures (lists, maps) are always heterogeneous — mixed-type literals are inferred as `list<dyn>` or `map<dyn, dyn>`. Optional types (`.?`, `[?]`, `optional.*` helpers) are always enabled.
|
|
@@ -161,6 +161,8 @@ Mirrors JS `Array.prototype.slice`. Negative indices count from the end (CEL's `
|
|
|
161
161
|
"hello".indexOf("l") // 2
|
|
162
162
|
"hello".lastIndexOf("l") // 3
|
|
163
163
|
"hello".matches("[a-z]+") // true (regex)
|
|
164
|
+
"hello".replace("l", "L") // "heLLo" (all occurrences)
|
|
165
|
+
"hello".replace("l", "L", 1) // "heLlo" (first N; N<0 = all, 0 = none)
|
|
164
166
|
"a,b,c".split(",") // ["a", "b", "c"]
|
|
165
167
|
"a,b,c".split(",", 2) // ["a", "b,c"]
|
|
166
168
|
["a", "b"].join() // "ab"
|
|
@@ -139,6 +139,14 @@ export function registerFunctions(registry) {
|
|
|
139
139
|
functionOverload("string.lowerAscii(): string", (a) => a.toLowerCase());
|
|
140
140
|
functionOverload("string.upperAscii(): string", (a) => a.toUpperCase());
|
|
141
141
|
functionOverload("string.trim(): string", (a) => a.trim());
|
|
142
|
+
functionOverload(
|
|
143
|
+
"string.replace(string, string): string",
|
|
144
|
+
(string, from, to) => string.replaceAll(from, to)
|
|
145
|
+
);
|
|
146
|
+
functionOverload(
|
|
147
|
+
"string.replace(string, string, number): string",
|
|
148
|
+
(string, from, to, limit) => replaceLimited(string, from, to, toNum(limit))
|
|
149
|
+
);
|
|
142
150
|
functionOverload(
|
|
143
151
|
"string.indexOf(string): number",
|
|
144
152
|
(string, search) => Decimal.from(string.indexOf(search))
|
|
@@ -436,3 +444,28 @@ function stringSize(str) {
|
|
|
436
444
|
for (const _ of str) count++;
|
|
437
445
|
return count;
|
|
438
446
|
}
|
|
447
|
+
function replaceLimited(str, from, to, limit) {
|
|
448
|
+
if (limit < 0) return str.replaceAll(from, to);
|
|
449
|
+
if (limit === 0 || from === to) return str;
|
|
450
|
+
let result = "";
|
|
451
|
+
let start = 0;
|
|
452
|
+
let count = 0;
|
|
453
|
+
while (count < limit) {
|
|
454
|
+
let j;
|
|
455
|
+
if (from === "") {
|
|
456
|
+
if (count > 0) {
|
|
457
|
+
if (start >= str.length) break;
|
|
458
|
+
j = start + 1;
|
|
459
|
+
} else {
|
|
460
|
+
j = start;
|
|
461
|
+
}
|
|
462
|
+
} else {
|
|
463
|
+
j = str.indexOf(from, start);
|
|
464
|
+
if (j < 0) break;
|
|
465
|
+
}
|
|
466
|
+
result += str.slice(start, j) + to;
|
|
467
|
+
start = j + from.length;
|
|
468
|
+
count++;
|
|
469
|
+
}
|
|
470
|
+
return result + str.slice(start);
|
|
471
|
+
}
|