@shwfed/config 2.7.5 → 2.7.7
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 +73 -21
- package/dist/module.json +1 -1
- package/dist/preview/assets/badge-B0tiCpa_.js +1 -0
- package/dist/preview/assets/config-BG9TRQcv.js +1 -0
- package/dist/preview/assets/{config-ulTPyAGw.js → config-Bfb2sH6S.js} +1 -1
- package/dist/preview/assets/config-C-XJ-8Rs.js +1 -0
- package/dist/preview/assets/{config-ISM4vT-S.js → config-CGvnv-5x.js} +1 -1
- package/dist/preview/assets/config-DDPihojt.js +1 -0
- package/dist/preview/assets/config-Dafqx9xC.js +1 -0
- package/dist/preview/assets/{config-DBviu6U0.js → config-DqMRy1WL.js} +1 -1
- package/dist/preview/assets/{config-CtPQb6dK.js → config-GCvXe12z.js} +1 -1
- package/dist/preview/assets/{config-CYixJlBY.js → config-jDPbLgBr.js} +1 -1
- package/dist/preview/assets/definition.vue_vue_type_script_setup_true_lang-DBXfCj4Q.js +1 -0
- package/dist/preview/assets/{index-CqWUukUH.css → index-B0PL01fm.css} +1 -1
- package/dist/preview/assets/index-CHzOsSTW.js +680 -0
- package/dist/preview/assets/index-CSfKAdi7.js +1 -0
- package/dist/preview/assets/{index-D6fhWrrp.js → index-D7jDE3kp.js} +1 -1
- package/dist/preview/assets/item-DV-Garrg.js +1 -0
- package/dist/preview/assets/runtime-BovPWken.js +1 -0
- package/dist/preview/assets/runtime-BxBBFFHA.js +1 -0
- package/dist/preview/assets/{runtime-B7NcvR9y.js → runtime-CwmJ9MLQ.js} +1 -1
- package/dist/preview/assets/runtime-Cyjx6haa.js +1 -0
- package/dist/preview/assets/runtime-D-LBi56N.js +1 -0
- package/dist/preview/assets/{runtime-BqlrYWt_.js → runtime-DA77AmOP.js} +1 -1
- package/dist/preview/assets/{runtime-jVzpCkuu.js → runtime-DHTqFEQI.js} +1 -1
- package/dist/preview/assets/runtime-DKtlQWwc.js +1 -0
- package/dist/preview/assets/runtime-UmLaEUGf.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/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/config/config.vue +9 -1
- package/dist/runtime/components/config/index.vue +11 -1
- package/dist/runtime/components/config/schema.d.ts +25 -0
- package/dist/runtime/components/config/schema.js +8 -0
- 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.js +2 -2
- 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/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-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-24/com.shwfed.table.column.combobox-single.remote.options-static/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/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-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-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.vue.d.ts +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/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.vue.d.ts +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/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.vue.d.ts +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/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/config.vue.d.ts +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/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/config.vue.d.ts +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/index.vue +3 -4
- package/dist/runtime/components/table/schema.js +3 -3
- package/dist/runtime/share/event-bus.d.ts +23 -4
- package/dist/runtime/share/expression.d.ts +13 -0
- package/dist/runtime/share/expression.js +1 -0
- 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 +2 -2
- package/dist/runtime/vendor/cel-js/PROMPT.md +35 -3
- package/dist/runtime/vendor/cel-js/lib/functions.js +2 -2
- package/dist/runtime/vendor/cel-js/lib/optional.js +52 -1
- package/package.json +1 -1
- package/dist/preview/assets/badge-DamXUB_x.js +0 -1
- package/dist/preview/assets/config-CXgHZFVu.js +0 -1
- package/dist/preview/assets/config-Dtj6xvFB.js +0 -1
- package/dist/preview/assets/config-DyKtOYYU.js +0 -1
- package/dist/preview/assets/config-v7KXfP3A.js +0 -1
- package/dist/preview/assets/definition.vue_vue_type_script_setup_true_lang-C-3KP_in.js +0 -1
- package/dist/preview/assets/index-CzxZSeNm.js +0 -680
- package/dist/preview/assets/index-DUSkLHHf.js +0 -1
- package/dist/preview/assets/item-BAj_4_7-.js +0 -1
- package/dist/preview/assets/runtime-CiWg_Jub.js +0 -1
- package/dist/preview/assets/runtime-CpMT9U1z.js +0 -1
- package/dist/preview/assets/runtime-CswN1gKf.js +0 -1
- package/dist/preview/assets/runtime-DOK5OTJn.js +0 -1
- package/dist/preview/assets/runtime-DldmFxn1.js +0 -1
- package/dist/preview/assets/runtime-WZBVKYom.js +0 -1
|
@@ -2,6 +2,19 @@ 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;
|
|
5
18
|
export declare function Expression(options: {
|
|
6
19
|
configure: (env: Environment) => void;
|
|
7
20
|
resultType?: ResultType;
|
|
@@ -2,6 +2,7 @@ import { Either, Schema } from "effect";
|
|
|
2
2
|
import { Environment } from "../vendor/cel-js/lib/index.js";
|
|
3
3
|
import { CelError } from "../vendor/cel-js/lib/errors.js";
|
|
4
4
|
import { Locale } from "./locale.js";
|
|
5
|
+
export const HttpRequestResult = (t) => t === "HttpRequest" || t === "optional<HttpRequest>" || t === "optional<dyn>" || t === "dyn";
|
|
5
6
|
function matchesResultType(actual, expected) {
|
|
6
7
|
if (typeof expected === "string") return expected === "dyn" || actual === expected;
|
|
7
8
|
if (Array.isArray(expected)) return expected.includes("dyn") || expected.includes(actual);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Effect, Option } from 'effect';
|
|
2
|
+
import type { Fetch } from 'fx-fetch';
|
|
3
|
+
import type { HttpRequestBuilder } from '../vendor/cel-js/lib/http-builder.js';
|
|
4
|
+
/**
|
|
5
|
+
* Normalize the value a request expression evaluates to into an
|
|
6
|
+
* `Option<HttpRequestBuilder>`.
|
|
7
|
+
*
|
|
8
|
+
* A request expression now expects `optional<HttpRequest>` — `None` means the
|
|
9
|
+
* author opted out ("no request, skip the fetch"), enabling conditional fetches
|
|
10
|
+
* (e.g. only when a `form_id` is present). For back-compat a bare `HttpRequest`
|
|
11
|
+
* still works (always fetch) and maps to `Some`. A stray `null`/`undefined` is
|
|
12
|
+
* also treated as `None`.
|
|
13
|
+
*
|
|
14
|
+
* We only distinguish *present* from *absent* here — we do NOT `instanceof`-
|
|
15
|
+
* guard the payload. The type-checker already guarantees an `HttpRequest` at
|
|
16
|
+
* this boundary (the `HttpRequestResult` matcher), and a misconfigured non-
|
|
17
|
+
* builder would fail at `.json()`/`.file()` exactly as it did before this
|
|
18
|
+
* contract existed. (Guarding on `instanceof HttpRequestBuilder` would also
|
|
19
|
+
* wrongly reject test doubles that aren't real instances.)
|
|
20
|
+
*/
|
|
21
|
+
export declare function asRequest(result: unknown): Option.Option<HttpRequestBuilder>;
|
|
22
|
+
/**
|
|
23
|
+
* Resolve a request expression's value to its JSON response as an `Option`:
|
|
24
|
+
* `Some(body)` when a request was produced and issued, `None` when the
|
|
25
|
+
* expression opted out (or produced no builder). The returned Effect needs a
|
|
26
|
+
* `Fetch` layer. Mirrors the `{ request?, data }` datasource shape, where the
|
|
27
|
+
* response is exposed to the `data` expression as the `json` Option.
|
|
28
|
+
*/
|
|
29
|
+
export declare function fetchJsonOption(result: unknown): Effect.Effect<Option.Option<unknown>, unknown, Fetch.Fetch>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Effect, Option } from "effect";
|
|
2
|
+
export function asRequest(result) {
|
|
3
|
+
if (Option.isOption(result)) return result;
|
|
4
|
+
return result == null ? Option.none() : Option.some(result);
|
|
5
|
+
}
|
|
6
|
+
export function fetchJsonOption(result) {
|
|
7
|
+
return Option.match(asRequest(result), {
|
|
8
|
+
onNone: () => Effect.succeed(Option.none()),
|
|
9
|
+
onSome: (builder) => Effect.map(builder.json(), Option.some)
|
|
10
|
+
});
|
|
11
|
+
}
|
|
@@ -18,7 +18,7 @@ A `range()` built-in has been added (not from upstream) — `range(number, numbe
|
|
|
18
18
|
|
|
19
19
|
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.
|
|
20
20
|
|
|
21
|
-
The custom `Optional` class has been replaced with Effect's `Option` type (`import { Option } from 'effect'`). Internal helpers `optionalOf(value)` and `optionalValue(opt)` in `optional.js` handle the CEL-specific semantics (treating `undefined` as `None`, throwing `EvaluationError` on missing value access).
|
|
21
|
+
The custom `Optional` class has been replaced with Effect's `Option` type (`import { Option } from 'effect'`). Internal helpers `optionalOf(value)` and `optionalValue(opt)` in `optional.js` handle the CEL-specific semantics (treating `undefined` as `None`, throwing `EvaluationError` on missing value access). The optional surface is `optional.of(A): optional<A>` (the lift / `pure`), `optional.none()`, `optional.hasValue()`, `optional.value()`, `optional.or(optional)`, `optional.orValue(value)`, plus `optional<A>.flatMap(var, body): optional<B>` — monadic bind, a local addition (not from upstream). `flatMap` is a variable-binding macro (registered with `(ast, ast)` arg types so its body stays unevaluated): on `Some` it binds the value and evaluates `body` (which must itself yield an `optional`); on `None` it short-circuits without touching `body`. Map (`fmap`) is the derived `o.flatMap(v, optional.of(f(v)))`.
|
|
22
22
|
|
|
23
23
|
An `http` built-in has been added (`http-builtins.ts`, `http-builder.ts`) — not from upstream. It registers the `http` constant and the `http` / `HttpRequest` types on `globalRegistry`, so `http.get(url).header(...).body(...)` expressions type-check and evaluate in every `Environment`. A CEL expression only builds an `HttpRequestBuilder` — a pure description of a request; it never issues one. Both terminal methods, `.json()` and `.file()`, are dispatched by the host on the returned builder (neither is a CEL method), so expression evaluation stays free of IO. Endpoints must be absolute URLs — there is no base-URL resolution. Depends on `fx-fetch`. The host can register process-wide default headers via `HttpRequestBuilder.setDefaultHeader(name, valueOrGetter)` / `clearDefaultHeader(name)`; they are merged in at `#buildRequest()` time, with case-insensitive precedence to an explicit `.header(...)` on the builder. A getter that returns `null` / `undefined` / `''` skips the header for that request, so the host can source values from live refs (e.g. the active i18n locale for `Accept-Language`) without baking in stale snapshots.
|
|
24
24
|
|
|
@@ -77,7 +77,7 @@ Internal-only (not re-exported from `index.js`): `parse`, standalone `evaluate`/
|
|
|
77
77
|
|
|
78
78
|
Primitives: `string`, `bool`, `number`, `bytes`, `null_type`, `type`
|
|
79
79
|
Composites: `list<T>`, `map<K, V>`, `optional<T>`, `dyn`, `message`
|
|
80
|
-
Custom: `Date` (backed by `TZDate` from `@date-fns/tz`), `URL` (backed by the native `URL`; method `URL.
|
|
80
|
+
Custom: `Date` (backed by `TZDate` from `@date-fns/tz`), `URL` (backed by the native `URL`; method `URL.query(string): optional<string>` reads a search param — `None` when absent, distinguishing it from a present-but-empty value), `File` (native), `FormData` (native — see `form-builtins.ts`), `http` / `HttpRequest` (local addition — see `http-builtins.ts`)
|
|
81
81
|
|
|
82
82
|
## Function Signature Format
|
|
83
83
|
|
|
@@ -242,10 +242,13 @@ range(date("2024-01-01"), date("2024-04-01"), "month")
|
|
|
242
242
|
### URL
|
|
243
243
|
A `URL` value is supplied by the host (e.g. a `location` variable bound to the
|
|
244
244
|
current page URL). You cannot construct one in CEL.
|
|
245
|
+
`query(name)` returns `optional<string>` — `Some(value)` when the param is
|
|
246
|
+
present (including a present-but-empty value), `None` when it is absent. Unwrap
|
|
247
|
+
it with `.orValue(...)` / `.hasValue()` / `.value()`.
|
|
245
248
|
```cel
|
|
246
|
-
location.
|
|
247
|
-
location.
|
|
248
|
-
location.
|
|
249
|
+
location.query("tab").orValue("") // value of the ?tab= search param, "" if absent
|
|
250
|
+
location.query("missing").hasValue() // false — absent params are None
|
|
251
|
+
location.query("id").orValue("") // first value when a param repeats
|
|
249
252
|
```
|
|
250
253
|
|
|
251
254
|
## HTTP
|
|
@@ -297,6 +300,35 @@ http.post("https://api.example.com/users")
|
|
|
297
300
|
.body({"name": "Alice"})
|
|
298
301
|
```
|
|
299
302
|
|
|
303
|
+
## Optionals
|
|
304
|
+
|
|
305
|
+
An `optional<T>` is either present (`Some`) or absent (`None`). They come from
|
|
306
|
+
`.?` / `[?]` access, `find`, and `URL.query`. Build them with `optional.of(x)`
|
|
307
|
+
(the lift — wraps a value as present) and `optional.none()`.
|
|
308
|
+
|
|
309
|
+
```cel
|
|
310
|
+
optional.of(5) // present, holds 5
|
|
311
|
+
optional.none() // absent
|
|
312
|
+
|
|
313
|
+
o.hasValue() // bool — is it present?
|
|
314
|
+
o.value() // unwrap — ERRORS if absent
|
|
315
|
+
o.orValue(default) // unwrap, or `default` when absent
|
|
316
|
+
o.or(otherOptional) // first present optional wins
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### flatMap — chain a computation that may itself be absent
|
|
320
|
+
`o.flatMap(v, body)` binds the present value to `v` and evaluates `body` — which
|
|
321
|
+
must itself return an `optional` — only when `o` is present; an absent `o`
|
|
322
|
+
short-circuits to `None` and `body` is never evaluated.
|
|
323
|
+
```cel
|
|
324
|
+
loc.query("id").flatMap(v, optional.of("user-" + v)).orValue("anon")
|
|
325
|
+
// "user-42" when ?id=42 is present; "anon" when absent
|
|
326
|
+
|
|
327
|
+
optional.of(2).flatMap(v, optional.none()).hasValue() // false — body collapsed it
|
|
328
|
+
```
|
|
329
|
+
Together with `optional.of` this is a lawful monad. A plain map (`fmap`) is the
|
|
330
|
+
derived form `o.flatMap(v, optional.of(f(v)))`.
|
|
331
|
+
|
|
300
332
|
## Macros
|
|
301
333
|
|
|
302
334
|
Macros are special forms — they look like method calls but have special evaluation semantics.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { evaluationError } from "./errors.js";
|
|
2
2
|
import { Decimal } from "./decimal.js";
|
|
3
3
|
import { TYPES, Type } from "./registry.js";
|
|
4
|
-
import { register as registerOptional } from "./optional.js";
|
|
4
|
+
import { register as registerOptional, optionalOf } from "./optional.js";
|
|
5
5
|
import { objKeys, arrayFrom } from "./globals.js";
|
|
6
6
|
import { TZDate } from "@date-fns/tz";
|
|
7
7
|
import { startOfDay, startOfWeek, startOfMonth, startOfYear, endOfDay, endOfWeek, endOfMonth, endOfYear, addDays, addWeeks, addMonths, addYears, addHours, addMinutes, setDate as setDayOfMonth, setMonth, setYear, format as formatDate } from "date-fns";
|
|
@@ -392,7 +392,7 @@ export function registerFunctions(registry) {
|
|
|
392
392
|
functionOverload("Date.format(string): string", (d, fmt) => formatDate(d, fmt));
|
|
393
393
|
registry.registerType("File", File);
|
|
394
394
|
registry.registerType("URL", URL);
|
|
395
|
-
functionOverload("URL.
|
|
395
|
+
functionOverload("URL.query(string): optional<string>", (url, key) => optionalOf(url.searchParams.get(key) ?? void 0));
|
|
396
396
|
registerOptional(registry);
|
|
397
397
|
}
|
|
398
398
|
function stringSize(str) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Effect, Option } from "effect";
|
|
2
|
-
import { evaluationError } from "./errors.js";
|
|
2
|
+
import { evaluationError, parseError } from "./errors.js";
|
|
3
3
|
export function optionalOf(value) {
|
|
4
4
|
return value === void 0 ? Option.none() : Option.some(value);
|
|
5
5
|
}
|
|
@@ -108,4 +108,55 @@ export function register(registry) {
|
|
|
108
108
|
}
|
|
109
109
|
})
|
|
110
110
|
);
|
|
111
|
+
registry.registerFunctionOverload(
|
|
112
|
+
"optional<A>.flatMap(ast, ast): optional<dyn>",
|
|
113
|
+
createFlatMapExpander()
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
function createFlatMapExpander() {
|
|
117
|
+
const functionDesc = "optional.flatMap(var, body)";
|
|
118
|
+
const invalidVar = `${functionDesc} invalid iteration variable`;
|
|
119
|
+
const invalidReceiver = `${functionDesc} receiver`;
|
|
120
|
+
const invalidBody = `${functionDesc} body`;
|
|
121
|
+
function ensureOptional(value, ast, description) {
|
|
122
|
+
if (Option.isOption(value)) return value;
|
|
123
|
+
throw evaluationError("optional_expected", `${description} must be optional`, ast);
|
|
124
|
+
}
|
|
125
|
+
function ensureOptionalType(checker, node, ctx, description) {
|
|
126
|
+
const type = checker.check(node, ctx);
|
|
127
|
+
if (type.kind === "optional") return type;
|
|
128
|
+
if (type.kind === "dyn") return checker.getType("optional");
|
|
129
|
+
throw checker.createError("optional_expected", `${description} must be optional, got '${type}'`, node);
|
|
130
|
+
}
|
|
131
|
+
function typeCheck(checker, macro, ctx) {
|
|
132
|
+
const receiverType = ensureOptionalType(checker, macro.receiver, ctx, invalidReceiver);
|
|
133
|
+
const innerType = receiverType.valueType ?? checker.getType("dyn");
|
|
134
|
+
macro.iterCtx = ctx.forkWithVariable(macro.iterVarName, innerType);
|
|
135
|
+
return ensureOptionalType(checker, macro.body, macro.iterCtx, invalidBody);
|
|
136
|
+
}
|
|
137
|
+
function evaluate(ev, macro, ctx) {
|
|
138
|
+
return Effect.gen(function* () {
|
|
139
|
+
const recv = yield* ev.eval(macro.receiver, ctx);
|
|
140
|
+
const optional = ensureOptional(recv, macro.receiver, invalidReceiver);
|
|
141
|
+
if (Option.isNone(optional)) return Option.none();
|
|
142
|
+
const iterCtx = macro.iterCtx.reuse(ctx);
|
|
143
|
+
const result = yield* ev.eval(macro.body, iterCtx.setIterValue(optional.value, ev));
|
|
144
|
+
return ensureOptional(result, macro.body, invalidBody);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
return (opts) => {
|
|
148
|
+
const { args, receiver, ast } = opts;
|
|
149
|
+
const iterVar = args[0];
|
|
150
|
+
if (iterVar.op !== "id") throw parseError("invalid_macro_argument", invalidVar, iterVar);
|
|
151
|
+
return {
|
|
152
|
+
ast,
|
|
153
|
+
receiver,
|
|
154
|
+
functionDesc,
|
|
155
|
+
iterVarName: iterVar.args,
|
|
156
|
+
body: args[1],
|
|
157
|
+
iterCtx: void 0,
|
|
158
|
+
evaluate,
|
|
159
|
+
typeCheck
|
|
160
|
+
};
|
|
161
|
+
};
|
|
111
162
|
}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{d as M,F,u as $,o as z,w as p,a as v,y as E,c as w,z as x,b as f,_ as y,G as I,H as L,I as N,J as P,K as S,e as t,g as V,f as m,i as A,p as G,l as H,j as J,r as K,k as O,q as T,L as W,M as D,t as Q,m as R,s as U}from"./index-CzxZSeNm.js";const Y=M({name:"ShwfedBlockCardBadge",inheritAttrs:!1,__name:"badge",props:{badge:{}},setup(n){const a=n,{locale:k}=F(),j=T(),o=K(void 0);function i(){return O(j)}const g=t(()=>o.value===void 0?R():U(o.value)),l=t(()=>W(a.badge.content,k.value)||""),C=t(()=>l.value?D(l.value,m,{...i(),json:g.value}):""),B=t(()=>{const e=a.badge.show;if(!e)return!0;try{return Q(m(e,{...i(),json:g.value}))}catch(r){return console.warn("[shwfed-card-badge] show evaluation failed",r),!0}});async function s(){const e=a.badge.request;if(!e)return;const r=i(),q=V(function*(){return yield*(yield*m(e,r)).json()});try{o.value=await A(G(q,H))}catch(h){console.warn("[shwfed-card-badge] fetch failed",h)}}const u=t(()=>!!a.badge.request&&(a.badge.interval??0)>0),_=t(()=>Math.max(1,a.badge.interval??1)*1e3),c=J(),{pause:b,resume:d}=$(()=>{s()},_,{immediate:!1});return z(()=>{s(),u.value&&c.value&&d()}),p(c,e=>{u.value&&(e?(s(),d()):b())}),p(()=>[a.badge.request??"",a.badge.interval??0].join("|"),()=>{s(),u.value&&c.value?d():b()}),(e,r)=>l.value&&B.value?(v(),E(P,{key:0},[n.badge.dot?(v(),w(f(y),x({key:0,variant:n.badge.variant??"default",class:"size-2.5 min-w-0 rounded-full p-0"},e.$attrs),null,16,["variant"])):(v(),w(f(y),x({key:1,variant:n.badge.variant??"default"},e.$attrs),{default:I(()=>[L(f(N),{source:C.value,class:"max-w-none text-inherit [&_*]:text-inherit [&_p]:m-0"},null,8,["source"])]),_:1},16,["variant"]))],64)):S("",!0)}});export{Y as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{d as g,P as d,a2 as u,az as f,y as m,H as s,G as i,b as r,a as p,T as _,V as v,W as x,a1 as h,S as T,e as V}from"./index-CzxZSeNm.js";const S={class:"flex flex-col gap-3"},C=g({name:"ShwfedEventDispatchActionConfig",__name:"config",props:{modelValue:{required:!0},modelModifiers:{}},emits:["update:modelValue"],setup(l){const t=d(l,"modelValue"),o=u(f(),"triggers")??"触发的操作",n=V(()=>t.value.triggers??[]);function c(a){const e={...t.value};a.length===0?Reflect.deleteProperty(e,"triggers"):e.triggers=a,t.value=e}return(a,e)=>(p(),m("div",S,[s(r(T),{orientation:"vertical"},{default:i(()=>[s(r(_),{class:"text-xs text-zinc-500"},{default:i(()=>[v(x(r(o)),1)]),_:1}),s(h,{triggers:n.value,"onUpdate:triggers":c},null,8,["triggers"])]),_:1})]))}});export{C as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{d as x,P as k,b0 as S,y as V,H as e,G as l,b as a,a as g,T as r,U as m,V as d,W as f,I as p,au as $,S as _,Y as b,a2 as w,a3 as y}from"./index-CzxZSeNm.js";const z={class:"flex flex-col gap-4"},h=x({name:"ShwfedMarkdownItemConfig",__name:"config",props:{modelValue:{required:!0},modelModifiers:{}},emits:["update:modelValue"],setup(v){const t=k(v,"modelValue"),c=S(),u=o=>w(c,o)??o,s=o=>y(c,o);return(o,n)=>(g(),V("div",z,[e(a(_),{orientation:"vertical"},{default:l(()=>[e(a(r),{class:"text-xs text-zinc-500"},m({default:l(()=>[d(" "+f(u("name")),1)]),_:2},[s("name")?{name:"tooltip",fn:l(()=>[e(a(p),{source:s("name"),block:"",class:"prose prose-sm prose-zinc"},null,8,["source"])]),key:"0"}:void 0]),1024),e(a($),{"model-value":t.value.name,placeholder:"仅用于编辑器内识别","onUpdate:modelValue":n[0]||(n[0]=i=>t.value={...t.value,name:String(i)})},null,8,["model-value"])]),_:1}),e(a(_),{orientation:"vertical"},{default:l(()=>[e(a(r),{class:"text-xs text-zinc-500"},m({default:l(()=>[d(" "+f(u("content")),1)]),_:2},[s("content")?{name:"tooltip",fn:l(()=>[e(a(p),{source:s("content"),block:"",class:"prose prose-sm prose-zinc"},null,8,["source"])]),key:"0"}:void 0]),1024),e(a(b),{markdown:"",multiline:"","model-value":t.value.content,"onUpdate:modelValue":n[1]||(n[1]=i=>t.value={...t.value,content:i})},null,8,["model-value"])]),_:1})]))}});export{h as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{d as z,a as y,y as E,v as V,N as T,b as e,O as U,P as $,Q as j,c as F,G as l,R as v,H as s,S as d,T as u,U as p,V as m,W as f,I as g,X as b,Y as N,Z as h,$ as B,J as C,a0 as H,a1 as O,a2 as R,a3 as D}from"./index-CzxZSeNm.js";const P=z({__name:"FieldGroup",props:{class:{type:[Boolean,null,String,Object,Array]}},setup(_){const r=_;return(x,i)=>(y(),E("div",{"data-slot":"field-group",class:T(e(U)("group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 *:data-[slot=field-group]:gap-4",r.class))},[V(x.$slots,"default")],2))}}),q={class:"grid grid-cols-2 gap-4"},I={class:"grid grid-cols-2 gap-4"},J={class:"flex items-start gap-2"},L={class:"grid grid-cols-2 gap-3"},G=z({name:"ShwfedHttpRequestConfirmActionConfig",__name:"config",props:{modelValue:{required:!0},modelModifiers:{}},emits:["update:modelValue"],setup(_){const r=$(_,"modelValue"),x=j(()=>{}),i=n=>R(x,n)??n,a=n=>D(x,n);function c(n){const t={...r.value,...n};for(const[o,k]of Object.entries(n))k===void 0&&Reflect.deleteProperty(t,o);r.value=t}const S=["onSuccess","onWarning","onError","onInfo"];function w(n,t){c({[n]:t.length===0?void 0:t})}return(n,t)=>(y(),F(e(P),null,{default:l(()=>[v("div",q,[s(e(d),{orientation:"vertical"},{default:l(()=>[s(e(u),{class:"text-xs text-zinc-500"},p({default:l(()=>[m(" "+f(i("expression")),1)]),_:2},[a("expression")?{name:"tooltip",fn:l(()=>[s(e(g),{source:a("expression"),block:"",class:"prose prose-sm prose-zinc"},null,8,["source"])]),key:"0"}:void 0]),1024),s(e(b),{"model-value":r.value.expression,multiline:"",placeholder:"例:http.post('/api/foo').body({ id: row.id })","result-type":"HttpRequest",class:"min-h-16","onUpdate:modelValue":t[0]||(t[0]=o=>c({expression:o}))},null,8,["model-value"])]),_:1}),s(e(d),{orientation:"vertical"},{default:l(()=>[s(e(u),{class:"text-xs text-zinc-500"},p({default:l(()=>[m(" "+f(i("markdown")),1)]),_:2},[a("markdown")?{name:"tooltip",fn:l(()=>[s(e(g),{source:a("markdown"),block:"",class:"prose prose-sm prose-zinc"},null,8,["source"])]),key:"0"}:void 0]),1024),s(e(N),{markdown:"","model-value":r.value.markdown,"onUpdate:modelValue":t[1]||(t[1]=o=>c({markdown:o}))},null,8,["model-value"])]),_:1})]),v("div",I,[s(e(d),{orientation:"vertical"},{default:l(()=>[s(e(u),{class:"text-xs text-zinc-500"},p({default:l(()=>[m(" "+f(i("icon")),1)]),_:2},[a("icon")?{name:"tooltip",fn:l(()=>[s(e(g),{source:a("icon"),block:"",class:"prose prose-sm prose-zinc"},null,8,["source"])]),key:"0"}:void 0]),1024),s(e(h),{"model-value":r.value.icon??"","onUpdate:modelValue":t[2]||(t[2]=o=>c(o.trim()===""?{icon:void 0}:{icon:o}))},null,8,["model-value"])]),_:1}),s(e(d),{orientation:"vertical"},{default:l(()=>[s(e(u),{class:"text-xs text-zinc-500"},p({default:l(()=>[m(" "+f(i("color")),1)]),_:2},[a("color")?{name:"tooltip",fn:l(()=>[s(e(g),{source:a("color"),block:"",class:"prose prose-sm prose-zinc"},null,8,["source"])]),key:"0"}:void 0]),1024),s(e(B),{"model-value":r.value.color??"","onUpdate:modelValue":t[3]||(t[3]=o=>c(o.trim()===""?{color:void 0}:{color:o}))},null,8,["model-value"])]),_:1})]),v("div",J,[s(e(d),{orientation:"vertical",class:"flex-1 basis-0 min-w-0"},{default:l(()=>[s(e(u),{class:"text-xs text-zinc-500"},p({default:l(()=>[m(" "+f(i("messageExpression")),1)]),_:2},[a("messageExpression")?{name:"tooltip",fn:l(()=>[s(e(g),{source:a("messageExpression"),block:"",class:"prose prose-sm prose-zinc"},null,8,["source"])]),key:"0"}:void 0]),1024),s(e(b),{"model-value":r.value.messageExpression??"",placeholder:"例:string(json.message)","result-type":"string","extra-vars":{json:{type:"dyn",label:"HTTP 响应体(已解析 JSON)"}},"onUpdate:modelValue":t[4]||(t[4]=o=>c({messageExpression:o===""?void 0:o}))},null,8,["model-value"])]),_:1}),s(e(d),{orientation:"vertical",class:"flex-1 basis-0 min-w-0"},{default:l(()=>[s(e(u),{class:"text-xs text-zinc-500"},p({default:l(()=>[m(" "+f(i("resultExpression")),1)]),_:2},[a("resultExpression")?{name:"tooltip",fn:l(()=>[s(e(g),{source:a("resultExpression"),block:"",class:"prose prose-sm prose-zinc"},null,8,["source"])]),key:"0"}:void 0]),1024),s(e(b),{"model-value":r.value.resultExpression??"",placeholder:"例:json.code == 0 ? 'success' : 'error'","result-type":"string","extra-vars":{json:{type:"dyn",label:"HTTP 响应体(已解析 JSON)"}},"onUpdate:modelValue":t[5]||(t[5]=o=>c({resultExpression:o===""?void 0:o}))},null,8,["model-value"])]),_:1})]),v("div",L,[(y(),E(C,null,H(S,o=>s(e(d),{key:o,orientation:"vertical",class:"min-w-0"},{default:l(()=>[s(e(u),{class:"text-xs text-zinc-500"},p({default:l(()=>[m(" "+f(i(o)),1)]),_:2},[a(o)?{name:"tooltip",fn:l(()=>[s(e(g),{source:a(o),block:"",class:"prose prose-sm prose-zinc"},null,8,["source"])]),key:"0"}:void 0]),1024),s(O,{triggers:r.value[o]??[],"onUpdate:triggers":k=>w(o,k)},null,8,["triggers","onUpdate:triggers"])]),_:2},1024)),64))])]),_:1}))}});export{G as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{d as _,P as y,a5 as x,a6 as b,y as c,R as i,H as n,G as o,b as t,a as l,a7 as v,a8 as u,a9 as g,aa as D,J as h,a0 as S,c as $,ab as k,W as p,ac as w}from"./index-CzxZSeNm.js";const B={class:"flex flex-col gap-3"},C={class:"flex-1"},V={class:"ml-auto text-xs tabular-nums text-zinc-400"},N=_({name:"ShwfedPrototypeActionConfig",__name:"config",props:{modelValue:{required:!0},modelModifiers:{}},emits:["update:modelValue"],setup(m){const r=y(m,"modelValue"),f=(()=>{const s=new Map;for(const e of x){if(e.type===b||e.deprecated)continue;const a=s.get(e.type);(!a||e.compatibilityDate>a.compatibilityDate)&&s.set(e.type,{type:e.type,compatibilityDate:e.compatibilityDate,name:e.metadata.name,icon:e.metadata.icon})}return[...s.values()].sort((e,a)=>e.name.localeCompare(a.name,"zh"))})();function d(s,e){r.value={type:s,compatibilityDate:e}}return(s,e)=>(l(),c("div",B,[e[0]||(e[0]=i("p",{class:"text-xs text-zinc-500"}," 原型按钮点击后无任何副作用,用于占位。选择下方任意类型可将其转换为正式按钮 —— 此转换仅能进行一次。 ",-1)),n(t(w),null,{default:o(()=>[n(t(v),{align:"inline-start"},{default:o(()=>[n(t(u),{icon:"fluent:arrow-swap-20-regular"})]),_:1}),n(t(g),null,{default:o(()=>[n(t(D),null,{default:o(()=>[(l(!0),c(h,null,S(t(f),a=>(l(),$(t(k),{key:a.type,value:a.type,onSelect:z=>d(a.type,a.compatibilityDate)},{default:o(()=>[n(t(u),{icon:a.icon,class:"size-4 shrink-0"},null,8,["icon"]),i("span",C,p(a.name),1),i("span",V,p(a.compatibilityDate),1)]),_:2},1032,["value","onSelect"]))),128))]),_:1})]),_:1})]),_:1})]))}});export{N as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{d as f,aZ as u,o as m,a_ as p,al as g,K as l,x as I,a$ as _}from"./index-CzxZSeNm.js";const w=f({name:"ShwfedActionDefinition",inheritAttrs:!1,__name:"definition",props:{actionId:{},effect:{}},setup(r){const n=r,a=u(),t=I(_,void 0),i=crypto.randomUUID(),c=import.meta.dev;let e,s=!1;function d(){!c||s||(s=!0,console.warn("[shwfed-action-definition] must be used inside <shwfed-actions>."))}function o(){if(!t){d();return}e&&e!==n.actionId&&t.unregisterAction(e,i),t.registerAction({ownerId:i,actionId:n.actionId,effect:n.effect,render:a.default}),e=n.actionId}return o(),m(()=>{o()}),p(()=>{o()}),g(()=>{!t||!e||t.unregisterAction(e,i)}),(y,A)=>l("",!0)}});export{w as _};
|