@shwfed/config 2.10.3 → 2.10.5

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.
Files changed (159) hide show
  1. package/dist/mcp.mjs +1600 -1317
  2. package/dist/module.json +1 -1
  3. package/dist/preview/assets/{FieldGroup.vue_vue_type_script_setup_true_lang-sT5i_dnE.js → FieldGroup.vue_vue_type_script_setup_true_lang-D-COryaS.js} +1 -1
  4. package/dist/preview/assets/{badge-ZFj45FMd.js → badge-Sb01O_E2.js} +1 -1
  5. package/dist/preview/assets/{config-3rP_f_3o.js → config-99L3dMcP.js} +1 -1
  6. package/dist/preview/assets/{config-cD091sze.js → config-BgJWNJ-L.js} +1 -1
  7. package/dist/preview/assets/{config-CEBzJOHo.js → config-BjSI3yTw.js} +1 -1
  8. package/dist/preview/assets/{config-BBvebIQw.js → config-BzMW9qCl.js} +1 -1
  9. package/dist/preview/assets/{config-BLesYihN.js → config-CEM0BCax.js} +1 -1
  10. package/dist/preview/assets/{config-D1uMzMiN.js → config-CtKXZjQl.js} +1 -1
  11. package/dist/preview/assets/{config-CSR1JNVB.js → config-CyRpAiSg.js} +1 -1
  12. package/dist/preview/assets/{config-Rz0II9u6.js → config-Cz3VQcLY.js} +1 -1
  13. package/dist/preview/assets/{config-2iinn_1E.js → config-D6BiWm3q.js} +1 -1
  14. package/dist/preview/assets/{config-lskK7grq.js → config-DA1Knc1V.js} +1 -1
  15. package/dist/preview/assets/{config-DfVc2Iy9.js → config-DGBuMIqU.js} +1 -1
  16. package/dist/preview/assets/{config-BwDPPmtn.js → config-DK0wxXG_.js} +1 -1
  17. package/dist/preview/assets/{config-DZPLqFqt.js → config-Du8kzY9H.js} +1 -1
  18. package/dist/preview/assets/{config-CgM75jSO.js → config-n4AGAnL-.js} +1 -1
  19. package/dist/preview/assets/{definition.vue_vue_type_script_setup_true_lang-Ce_NeQUa.js → definition.vue_vue_type_script_setup_true_lang-BtOF0dda.js} +1 -1
  20. package/dist/preview/assets/{index-_KA5_QIV.js → index-BOnw60vg.js} +1 -1
  21. package/dist/preview/assets/index-BZlqSG2R.js +763 -0
  22. package/dist/preview/assets/index-D3Az3yzR.css +1 -0
  23. package/dist/preview/assets/index-Rj5bF6fM.js +1 -0
  24. package/dist/preview/assets/{item-CBFJ6f6b.js → item-D7avZRKo.js} +1 -1
  25. package/dist/preview/assets/{runtime-DO9HS0Rb.js → runtime-BWlX7BAG.js} +1 -1
  26. package/dist/preview/assets/{runtime-BKqyqEeD.js → runtime-Bek88ifk.js} +1 -1
  27. package/dist/preview/assets/{runtime-CIc3k_jd.js → runtime-C9kOkTYc.js} +1 -1
  28. package/dist/preview/assets/{runtime-Q_isegB9.js → runtime-CSrgcLuC.js} +1 -1
  29. package/dist/preview/assets/{runtime-jWibKv1T.js → runtime-CWTz9Iy4.js} +1 -1
  30. package/dist/preview/assets/{runtime-Cu0RJn8g.js → runtime-D-HZWcV-.js} +1 -1
  31. package/dist/preview/assets/{runtime-CvMryNNx.js → runtime-DMsPs0Pz.js} +1 -1
  32. package/dist/preview/assets/{runtime-BIGEoc5L.js → runtime-DOqVHcvv.js} +1 -1
  33. package/dist/preview/assets/{runtime-DQXLscBz.js → runtime-Dhl0NpTL.js} +1 -1
  34. package/dist/preview/assets/{runtime-enspc5HG.js → runtime-Dxb1-gUN.js} +1 -1
  35. package/dist/preview/assets/{schema-meta-B5tln_XH.js → schema-meta-DXS0vi6v.js} +1 -1
  36. package/dist/preview/index.html +2 -2
  37. package/dist/runtime/components/block-layout-editor/index.vue +8 -0
  38. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/schema.d.ts +1 -0
  39. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/schema.js +5 -1
  40. package/dist/runtime/components/config/blocks/2026-06-17/com.shwfed.block.tree.single/config.d.vue.ts +223 -0
  41. package/dist/runtime/components/config/blocks/2026-06-17/com.shwfed.block.tree.single/config.vue +496 -0
  42. package/dist/runtime/components/config/blocks/2026-06-17/com.shwfed.block.tree.single/config.vue.d.ts +223 -0
  43. package/dist/runtime/components/config/blocks/2026-06-17/com.shwfed.block.tree.single/node-actions.d.vue.ts +10 -0
  44. package/dist/runtime/components/config/blocks/2026-06-17/com.shwfed.block.tree.single/node-actions.vue +25 -0
  45. package/dist/runtime/components/config/blocks/2026-06-17/com.shwfed.block.tree.single/node-actions.vue.d.ts +10 -0
  46. package/dist/runtime/components/config/blocks/2026-06-17/com.shwfed.block.tree.single/runtime.d.vue.ts +228 -0
  47. package/dist/runtime/components/config/blocks/2026-06-17/com.shwfed.block.tree.single/runtime.vue +355 -0
  48. package/dist/runtime/components/config/blocks/2026-06-17/com.shwfed.block.tree.single/runtime.vue.d.ts +228 -0
  49. package/dist/runtime/components/config/blocks/2026-06-17/com.shwfed.block.tree.single/schema.d.ts +227 -0
  50. package/dist/runtime/components/config/blocks/2026-06-17/com.shwfed.block.tree.single/schema.js +130 -0
  51. package/dist/runtime/components/config/utils/resolve.d.ts +16 -0
  52. package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.text/config.d.vue.ts +134 -0
  53. package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.text/config.vue +78 -2
  54. package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.text/config.vue.d.ts +134 -0
  55. package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.text/runtime.vue +24 -0
  56. package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.text/schema.d.ts +132 -0
  57. package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.text/schema.js +14 -1
  58. package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.number/config.d.vue.ts +134 -0
  59. package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.number/config.vue +77 -2
  60. package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.number/config.vue.d.ts +134 -0
  61. package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.number/runtime.vue +24 -0
  62. package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.number/schema.d.ts +132 -0
  63. package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.number/schema.js +14 -1
  64. package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/config.d.vue.ts +22 -22
  65. package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/config.vue.d.ts +22 -22
  66. package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/schema.js +2 -1
  67. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.d.vue.ts +22 -22
  68. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.vue.d.ts +22 -22
  69. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/schema.js +2 -1
  70. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.d.vue.ts +22 -22
  71. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.vue.d.ts +22 -22
  72. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/schema.js +2 -1
  73. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.d.vue.ts +22 -22
  74. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.vue.d.ts +22 -22
  75. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/schema.js +2 -1
  76. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.d.vue.ts +22 -22
  77. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.vue.d.ts +22 -22
  78. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/schema.js +2 -1
  79. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.d.vue.ts +22 -22
  80. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.vue.d.ts +22 -22
  81. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/schema.js +2 -1
  82. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.d.vue.ts +22 -22
  83. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.vue.d.ts +22 -22
  84. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/schema.js +2 -1
  85. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.select/runtime.vue +3 -3
  86. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.text/runtime.vue +54 -2
  87. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.combobox-single/config.d.vue.ts +2 -2
  88. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.combobox-single/config.vue.d.ts +2 -2
  89. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.d.vue.ts +2 -2
  90. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.vue.d.ts +2 -2
  91. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/config.d.vue.ts +2 -2
  92. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/config.vue.d.ts +2 -2
  93. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi/config.d.vue.ts +2 -2
  94. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi/config.vue.d.ts +2 -2
  95. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.d.vue.ts +2 -2
  96. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.vue.d.ts +2 -2
  97. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.d.vue.ts +2 -2
  98. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.vue.d.ts +2 -2
  99. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/config.d.vue.ts +2 -2
  100. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/config.vue.d.ts +2 -2
  101. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.d.vue.ts +2 -2
  102. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.vue.d.ts +2 -2
  103. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/config.d.vue.ts +2 -2
  104. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/config.vue.d.ts +2 -2
  105. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.d.vue.ts +2 -2
  106. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.vue.d.ts +2 -2
  107. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/config.d.vue.ts +2 -2
  108. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +2 -2
  109. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/schema.js +2 -1
  110. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/config.d.vue.ts +2 -2
  111. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +2 -2
  112. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/schema.js +2 -1
  113. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/config.d.vue.ts +2 -2
  114. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/config.vue.d.ts +2 -2
  115. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/config.d.vue.ts +2 -2
  116. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/config.vue.d.ts +2 -2
  117. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/config.d.vue.ts +2 -2
  118. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +2 -2
  119. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/schema.js +2 -1
  120. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/config.d.vue.ts +2 -2
  121. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +2 -2
  122. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/schema.js +2 -1
  123. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/config.d.vue.ts +2 -2
  124. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/config.vue.d.ts +2 -2
  125. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/config.d.vue.ts +2 -2
  126. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/config.vue.d.ts +2 -2
  127. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/config.d.vue.ts +2 -2
  128. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +2 -2
  129. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/schema.js +2 -1
  130. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/config.d.vue.ts +2 -2
  131. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +2 -2
  132. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/schema.js +2 -1
  133. package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/config.d.vue.ts +10 -0
  134. package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/config.vue +543 -0
  135. package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/config.vue.d.ts +10 -0
  136. package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/runtime.d.vue.ts +9 -0
  137. package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/runtime.vue +110 -0
  138. package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/runtime.vue.d.ts +9 -0
  139. package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/schema.d.ts +76 -0
  140. package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/schema.js +89 -0
  141. package/dist/runtime/components/ui/tree/Tree.d.vue.ts +13 -0
  142. package/dist/runtime/components/ui/tree/Tree.vue +8 -1
  143. package/dist/runtime/components/ui/tree/Tree.vue.d.ts +13 -0
  144. package/dist/runtime/components/ui/tree/TreeNode.d.vue.ts +2 -0
  145. package/dist/runtime/components/ui/tree/TreeNode.vue +5 -2
  146. package/dist/runtime/components/ui/tree/TreeNode.vue.d.ts +2 -0
  147. package/dist/runtime/share/slot-renderer.d.vue.ts +5 -0
  148. package/dist/runtime/share/slot-renderer.vue +43 -28
  149. package/dist/runtime/share/slot-renderer.vue.d.ts +5 -0
  150. package/dist/runtime/share/tree-node-var.d.ts +25 -0
  151. package/dist/runtime/share/tree-node-var.js +10 -0
  152. package/dist/runtime/vendor/cel-js/CLAUDE.md +1 -1
  153. package/dist/runtime/vendor/cel-js/PROMPT.md +6 -0
  154. package/dist/runtime/vendor/cel-js/lib/http-builtins.d.ts +0 -14
  155. package/dist/runtime/vendor/cel-js/lib/http-builtins.js +17 -0
  156. package/package.json +1 -1
  157. package/dist/preview/assets/index-Zc4Mcm3J.js +0 -761
  158. package/dist/preview/assets/index-pkoEF5dC.css +0 -1
  159. package/dist/preview/assets/index-snO3CfdE.js +0 -1
