@shwfed/nuxt 0.11.22 → 0.11.24

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@shwfed/nuxt",
3
3
  "configKey": "shwfed",
4
- "version": "0.11.22",
4
+ "version": "0.11.24",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
@@ -2,10 +2,15 @@
2
2
  import { computed, defineComponent } from "vue";
3
3
  import ShwfedModal from "../../modal.vue";
4
4
  import { useOverlay } from "../../../composables/useOverlay";
5
+ import { provideCELContext } from "../../../plugins/cel/context";
5
6
  const overlay = useOverlay();
6
7
  const OverlayBody = defineComponent({
7
8
  name: "OverlayBody",
8
9
  props: {
10
+ celContext: {
11
+ type: Object,
12
+ required: true
13
+ },
9
14
  render: {
10
15
  type: Function,
11
16
  required: true
@@ -16,6 +21,7 @@ const OverlayBody = defineComponent({
16
21
  }
17
22
  },
18
23
  setup(props) {
24
+ provideCELContext(props.celContext);
19
25
  return () => props.render(props.slotProps);
20
26
  }
21
27
  });
@@ -51,6 +57,7 @@ const renderedSessions = computed(() => {
51
57
  },
52
58
  descriptionSrOnly: session.shell.descriptionSrOnly,
53
59
  props: session.props,
60
+ celContext: session.celContext,
54
61
  definition
55
62
  });
56
63
  }
