@shwfed/config 2.12.1 → 2.12.2
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-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-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 +9 -1
- 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 +9 -1
- 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 +9 -1
- 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 +9 -1
- 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/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
|
@@ -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
|
+
}
|