@shwfed/config 2.11.1 → 2.11.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.
- package/dist/mcp.mjs +1592 -1220
- package/dist/module.json +1 -1
- package/dist/preview/assets/{FieldGroup.vue_vue_type_script_setup_true_lang-CosmpPSu.js → FieldGroup.vue_vue_type_script_setup_true_lang-BK4nj6mF.js} +1 -1
- package/dist/preview/assets/{badge-BkYCxTFK.js → badge-Df9KgnrB.js} +1 -1
- package/dist/preview/assets/config-B3NwVBxT.js +1 -0
- package/dist/preview/assets/{config-Dt8k1gnT.js → config-BrtNnMlJ.js} +1 -1
- package/dist/preview/assets/{config-Cbp7aAAw.js → config-CUJNegvX.js} +1 -1
- package/dist/preview/assets/{config-C_Ia1CDq.js → config-ChrXUmKf.js} +1 -1
- package/dist/preview/assets/{config-B62b9dMF.js → config-CmEXMpIU.js} +1 -1
- package/dist/preview/assets/{config-Dk9OegYx.js → config-CrBoFiYB.js} +1 -1
- package/dist/preview/assets/{config-74YmXQsH.js → config-D-Hf0dls.js} +1 -1
- package/dist/preview/assets/{config-Bt6--diX.js → config-D4cXwy75.js} +1 -1
- package/dist/preview/assets/{config-BcZe-bR9.js → config-DCj5Qyiq.js} +1 -1
- package/dist/preview/assets/{config-sCP15_0f.js → config-DPfx03nM.js} +1 -1
- package/dist/preview/assets/{config-Bbbyd5lB.js → config-DWF0bcmF.js} +1 -1
- package/dist/preview/assets/{config-CPsd0ppi.js → config-Do4K9hI7.js} +1 -1
- package/dist/preview/assets/config-DwblM1r8.js +1 -0
- package/dist/preview/assets/{config-CYVafGLc.js → config-MW5Hs8yE.js} +1 -1
- package/dist/preview/assets/{config-COr2MFhN.js → config-uNoNEc-1.js} +1 -1
- package/dist/preview/assets/{definition.vue_vue_type_script_setup_true_lang-C3NiB99t.js → definition.vue_vue_type_script_setup_true_lang-CbtpddWK.js} +1 -1
- package/dist/preview/assets/index-Bm7I4Tr0.css +1 -0
- package/dist/preview/assets/{index-DjG-VVR4.js → index-CkyV576r.js} +217 -205
- package/dist/preview/assets/{index-BMOizF8g.js → index-CtW2E0ME.js} +1 -1
- package/dist/preview/assets/index-xDmBF3zO.js +1 -0
- package/dist/preview/assets/{item-C1efxuFt.js → item-D0e9Cx1Q.js} +1 -1
- package/dist/preview/assets/{runtime-Du0ghzR2.js → runtime-3tGIbclh.js} +1 -1
- package/dist/preview/assets/{runtime-7z9N9JGG.js → runtime-BCePD3XR.js} +1 -1
- package/dist/preview/assets/runtime-BMyFUaSM.js +1 -0
- package/dist/preview/assets/runtime-BXZU3EqA.js +1 -0
- package/dist/preview/assets/{runtime-LgZuN2Tf.js → runtime-BySNFNSO.js} +1 -1
- package/dist/preview/assets/{runtime-Dz7SCudL.js → runtime-CI02gDFj.js} +1 -1
- package/dist/preview/assets/{runtime-DoLpKFu-.js → runtime-DCo1Qp8a.js} +1 -1
- package/dist/preview/assets/runtime-DDSKV70N.js +1 -0
- package/dist/preview/assets/runtime-Dc7pytUy.js +1 -0
- package/dist/preview/assets/{runtime-S9eZ2nJS.js → runtime-ckLrkTMm.js} +1 -1
- package/dist/preview/assets/runtime-y4oJ8VkY.js +1 -0
- package/dist/preview/assets/{schema-meta-CYKPEnu9.js → schema-meta-D0y0sKal.js} +1 -1
- package/dist/preview/index.html +2 -2
- package/dist/runtime/components/actions/buttons/2026-06-25/com.shwfed.actions.button.state.write/config.d.vue.ts +39 -0
- package/dist/runtime/components/actions/buttons/2026-06-25/com.shwfed.actions.button.state.write/config.vue +127 -0
- package/dist/runtime/components/actions/buttons/2026-06-25/com.shwfed.actions.button.state.write/config.vue.d.ts +39 -0
- package/dist/runtime/components/actions/buttons/2026-06-25/com.shwfed.actions.button.state.write/runtime.d.vue.ts +8 -0
- package/dist/runtime/components/actions/buttons/2026-06-25/com.shwfed.actions.button.state.write/runtime.vue +62 -0
- package/dist/runtime/components/actions/buttons/2026-06-25/com.shwfed.actions.button.state.write/runtime.vue.d.ts +8 -0
- package/dist/runtime/components/actions/buttons/2026-06-25/com.shwfed.actions.button.state.write/schema.d.ts +25 -0
- package/dist/runtime/components/actions/buttons/2026-06-25/com.shwfed.actions.button.state.write/schema.js +41 -0
- package/dist/runtime/components/config/blocks/2026-06-17/com.shwfed.block.tree.single/runtime.vue +5 -22
- package/dist/runtime/components/config/blocks/2026-06-25/com.shwfed.block.loop/config.d.vue.ts +70 -0
- package/dist/runtime/components/config/blocks/2026-06-25/com.shwfed.block.loop/config.vue +349 -0
- package/dist/runtime/components/config/blocks/2026-06-25/com.shwfed.block.loop/config.vue.d.ts +70 -0
- package/dist/runtime/components/config/blocks/2026-06-25/com.shwfed.block.loop/loop-item.d.vue.ts +33 -0
- package/dist/runtime/components/config/blocks/2026-06-25/com.shwfed.block.loop/loop-item.vue +37 -0
- package/dist/runtime/components/config/blocks/2026-06-25/com.shwfed.block.loop/loop-item.vue.d.ts +33 -0
- package/dist/runtime/components/config/blocks/2026-06-25/com.shwfed.block.loop/loop-scope-provider.d.vue.ts +13 -0
- package/dist/runtime/components/config/blocks/2026-06-25/com.shwfed.block.loop/loop-scope-provider.vue +22 -0
- package/dist/runtime/components/config/blocks/2026-06-25/com.shwfed.block.loop/loop-scope-provider.vue.d.ts +13 -0
- package/dist/runtime/components/config/blocks/2026-06-25/com.shwfed.block.loop/runtime.d.vue.ts +70 -0
- package/dist/runtime/components/config/blocks/2026-06-25/com.shwfed.block.loop/runtime.vue +62 -0
- package/dist/runtime/components/config/blocks/2026-06-25/com.shwfed.block.loop/runtime.vue.d.ts +70 -0
- package/dist/runtime/components/config/blocks/2026-06-25/com.shwfed.block.loop/schema.d.ts +85 -0
- package/dist/runtime/components/config/blocks/2026-06-25/com.shwfed.block.loop/schema.js +60 -0
- package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.textarea/config.d.vue.ts +2 -2
- package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.textarea/config.vue.d.ts +2 -2
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.daterange/config.d.vue.ts +4 -4
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.daterange/config.vue.d.ts +4 -4
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetimerange/config.d.vue.ts +6 -6
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetimerange/config.vue.d.ts +6 -6
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.timerange/config.d.vue.ts +2 -2
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.timerange/config.vue.d.ts +2 -2
- package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/config.d.vue.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/config.vue.d.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.monthrange/config.d.vue.ts +4 -4
- package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.monthrange/config.vue.d.ts +4 -4
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.d.vue.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.vue.d.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.d.vue.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.vue.d.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.d.vue.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.vue.d.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.d.vue.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.vue.d.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.d.vue.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.vue.d.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/runtime.vue +2 -19
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.d.vue.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.vue.d.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/runtime.vue +5 -22
- package/dist/runtime/components/operations/2026-06-15/com.shwfed.operation.http.download/config.d.vue.ts +2 -0
- package/dist/runtime/components/operations/2026-06-15/com.shwfed.operation.http.download/config.vue +49 -22
- package/dist/runtime/components/operations/2026-06-15/com.shwfed.operation.http.download/config.vue.d.ts +2 -0
- package/dist/runtime/components/operations/2026-06-15/com.shwfed.operation.http.download/runtime.js +17 -10
- package/dist/runtime/components/operations/2026-06-15/com.shwfed.operation.http.download/schema.d.ts +1 -0
- package/dist/runtime/components/operations/2026-06-15/com.shwfed.operation.http.download/schema.js +25 -3
- 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-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-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.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-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-06-14/com.shwfed.table.column.combobox-multi/runtime.vue +5 -1
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/runtime.vue +5 -1
- package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/config.vue +81 -2
- package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/runtime.vue +35 -1
- package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/schema.d.ts +132 -0
- package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/schema.js +28 -2
- package/dist/runtime/components/ui/date-picker/DatePicker.d.vue.ts +11 -1
- package/dist/runtime/components/ui/date-picker/DatePicker.vue +8 -1
- package/dist/runtime/components/ui/date-picker/DatePicker.vue.d.ts +11 -1
- package/dist/runtime/components/ui/date-picker/DatePickerInput.d.vue.ts +12 -2
- package/dist/runtime/components/ui/date-picker/DatePickerInput.vue +4 -0
- package/dist/runtime/components/ui/date-picker/DatePickerInput.vue.d.ts +12 -2
- package/dist/runtime/components/ui/date-picker/DatePickerTimeInput.d.vue.ts +1 -1
- package/dist/runtime/components/ui/date-picker/DatePickerTimeInput.vue.d.ts +1 -1
- package/dist/runtime/components/ui/date-range-picker/DateRangePickerInput.d.vue.ts +1 -1
- package/dist/runtime/components/ui/date-range-picker/DateRangePickerInput.vue.d.ts +1 -1
- package/dist/runtime/components/ui/date-range-picker/DateRangePickerTimeInput.d.vue.ts +2 -2
- package/dist/runtime/components/ui/date-range-picker/DateRangePickerTimeInput.vue.d.ts +2 -2
- package/dist/runtime/components/ui/expression-editor/ExpressionEditor.vue +1 -1
- package/dist/runtime/share/loop-item-var.d.ts +21 -0
- package/dist/runtime/share/loop-item-var.js +13 -0
- package/dist/runtime/vendor/cel-js/CLAUDE.md +2 -2
- package/dist/runtime/vendor/cel-js/PROMPT.md +7 -0
- package/dist/runtime/vendor/cel-js/lib/functions.js +25 -1
- package/dist/runtime/vendor/cel-js/lib/http-builder.d.ts +38 -3
- package/dist/runtime/vendor/cel-js/lib/http-builder.js +33 -0
- package/package.json +1 -1
- package/dist/preview/assets/config-BHYlKhDX.js +0 -1
- package/dist/preview/assets/index-C9G8y6qZ.js +0 -1
- package/dist/preview/assets/index-DqRQ67sX.css +0 -1
- package/dist/preview/assets/runtime-Bpa1zRxG.js +0 -1
- package/dist/preview/assets/runtime-Csv04MYG.js +0 -1
- package/dist/preview/assets/runtime-D0bjM4NL.js +0 -1
- package/dist/preview/assets/runtime-Dz3ZQYdq.js +0 -1
|
@@ -49,6 +49,138 @@ export declare function schema(configure: (env: Environment) => void): Schema.St
|
|
|
49
49
|
}>]>;
|
|
50
50
|
value: Schema.Schema<string, string, never>;
|
|
51
51
|
}>>>;
|
|
52
|
+
addon: Schema.optional<Schema.Struct<{
|
|
53
|
+
groups: Schema.optionalWith<Schema.Array$<Schema.Struct<{
|
|
54
|
+
id: Schema.refine<string, typeof Schema.String>;
|
|
55
|
+
variant: Schema.optional<Schema.Literal<["default", "primary", "destructive", "ghost", "link"]>>;
|
|
56
|
+
}>>, {
|
|
57
|
+
default: () => never[];
|
|
58
|
+
}>;
|
|
59
|
+
items: Schema.optionalWith<Schema.Array$<Schema.Schema<import("../../../../actions/schema.js").RegistryItemValue | {
|
|
60
|
+
readonly disabled?: string | undefined;
|
|
61
|
+
readonly id: string;
|
|
62
|
+
readonly title: readonly [{
|
|
63
|
+
readonly locale: "zh";
|
|
64
|
+
readonly message: string;
|
|
65
|
+
}, ...{
|
|
66
|
+
readonly locale: "en" | "ja" | "ko";
|
|
67
|
+
readonly message: string;
|
|
68
|
+
}[]];
|
|
69
|
+
readonly icon?: string | undefined;
|
|
70
|
+
readonly hidden?: string | undefined;
|
|
71
|
+
readonly tooltip?: readonly [{
|
|
72
|
+
readonly locale: "zh";
|
|
73
|
+
readonly message: string;
|
|
74
|
+
}, ...{
|
|
75
|
+
readonly locale: "en" | "ja" | "ko";
|
|
76
|
+
readonly message: string;
|
|
77
|
+
}[]] | undefined;
|
|
78
|
+
readonly variant?: "default" | "link" | "destructive" | "primary" | "ghost" | undefined;
|
|
79
|
+
readonly action?: any;
|
|
80
|
+
readonly groupId: string;
|
|
81
|
+
readonly hideTitle?: boolean | undefined;
|
|
82
|
+
} | {
|
|
83
|
+
readonly id: string;
|
|
84
|
+
readonly title: readonly [{
|
|
85
|
+
readonly locale: "zh";
|
|
86
|
+
readonly message: string;
|
|
87
|
+
}, ...{
|
|
88
|
+
readonly locale: "en" | "ja" | "ko";
|
|
89
|
+
readonly message: string;
|
|
90
|
+
}[]];
|
|
91
|
+
readonly icon?: string | undefined;
|
|
92
|
+
readonly items: readonly (import("../../../../actions/schema.js").RegistrySubItemValue | {
|
|
93
|
+
readonly disabled?: string | undefined;
|
|
94
|
+
readonly id: string;
|
|
95
|
+
readonly title: readonly [{
|
|
96
|
+
readonly locale: "zh";
|
|
97
|
+
readonly message: string;
|
|
98
|
+
}, ...{
|
|
99
|
+
readonly locale: "en" | "ja" | "ko";
|
|
100
|
+
readonly message: string;
|
|
101
|
+
}[]];
|
|
102
|
+
readonly icon?: string | undefined;
|
|
103
|
+
readonly hidden?: string | undefined;
|
|
104
|
+
readonly tooltip?: readonly [{
|
|
105
|
+
readonly locale: "zh";
|
|
106
|
+
readonly message: string;
|
|
107
|
+
}, ...{
|
|
108
|
+
readonly locale: "en" | "ja" | "ko";
|
|
109
|
+
readonly message: string;
|
|
110
|
+
}[]] | undefined;
|
|
111
|
+
readonly variant?: "default" | "link" | "destructive" | "primary" | "ghost" | undefined;
|
|
112
|
+
readonly action?: any;
|
|
113
|
+
})[];
|
|
114
|
+
readonly groupId: string;
|
|
115
|
+
readonly hideTitle?: boolean | undefined;
|
|
116
|
+
}, import("../../../../actions/schema.js").RegistryItemValue | {
|
|
117
|
+
readonly id: string;
|
|
118
|
+
readonly title: readonly [{
|
|
119
|
+
readonly locale: "zh";
|
|
120
|
+
readonly message: string;
|
|
121
|
+
}, ...{
|
|
122
|
+
readonly locale: "en" | "ja" | "ko";
|
|
123
|
+
readonly message: string;
|
|
124
|
+
}[]];
|
|
125
|
+
readonly groupId: string;
|
|
126
|
+
readonly disabled?: string | undefined;
|
|
127
|
+
readonly icon?: string | undefined;
|
|
128
|
+
readonly hidden?: string | undefined;
|
|
129
|
+
readonly tooltip?: readonly [{
|
|
130
|
+
readonly locale: "zh";
|
|
131
|
+
readonly message: string;
|
|
132
|
+
}, ...{
|
|
133
|
+
readonly locale: "en" | "ja" | "ko";
|
|
134
|
+
readonly message: string;
|
|
135
|
+
}[]] | undefined;
|
|
136
|
+
readonly variant?: "default" | "link" | "destructive" | "primary" | "ghost" | undefined;
|
|
137
|
+
readonly action?: any;
|
|
138
|
+
readonly hideTitle?: boolean | undefined;
|
|
139
|
+
} | {
|
|
140
|
+
readonly id: string;
|
|
141
|
+
readonly title: readonly [{
|
|
142
|
+
readonly locale: "zh";
|
|
143
|
+
readonly message: string;
|
|
144
|
+
}, ...{
|
|
145
|
+
readonly locale: "en" | "ja" | "ko";
|
|
146
|
+
readonly message: string;
|
|
147
|
+
}[]];
|
|
148
|
+
readonly items: readonly (import("../../../../actions/schema.js").RegistrySubItemValue | {
|
|
149
|
+
readonly id: string;
|
|
150
|
+
readonly title: readonly [{
|
|
151
|
+
readonly locale: "zh";
|
|
152
|
+
readonly message: string;
|
|
153
|
+
}, ...{
|
|
154
|
+
readonly locale: "en" | "ja" | "ko";
|
|
155
|
+
readonly message: string;
|
|
156
|
+
}[]];
|
|
157
|
+
readonly disabled?: string | undefined;
|
|
158
|
+
readonly icon?: string | undefined;
|
|
159
|
+
readonly hidden?: string | undefined;
|
|
160
|
+
readonly tooltip?: readonly [{
|
|
161
|
+
readonly locale: "zh";
|
|
162
|
+
readonly message: string;
|
|
163
|
+
}, ...{
|
|
164
|
+
readonly locale: "en" | "ja" | "ko";
|
|
165
|
+
readonly message: string;
|
|
166
|
+
}[]] | undefined;
|
|
167
|
+
readonly variant?: "default" | "link" | "destructive" | "primary" | "ghost" | undefined;
|
|
168
|
+
readonly action?: any;
|
|
169
|
+
})[];
|
|
170
|
+
readonly groupId: string;
|
|
171
|
+
readonly icon?: string | undefined;
|
|
172
|
+
readonly hideTitle?: boolean | undefined;
|
|
173
|
+
}, never>>, {
|
|
174
|
+
default: () => never[];
|
|
175
|
+
}>;
|
|
176
|
+
size: Schema.optionalWith<Schema.Literal<["default", "sm", "xs"]>, {
|
|
177
|
+
default: () => "default";
|
|
178
|
+
}>;
|
|
179
|
+
gap: Schema.optionalWith<Schema.filter<Schema.filter<typeof Schema.Number>>, {
|
|
180
|
+
default: () => number;
|
|
181
|
+
}>;
|
|
182
|
+
style: Schema.optional<typeof Schema.String>;
|
|
183
|
+
}>>;
|
|
52
184
|
title: Schema.TupleType<readonly [Schema.Struct<{
|
|
53
185
|
locale: Schema.Literal<["zh"]>;
|
|
54
186
|
message: Schema.SchemaClass<string, string, never>;
|
|
@@ -1,13 +1,29 @@
|
|
|
1
1
|
import { Schema } from "effect";
|
|
2
2
|
import { getProperty } from "dot-prop";
|
|
3
3
|
import { Locale } from "../../../../../share/locale.js";
|
|
4
|
-
import {
|
|
4
|
+
import { ActionSchemaFields } from "../../../../actions/schema.js";
|
|
5
|
+
import { Align, CelRowAccess, derivedRowField, editableColumnFields, editableHeader, registerRowVariablesIfAbsent } from "../../../utils/shared.js";
|
|
5
6
|
export const type = "com.shwfed.table.column.date-input";
|
|
6
7
|
export const compatibilityDate = "2026-06-17";
|
|
7
8
|
export const metadata = {
|
|
8
9
|
name: "\u65E5\u671F\u8F93\u5165",
|
|
9
10
|
icon: "fluent:calendar-ltr-20-regular"
|
|
10
11
|
};
|
|
12
|
+
function AddonActions(configure) {
|
|
13
|
+
const configureWithRow = (env) => {
|
|
14
|
+
configure(env);
|
|
15
|
+
registerRowVariablesIfAbsent(env);
|
|
16
|
+
};
|
|
17
|
+
const { groups, items, ...rest } = ActionSchemaFields(configureWithRow).fields;
|
|
18
|
+
return Schema.Struct({
|
|
19
|
+
...rest,
|
|
20
|
+
groups: Schema.optionalWith(groups, { default: () => [] }),
|
|
21
|
+
items: Schema.optionalWith(items, { default: () => [] })
|
|
22
|
+
}).annotations({
|
|
23
|
+
title: "\u8F93\u5165\u6846\u5185\u6309\u94AE",
|
|
24
|
+
description: "\u5728\u8F93\u5165\u6846\u53F3\u4FA7\u5185\u5D4C\u4E00\u7EC4\u64CD\u4F5C\u6309\u94AE"
|
|
25
|
+
});
|
|
26
|
+
}
|
|
11
27
|
export function presetSchema(configure) {
|
|
12
28
|
const CelDate = CelRowAccess(configure, { resultType: "Date" });
|
|
13
29
|
return Schema.Struct({
|
|
@@ -56,7 +72,17 @@ export function schema(configure) {
|
|
|
56
72
|
presets: Schema.optional(Schema.Array(Preset).annotations({
|
|
57
73
|
title: "\u5FEB\u6377\u9009\u9879",
|
|
58
74
|
description: "\u5728\u9009\u62E9\u5668\u4FA7\u680F\u5C55\u793A\u7684\u5FEB\u6377\u9884\u8BBE\uFF1B\u7559\u7A7A\u5219\u4E0D\u6E32\u67D3\u4FA7\u680F"
|
|
59
|
-
}))
|
|
75
|
+
})),
|
|
76
|
+
// `Schema.optional` rebuilds the struct's union member, and because the
|
|
77
|
+
// `optionalWith`-default fields make `AddonActions` a `Transformation`, the
|
|
78
|
+
// inner struct's `title`/`description` don't survive onto the rebuilt
|
|
79
|
+
// member. The config editor's `getStructFieldTitle('addon')` would then fall
|
|
80
|
+
// back to the raw key "addon". Re-state them on the property signature,
|
|
81
|
+
// which the meta reader checks before the field type.
|
|
82
|
+
addon: Schema.optional(AddonActions(configure)).annotations({
|
|
83
|
+
title: "\u8F93\u5165\u6846\u5185\u6309\u94AE",
|
|
84
|
+
description: "\u5728\u8F93\u5165\u6846\u53F3\u4FA7\u5185\u5D4C\u4E00\u7EC4\u64CD\u4F5C\u6309\u94AE"
|
|
85
|
+
})
|
|
60
86
|
}).annotations({ title: "DateInputRenderer", description: "\u65E5\u671F\u8F93\u5165\u6E32\u67D3\u5668\uFF08\u53EF\u7F16\u8F91\uFF09" });
|
|
61
87
|
}
|
|
62
88
|
export function defaults() {
|
|
@@ -28,7 +28,11 @@ type __VLS_Props = {
|
|
|
28
28
|
shortcuts?: ReadonlyArray<DatePickerShortcut>;
|
|
29
29
|
size?: 'sm' | 'md' | 'lg';
|
|
30
30
|
};
|
|
31
|
-
declare
|
|
31
|
+
declare var __VLS_33: {};
|
|
32
|
+
type __VLS_Slots = {} & {
|
|
33
|
+
trailing?: (props: typeof __VLS_33) => any;
|
|
34
|
+
};
|
|
35
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
32
36
|
clear: () => any;
|
|
33
37
|
blur: (args_0: FocusEvent) => any;
|
|
34
38
|
change: (args_0: string | undefined) => any;
|
|
@@ -47,5 +51,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
47
51
|
clearable: boolean;
|
|
48
52
|
timeGranularity: "hour" | "minute" | "second";
|
|
49
53
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
54
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
50
55
|
declare const _default: typeof __VLS_export;
|
|
51
56
|
export default _default;
|
|
57
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
58
|
+
new (): {
|
|
59
|
+
$slots: S;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
@@ -212,7 +212,14 @@ function applyShortcut(index) {
|
|
|
212
212
|
@focus="onInputFocus"
|
|
213
213
|
@blur="onInputBlur"
|
|
214
214
|
@clear="onInputClear"
|
|
215
|
-
|
|
215
|
+
>
|
|
216
|
+
<template
|
|
217
|
+
v-if="$slots.trailing"
|
|
218
|
+
#trailing
|
|
219
|
+
>
|
|
220
|
+
<slot name="trailing" />
|
|
221
|
+
</template>
|
|
222
|
+
</DatePickerInput>
|
|
216
223
|
</PopoverAnchor>
|
|
217
224
|
<PopoverContent
|
|
218
225
|
align="start"
|
|
@@ -28,7 +28,11 @@ type __VLS_Props = {
|
|
|
28
28
|
shortcuts?: ReadonlyArray<DatePickerShortcut>;
|
|
29
29
|
size?: 'sm' | 'md' | 'lg';
|
|
30
30
|
};
|
|
31
|
-
declare
|
|
31
|
+
declare var __VLS_33: {};
|
|
32
|
+
type __VLS_Slots = {} & {
|
|
33
|
+
trailing?: (props: typeof __VLS_33) => any;
|
|
34
|
+
};
|
|
35
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
32
36
|
clear: () => any;
|
|
33
37
|
blur: (args_0: FocusEvent) => any;
|
|
34
38
|
change: (args_0: string | undefined) => any;
|
|
@@ -47,5 +51,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
47
51
|
clearable: boolean;
|
|
48
52
|
timeGranularity: "hour" | "minute" | "second";
|
|
49
53
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
54
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
50
55
|
declare const _default: typeof __VLS_export;
|
|
51
56
|
export default _default;
|
|
57
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
58
|
+
new (): {
|
|
59
|
+
$slots: S;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
@@ -12,7 +12,11 @@ type __VLS_Props = {
|
|
|
12
12
|
size?: 'sm' | 'md' | 'lg';
|
|
13
13
|
class?: HTMLAttributes['class'];
|
|
14
14
|
};
|
|
15
|
-
declare
|
|
15
|
+
declare var __VLS_49: {};
|
|
16
|
+
type __VLS_Slots = {} & {
|
|
17
|
+
trailing?: (props: typeof __VLS_49) => any;
|
|
18
|
+
};
|
|
19
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
16
20
|
clear: () => any;
|
|
17
21
|
blur: (args_0: FocusEvent) => any;
|
|
18
22
|
focus: (args_0: FocusEvent) => any;
|
|
@@ -24,8 +28,14 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
24
28
|
"onUpdate:modelValue"?: ((args_0: Date | undefined) => any) | undefined;
|
|
25
29
|
}>, {
|
|
26
30
|
size: "sm" | "md" | "lg";
|
|
27
|
-
clearIcon: string;
|
|
28
31
|
clearable: boolean;
|
|
32
|
+
clearIcon: string;
|
|
29
33
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
34
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
30
35
|
declare const _default: typeof __VLS_export;
|
|
31
36
|
export default _default;
|
|
37
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
38
|
+
new (): {
|
|
39
|
+
$slots: S;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
@@ -120,5 +120,9 @@ const showClear = computed(
|
|
|
120
120
|
/>
|
|
121
121
|
</InputGroupButton>
|
|
122
122
|
</InputGroupAddon>
|
|
123
|
+
<!-- A trailing slot for consumer-supplied addons (e.g. the table date-input
|
|
124
|
+
column's embedded action buttons). Rendered inside the `InputGroup` so
|
|
125
|
+
the consumer can drop its own `InputGroupAddon`. -->
|
|
126
|
+
<slot name="trailing" />
|
|
123
127
|
</InputGroup>
|
|
124
128
|
</template>
|
|
@@ -12,7 +12,11 @@ type __VLS_Props = {
|
|
|
12
12
|
size?: 'sm' | 'md' | 'lg';
|
|
13
13
|
class?: HTMLAttributes['class'];
|
|
14
14
|
};
|
|
15
|
-
declare
|
|
15
|
+
declare var __VLS_49: {};
|
|
16
|
+
type __VLS_Slots = {} & {
|
|
17
|
+
trailing?: (props: typeof __VLS_49) => any;
|
|
18
|
+
};
|
|
19
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
16
20
|
clear: () => any;
|
|
17
21
|
blur: (args_0: FocusEvent) => any;
|
|
18
22
|
focus: (args_0: FocusEvent) => any;
|
|
@@ -24,8 +28,14 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
24
28
|
"onUpdate:modelValue"?: ((args_0: Date | undefined) => any) | undefined;
|
|
25
29
|
}>, {
|
|
26
30
|
size: "sm" | "md" | "lg";
|
|
27
|
-
clearIcon: string;
|
|
28
31
|
clearable: boolean;
|
|
32
|
+
clearIcon: string;
|
|
29
33
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
34
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
30
35
|
declare const _default: typeof __VLS_export;
|
|
31
36
|
export default _default;
|
|
37
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
38
|
+
new (): {
|
|
39
|
+
$slots: S;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
@@ -22,8 +22,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
22
22
|
size: "sm" | "md" | "lg";
|
|
23
23
|
granularity: "hour" | "minute" | "second";
|
|
24
24
|
hourCycle: 12 | 24;
|
|
25
|
-
clearIcon: string;
|
|
26
25
|
clearable: boolean;
|
|
26
|
+
clearIcon: string;
|
|
27
27
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
28
28
|
declare const _default: typeof __VLS_export;
|
|
29
29
|
export default _default;
|
|
@@ -22,8 +22,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
22
22
|
size: "sm" | "md" | "lg";
|
|
23
23
|
granularity: "hour" | "minute" | "second";
|
|
24
24
|
hourCycle: 12 | 24;
|
|
25
|
-
clearIcon: string;
|
|
26
25
|
clearable: boolean;
|
|
26
|
+
clearIcon: string;
|
|
27
27
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
28
28
|
declare const _default: typeof __VLS_export;
|
|
29
29
|
export default _default;
|
|
@@ -29,8 +29,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
29
29
|
"onUpdate:endValue"?: ((args_0: Date | undefined) => any) | undefined;
|
|
30
30
|
}>, {
|
|
31
31
|
size: "sm" | "md" | "lg";
|
|
32
|
-
clearIcon: string;
|
|
33
32
|
clearable: boolean;
|
|
33
|
+
clearIcon: string;
|
|
34
34
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
35
35
|
declare const _default: typeof __VLS_export;
|
|
36
36
|
export default _default;
|
|
@@ -29,8 +29,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
29
29
|
"onUpdate:endValue"?: ((args_0: Date | undefined) => any) | undefined;
|
|
30
30
|
}>, {
|
|
31
31
|
size: "sm" | "md" | "lg";
|
|
32
|
-
clearIcon: string;
|
|
33
32
|
clearable: boolean;
|
|
33
|
+
clearIcon: string;
|
|
34
34
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
35
35
|
declare const _default: typeof __VLS_export;
|
|
36
36
|
export default _default;
|
|
@@ -26,9 +26,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
26
26
|
size: "sm" | "md" | "lg";
|
|
27
27
|
granularity: "hour" | "minute" | "second";
|
|
28
28
|
hourCycle: 12 | 24;
|
|
29
|
-
rangeSeparatorIcon: string;
|
|
30
|
-
clearIcon: string;
|
|
31
29
|
clearable: boolean;
|
|
30
|
+
clearIcon: string;
|
|
31
|
+
rangeSeparatorIcon: string;
|
|
32
32
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
33
33
|
declare const _default: typeof __VLS_export;
|
|
34
34
|
export default _default;
|
|
@@ -26,9 +26,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
26
26
|
size: "sm" | "md" | "lg";
|
|
27
27
|
granularity: "hour" | "minute" | "second";
|
|
28
28
|
hourCycle: 12 | 24;
|
|
29
|
-
rangeSeparatorIcon: string;
|
|
30
|
-
clearIcon: string;
|
|
31
29
|
clearable: boolean;
|
|
30
|
+
clearIcon: string;
|
|
31
|
+
rangeSeparatorIcon: string;
|
|
32
32
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
33
33
|
declare const _default: typeof __VLS_export;
|
|
34
34
|
export default _default;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Environment } from '../vendor/cel-js/lib/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* The per-iteration CEL variables a `loop` block exposes to the blocks inside
|
|
4
|
+
* its slot: `item` (the current list element) and `index` (its 0-based
|
|
5
|
+
* position). Mirrors the form list field's row scope and the table row's
|
|
6
|
+
* `row`/`index`. `item` is always `dyn` — the element shape is backend-defined
|
|
7
|
+
* and unknowable at design time.
|
|
8
|
+
*/
|
|
9
|
+
export declare const ITEM_VAR_TYPE = "dyn";
|
|
10
|
+
export declare const ITEM_VAR_DESCRIPTION = "\u5F53\u524D\u5FAA\u73AF\u9879\uFF1B\u7531 `\u5217\u8868` \u8868\u8FBE\u5F0F\u8FD4\u56DE\u7684\u6BCF\u4E00\u9879";
|
|
11
|
+
export declare const INDEX_VAR_TYPE = "number";
|
|
12
|
+
export declare const INDEX_VAR_DESCRIPTION = "\u5F53\u524D\u5FAA\u73AF\u9879\u7D22\u5F15\uFF0C\u4ECE `0` \u5F00\u59CB";
|
|
13
|
+
/**
|
|
14
|
+
* Register the per-iteration `item` (dyn) and `index` (number) CEL variables,
|
|
15
|
+
* skipping each when an enclosing `configure` already declared it. Idempotent
|
|
16
|
+
* so a loop nested inside another loop (or any host that already exposes these
|
|
17
|
+
* names) doesn't re-register — the CEL registry throws `'item' is already
|
|
18
|
+
* registered` on a second declaration. Mirrors `registerNodeVariableIfAbsent`
|
|
19
|
+
* (share/tree-node-var.ts).
|
|
20
|
+
*/
|
|
21
|
+
export declare function registerLoopVariablesIfAbsent(env: Environment): void;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const ITEM_VAR_TYPE = "dyn";
|
|
2
|
+
export const ITEM_VAR_DESCRIPTION = "\u5F53\u524D\u5FAA\u73AF\u9879\uFF1B\u7531 `\u5217\u8868` \u8868\u8FBE\u5F0F\u8FD4\u56DE\u7684\u6BCF\u4E00\u9879";
|
|
3
|
+
export const INDEX_VAR_TYPE = "number";
|
|
4
|
+
export const INDEX_VAR_DESCRIPTION = "\u5F53\u524D\u5FAA\u73AF\u9879\u7D22\u5F15\uFF0C\u4ECE `0` \u5F00\u59CB";
|
|
5
|
+
export function registerLoopVariablesIfAbsent(env) {
|
|
6
|
+
const declared = new Set(env.getDefinitions().variables.map((v) => v.name));
|
|
7
|
+
if (!declared.has("item")) {
|
|
8
|
+
env.registerVariable("item", ITEM_VAR_TYPE, { description: ITEM_VAR_DESCRIPTION });
|
|
9
|
+
}
|
|
10
|
+
if (!declared.has("index")) {
|
|
11
|
+
env.registerVariable("index", INDEX_VAR_TYPE, { description: INDEX_VAR_DESCRIPTION });
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -10,7 +10,7 @@ When modifying this library, keep both `CLAUDE.md` and `PROMPT.md` in sync with
|
|
|
10
10
|
|
|
11
11
|
`int` and `uint` types have been removed in favor of a unified `number` type backed by `Decimal` (arbitrary-precision arithmetic via BigInt). All numeric literals, arithmetic results, and size/index returns are `Decimal` instances. The `int()`, `uint()`, and `double()` conversion functions still exist as aliases but all return `number`.
|
|
12
12
|
|
|
13
|
-
`google.protobuf.Timestamp` and `google.protobuf.Duration` have been removed. Replaced with a `Date` type backed by `TZDate` from `@date-fns/tz`, constructed via `date(string)` or `date(number)` (a Unix timestamp — the seconds-vs-milliseconds unit is auto-detected by magnitude: values `< 1e11` are read as seconds, the rest as milliseconds). Date manipulation uses date-fns functions (`startOf`, `endOf`, `offset`, `set`, `format`).
|
|
13
|
+
`google.protobuf.Timestamp` and `google.protobuf.Duration` have been removed. Replaced with a `Date` type backed by `TZDate` from `@date-fns/tz`, constructed via `date(string)` or `date(number)` (a Unix timestamp — the seconds-vs-milliseconds unit is auto-detected by magnitude: values `< 1e11` are read as seconds, the rest as milliseconds). Date manipulation uses date-fns functions (`startOf`, `endOf`, `offset`, `set`, `format`). `Date.diff(Date, string): number` returns the signed, truncated-toward-zero distance between two dates in a given unit (`millisecond` / `second` / `minute` / `hour` / `day` / `week` / `month` / `year`, plural tolerated) — the receiver is the minuend (`a.diff(b, unit)` = `a − b`, mirroring date-fns `differenceInX(left, right)`); there is no `Date − Date` operator and no duration type, so this is the way to measure elapsed time.
|
|
14
14
|
|
|
15
15
|
A `range()` built-in has been added (not from upstream) — `range(number, number)`, `range(number, number, number)` and `range(Date, Date, string)`. It builds an end-exclusive list; the direction follows the operands (counts down when `start > end`); `step` is a positive magnitude; the date unit is `year` / `month` / `day` / `hour` / `minute`. Output length is capped at 100000.
|
|
16
16
|
|
|
@@ -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.
|
|
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. The terminal methods `.json()`, `.file()`, and `.fileOrJson()` are dispatched by the host on the returned builder (none is a CEL method), so expression evaluation stays free of IO. `.fileOrJson()` branches on the response `Content-Type`: a JSON media type (`application/json` or a `+json` suffix) is parsed and returned as `{ _tag: 'json', json }`; anything else is returned as `{ _tag: 'file', file }`. Note the `Fetch` service itself `ensureOk`s (both `FetchLive` and the mock layer), so a non-2xx fails at `Fetch.fetch` before the branch and this only ever distinguishes 2xx bodies — i.e. the HTTP-200-with-error-envelope case. The download operation uses it so a backend that answers a download with a JSON error envelope (commonly `{ code: -1 }` on a 200) is classified rather than saved as the file. 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`.
|
|
@@ -234,6 +234,13 @@ d.offset(-1, "month") // 1 month earlier
|
|
|
234
234
|
d.offset(2, "weeks") // 2 weeks later
|
|
235
235
|
d.offset(1, "year") // 1 year later
|
|
236
236
|
|
|
237
|
+
// Difference between two dates (signed, truncated toward zero):
|
|
238
|
+
// receiver is the minuend, so `a.diff(b, unit)` == a − b
|
|
239
|
+
d.diff(other, "day") // whole days from other to d (negative if d is earlier)
|
|
240
|
+
d.diff(other, "hour") // whole hours
|
|
241
|
+
d.diff(other, "minute") // whole minutes
|
|
242
|
+
// units: millisecond / second / minute / hour / day / week / month / year (plural ok)
|
|
243
|
+
|
|
237
244
|
// Set specific fields:
|
|
238
245
|
d.set("day", 15) // set day of month to 15
|
|
239
246
|
d.set("month", 6) // set to June (1-based)
|
|
@@ -4,7 +4,7 @@ import { TYPES, Type } from "./registry.js";
|
|
|
4
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
|
-
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";
|
|
7
|
+
import { startOfDay, startOfWeek, startOfMonth, startOfYear, endOfDay, endOfWeek, endOfMonth, endOfYear, addDays, addWeeks, addMonths, addYears, addHours, addMinutes, setDate as setDayOfMonth, setMonth, setYear, format as formatDate, differenceInMilliseconds, differenceInSeconds, differenceInMinutes, differenceInHours, differenceInDays, differenceInWeeks, differenceInMonths, differenceInYears } from "date-fns";
|
|
8
8
|
function toNum(v) {
|
|
9
9
|
if (v instanceof Decimal) return v.toNumber();
|
|
10
10
|
if (typeof v === "bigint") return Number(v);
|
|
@@ -387,6 +387,30 @@ export function registerFunctions(registry) {
|
|
|
387
387
|
throw evaluationError("invalid_unit", `offset(): unknown unit "${unit}"`);
|
|
388
388
|
}
|
|
389
389
|
});
|
|
390
|
+
functionOverload("Date.diff(Date, string): number", (d, other, unit) => {
|
|
391
|
+
const left = d;
|
|
392
|
+
const right = other;
|
|
393
|
+
switch (unit.replace(/s$/, "")) {
|
|
394
|
+
case "millisecond":
|
|
395
|
+
return Decimal.from(differenceInMilliseconds(left, right));
|
|
396
|
+
case "second":
|
|
397
|
+
return Decimal.from(differenceInSeconds(left, right));
|
|
398
|
+
case "minute":
|
|
399
|
+
return Decimal.from(differenceInMinutes(left, right));
|
|
400
|
+
case "hour":
|
|
401
|
+
return Decimal.from(differenceInHours(left, right));
|
|
402
|
+
case "day":
|
|
403
|
+
return Decimal.from(differenceInDays(left, right));
|
|
404
|
+
case "week":
|
|
405
|
+
return Decimal.from(differenceInWeeks(left, right));
|
|
406
|
+
case "month":
|
|
407
|
+
return Decimal.from(differenceInMonths(left, right));
|
|
408
|
+
case "year":
|
|
409
|
+
return Decimal.from(differenceInYears(left, right));
|
|
410
|
+
default:
|
|
411
|
+
throw evaluationError("invalid_unit", `diff(): unknown unit "${unit}"`);
|
|
412
|
+
}
|
|
413
|
+
});
|
|
390
414
|
functionOverload("Date.set(string, number): Date", (d, field, value) => {
|
|
391
415
|
const date = d;
|
|
392
416
|
const val = toNum(value);
|
|
@@ -2,15 +2,26 @@
|
|
|
2
2
|
* `HttpRequestBuilder` — the value an `http.*` CEL expression evaluates to.
|
|
3
3
|
*
|
|
4
4
|
* A local (non-upstream) extension. A CEL expression only *describes* a
|
|
5
|
-
* request — it never issues one.
|
|
6
|
-
* `.
|
|
7
|
-
* expression evaluation free of IO.
|
|
5
|
+
* request — it never issues one. The terminal methods `.json()`, `.file()`,
|
|
6
|
+
* and `.fileOrJson()` are dispatched by the host on the returned builder,
|
|
7
|
+
* keeping expression evaluation free of IO.
|
|
8
8
|
*
|
|
9
9
|
* Endpoints are used verbatim — there is no base-URL resolution, so callers
|
|
10
10
|
* must pass absolute URLs.
|
|
11
11
|
*/
|
|
12
12
|
import { Effect } from 'effect';
|
|
13
13
|
import { Fetch } from 'fx-fetch';
|
|
14
|
+
/**
|
|
15
|
+
* The outcome of `.fileOrJson()` — discriminated on what the server actually
|
|
16
|
+
* returned, so the host can save a binary body but classify a JSON envelope.
|
|
17
|
+
*/
|
|
18
|
+
export type FileOrJson = {
|
|
19
|
+
readonly _tag: 'file';
|
|
20
|
+
readonly file: File;
|
|
21
|
+
} | {
|
|
22
|
+
readonly _tag: 'json';
|
|
23
|
+
readonly json: unknown;
|
|
24
|
+
};
|
|
14
25
|
export declare class HttpRequestBuilder {
|
|
15
26
|
#private;
|
|
16
27
|
static setDefaultHeader(name: string, value: string | (() => string | null | undefined)): void;
|
|
@@ -42,4 +53,28 @@ export declare class HttpRequestBuilder {
|
|
|
42
53
|
};
|
|
43
54
|
json(): Effect.Effect<unknown, import("fx-fetch/Cause").MalformedJsonError | Fetch.Fetch.ErrorType, Fetch.Fetch>;
|
|
44
55
|
file(): Effect.Effect<File, Fetch.Fetch.ErrorType | import("fx-fetch/Cause").MalformedBlobError, Fetch.Fetch>;
|
|
56
|
+
/**
|
|
57
|
+
* A download that branches on the response Content-Type:
|
|
58
|
+
* - JSON (`application/json` / a `+json` type) → parse the body and return
|
|
59
|
+
* `{ _tag: 'json', json }`. A download endpoint that answers with JSON has
|
|
60
|
+
* almost always returned an error envelope (e.g. `{ code: -1 }` on a 200)
|
|
61
|
+
* rather than the file — the host classifies it instead of saving the
|
|
62
|
+
* bytes. This branch deliberately does not `ensureOk`, but the `Fetch`
|
|
63
|
+
* service already does (both `FetchLive` and the mock layer), so under the
|
|
64
|
+
* standard layer a non-2xx has already failed at `Fetch.fetch` above and
|
|
65
|
+
* this branch sees only 2xx — the HTTP-200-with-error-envelope case.
|
|
66
|
+
* - anything else → the bytes are the file. `ensureOk` is kept for parity
|
|
67
|
+
* with `.file()` (redundant under the standard `Fetch` service, defensive
|
|
68
|
+
* against a layer that doesn't), then return `{ _tag: 'file', file }` with
|
|
69
|
+
* the filename from `Content-Disposition`.
|
|
70
|
+
*/
|
|
71
|
+
fileOrJson(): Effect.Effect<{
|
|
72
|
+
_tag: "json";
|
|
73
|
+
json: unknown;
|
|
74
|
+
file?: undefined;
|
|
75
|
+
} | {
|
|
76
|
+
_tag: "file";
|
|
77
|
+
file: File;
|
|
78
|
+
json?: undefined;
|
|
79
|
+
}, import("fx-fetch/Cause").MalformedJsonError | Fetch.Fetch.ErrorType | import("fx-fetch/Cause").MalformedBlobError, Fetch.Fetch>;
|
|
45
80
|
}
|
|
@@ -23,6 +23,9 @@ function normalizeBody(value) {
|
|
|
23
23
|
}
|
|
24
24
|
return value;
|
|
25
25
|
}
|
|
26
|
+
function isJsonContentType(contentType) {
|
|
27
|
+
return /application\/(?:[\w.+-]+\+)?json\b/i.test(contentType);
|
|
28
|
+
}
|
|
26
29
|
function extractFilename(response, url) {
|
|
27
30
|
const disposition = FxResponse.getHeader(response, "content-disposition");
|
|
28
31
|
if (disposition) {
|
|
@@ -126,6 +129,36 @@ export class HttpRequestBuilder {
|
|
|
126
129
|
return new File([blob], extractFilename(response, url));
|
|
127
130
|
});
|
|
128
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* A download that branches on the response Content-Type:
|
|
134
|
+
* - JSON (`application/json` / a `+json` type) → parse the body and return
|
|
135
|
+
* `{ _tag: 'json', json }`. A download endpoint that answers with JSON has
|
|
136
|
+
* almost always returned an error envelope (e.g. `{ code: -1 }` on a 200)
|
|
137
|
+
* rather than the file — the host classifies it instead of saving the
|
|
138
|
+
* bytes. This branch deliberately does not `ensureOk`, but the `Fetch`
|
|
139
|
+
* service already does (both `FetchLive` and the mock layer), so under the
|
|
140
|
+
* standard layer a non-2xx has already failed at `Fetch.fetch` above and
|
|
141
|
+
* this branch sees only 2xx — the HTTP-200-with-error-envelope case.
|
|
142
|
+
* - anything else → the bytes are the file. `ensureOk` is kept for parity
|
|
143
|
+
* with `.file()` (redundant under the standard `Fetch` service, defensive
|
|
144
|
+
* against a layer that doesn't), then return `{ _tag: 'file', file }` with
|
|
145
|
+
* the filename from `Content-Disposition`.
|
|
146
|
+
*/
|
|
147
|
+
fileOrJson() {
|
|
148
|
+
const url = this.#url;
|
|
149
|
+
const request = this.#buildRequest();
|
|
150
|
+
return Effect.gen(function* () {
|
|
151
|
+
const response = yield* Fetch.fetch(request);
|
|
152
|
+
const contentType = FxResponse.getHeader(response, "content-type")?.[0] ?? "";
|
|
153
|
+
if (isJsonContentType(contentType)) {
|
|
154
|
+
const json = yield* FxResponse.readJson(response);
|
|
155
|
+
return { _tag: "json", json };
|
|
156
|
+
}
|
|
157
|
+
yield* FxResponse.ensureOk(response);
|
|
158
|
+
const blob = yield* FxResponse.readBlob(response);
|
|
159
|
+
return { _tag: "file", file: new File([blob], extractFilename(response, url)) };
|
|
160
|
+
});
|
|
161
|
+
}
|
|
129
162
|
#buildRequest() {
|
|
130
163
|
const parts = {
|
|
131
164
|
url: this.#url,
|