@@ -0,0 +1,76 @@
1
+ import { Schema } from 'effect';
2
+ import type { ColumnDef } from '@tanstack/vue-table';
3
+ import type { Environment } from '../../../../../vendor/cel-js/lib/index.js';
4
+ import type { ColumnDefDeps } from '../../../utils/resolve.js';
5
+ export declare const type: "com.shwfed.table.column.date-input";
6
+ export declare const compatibilityDate: "2026-06-17";
7
+ export declare const metadata: {
8
+ readonly name: "日期输入";
9
+ readonly icon: "fluent:calendar-ltr-20-regular";
10
+ };
11
+ export declare function presetSchema(configure: (env: Environment) => void): Schema.Struct<{
12
+ id: Schema.refine<string, typeof Schema.String>;
13
+ label: Schema.TupleType<readonly [Schema.Struct<{
14
+ locale: Schema.Literal<["zh"]>;
15
+ message: Schema.SchemaClass<string, string, never>;
16
+ }>], [Schema.Struct<{
17
+ locale: Schema.Literal<["ja", "en", "ko"]>;
18
+ message: Schema.SchemaClass<string, string, never>;
19
+ }>]>;
20
+ value: Schema.Schema<string, string, never>;
21
+ }>;
22
+ export declare function schema(configure: (env: Environment) => void): Schema.Struct<{
23
+ placeholder: Schema.optional<Schema.TupleType<readonly [Schema.Struct<{
24
+ locale: Schema.Literal<["zh"]>;
25
+ message: Schema.SchemaClass<string, string, never>;
26
+ }>], [Schema.Struct<{
27
+ locale: Schema.Literal<["ja", "en", "ko"]>;
28
+ message: Schema.SchemaClass<string, string, never>;
29
+ }>]>>;
30
+ hidden: Schema.optional<Schema.Schema<string, string, never>>;
31
+ disabled: Schema.optional<Schema.Schema<string, string, never>>;
32
+ readonly: Schema.optional<Schema.Schema<string, string, never>>;
33
+ derived: Schema.optional<Schema.Struct<{
34
+ mode: Schema.Literal<["formula", "prefill"]>;
35
+ expression: Schema.Schema<string, string, never>;
36
+ }>>;
37
+ format: Schema.optional<Schema.refine<string, typeof Schema.String>>;
38
+ valueFormat: Schema.optional<Schema.refine<string, typeof Schema.String>>;
39
+ presets: Schema.optional<Schema.Array$<Schema.Struct<{
40
+ id: Schema.refine<string, typeof Schema.String>;
41
+ label: Schema.TupleType<readonly [Schema.Struct<{
42
+ locale: Schema.Literal<["zh"]>;
43
+ message: Schema.SchemaClass<string, string, never>;
44
+ }>], [Schema.Struct<{
45
+ locale: Schema.Literal<["ja", "en", "ko"]>;
46
+ message: Schema.SchemaClass<string, string, never>;
47
+ }>]>;
48
+ value: Schema.Schema<string, string, never>;
49
+ }>>>;
50
+ title: Schema.TupleType<readonly [Schema.Struct<{
51
+ locale: Schema.Literal<["zh"]>;
52
+ message: Schema.SchemaClass<string, string, never>;
53
+ }>], [Schema.Struct<{
54
+ locale: Schema.Literal<["ja", "en", "ko"]>;
55
+ message: Schema.SchemaClass<string, string, never>;
56
+ }>]>;
57
+ binding: Schema.refine<string, typeof Schema.String>;
58
+ enableSorting: Schema.optional<Schema.SchemaClass<boolean, boolean, never>>;
59
+ sortKey: Schema.optional<Schema.refine<string, typeof Schema.String>>;
60
+ size: Schema.optional<Schema.refine<number, Schema.filter<typeof Schema.Number>>>;
61
+ grow: Schema.optional<Schema.SchemaClass<boolean, boolean, never>>;
62
+ tooltip: Schema.optional<Schema.TupleType<readonly [Schema.Struct<{
63
+ locale: Schema.Literal<["zh"]>;
64
+ message: Schema.SchemaClass<string, string, never>;
65
+ }>], [Schema.Struct<{
66
+ locale: Schema.Literal<["ja", "en", "ko"]>;
67
+ message: Schema.SchemaClass<string, string, never>;
68
+ }>]>>;
69
+ id: Schema.refine<string, typeof Schema.String>;
70
+ groupId: Schema.optional<typeof Schema.UUID>;
71
+ type: Schema.Literal<["com.shwfed.table.column.date-input"]>;
72
+ compatibilityDate: Schema.Literal<["2026-06-17"]>;
73
+ }>;
74
+ export type Value = Schema.Schema.Type<ReturnType<typeof schema>>;
75
+ export declare function defaults(): Partial<Value>;
76
+ export declare function toColumnDef(value: Value, { getLocaleText }: ColumnDefDeps): Partial<ColumnDef<unknown, unknown>>;
@@ -0,0 +1,89 @@
1
+ import { Schema } from "effect";
2
+ import { getProperty } from "dot-prop";
3
+ import { Locale } from "../../../../../share/locale.js";
4
+ import { CelRowAccess, derivedRowField, editableColumnFields, editableHeader } from "../../../utils/shared.js";
5
+ export const type = "com.shwfed.table.column.date-input";
6
+ export const compatibilityDate = "2026-06-17";
7
+ export const metadata = {
8
+ name: "\u65E5\u671F\u8F93\u5165",
9
+ icon: "fluent:calendar-ltr-20-regular"
10
+ };
11
+ export function presetSchema(configure) {
12
+ const CelDate = CelRowAccess(configure, { resultType: "Date" });
13
+ return Schema.Struct({
14
+ id: Schema.UUID.annotations({ description: "\u9884\u8BBE\u552F\u4E00\u6807\u8BC6\uFF0C\u7528\u4E8E\u7A33\u5B9A\u7684 v-for key" }),
15
+ label: Locale.annotations({
16
+ title: "\u6807\u7B7E",
17
+ description: "\u5FEB\u6377\u9009\u9879\u5C55\u793A\u7684\u672C\u5730\u5316\u6587\u672C"
18
+ }),
19
+ value: CelDate.annotations({
20
+ title: "\u503C",
21
+ description: '\u70B9\u51FB\u8BE5\u9884\u8BBE\u65F6\u8BA1\u7B97\u51FA\u7684\u65E5\u671F\uFF0C\u4F8B\u5982 `now.offset(-7, "days")`'
22
+ })
23
+ }).annotations({
24
+ title: "DateInputPreset"
25
+ });
26
+ }
27
+ export function schema(configure) {
28
+ const CelBool = CelRowAccess(configure, { resultType: "bool" });
29
+ const Preset = presetSchema(configure);
30
+ return Schema.Struct({
31
+ type: Schema.Literal(type),
32
+ compatibilityDate: Schema.Literal(compatibilityDate),
33
+ ...editableColumnFields(),
34
+ placeholder: Schema.optional(Locale.annotations({
35
+ title: "\u5360\u4F4D\u7B26",
36
+ description: "\u672A\u9009\u4E2D\u65E5\u671F\u65F6\u8F93\u5165\u6846\u4E2D\u7684\u5360\u4F4D\u6587\u672C"
37
+ })),
38
+ hidden: Schema.optional(CelBool.annotations({
39
+ title: "\u9690\u85CF\u6761\u4EF6",
40
+ description: "\u8FD4\u56DE `true` \u65F6\u8BE5\u884C\u7684\u8F93\u5165\u6846\u4E0D\u6E32\u67D3\uFF08\u5176\u4F59\u884C\u4E0D\u53D7\u5F71\u54CD\uFF09"
41
+ })),
42
+ disabled: Schema.optional(CelBool.annotations({
43
+ title: "\u7981\u7528\u6761\u4EF6",
44
+ description: "\u8FD4\u56DE `true` \u65F6\u8F93\u5165\u6846\u4ECD\u7136\u6E32\u67D3\u4F46\u4E0D\u53EF\u7F16\u8F91"
45
+ })),
46
+ readonly: Schema.optional(CelBool.annotations({
47
+ title: "\u53EA\u8BFB\u6761\u4EF6",
48
+ description: "\u8FD4\u56DE `true` \u65F6\u4EC5\u4EE5\u7EAF\u6587\u672C\u5C55\u793A\u5F53\u524D\u503C"
49
+ })),
50
+ derived: derivedRowField(configure, "string"),
51
+ format: Schema.optional(Schema.String.pipe(Schema.minLength(1)).annotations({
52
+ title: "\u5C55\u793A\u683C\u5F0F",
53
+ description: "\u8F93\u5165\u6846\u4E2D\u5C55\u793A\u65E5\u671F\u7684 `date-fns` \u683C\u5F0F\u4E32\uFF1B\u7559\u7A7A\u65F6\u4F7F\u7528\u9ED8\u8BA4 `yyyy-MM-dd`"
54
+ })),
55
+ valueFormat: Schema.optional(Schema.String.pipe(Schema.minLength(1)).annotations({
56
+ title: "\u5B58\u50A8\u683C\u5F0F",
57
+ description: "\u5199\u5165\u884C\u6570\u636E\u7684 `date-fns` \u683C\u5F0F\u4E32\uFF1B\u7559\u7A7A\u65F6\u4F7F\u7528\u9ED8\u8BA4 `yyyy-MM-dd`"
58
+ })),
59
+ presets: Schema.optional(Schema.Array(Preset).annotations({
60
+ title: "\u5FEB\u6377\u9009\u9879",
61
+ description: "\u5728\u9009\u62E9\u5668\u4FA7\u680F\u5C55\u793A\u7684\u5FEB\u6377\u9884\u8BBE\uFF1B\u7559\u7A7A\u5219\u4E0D\u6E32\u67D3\u4FA7\u680F"
62
+ }))
63
+ }).annotations({ title: "DateInputRenderer", description: "\u65E5\u671F\u8F93\u5165\u6E32\u67D3\u5668\uFF08\u53EF\u7F16\u8F91\uFF09" });
64
+ }
65
+ export function defaults() {
66
+ return {
67
+ title: [{ locale: "zh", message: "" }],
68
+ binding: "",
69
+ size: 120
70
+ };
71
+ }
72
+ export function toColumnDef(value, { getLocaleText }) {
73
+ return {
74
+ header: editableHeader(getLocaleText(value.title)),
75
+ // `binding` is a dot-prop path (validated non-empty); the cell renderer
76
+ // reads through the same path it writes to. No CEL — accessor is literal.
77
+ accessorFn: (row) => {
78
+ if (!row || typeof row !== "object") return void 0;
79
+ return getProperty(row, value.binding);
80
+ },
81
+ enableSorting: value.enableSorting ?? false,
82
+ sortingFn: "alphanumeric",
83
+ size: value.size,
84
+ meta: {
85
+ grow: value.grow ?? false,
86
+ tooltip: getLocaleText(value.tooltip)
87
+ }
88
+ };
89
+ }
@@ -30,6 +30,19 @@ declare const __VLS_export: <Node>(__VLS_props: NonNullable<Awaited<typeof __VLS
30
30
  * it off so a stray click doesn't leave a permanent highlight.
31
31
  */
32
32
  showFocusedRow?: boolean;
33
+ /**
34
+ * Cursor shown over a selectable row. Defaults to `'pointer'` (a row is
35
+ * clickable to select); `'default'` opts out for surfaces that prefer the
36
+ * arrow cursor while still selecting on click.
37
+ */
38
+ selectCursor?: "pointer" | "default";
39
+ /**
40
+ * `single` mode only. When `true`, clicking the already-selected node
41
+ * clears the selection (toggle); when `false` (default), a click always
42
+ * picks and never toggles off — the right default for a required form
43
+ * field. A navigator that uses selection as a filter opts in.
44
+ */
45
+ singleToggle?: boolean;
33
46
  } & {
34
47
  onMove?: ((payload: MoveEventPayload) => any) | undefined;
35
48
  "onUpdate:modelValue"?: ((value: string | string[] | undefined) => any) | undefined;
@@ -17,7 +17,9 @@ const props = defineProps({
17
17
  filterPredicate: { type: Function, required: false, default: void 0 },
18
18
  filterQuery: { type: String, required: false, default: "" },
19
19
  initialExpanded: { type: Array, required: false, default: () => [] },
20
- showFocusedRow: { type: Boolean, required: false, default: true }
20
+ showFocusedRow: { type: Boolean, required: false, default: true },
21
+ selectCursor: { type: String, required: false, default: "pointer" },
22
+ singleToggle: { type: Boolean, required: false, default: false }
21
23
  });
22
24
  const emit = defineEmits(["update:modelValue", "update:roots", "update:expanded", "move"]);
23
25
  defineSlots();
@@ -121,6 +123,10 @@ function handleToggleSelect(key) {
121
123
  if (props.selectionMode === "single") {
122
124
  const loc = state.locate(key);
123
125
  if (!loc || !props.selectable(loc.node, loc.depth)) return;
126
+ if (props.singleToggle && state.selected.has(key)) {
127
+ state.deselectKey(key);
128
+ return;
129
+ }
124
130
  state.selectKey(key);
125
131
  return;
126
132
  }
@@ -282,6 +288,7 @@ const selectedPanePayload = computed(() => ({
282
288
  :tree="tree"
283
289
  :focused-key="state.focusedKey.value"
284
290
  :show-focused-row="showFocusedRow"
291
+ :select-cursor="selectCursor"
285
292
  @toggle-expand="handleToggleExpand"
286
293
  @toggle-select="handleToggleSelect"
287
294
  @focus-row="handleFocusRow"
@@ -30,6 +30,19 @@ declare const __VLS_export: <Node>(__VLS_props: NonNullable<Awaited<typeof __VLS
30
30
  * it off so a stray click doesn't leave a permanent highlight.
31
31
  */
32
32
  showFocusedRow?: boolean;
33
+ /**
34
+ * Cursor shown over a selectable row. Defaults to `'pointer'` (a row is
35
+ * clickable to select); `'default'` opts out for surfaces that prefer the
36
+ * arrow cursor while still selecting on click.
37
+ */
38
+ selectCursor?: "pointer" | "default";
39
+ /**
40
+ * `single` mode only. When `true`, clicking the already-selected node
41
+ * clears the selection (toggle); when `false` (default), a click always
42
+ * picks and never toggles off — the right default for a required form
43
+ * field. A navigator that uses selection as a filter opts in.
44
+ */
45
+ singleToggle?: boolean;
33
46
  } & {
34
47
  onMove?: ((payload: MoveEventPayload) => any) | undefined;
35
48
  "onUpdate:modelValue"?: ((value: string | string[] | undefined) => any) | undefined;
@@ -26,6 +26,8 @@ declare const __VLS_export: <Node>(__VLS_props: NonNullable<Awaited<typeof __VLS
26
26
  tree: TreeHandle<Node>;
27
27
  focusedKey: NodeKey | null;
28
28
  showFocusedRow: boolean;
29
+ /** Cursor over a selectable row. `'default'` opts out of the pointer. */
30
+ selectCursor: "pointer" | "default";
29
31
  } & {
30
32
  "onToggle-expand"?: ((key: string) => any) | undefined;
31
33
  "onToggle-select"?: ((key: string) => any) | undefined;
@@ -27,7 +27,8 @@ const props = defineProps({
27
27
  isExpandable: { type: Function, required: true },
28
28
  tree: { type: Object, required: true },
29
29
  focusedKey: { type: [String, null], required: true },
30
- showFocusedRow: { type: Boolean, required: true }
30
+ showFocusedRow: { type: Boolean, required: true },
31
+ selectCursor: { type: String, required: true }
31
32
  });
32
33
  const emit = defineEmits(["toggle-expand", "toggle-select", "focus-row"]);
33
34
  defineSlots();
@@ -115,7 +116,8 @@ const showChildren = computed(
115
116
  v-if="subtreeMatches"
116
117
  :class="cn(
117
118
  'group flex items-center justify-between gap-2 rounded px-1 py-1 outline-none transition-colors',
118
- selectionMode !== 'none' && userSelectable && 'cursor-pointer hover:bg-zinc-100/70',
119
+ selectionMode !== 'none' && userSelectable && 'hover:bg-zinc-100/70',
120
+ selectionMode !== 'none' && userSelectable && (selectCursor === 'default' ? 'cursor-default' : 'cursor-pointer'),
119
121
  selectedFlag && !indeterminateFlag && 'bg-(--primary)/10 hover:bg-(--primary)/15',
120
122
  showFocusedRow && focusedKey === key && 'bg-(--primary)/10'
121
123
  )"
@@ -242,6 +244,7 @@ const showChildren = computed(
242
244
  :tree="tree"
243
245
  :focused-key="focusedKey"
244
246
  :show-focused-row="showFocusedRow"
247
+ :select-cursor="selectCursor"
245
248
  @toggle-expand="(k) => emit('toggle-expand', k)"
246
249
  @toggle-select="(k) => emit('toggle-select', k)"
247
250
  @focus-row="(k) => emit('focus-row', k)"
@@ -26,6 +26,8 @@ declare const __VLS_export: <Node>(__VLS_props: NonNullable<Awaited<typeof __VLS
26
26
  tree: TreeHandle<Node>;
27
27
  focusedKey: NodeKey | null;
28
28
  showFocusedRow: boolean;
29
+ /** Cursor over a selectable row. `'default'` opts out of the pointer. */
30
+ selectCursor: "pointer" | "default";
29
31
  } & {
30
32
  "onToggle-expand"?: ((key: string) => any) | undefined;
31
33
  "onToggle-select"?: ((key: string) => any) | undefined;
@@ -3,6 +3,11 @@ import type { Environment } from '../vendor/cel-js/lib/index.js';
3
3
  import type { SlotValue } from './layout.js';
4
4
  type EntryLike = Readonly<{
5
5
  runtime: Component;
6
+ metadata?: Readonly<{
7
+ h?: Readonly<{
8
+ grow?: boolean;
9
+ }>;
10
+ }>;
6
11
  }>;
7
12
  type __VLS_Props = {
8
13
  slotValue: SlotValue;
@@ -26,16 +26,50 @@ function pickLayout(sets) {
26
26
  return sets[sets.length - 1];
27
27
  }
28
28
  const activeLayout = computed(() => pickLayout(props.slotValue.layouts));
29
+ const warnedMissing = /* @__PURE__ */ new Set();
30
+ const placedBlocks = computed(() => {
31
+ const layout = activeLayout.value?.layout;
32
+ if (!layout) return [];
33
+ const out = [];
34
+ for (const b of props.slotValue.blocks) {
35
+ const block = b;
36
+ const placement = layout.placements[block.id];
37
+ if (!placement) continue;
38
+ const entry = props.findEntry(block.type, block.compatibilityDate);
39
+ if (!entry) {
40
+ const key = `${block.type}@${block.compatibilityDate}`;
41
+ if (!warnedMissing.has(key)) {
42
+ warnedMissing.add(key);
43
+ console.warn(`[shwfed-slot-renderer] no registered block type for ${key}`);
44
+ }
45
+ continue;
46
+ }
47
+ out.push({ block, placement, entry });
48
+ }
49
+ return out;
50
+ });
29
51
  const gridStyle = computed(() => {
30
52
  const l = activeLayout.value?.layout;
31
53
  if (!l) return "";
32
54
  const tracks = (n, min) => `repeat(${n}, minmax(${min}, 1fr))`;
33
55
  const gap = `calc(${l.gap ?? DEFAULT_GAP} * 0.25rem)`;
34
56
  const colGap = l.columns > 1 ? `min(${gap}, calc(100% / ${l.columns - 1}))` : gap;
57
+ let rowTemplate = "";
58
+ if (l.rows) {
59
+ const grows = Array.from({ length: l.rows }, () => false);
60
+ for (const p of placedBlocks.value) {
61
+ if (!p.entry.metadata?.h?.grow) continue;
62
+ const [[, y1], [, y2]] = p.placement.area;
63
+ const lo = Math.max(1, y1);
64
+ const hi = Math.min(l.rows, y2 - 1);
65
+ for (let r = lo; r <= hi; r++) grows[r - 1] = true;
66
+ }
67
+ rowTemplate = grows.map((g) => g ? "auto" : "minmax(auto, 1fr)").join(" ");
68
+ }
35
69
  const parts = [
36
70
  "display: grid",
37
71
  `grid-template-columns: ${tracks(l.columns, "0")}`,
38
- l.rows ? `grid-template-rows: ${tracks(l.rows, "auto")}` : "",
72
+ rowTemplate ? `grid-template-rows: ${rowTemplate}` : "",
39
73
  `column-gap: ${colGap}`,
40
74
  `row-gap: ${gap}`,
41
75
  l.style ?? ""
@@ -55,33 +89,14 @@ function cellStyle(placement) {
55
89
  }
56
90
  return parts.join("; ");
57
91
  }
58
- const warnedMissing = /* @__PURE__ */ new Set();
59
- const rendered = computed(() => {
60
- const layout = activeLayout.value?.layout;
61
- if (!layout) return [];
62
- const out = [];
63
- for (const b of props.slotValue.blocks) {
64
- const block = b;
65
- const placement = layout.placements[block.id];
66
- if (!placement) continue;
67
- const entry = props.findEntry(block.type, block.compatibilityDate);
68
- if (!entry) {
69
- const key = `${block.type}@${block.compatibilityDate}`;
70
- if (!warnedMissing.has(key)) {
71
- warnedMissing.add(key);
72
- console.warn(`[shwfed-slot-renderer] no registered block type for ${key}`);
73
- }
74
- continue;
75
- }
76
- out.push({
77
- key: block.id,
78
- style: cellStyle(placement),
79
- component: entry.runtime,
80
- block
81
- });
82
- }
83
- return out;
84
- });
92
+ const rendered = computed(
93
+ () => placedBlocks.value.map((p) => ({
94
+ key: p.block.id,
95
+ style: cellStyle(p.placement),
96
+ component: p.entry.runtime,
97
+ block: p.block
98
+ }))
99
+ );
85
100
  function updateBlock(id, next) {
86
101
  const blocks = props.slotValue.blocks.map((b) => b.id === id ? next : b);
87
102
  emit("update:slotValue", { ...props.slotValue, blocks });
@@ -3,6 +3,11 @@ import type { Environment } from '../vendor/cel-js/lib/index.js';
3
3
  import type { SlotValue } from './layout.js';
4
4
  type EntryLike = Readonly<{
5
5
  runtime: Component;
6
+ metadata?: Readonly<{
7
+ h?: Readonly<{
8
+ grow?: boolean;
9
+ }>;
10
+ }>;
6
11
  }>;
7
12
  type __VLS_Props = {
8
13
  slotValue: SlotValue;
@@ -0,0 +1,25 @@
1
+ import type { Environment } from '../vendor/cel-js/lib/index.js';
2
+ /**
3
+ * The per-node `node` CEL variable shared by every tree surface — the tree form
4
+ * fields, the tree-combobox table columns, and the `tree.single` config block.
5
+ * Always `dyn`: the node payload shape is backend-defined and unknowable at
6
+ * design time. The description varies a little per surface, so it is a
7
+ * parameter rather than baked in here.
8
+ */
9
+ export declare const NODE_VAR_TYPE = "dyn";
10
+ export declare const NODE_VAR_DESCRIPTION = "\u5F53\u524D\u8282\u70B9\uFF1B\u7531 `\u6570\u636E` \u8868\u8FBE\u5F0F\u8FD4\u56DE\u7684\u6BCF\u4E00\u9879";
11
+ /**
12
+ * Register the per-node `node` (dyn) CEL variable, skipping it when an enclosing
13
+ * `configure` already declared it. Idempotent so a tree field/column/block
14
+ * nested inside a `configure` that already exposes `node` doesn't re-register
15
+ * it — the CEL registry throws `'node' is already registered` on the second
16
+ * declaration. This is the case the `tree.single` config block hits: it threads
17
+ * `node` into its per-node Actions, whose modal-layout button may host a form
18
+ * (or table) containing another tree surface, so building that nested schema
19
+ * would otherwise declare `node` twice on one env. Mirrors
20
+ * `registerRowVariablesIfAbsent` / `registerFormVariablesIfAbsent`.
21
+ */
22
+ export declare function registerNodeVariableIfAbsent(env: Environment, meta?: {
23
+ label?: string;
24
+ description?: string;
25
+ }): void;
@@ -0,0 +1,10 @@
1
+ export const NODE_VAR_TYPE = "dyn";
2
+ export const NODE_VAR_DESCRIPTION = "\u5F53\u524D\u8282\u70B9\uFF1B\u7531 `\u6570\u636E` \u8868\u8FBE\u5F0F\u8FD4\u56DE\u7684\u6BCF\u4E00\u9879";
3
+ export function registerNodeVariableIfAbsent(env, meta = {}) {
4
+ const declared = new Set(env.getDefinitions().variables.map((v) => v.name));
5
+ if (declared.has("node")) return;
6
+ env.registerVariable("node", NODE_VAR_TYPE, {
7
+ ...meta.label !== void 0 ? { label: meta.label } : {},
8
+ description: meta.description ?? NODE_VAR_DESCRIPTION
9
+ });
10
+ }
@@ -24,7 +24,7 @@ The `homogeneousAggregateLiterals` and `enableOptionalTypes` environment options
24
24
 
25
25
  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) and `optional<A>.map(var, body): optional<B>` (the Functor `fmap`) — all local additions (not from upstream). Both are variable-binding macros (registered with `(ast, ast)` arg types so the body stays unevaluated): on `Some` they bind the value and evaluate `body`; on `None` they short-circuit without touching `body`. `flatMap`'s body must itself yield an `optional`; `map`'s body is a plain value that gets re-wrapped in `Some`. `map` is the derived `o.flatMap(v, optional.of(body))` promoted to a first-class macro. NOTE: `map` is **registered in `macros.ts`**, not here — the parser resolves a macro by name before types are known, so the optional `map` and the list-comprehension `map` must share one expander that dispatches on the receiver type at type-check (an `optional` receiver → fmap; `list`/`map` → comprehension; a `dyn` receiver is deferred to a runtime `Option.isOption` check).
26
26
 
27
- 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.
27
+ 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. `.query` accepts `(string, string)` / `(string, number)`, the optional-valued `(string, optional<string>)` / `(string, optional<number>)` (a `None`, e.g. an absent `.?` field, drops the param rather than emitting `key=`; `Some` appends it via the string/number coercion), and the record-splat `(dyn)`.
28
28
 
29
29
  A `form(dyn): FormData` built-in has been added (`form-builtins.ts`) — not from upstream. It registers the `FormData` type on `globalRegistry` and a global `form` function that turns a CEL map into a native `FormData`, so authors can write `http.post(url).body(form({"file": myFile, "name": "Alice"}))` (`.body()` passes `FormData` through verbatim; `#buildRequest()` serializes it). NOTE: `#buildRequest()` must serialize a `FormData` body itself rather than hand it to fx-fetch — fx-fetch clones bodies via `new Response(body).blob()`, and the File API ASCII-lowercases `Blob#type`, so in Chrome the multipart boundary in the derived `Content-Type` loses its case while the body bytes keep it (boundaries are case-sensitive → every parser sees zero parts). The builder lifts the case-preserved `Content-Type` off the `Response` *header* (header values are never case-normalized), adds it as an explicit header (unless the author set their own `Content-Type`), and passes the bytes as a `Promise<Blob>` (fx-fetch resolves promises verbatim). Value coercion mirrors `.query()`'s flat-record semantics: `null` / `undefined` / `Option.None` skip the key; `Option.Some(x)` recurses on `x`; `File` / `Blob` pass through (preserves the `File` filename); `Decimal` → `.toString()` (preserves precision past safe-integer); `Date` (`TZDate`) → `.toISOString()`; `bool` → `'true'` / `'false'`; arrays append one entry per element; nested objects throw (`multipart/form-data` is flat — same rule as `.query(dyn)`). Top-level input must be a map literal / record (Map or plain object); passing an array or scalar throws.
30
30
  The `__proto__` / `constructor` / `prototype` keys are skipped on the top-level record, mirroring `safeFromEntries`.
@@ -302,6 +302,12 @@ http.get("https://api.example.com/users")
302
302
  .query(form)
303
303
  .query("page", string(pageIndex))
304
304
 
305
+ // An optional value is unwrapped — `Some` appends the param, `None` drops it
306
+ // entirely (no `key=`). Handy for forwarding an optional `.?` field or filter:
307
+ http.get("https://api.example.com/users")
308
+ .query("channel", query.?channel)
309
+ .query("page", optional.of(pageIndex))
310
+
305
311
  // Set request body. An object serializes to JSON; set the Content-Type
306
312
  // header yourself. Optional values are unwrapped — a present `.?` field
307
313
  // keeps its value, an absent one becomes `null` (the key is kept):
@@ -1,16 +1,2 @@
1
- /**
2
- * HTTP built-ins for CEL — a local (non-upstream) extension.
3
- *
4
- * Registers the `http` / `HttpRequest` types, the `http` constant, and the
5
- * request-builder functions on the registry. `http.get(url).header(...).body(...)`
6
- * builds an `HttpRequestBuilder` — a pure *description* of a request. CEL never
7
- * issues it: both `.json()` and `.file()` are dispatched by the host on the
8
- * returned builder, so expression evaluation stays free of IO.
9
- *
10
- * Wired into `globalRegistry` at module load (see `evaluator.ts`), so every
11
- * `Environment` gets HTTP for free — both type-checking and evaluation.
12
- *
13
- * Endpoints must be absolute URLs; there is no base-URL resolution.
14
- */
15
1
  import type { Registry } from './registry.js.js';
16
2
  export declare function registerHttpBuiltins(registry: Registry): void;
@@ -1,3 +1,4 @@
1
+ import { Option } from "effect";
1
2
  import { HttpRequestBuilder } from "./http-builder.js";
2
3
  class Http {
3
4
  brand = "http";
@@ -44,6 +45,22 @@ export function registerHttpBuiltins(registry) {
44
45
  "HttpRequest.query(string, number): HttpRequest",
45
46
  (b, k, v) => b.query(k, Number(v))
46
47
  );
48
+ registry.registerFunctionOverload(
49
+ "HttpRequest.query(string, optional<string>): HttpRequest",
50
+ (b, k, v) => {
51
+ const builder = b;
52
+ const value = v;
53
+ return Option.isSome(value) ? builder.query(k, value.value) : builder;
54
+ }
55
+ );
56
+ registry.registerFunctionOverload(
57
+ "HttpRequest.query(string, optional<number>): HttpRequest",
58
+ (b, k, v) => {
59
+ const builder = b;
60
+ const value = v;
61
+ return Option.isSome(value) ? builder.query(k, Number(value.value)) : builder;
62
+ }
63
+ );
47
64
  registry.registerFunctionOverload(
48
65
  "HttpRequest.query(dyn): HttpRequest",
49
66
  (b, record) => b.query(record)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shwfed/config",
3
- "version": "2.10.3",
3
+ "version": "2.10.5",
4
4
  "description": "Configurable UI for SHWFED",
5
5
  "type": "module",
6
6
  "publishConfig": {