@@ -95,6 +102,7 @@ const renderedSessions = computed(() => {
95
102
 
96
103
  <template #default="modalSlotProps">
97
104
  <OverlayBody
105
+ :cel-context="session.celContext"
98
106
  :render="session.definition.render"
99
107
  :slot-props="{
100
108
  props: session.props,
@@ -13,6 +13,7 @@ import {
13
13
  provideOverlay,
14
14
  useOverlay
15
15
  } from "../../../composables/useOverlay";
16
+ import { useCELContext } from "../../../plugins/cel/context";
16
17
  import { getLocalizedText, hasVisibleLocaleValue } from "../../../utils/coders";
17
18
  import { cn } from "../../../utils/cn";
18
19
  import ButtonConfiguratorDialog from "../button-configurator/ButtonConfiguratorDialog.vue";
@@ -45,6 +46,7 @@ const attrs = useAttrs();
45
46
  const { locale, t } = useI18n();
46
47
  const { $dsl } = useNuxtApp();
47
48
  const overlay = useOverlay();
49
+ const celContext = useCELContext();
48
50
  const isCheating = useCheating();
49
51
  const isConfiguratorOpen = ref(false);
50
52
  const pendingIds = ref([]);
@@ -253,7 +255,8 @@ function createButtonActionRuntime(button) {
253
255
  locale: locale.value,
254
256
  title: getButtonLabel(button),
255
257
  description: tooltip,
256
- tooltip
258
+ tooltip,
259
+ celContext
257
260
  };
258
261
  }
259
262
  function resolveButtonEffect(button) {
@@ -10,6 +10,7 @@ import { deleteProperty, getProperty, hasProperty, setProperty } from "dot-prop"
10
10
  import { computed, nextTick, readonly, ref, toRaw, useId, watch, watchEffect } from "vue";
11
11
  import { useI18n } from "vue-i18n";
12
12
  import { useCheating } from "#imports";
13
+ import { mergeDslContexts, useCELContext } from "../../../plugins/cel/context";
13
14
  import { Calendar } from "../calendar";
14
15
  import { Button } from "../button";
15
16
  import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "../command";
@@ -33,6 +34,7 @@ const emit = defineEmits(["update:config", "initial-value-ready"]);
33
34
  const config = computedAsync(async () => FieldsConfigC.parse(await props.config.pipe(Effect.runPromise) ?? defaultConfig));
34
35
  const { t, locale } = useI18n();
35
36
  const { $dsl, $md } = useNuxtApp();
37
+ const dslContext = useCELContext();
36
38
  const modelValue = defineModel("modelValue", { type: Object, ...{
37
39
  default: () => ({})
38
40
  } });
@@ -67,7 +69,7 @@ function tryEvaluateExpression(source, context) {
67
69
  try {
68
70
  return {
69
71
  ok: true,
70
- value: $dsl.evaluate`${source}`(context)
72
+ value: $dsl.evaluate`${source}`(mergeDslContexts(context, dslContext))
71
73
  };
72
74
  } catch {
73
75
  return {
@@ -338,7 +340,7 @@ function isFieldRequired(field) {
338
340
  function renderValidationMessage(field) {
339
341
  const error = validationErrors.value[field.path];
340
342
  if (!error) return "";
341
- return $md.inline`${error.message}`(error.context);
343
+ return $md.inline`${error.message}`(mergeDslContexts(error.context, dslContext));
342
344
  }
343
345
  function isCalendarDateDisabled(field, date) {
344
346
  if (!field.disableDate) {
@@ -2,12 +2,17 @@ import z from "zod";
2
2
  import { createComponentConfig, createComponentConfigMetadataShape } from "../../component-config.js";
3
3
  import { dotPropC, expressionC, localeC } from "../../../utils/coders.js";
4
4
  const fieldIdC = z.uuid().describe("\u5B57\u6BB5\u552F\u4E00\u6807\u8BC6\uFF0C\u5FC5\u987B\u662F UUID");
5
+ const inheritedFieldContext = {
6
+ form: "map<string, dyn>",
7
+ row: "map<string, dyn>",
8
+ index: "int"
9
+ };
5
10
  export const KIND = "shwfed.component.fields";
6
11
  export const CURRENT_COMPATIBILITY_DATE = "2026-03-20";
7
12
  export const SUPPORTED_COMPATIBILITY_DATES = [CURRENT_COMPATIBILITY_DATE];
8
13
  export const ValidationRuleC = z.object({
9
- expression: expressionC("bool", { value: "dyn", form: "map<string, dyn>" }).describe("\u8FD4\u56DE\u5E03\u5C14\u503C\u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u53EF\u4F7F\u7528 value \u548C form \u53D8\u91CF"),
10
- message: z.string().describe("\u6821\u9A8C\u5931\u8D25\u65F6\u5C55\u793A\u7684 Markdown \u6D88\u606F\uFF0C\u53EF\u5728 {{ expression }} \u4E2D\u4F7F\u7528 value \u548C form \u53D8\u91CF")
14
+ expression: expressionC(["bool", "dyn"], { value: "dyn", ...inheritedFieldContext }).describe("\u8FD4\u56DE\u5E03\u5C14\u503C\u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u53EF\u4F7F\u7528 value\u3001form\u3001row \u548C index \u53D8\u91CF"),
15
+ message: z.string().describe("\u6821\u9A8C\u5931\u8D25\u65F6\u5C55\u793A\u7684 Markdown \u6D88\u606F\uFF0C\u53EF\u5728 {{ expression }} \u4E2D\u4F7F\u7528 value\u3001form\u3001row \u548C index \u53D8\u91CF")
11
16
  }).readonly();
12
17
  export const validationC = z.array(ValidationRuleC).readonly().optional().describe("\u5B57\u6BB5\u5931\u7126\u65F6\u6309\u987A\u5E8F\u6267\u884C\u7684\u6821\u9A8C\u89C4\u5219\uFF0C\u547D\u4E2D\u7B2C\u4E00\u4E2A\u5931\u8D25\u89C4\u5219\u540E\u505C\u6B62");
13
18
  export const StringFieldC = z.object({
@@ -19,10 +24,10 @@ export const StringFieldC = z.object({
19
24
  icon: z.string().optional().describe("Iconify \u56FE\u6807\u6807\u8BC6\u7B26\uFF0C\u663E\u793A\u5728\u8F93\u5165\u6846\u5185\u4FA7"),
20
25
  style: z.string().optional().describe("CSS \u6837\u5F0F\u5BF9\u8C61\u8868\u8FBE\u5F0F\uFF0C\u63A7\u5236\u5B57\u6BB5\u7684\u5E03\u5C40\u4E0E\u5916\u89C2"),
21
26
  discardEmptyString: z.boolean().optional().describe("\u4E3A true \u65F6\uFF0C\u7A7A\u5B57\u7B26\u4E32\u4F5C\u4E3A\u6709\u6548\u503C\u5B58\u50A8\uFF1B\u5426\u5219\u6E05\u7A7A\u8F93\u5165\u5C06\u5220\u9664\u5BF9\u5E94\u5C5E\u6027"),
22
- initialValue: expressionC("string", { form: "map<string, dyn>" }).optional().describe("\u8FD4\u56DE string \u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u5728\u5B57\u6BB5\u9996\u6B21\u521D\u59CB\u5316\u4E14 path \u4E0D\u5B58\u5728\u65F6\u5199\u5165\u521D\u59CB\u503C\uFF0C\u53EF\u4F7F\u7528 form \u53D8\u91CF"),
27
+ initialValue: expressionC(["string", "dyn"], inheritedFieldContext).optional().describe("\u8FD4\u56DE string \u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u5728\u5B57\u6BB5\u9996\u6B21\u521D\u59CB\u5316\u4E14 path \u4E0D\u5B58\u5728\u65F6\u5199\u5165\u521D\u59CB\u503C\uFF0C\u53EF\u4F7F\u7528 form\u3001row \u548C index \u53D8\u91CF"),
23
28
  maxLength: expressionC("int").optional().describe('\u8FD4\u56DE\u6574\u6570\u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u9650\u5236\u8F93\u5165\u7684\u6700\u5927\u5B57\u7B26\u6570\uFF0C\u5982 "100"'),
24
- hidden: expressionC("bool", { form: "map<string, dyn>" }).optional().describe("\u4E3A true \u65F6\uFF0C\u9690\u85CF\u8FD9\u4E2A\u5B57\u6BB5"),
25
- disabled: expressionC("bool", { form: "map<string, dyn>" }).optional().describe("\u4E3A true \u65F6\uFF0C\u7981\u7528\u8FD9\u4E2A\u5B57\u6BB5"),
29
+ hidden: expressionC(["bool", "dyn"], inheritedFieldContext).optional().describe("\u4E3A true \u65F6\uFF0C\u9690\u85CF\u8FD9\u4E2A\u5B57\u6BB5\uFF0C\u53EF\u4F7F\u7528 form\u3001row \u548C index \u53D8\u91CF"),
30
+ disabled: expressionC(["bool", "dyn"], inheritedFieldContext).optional().describe("\u4E3A true \u65F6\uFF0C\u7981\u7528\u8FD9\u4E2A\u5B57\u6BB5\uFF0C\u53EF\u4F7F\u7528 form\u3001row \u548C index \u53D8\u91CF"),
26
31
  validation: validationC
27
32
  });
28
33
  export const TextareaFieldC = z.object({
@@ -34,10 +39,10 @@ export const TextareaFieldC = z.object({
34
39
  icon: z.string().optional().describe("Iconify \u56FE\u6807\u6807\u8BC6\u7B26\uFF0C\u663E\u793A\u5728\u8F93\u5165\u6846\u5185\u4FA7"),
35
40
  style: z.string().optional().describe("CSS \u6837\u5F0F\u5BF9\u8C61\u8868\u8FBE\u5F0F\uFF0C\u63A7\u5236\u5B57\u6BB5\u7684\u5E03\u5C40\u4E0E\u5916\u89C2"),
36
41
  discardEmptyString: z.boolean().optional().describe("\u4E3A true \u65F6\uFF0C\u7A7A\u5B57\u7B26\u4E32\u4F5C\u4E3A\u6709\u6548\u503C\u5B58\u50A8\uFF1B\u5426\u5219\u6E05\u7A7A\u8F93\u5165\u5C06\u5220\u9664\u5BF9\u5E94\u5C5E\u6027"),
37
- initialValue: expressionC("string", { form: "map<string, dyn>" }).optional().describe("\u8FD4\u56DE string \u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u5728\u5B57\u6BB5\u9996\u6B21\u521D\u59CB\u5316\u4E14 path \u4E0D\u5B58\u5728\u65F6\u5199\u5165\u521D\u59CB\u503C\uFF0C\u53EF\u4F7F\u7528 form \u53D8\u91CF"),
42
+ initialValue: expressionC(["string", "dyn"], inheritedFieldContext).optional().describe("\u8FD4\u56DE string \u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u5728\u5B57\u6BB5\u9996\u6B21\u521D\u59CB\u5316\u4E14 path \u4E0D\u5B58\u5728\u65F6\u5199\u5165\u521D\u59CB\u503C\uFF0C\u53EF\u4F7F\u7528 form\u3001row \u548C index \u53D8\u91CF"),
38
43
  maxLength: expressionC("int").optional().describe('\u8FD4\u56DE\u6574\u6570\u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u9650\u5236\u8F93\u5165\u7684\u6700\u5927\u5B57\u7B26\u6570\uFF0C\u5982 "100"'),
39
- hidden: expressionC("bool", { form: "map<string, dyn>" }).optional().describe("\u4E3A true \u65F6\uFF0C\u9690\u85CF\u8FD9\u4E2A\u5B57\u6BB5"),
40
- disabled: expressionC("bool", { form: "map<string, dyn>" }).optional().describe("\u4E3A true \u65F6\uFF0C\u7981\u7528\u8FD9\u4E2A\u5B57\u6BB5"),
44
+ hidden: expressionC(["bool", "dyn"], inheritedFieldContext).optional().describe("\u4E3A true \u65F6\uFF0C\u9690\u85CF\u8FD9\u4E2A\u5B57\u6BB5\uFF0C\u53EF\u4F7F\u7528 form\u3001row \u548C index \u53D8\u91CF"),
45
+ disabled: expressionC(["bool", "dyn"], inheritedFieldContext).optional().describe("\u4E3A true \u65F6\uFF0C\u7981\u7528\u8FD9\u4E2A\u5B57\u6BB5\uFF0C\u53EF\u4F7F\u7528 form\u3001row \u548C index \u53D8\u91CF"),
41
46
  validation: validationC
42
47
  });
43
48
  export const NumberFieldC = z.object({
@@ -48,12 +53,12 @@ export const NumberFieldC = z.object({
48
53
  required: z.boolean().optional().describe("\u4E3A true \u65F6\uFF0C\u4EC5\u5728\u5B57\u6BB5\u6807\u7B7E\u540E\u663E\u793A\u5FC5\u586B\u63D0\u793A\u661F\u53F7\uFF0C\u4E0D\u5F71\u54CD\u5B9E\u9645\u6821\u9A8C\u903B\u8F91"),
49
54
  icon: z.string().optional().describe("Iconify \u56FE\u6807\u6807\u8BC6\u7B26\uFF0C\u663E\u793A\u5728\u8F93\u5165\u6846\u5185\u4FA7"),
50
55
  style: z.string().optional().describe("CSS \u6837\u5F0F\u5BF9\u8C61\u8868\u8FBE\u5F0F\uFF0C\u63A7\u5236\u5B57\u6BB5\u7684\u5E03\u5C40\u4E0E\u5916\u89C2"),
51
- initialValue: expressionC(["int", "double"], { form: "map<string, dyn>" }).optional().describe("\u8FD4\u56DE number \u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u5728\u5B57\u6BB5\u9996\u6B21\u521D\u59CB\u5316\u4E14 path \u4E0D\u5B58\u5728\u65F6\u5199\u5165\u521D\u59CB\u503C\uFF0C\u53EF\u4F7F\u7528 form \u53D8\u91CF"),
56
+ initialValue: expressionC(["int", "double", "dyn"], inheritedFieldContext).optional().describe("\u8FD4\u56DE number \u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u5728\u5B57\u6BB5\u9996\u6B21\u521D\u59CB\u5316\u4E14 path \u4E0D\u5B58\u5728\u65F6\u5199\u5165\u521D\u59CB\u503C\uFF0C\u53EF\u4F7F\u7528 form\u3001row \u548C index \u53D8\u91CF"),
52
57
  min: expressionC("double").optional().describe('\u8FD4\u56DE\u6D6E\u70B9\u6570\u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u9650\u5236\u5141\u8BB8\u7684\u6700\u5C0F\u503C\uFF0C\u5982 "0.0"'),
53
58
  max: expressionC("double").optional().describe('\u8FD4\u56DE\u6D6E\u70B9\u6570\u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u9650\u5236\u5141\u8BB8\u7684\u6700\u5927\u503C\uFF0C\u5982 "100.0"'),
54
59
  step: expressionC("double").optional().describe('\u8FD4\u56DE\u6D6E\u70B9\u6570\u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u63A7\u5236\u6570\u503C\u9012\u589E\u6B65\u957F\uFF0C\u5982 "0.5"'),
55
- hidden: expressionC("bool", { form: "map<string, dyn>" }).optional().describe("\u4E3A true \u65F6\uFF0C\u9690\u85CF\u8FD9\u4E2A\u5B57\u6BB5"),
56
- disabled: expressionC("bool", { form: "map<string, dyn>" }).optional().describe("\u4E3A true \u65F6\uFF0C\u7981\u7528\u8FD9\u4E2A\u5B57\u6BB5"),
60
+ hidden: expressionC(["bool", "dyn"], inheritedFieldContext).optional().describe("\u4E3A true \u65F6\uFF0C\u9690\u85CF\u8FD9\u4E2A\u5B57\u6BB5\uFF0C\u53EF\u4F7F\u7528 form\u3001row \u548C index \u53D8\u91CF"),
61
+ disabled: expressionC(["bool", "dyn"], inheritedFieldContext).optional().describe("\u4E3A true \u65F6\uFF0C\u7981\u7528\u8FD9\u4E2A\u5B57\u6BB5\uFF0C\u53EF\u4F7F\u7528 form\u3001row \u548C index \u53D8\u91CF"),
57
62
  validation: validationC
58
63
  });
59
64
  export const SelectFieldC = z.object({
@@ -68,9 +73,9 @@ export const SelectFieldC = z.object({
68
73
  value: expressionC(/.+/, { option: "dyn" }).describe("\u8FD4\u56DE\u4EFB\u610F\u503C\u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u63D0\u4F9B option \u53D8\u91CF\uFF0C\u8FD4\u56DE\u503C\u5C06\u88AB\u5199\u5165\u7ED1\u5B9A\u5B57\u6BB5"),
69
74
  key: expressionC("string", { option: "dyn" }).describe("\u8FD4\u56DE\u5B57\u7B26\u4E32\u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u63D0\u4F9B option \u53D8\u91CF\uFF0C\u8FD4\u56DE\u503C\u4E0E\u9009\u9879\u6784\u6210\u5168\u6620\u5C04"),
70
75
  style: z.string().optional().describe("CSS \u6837\u5F0F\u5BF9\u8C61\u8868\u8FBE\u5F0F\uFF0C\u63A7\u5236\u5B57\u6BB5\u7684\u5E03\u5C40\u4E0E\u5916\u89C2"),
71
- initialValue: expressionC(/.+/, { form: "map<string, dyn>" }).optional().describe("\u8FD4\u56DE\u4EFB\u610F\u503C\u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u5728\u5B57\u6BB5\u9996\u6B21\u521D\u59CB\u5316\u4E14 path \u4E0D\u5B58\u5728\u65F6\u5199\u5165\u521D\u59CB\u503C\uFF0C\u53EF\u4F7F\u7528 form \u53D8\u91CF"),
72
- hidden: expressionC("bool", { form: "map<string, dyn>" }).optional().describe("\u4E3A true \u65F6\uFF0C\u9690\u85CF\u8FD9\u4E2A\u5B57\u6BB5"),
73
- disabled: expressionC("bool", { form: "map<string, dyn>" }).optional().describe("\u4E3A true \u65F6\uFF0C\u7981\u7528\u8FD9\u4E2A\u5B57\u6BB5"),
76
+ initialValue: expressionC(/.+/, inheritedFieldContext).optional().describe("\u8FD4\u56DE\u4EFB\u610F\u503C\u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u5728\u5B57\u6BB5\u9996\u6B21\u521D\u59CB\u5316\u4E14 path \u4E0D\u5B58\u5728\u65F6\u5199\u5165\u521D\u59CB\u503C\uFF0C\u53EF\u4F7F\u7528 form\u3001row \u548C index \u53D8\u91CF"),
77
+ hidden: expressionC(["bool", "dyn"], inheritedFieldContext).optional().describe("\u4E3A true \u65F6\uFF0C\u9690\u85CF\u8FD9\u4E2A\u5B57\u6BB5\uFF0C\u53EF\u4F7F\u7528 form\u3001row \u548C index \u53D8\u91CF"),
78
+ disabled: expressionC(["bool", "dyn"], inheritedFieldContext).optional().describe("\u4E3A true \u65F6\uFF0C\u7981\u7528\u8FD9\u4E2A\u5B57\u6BB5\uFF0C\u53EF\u4F7F\u7528 form\u3001row \u548C index \u53D8\u91CF"),
74
79
  validation: validationC
75
80
  });
76
81
  export const CalendarFieldC = z.object({
@@ -84,10 +89,10 @@ export const CalendarFieldC = z.object({
84
89
  mode: z.enum(["year", "month", "date"]).describe("\u65E5\u5386\u9009\u62E9\u7CBE\u5EA6\uFF1Ayear \u4EC5\u9009\u5E74\uFF0Cmonth \u9009\u5E74\u6708\uFF0Cdate \u9009\u5E74\u6708\u65E5"),
85
90
  display: z.string().optional().describe('date-fns \u683C\u5F0F\u5B57\u7B26\u4E32\uFF0C\u63A7\u5236\u8F93\u5165\u6846\u4E2D\u7684\u5C55\u793A\u683C\u5F0F\uFF0C\u5982 "yyyy\u5E74MM\u6708dd\u65E5"\uFF1B\u7559\u7A7A\u5219\u663E\u793A\u539F\u59CB\u5B58\u50A8\u503C'),
86
91
  value: z.string().describe('date-fns \u683C\u5F0F\u5B57\u7B26\u4E32\uFF0C\u5B9A\u4E49\u65E5\u671F\u5728 model \u4E2D\u7684\u5B58\u50A8\u683C\u5F0F\uFF0C\u5982 "yyyy-MM-dd"'),
87
- initialValue: expressionC("string", { form: "map<string, dyn>" }).optional().describe("\u8FD4\u56DE string \u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u5728\u5B57\u6BB5\u9996\u6B21\u521D\u59CB\u5316\u4E14 path \u4E0D\u5B58\u5728\u65F6\u5199\u5165\u521D\u59CB\u503C\uFF0C\u53EF\u4F7F\u7528 form \u53D8\u91CF"),
88
- disableDate: expressionC("bool", { date: "Date" }).optional().describe("\u8FD4\u56DE\u5E03\u5C14\u503C\u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u4EE5 date\uFF08Date \u7C7B\u578B\uFF09\u4E3A\u53D8\u91CF\uFF0C\u8FD4\u56DE true \u65F6\u8BE5\u65E5\u671F\u5728\u65E5\u5386\u4E2D\u88AB\u7981\u7528"),
89
- hidden: expressionC("bool", { form: "map<string, dyn>" }).optional().describe("\u4E3A true \u65F6\uFF0C\u9690\u85CF\u8FD9\u4E2A\u5B57\u6BB5"),
90
- disabled: expressionC("bool", { form: "map<string, dyn>" }).optional().describe("\u4E3A true \u65F6\uFF0C\u7981\u7528\u8FD9\u4E2A\u5B57\u6BB5"),
92
+ initialValue: expressionC(["string", "dyn"], inheritedFieldContext).optional().describe("\u8FD4\u56DE string \u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u5728\u5B57\u6BB5\u9996\u6B21\u521D\u59CB\u5316\u4E14 path \u4E0D\u5B58\u5728\u65F6\u5199\u5165\u521D\u59CB\u503C\uFF0C\u53EF\u4F7F\u7528 form\u3001row \u548C index \u53D8\u91CF"),
93
+ disableDate: expressionC(["bool", "dyn"], { date: "Date" }).optional().describe("\u8FD4\u56DE\u5E03\u5C14\u503C\u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u4EE5 date\uFF08Date \u7C7B\u578B\uFF09\u4E3A\u53D8\u91CF\uFF0C\u8FD4\u56DE true \u65F6\u8BE5\u65E5\u671F\u5728\u65E5\u5386\u4E2D\u88AB\u7981\u7528"),
94
+ hidden: expressionC(["bool", "dyn"], inheritedFieldContext).optional().describe("\u4E3A true \u65F6\uFF0C\u9690\u85CF\u8FD9\u4E2A\u5B57\u6BB5\uFF0C\u53EF\u4F7F\u7528 form\u3001row \u548C index \u53D8\u91CF"),
95
+ disabled: expressionC(["bool", "dyn"], inheritedFieldContext).optional().describe("\u4E3A true \u65F6\uFF0C\u7981\u7528\u8FD9\u4E2A\u5B57\u6BB5\uFF0C\u53EF\u4F7F\u7528 form\u3001row \u548C index \u53D8\u91CF"),
91
96
  validation: validationC
92
97
  });
93
98
  export const SlotFieldC = z.strictObject({
@@ -110,9 +115,9 @@ export const FieldC = z.discriminatedUnion("type", [
110
115
  EmptyFieldC
111
116
  ]);
112
117
  export const FieldsOrientationC = z.enum(["horizontal", "vertical", "floating"]);
113
- export const FieldsStyleC = expressionC(/^map/, {
114
- form: "map<string, dyn>"
115
- }).optional().describe("\u8FD4\u56DE\u5B57\u6BB5\u96C6\u5408\u5BB9\u5668\u6837\u5F0F\u5BF9\u8C61\u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u53EF\u4F7F\u7528 form \u53D8\u91CF\u3002");
118
+ export const FieldsStyleC = expressionC([/^map/, "dyn"], {
119
+ ...inheritedFieldContext
120
+ }).optional().describe("\u8FD4\u56DE\u5B57\u6BB5\u96C6\u5408\u5BB9\u5668\u6837\u5F0F\u5BF9\u8C61\u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u53EF\u4F7F\u7528 form\u3001row \u548C index \u53D8\u91CF\u3002");
116
121
  const FieldsBodyObjectC = z.object({
117
122
  orientation: FieldsOrientationC.optional().describe("\u5B57\u6BB5\u5E03\u5C40\u65B9\u5411\uFF0C\u53EF\u9009 horizontal\u3001vertical \u6216 floating\uFF1B\u7559\u7A7A\u65F6\u9ED8\u8BA4 horizontal"),
118
123
  style: FieldsStyleC,
@@ -6,6 +6,7 @@ import { computedAsync } from "@vueuse/core";
6
6
  import { Effect } from "effect";
7
7
  import { computed, ref, watch } from "vue";
8
8
  import { useI18n } from "vue-i18n";
9
+ import { mergeDslContexts, useCELContext } from "../../../plugins/cel/context";
9
10
  import { getLocalizedText } from "../../../utils/coders";
10
11
  import { Button } from "../button";
11
12
  import { Skeleton } from "../skeleton";
@@ -22,7 +23,9 @@ const displayConfig = ref(defaultConfig);
22
23
  const { $dsl, $md } = useNuxtApp();
23
24
  const { t, locale } = useI18n();
24
25
  const isCheating = useCheating();
26
+ const inheritedContext = useCELContext();
25
27
  const isConfiguratorOpen = ref(false);
28
+ const resolvedContext = computed(() => mergeDslContexts(props.context, inheritedContext));
26
29
  function normalizeStyle(value) {
27
30
  const style = {};
28
31
  if (!value || typeof value !== "object" || Array.isArray(value)) {
@@ -40,7 +43,7 @@ const renderedStyle = computed(() => {
40
43
  return {};
41
44
  }
42
45
  try {
43
- return normalizeStyle($dsl.evaluate`${displayConfig.value.style}`(props.context ?? {}));
46
+ return normalizeStyle($dsl.evaluate`${displayConfig.value.style}`(resolvedContext.value));
44
47
  } catch {
45
48
  return {};
46
49
  }
@@ -51,9 +54,9 @@ const renderedMarkdown = computed(() => {
51
54
  return "";
52
55
  }
53
56
  if (displayConfig.value.inline) {
54
- return $md.inline`${markdownSource.value}`(props.context);
57
+ return $md.inline`${markdownSource.value}`(resolvedContext.value);
55
58
  }
56
- return $md.block`${markdownSource.value}`(props.context);
59
+ return $md.block`${markdownSource.value}`(resolvedContext.value);
57
60
  });
58
61
  function handleConfiguratorConfirm(nextConfig) {
59
62
  displayConfig.value = nextConfig;
@@ -107,7 +110,7 @@ export {
107
110
  v-if="resolvedConfig !== void 0"
108
111
  v-model:open="isConfiguratorOpen"
109
112
  :config="displayConfig"
110
- :context="props.context"
113
+ :context="resolvedContext"
111
114
  @confirm="handleConfiguratorConfirm"
112
115
  />
113
116
 
@@ -6,6 +6,7 @@ import { computedAsync } from "@vueuse/core";
6
6
  import { Effect } from "effect";
7
7
  import { computed, nextTick, onMounted, onUnmounted, ref, watch } from "vue";
8
8
  import { useI18n } from "vue-i18n";
9
+ import { mergeDslContexts, useCELContext } from "../../../plugins/cel/context";
9
10
  import { getLocalizedText } from "../../../utils/coders";
10
11
  import { Button } from "../button";
11
12
  import MenuTabsConfiguratorDialog from "../menu-tabs-configurator/MenuTabsConfiguratorDialog.vue";
@@ -27,6 +28,7 @@ const route = useRoute();
27
28
  const router = useRouter();
28
29
  const { locale, t } = useI18n();
29
30
  const isCheating = useCheating();
31
+ const inheritedContext = useCELContext();
30
32
  const resolvedConfig = computedAsync(
31
33
  async () => MenuTabsConfigC.parse(await props.config.pipe(Effect.runPromise) ?? defaultConfig)
32
34
  );
@@ -43,9 +45,10 @@ function cleanPath(path) {
43
45
  return normalizedPath.length > 0 ? normalizedPath : "/";
44
46
  }
45
47
  function getEvaluationContext() {
48
+ const context = mergeDslContexts(props.context, inheritedContext);
46
49
  return {
47
- ...props.context ?? {},
48
- context: props.context ?? {}
50
+ ...context,
51
+ context
49
52
  };
50
53
  }
51
54
  const resolvedMenus = computed(
@@ -15,8 +15,9 @@ import { computedAsync } from "@vueuse/core";
15
15
  import { getProperty } from "dot-prop";
16
16
  import { Effect } from "effect";
17
17
  import { Pagination } from "reka-ui/namespaced";
18
- import { computed, ref, watch } from "vue";
18
+ import { computed, defineComponent, ref, watch } from "vue";
19
19
  import { useI18n } from "vue-i18n";
20
+ import { mergeDslContexts, provideCELContext, useCELContext } from "../../../plugins/cel/context";
20
21
  import { useTableRenderers } from "../../../composables/useTableRenderers";
21
22
  import { getLocalizedText } from "../../../utils/coders";
22
23
  import {
@@ -53,6 +54,7 @@ const { t, locale } = useI18n();
53
54
  const slots = defineSlots();
54
55
  const { $dsl } = useNuxtApp();
55
56
  const isCheating = useCheating();
57
+ const inheritedDslContext = useCELContext();
56
58
  const { resolveTableRenderer } = useTableRenderers();
57
59
  const containerRef = ref(null);
58
60
  const appliedInitialStateKey = ref("");
@@ -77,6 +79,12 @@ function getColumnTitle(column) {
77
79
  function getColumnTooltip(column) {
78
80
  return getLocalizedText(column.tooltip, locale.value);
79
81
  }
82
+ function getRowDslContext(row, index) {
83
+ return mergeDslContexts({
84
+ row,
85
+ index: BigInt(index)
86
+ }, inheritedDslContext);
87
+ }
80
88
  function translate(column) {
81
89
  if (Array.isArray(column.columns) && column.columns.length > 0) {
82
90
  return {
@@ -104,7 +112,11 @@ function translate(column) {
104
112
  if (slot) {
105
113
  return slot({ cell: ctx });
106
114
  }
107
- return renderer.cell({ ctx, options });
115
+ return renderer.cell({
116
+ ctx,
117
+ dslContext: getRowDslContext(ctx.row.original, ctx.row.index),
118
+ options
119
+ });
108
120
  },
109
121
  accessorFn: (row, index) => {
110
122
  const key = column.accessor;
@@ -112,10 +124,7 @@ function translate(column) {
112
124
  return getProperty(row, key);
113
125
  } else if (key !== void 0) {
114
126
  try {
115
- return $dsl.evaluate`${key.read}`({
116
- row,
117
- index: BigInt(index)
118
- });
127
+ return $dsl.evaluate`${key.read}`(getRowDslContext(row, index));
119
128
  } catch (e) {
120
129
  console.error(e);
121
130
  return void 0;
@@ -144,6 +153,25 @@ const paginationLeft = computed(() => currentConfig.value?.paginationLeft ?? "")
144
153
  const paginationRight = computed(() => currentConfig.value?.paginationRight ?? "");
145
154
  const resolvedPaginationPageSizes = computed(() => normalizePaginationPageSizes(currentConfig.value?.paginationPageSizes));
146
155
  const isConfiguratorOpen = ref(false);
156
+ const TableRowCELContext = defineComponent({
157
+ name: "TableRowCELContext",
158
+ props: {
159
+ row: {
160
+ default: void 0
161
+ },
162
+ index: {
163
+ type: Number,
164
+ required: true
165
+ }
166
+ },
167
+ setup(props2, { slots: slots2 }) {
168
+ provideCELContext({
169
+ row: props2.row,
170
+ index: BigInt(props2.index)
171
+ });
172
+ return () => slots2.default?.();
173
+ }
174
+ });
147
175
  function handleConfiguratorConfirm(nextConfig) {
148
176
  currentConfig.value = nextConfig;
149
177
  emit("update:config", nextConfig);
@@ -174,7 +202,7 @@ function getRowId(originalRow, index, parent) {
174
202
  const key = $dsl.evaluate`${expression}`(
175
203
  {
176
204
  row: originalRow,
177
- index,
205
+ index: BigInt(index),
178
206
  parent: parent ? {
179
207
  id: parent.id,
180
208
  index: BigInt(parent.index),
@@ -196,10 +224,7 @@ function getSubRows(row, index) {
196
224
  return void 0;
197
225
  }
198
226
  try {
199
- const value = $dsl.evaluate`${expression}`({
200
- row,
201
- index
202
- });
227
+ const value = $dsl.evaluate`${expression}`(getRowDslContext(row, index));
203
228
  return Array.isArray(value) ? value : void 0;
204
229
  } catch (e) {
205
230
  console.error(e);
@@ -212,11 +237,11 @@ function enableRowSelection(row) {
212
237
  return true;
213
238
  }
214
239
  try {
215
- return Boolean($dsl.evaluate`${expression}`({
240
+ return Boolean($dsl.evaluate`${expression}`(mergeDslContexts({
216
241
  row: row.original,
217
242
  index: BigInt(row.index),
218
243
  id: row.id
219
- }));
244
+ }, inheritedDslContext)));
220
245
  } catch (e) {
221
246
  console.error(e);
222
247
  return true;
@@ -228,11 +253,11 @@ function enableMultiRowSelection(row) {
228
253
  return true;
229
254
  }
230
255
  try {
231
- return Boolean($dsl.evaluate`${expression}`({
256
+ return Boolean($dsl.evaluate`${expression}`(mergeDslContexts({
232
257
  row: row.original,
233
258
  index: BigInt(row.index),
234
259
  id: row.id
235
- }));
260
+ }, inheritedDslContext)));
236
261
  } catch (e) {
237
262
  console.error(e);
238
263
  return true;
@@ -352,13 +377,13 @@ function getCellStyles(ctx) {
352
377
  if (!expression)
353
378
  return {};
354
379
  try {
355
- const result = $dsl.evaluate`${expression}`({
380
+ const result = $dsl.evaluate`${expression}`(mergeDslContexts({
356
381
  row: ctx.row.original,
357
382
  index: BigInt(ctx.row.index),
358
383
  id: ctx.column.id,
359
384
  selected: ctx.row.getIsSelected(),
360
385
  pinned: ctx.column.getIsPinned()
361
- });
386
+ }, inheritedDslContext));
362
387
  return isStyleRecord(result) ? result : {};
363
388
  } catch (e) {
364
389
  console.error(e);
@@ -737,10 +762,15 @@ export {
737
762
  ...getCellStyles(cell.getContext())
738
763
  }"
739
764
  >
740
- <FlexRender
741
- :render="cell.column.columnDef.cell"
742
- :props="cell.getContext()"
743
- />
765
+ <TableRowCELContext
766
+ :row="cell.row.original"
767
+ :index="cell.row.index"
768
+ >
769
+ <FlexRender
770
+ :render="cell.column.columnDef.cell"
771
+ :props="cell.getContext()"
772
+ />
773
+ </TableRowCELContext>
744
774
  </td>
745
775
  </tr>
746
776
  </tbody>
@@ -0,0 +1 @@
1
+ export { provideCELContext } from '../plugins/cel/context.js';
@@ -0,0 +1 @@
1
+ export { provideCELContext } from "../plugins/cel/context.js";
@@ -6,6 +6,7 @@ export type ButtonActionRuntime = Readonly<{
6
6
  title: string;
7
7
  description?: string;
8
8
  tooltip?: string;
9
+ celContext: Record<string, unknown>;
9
10
  }>;
10
11
  declare const ButtonActionService_base: Context.TagClass<ButtonActionService, "shwfed/ButtonActionService", Readonly<{
11
12
  id: string;
@@ -13,6 +14,7 @@ declare const ButtonActionService_base: Context.TagClass<ButtonActionService, "s
13
14
  title: string;
14
15
  description?: string;
15
16
  tooltip?: string;
17
+ celContext: Record<string, unknown>;
16
18
  }>>;
17
19
  export declare class ButtonActionService extends ButtonActionService_base {
18
20
  }
@@ -0,0 +1 @@
1
+ export { useCELContext } from '../plugins/cel/context.js';
@@ -0,0 +1 @@
1
+ export { useCELContext } from "../plugins/cel/context.js";
@@ -12,6 +12,7 @@ export type OverlayBodyProps = Readonly<Record<string, unknown>>;
12
12
  export type OverlaySessionInput = Readonly<{
13
13
  shell?: Partial<OverlayShellProps>;
14
14
  props?: Record<string, unknown>;
15
+ celContext?: Record<string, unknown>;
15
16
  }>;
16
17
  export type OverlaySessionPatch = Readonly<{
17
18
  shell?: Partial<OverlayShellProps>;
@@ -41,6 +42,7 @@ type OverlaySession = {
41
42
  open: boolean;
42
43
  shell: OverlayShellState;
43
44
  props: Record<string, unknown>;
45
+ celContext: Record<string, unknown>;
44
46
  deferred: Deferred.Deferred<OverlayResult, never>;
45
47
  pendingResult?: OverlayResult;
46
48
  };
@@ -1,6 +1,7 @@
1
1
  import { Context, Deferred, Effect, Option } from "effect";
2
2
  import { reactive, ref } from "vue";
3
3
  import { ButtonActionService } from "./useButtonAction.js";
4
+ import { mergeDslContexts } from "../plugins/cel/context.js";
4
5
  export class OverlayService extends Context.Tag("shwfed/OverlayService")() {
5
6
  }
6
7
  function createDefinitionNotFoundError(definitionId) {
@@ -180,6 +181,7 @@ function createOverlayRuntime() {
180
181
  props: {
181
182
  ...options?.props
182
183
  },
184
+ celContext: mergeDslContexts(options?.celContext, buttonAction?.celContext),
183
185
  deferred
184
186
  };
185
187
  sessions.value.push(session);
@@ -1,2 +1,6 @@
1
+ export declare function mergeDslContexts(...contexts: Array<Record<string, unknown> | undefined>): Record<string, unknown>;
1
2
  export declare function setGlobalDslContext(context: Record<string, unknown>): void;
2
3
  export declare function getGlobalDslContext(): Record<string, unknown>;
4
+ export declare function getProvidedDslContext(): Record<string, unknown>;
5
+ export declare function provideCELContext(context: Record<string, unknown>): void;
6
+ export declare function useCELContext(overrides?: Record<string, unknown>): Record<string, unknown>;
@@ -1,7 +1,27 @@
1
+ import defu from "defu";
2
+ import { hasInjectionContext, inject, provide } from "vue";
3
+ const dslContextKey = Symbol("shwfed-cel-context");
4
+ const emptyDslContext = {};
1
5
  let globalDslContext = {};
6
+ export function mergeDslContexts(...contexts) {
7
+ const definedContexts = contexts.filter((context) => context !== void 0);
8
+ return defu({}, ...definedContexts);
9
+ }
2
10
  export function setGlobalDslContext(context) {
3
11
  globalDslContext = context;
4
12
  }
5
13
  export function getGlobalDslContext() {
6
14
  return globalDslContext;
7
15
  }
16
+ export function getProvidedDslContext() {
17
+ if (!hasInjectionContext()) {
18
+ return emptyDslContext;
19
+ }
20
+ return inject(dslContextKey, emptyDslContext);
21
+ }
22
+ export function provideCELContext(context) {
23
+ provide(dslContextKey, mergeDslContexts(context, getProvidedDslContext()));
24
+ }
25
+ export function useCELContext(overrides) {
26
+ return mergeDslContexts(overrides, getProvidedDslContext());
27
+ }
@@ -1,7 +1,7 @@
1
1
  import { defineNuxtPlugin, useRuntimeConfig } from "#app";
2
2
  import defu from "defu";
3
3
  import { createEnvironment } from "./env.js";
4
- import { getGlobalDslContext } from "./context.js";
4
+ import { getGlobalDslContext, getProvidedDslContext } from "./context.js";
5
5
  import { useNavigatorLanguage } from "@vueuse/core";
6
6
  import { TZDate } from "@date-fns/tz";
7
7
  export default defineNuxtPlugin({
@@ -14,7 +14,7 @@ export default defineNuxtPlugin({
14
14
  build: config.ci.build !== void 0 ? BigInt(config.ci.build) : void 0
15
15
  });
16
16
  const evaluate = (...args) => (context) => {
17
- return env.evaluate(String.raw(...args), defu({}, getGlobalDslContext(), context, {
17
+ return env.evaluate(String.raw(...args), defu({}, context, getProvidedDslContext(), getGlobalDslContext(), {
18
18
  now: new TZDate(),
19
19
  today: new TZDate(),
20
20
  location: new URL(location.href),
@@ -387,7 +387,7 @@ defineTableRenderer(
387
387
  align: z.enum(["left", "center", "right"]).default("left")
388
388
  },
389
389
  {
390
- cell: ({ ctx, options }) => {
390
+ cell: ({ ctx, dslContext, options }) => {
391
391
  const rawValue = ctx.cell.getValue();
392
392
  const isEmpty = rawValue === void 0 || rawValue === null;
393
393
  const align = isEmpty ? "center" : options.align ?? "left";
@@ -397,10 +397,7 @@ defineTableRenderer(
397
397
  try {
398
398
  let text = String(ctx.cell.getValue());
399
399
  if (options.copyExpression) {
400
- text = String($dsl.evaluate`${options.copyExpression}`({
401
- row: ctx.row.original,
402
- index: BigInt(ctx.row.index)
403
- }));
400
+ text = String($dsl.evaluate`${options.copyExpression}`(dslContext));
404
401
  }
405
402
  await navigator.clipboard.writeText(text);
406
403
  } catch (e) {
@@ -5,6 +5,7 @@ export type TableRendererId = string;
5
5
  export type TableRendererColumnDefOverrides<TData extends RowData = unknown> = Partial<Pick<ColumnDef<TData, unknown>, 'enableResizing' | 'enableSorting' | 'enableMultiSort' | 'enablePinning' | 'sortingFn' | 'size' | 'meta'>>;
6
6
  export type TableRendererCellArgs<TData extends RowData, TValue, TOptions> = Readonly<{
7
7
  ctx: CellContext<TData, TValue>;
8
+ dslContext: Record<string, unknown>;
8
9
  options: TOptions;
9
10
  }>;
10
11
  export type TableRendererHeaderArgs<TData extends RowData, TValue, TOptions> = Readonly<{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shwfed/nuxt",
3
- "version": "0.11.22",
3
+ "version": "0.11.24",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "type": "module",