@effect-app/vue-components 4.0.0-beta.93 → 4.0.0-beta.95
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.
|
@@ -91,6 +91,14 @@ export type FieldValidators<T> = {
|
|
|
91
91
|
export type BaseFieldMeta = {
|
|
92
92
|
required: boolean;
|
|
93
93
|
nullableOrUndefined?: false | "undefined" | "null";
|
|
94
|
+
/**
|
|
95
|
+
* True when the schema property is `S.optionalKey` (AST
|
|
96
|
+
* `context.isOptional`) — i.e. the key should be ABSENT from the submitted
|
|
97
|
+
* object when empty, not present with `undefined`. Distinct from
|
|
98
|
+
* `required: false`, which may also mean "empty string is valid" for
|
|
99
|
+
* unconstrained `S.String` fields.
|
|
100
|
+
*/
|
|
101
|
+
isOptionalKey?: boolean;
|
|
94
102
|
};
|
|
95
103
|
export type StringFieldMeta = BaseFieldMeta & {
|
|
96
104
|
type: "string";
|
|
@@ -79,9 +79,9 @@ var o = /* @__PURE__ */ new Set(), s = () => globalThis.process?.env?.NODE_ENV !
|
|
|
79
79
|
});
|
|
80
80
|
if (r) {
|
|
81
81
|
for (let n of r) {
|
|
82
|
-
let r = t ? `${t}.${n.name.toString()}` : n.name.toString(), o = f(n.type), s;
|
|
83
|
-
|
|
84
|
-
let
|
|
82
|
+
let r = t ? `${t}.${n.name.toString()}` : n.name.toString(), o = f(n.type), s = n.type.context?.isOptional === !0, l;
|
|
83
|
+
l = e._isNullableDiscriminatedUnion && n.name.toString() === "_tag" || e.required === !1 || s ? !1 : !o;
|
|
84
|
+
let u = c(n.type);
|
|
85
85
|
if (a.AST.isUnion(n.type)) {
|
|
86
86
|
let e = m(n.type.types);
|
|
87
87
|
if (e.some(a.AST.isObjects)) {
|
|
@@ -89,7 +89,7 @@ var o = /* @__PURE__ */ new Set(), s = () => globalThis.process?.env?.NODE_ENV !
|
|
|
89
89
|
parent: r,
|
|
90
90
|
property: n.type,
|
|
91
91
|
meta: {
|
|
92
|
-
required:
|
|
92
|
+
required: l,
|
|
93
93
|
nullableOrUndefined: o
|
|
94
94
|
}
|
|
95
95
|
}));
|
|
@@ -112,7 +112,7 @@ var o = /* @__PURE__ */ new Set(), s = () => globalThis.process?.env?.NODE_ENV !
|
|
|
112
112
|
type: "multiple",
|
|
113
113
|
members: e.elements,
|
|
114
114
|
rest: e.rest,
|
|
115
|
-
required:
|
|
115
|
+
required: l,
|
|
116
116
|
nullableOrUndefined: o
|
|
117
117
|
}, e.rest && e.rest.length > 0) {
|
|
118
118
|
let t = c(e.rest[0]);
|
|
@@ -145,16 +145,16 @@ var o = /* @__PURE__ */ new Set(), s = () => globalThis.process?.env?.NODE_ENV !
|
|
|
145
145
|
parent: r,
|
|
146
146
|
property: n.type,
|
|
147
147
|
meta: {
|
|
148
|
-
required:
|
|
148
|
+
required: l,
|
|
149
149
|
nullableOrUndefined: o
|
|
150
150
|
}
|
|
151
151
|
});
|
|
152
152
|
}
|
|
153
|
-
} else if (a.AST.isObjects(
|
|
153
|
+
} else if (a.AST.isObjects(u)) Object.assign(i, b({
|
|
154
154
|
parent: r,
|
|
155
|
-
propertySignatures:
|
|
155
|
+
propertySignatures: u.propertySignatures,
|
|
156
156
|
meta: {
|
|
157
|
-
required:
|
|
157
|
+
required: l,
|
|
158
158
|
nullableOrUndefined: o
|
|
159
159
|
}
|
|
160
160
|
}));
|
|
@@ -195,15 +195,16 @@ var o = /* @__PURE__ */ new Set(), s = () => globalThis.process?.env?.NODE_ENV !
|
|
|
195
195
|
type: "multiple",
|
|
196
196
|
members: n.type.elements,
|
|
197
197
|
rest: n.type.rest,
|
|
198
|
-
required:
|
|
198
|
+
required: l,
|
|
199
199
|
nullableOrUndefined: o
|
|
200
200
|
};
|
|
201
201
|
else i[r] = b({
|
|
202
202
|
parent: r,
|
|
203
203
|
property: n.type,
|
|
204
204
|
meta: {
|
|
205
|
-
required:
|
|
206
|
-
nullableOrUndefined: o
|
|
205
|
+
required: l && (!a.AST.isString(u) || !!y(u).minLength),
|
|
206
|
+
nullableOrUndefined: o,
|
|
207
|
+
...s ? { isOptionalKey: !0 } : {}
|
|
207
208
|
}
|
|
208
209
|
});
|
|
209
210
|
}
|
|
@@ -33,7 +33,8 @@ var b = /* @__PURE__ */ o({
|
|
|
33
33
|
id: D
|
|
34
34
|
})));
|
|
35
35
|
let j = t(() => k.value[b.field.name]?.errors ?? []), M = t(() => j.value.map((e) => e?.message).filter(Boolean)), N = (e) => e == null || e === !1 || e === "" || Number.isNaN(e), P = (e) => {
|
|
36
|
-
|
|
36
|
+
let t = !1;
|
|
37
|
+
N(e) && b.meta?.type !== "boolean" ? b.meta?.nullableOrUndefined ? b.field.handleChange(b.meta.nullableOrUndefined === "undefined" ? void 0 : null) : b.meta?.isOptionalKey ? (b.field.form.deleteField(b.field.name), t = !0) : b.field.handleChange(e) : b.field.handleChange(e), t || b.field.setMeta((e) => ({
|
|
37
38
|
...e,
|
|
38
39
|
errorMap: {
|
|
39
40
|
...e.errorMap,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect-app/vue-components",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.95",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"@mdi/js": "^7.4.47",
|
|
6
6
|
"effect": "^4.0.0-beta.47",
|
|
@@ -58,8 +58,8 @@
|
|
|
58
58
|
"highlight.js": "^11.11.1",
|
|
59
59
|
"mitt": "^3.0.1",
|
|
60
60
|
"vue3-highlightjs": "^1.0.5",
|
|
61
|
-
"
|
|
62
|
-
"effect-app": "4.0.0-beta.
|
|
61
|
+
"effect-app": "4.0.0-beta.95",
|
|
62
|
+
"@effect-app/vue": "4.0.0-beta.95"
|
|
63
63
|
},
|
|
64
64
|
"scripts": {
|
|
65
65
|
"check": "vue-tsc",
|
|
@@ -256,6 +256,14 @@ export type FieldValidators<T> = {
|
|
|
256
256
|
export type BaseFieldMeta = {
|
|
257
257
|
required: boolean
|
|
258
258
|
nullableOrUndefined?: false | "undefined" | "null"
|
|
259
|
+
/**
|
|
260
|
+
* True when the schema property is `S.optionalKey` (AST
|
|
261
|
+
* `context.isOptional`) — i.e. the key should be ABSENT from the submitted
|
|
262
|
+
* object when empty, not present with `undefined`. Distinct from
|
|
263
|
+
* `required: false`, which may also mean "empty string is valid" for
|
|
264
|
+
* unconstrained `S.String` fields.
|
|
265
|
+
*/
|
|
266
|
+
isOptionalKey?: boolean
|
|
259
267
|
}
|
|
260
268
|
|
|
261
269
|
export type StringFieldMeta = BaseFieldMeta & {
|
|
@@ -519,6 +527,8 @@ export const createMeta = <T = any>(
|
|
|
519
527
|
const key = parent ? `${parent}.${p.name.toString()}` : p.name.toString()
|
|
520
528
|
const nullableOrUndefined = isNullableOrUndefined(p.type)
|
|
521
529
|
|
|
530
|
+
const isOptionalKey = (p.type as any).context?.isOptional === true
|
|
531
|
+
|
|
522
532
|
// Determine if this field should be required:
|
|
523
533
|
// - For nullable discriminated unions, only _tag should be non-required
|
|
524
534
|
// - optionalKey fields are not required
|
|
@@ -530,7 +540,7 @@ export const createMeta = <T = any>(
|
|
|
530
540
|
} else if (meta.required === false) {
|
|
531
541
|
// Explicitly set to non-required (legacy behavior for backwards compatibility)
|
|
532
542
|
isRequired = false
|
|
533
|
-
} else if (
|
|
543
|
+
} else if (isOptionalKey) {
|
|
534
544
|
isRequired = false
|
|
535
545
|
} else {
|
|
536
546
|
// Calculate from the property itself
|
|
@@ -741,7 +751,8 @@ export const createMeta = <T = any>(
|
|
|
741
751
|
// TODO: handle this better via the createMeta minLength parsing
|
|
742
752
|
required: isRequired
|
|
743
753
|
&& (!S.AST.isString(typeToProcess) || !!getFieldMetadataFromAst(typeToProcess).minLength),
|
|
744
|
-
nullableOrUndefined
|
|
754
|
+
nullableOrUndefined,
|
|
755
|
+
...(isOptionalKey ? { isOptionalKey: true } : {})
|
|
745
756
|
}
|
|
746
757
|
})
|
|
747
758
|
|
|
@@ -119,6 +119,7 @@ const isFalsyButNotZero = (value: unknown): boolean => {
|
|
|
119
119
|
// we remove value and errors when the field is empty and not required
|
|
120
120
|
// convert nullish value to null or undefined based on schema
|
|
121
121
|
const handleChange: OmegaFieldInternalApi<From, Name>["handleChange"] = (value) => {
|
|
122
|
+
let fieldDeleted = false
|
|
122
123
|
if (isFalsyButNotZero(value) && props.meta?.type !== "boolean") {
|
|
123
124
|
// Only convert to null/undefined if the field is actually nullable or optional
|
|
124
125
|
if (props.meta?.nullableOrUndefined) {
|
|
@@ -128,6 +129,14 @@ const handleChange: OmegaFieldInternalApi<From, Name>["handleChange"] = (value)
|
|
|
128
129
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
129
130
|
: null as any
|
|
130
131
|
)
|
|
132
|
+
} else if (props.meta?.isOptionalKey) {
|
|
133
|
+
// `S.optionalKey` expects the key to be ABSENT from the submitted
|
|
134
|
+
// object, not present-with-undefined. Remove it from form state
|
|
135
|
+
// rather than setting it to `undefined`. Note: this is distinct
|
|
136
|
+
// from `required: false`, which may also just mean "empty string
|
|
137
|
+
// is valid" for unconstrained `S.String` fields.
|
|
138
|
+
props.field.form.deleteField(props.field.name)
|
|
139
|
+
fieldDeleted = true
|
|
131
140
|
} else {
|
|
132
141
|
// Keep the actual value (e.g., empty string for S.String fields)
|
|
133
142
|
props.field.handleChange(value)
|
|
@@ -138,7 +147,10 @@ const handleChange: OmegaFieldInternalApi<From, Name>["handleChange"] = (value)
|
|
|
138
147
|
|
|
139
148
|
// whenever we change the field, regardless if we set it to null, we should reset onSubmit.
|
|
140
149
|
// not sure why this is not the case in tanstack form.
|
|
141
|
-
|
|
150
|
+
// Skip when the field was deleted — its meta no longer exists in the form store.
|
|
151
|
+
if (!fieldDeleted) {
|
|
152
|
+
props.field.setMeta((m) => ({ ...m, errorMap: { ...m.errorMap, onSubmit: undefined } }))
|
|
153
|
+
}
|
|
142
154
|
}
|
|
143
155
|
|
|
144
156
|
// Note: Default value normalization (converting empty strings to null/undefined for nullable fields)
|