@effect-app/vue-components 4.0.0-beta.310 → 4.0.0-beta.312

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.
@@ -1,15 +1,16 @@
1
1
  import * as e from "effect-app/Schema";
2
2
  //#region src/components/OmegaForm/meta/checks.ts
3
- var t = (e) => (e.checks ?? []).flatMap((e) => {
4
- if (e._tag === "FilterGroup") return e.checks.flatMap((e) => {
5
- let t = e.annotations?.meta;
6
- return t && typeof t == "object" ? [t] : [];
7
- });
8
- let t = e.annotations?.meta;
9
- return t && typeof t == "object" ? [t] : [];
10
- }), n = (n) => {
11
- let r = { description: e.AST.resolveDescription(n) }, i = t(n);
12
- if (e.AST.isString(n)) {
3
+ var t = (e) => {
4
+ let t = e.annotations?.representation;
5
+ if (t && typeof t.id == "string") return [{
6
+ _tag: t.id.replace(/^effect\/schema\//, ""),
7
+ ...t.payload !== null && typeof t.payload == "object" ? t.payload : {}
8
+ }];
9
+ let n = e.annotations?.meta;
10
+ return n && typeof n == "object" ? [n] : [];
11
+ }, n = (e) => (e.checks ?? []).flatMap((e) => e._tag === "FilterGroup" ? e.checks.flatMap((e) => t(e)) : t(e)), r = (t) => {
12
+ let r = { description: e.AST.resolveDescription(t) }, i = n(t);
13
+ if (e.AST.isString(t)) {
13
14
  r.type = "string";
14
15
  for (let e of i) switch (e._tag) {
15
16
  case "isMinLength":
@@ -19,8 +20,8 @@ var t = (e) => (e.checks ?? []).flatMap((e) => {
19
20
  r.maxLength = e.maxLength;
20
21
  break;
21
22
  }
22
- n.annotations?.format === "email" && (r.format = "email");
23
- } else if (e.AST.isNumber(n)) {
23
+ t.annotations?.format === "email" && (r.format = "email");
24
+ } else if (e.AST.isNumber(t)) {
24
25
  r.type = "number";
25
26
  for (let e of i) switch (e._tag) {
26
27
  case "isInt":
@@ -42,8 +43,8 @@ var t = (e) => (e.checks ?? []).flatMap((e) => {
42
43
  r.exclusiveMaximum = e.exclusiveMaximum;
43
44
  break;
44
45
  }
45
- } else e.AST.isBoolean(n) ? r.type = "boolean" : e.AST.isDeclaration(n) && n.annotations?.typeConstructor?._tag === "Date" ? r.type = "date" : r.type = "unknown";
46
+ } else e.AST.isBoolean(t) ? r.type = "boolean" : e.AST.isDeclaration(t) && t.annotations?.typeConstructor?._tag === "Date" ? r.type = "date" : r.type = "unknown";
46
47
  return r;
47
48
  };
48
49
  //#endregion
49
- export { n as getFieldMetadataFromAst };
50
+ export { r as getFieldMetadataFromAst };
@@ -11,7 +11,7 @@ var a = (e) => {
11
11
  return;
12
12
  }
13
13
  }, o = (e) => {
14
- let t = e.context?.defaultValue?.[0], n = a(t);
14
+ let t = e.context?.constructorDefault, n = a(t);
15
15
  if (n !== void 0) return n;
16
16
  let r = e.encoding?.[0];
17
17
  if (r && e.context?.isOptional) return a(r);
@@ -1,6 +1,10 @@
1
1
  import * as e from "effect-app/Schema";
2
2
  //#region src/components/OmegaForm/meta/redacted.ts
3
- var t = (t) => e.AST.isDeclaration(t) && t.annotations?.typeConstructor?._tag === "effect/Redacted" && !t.encoding, n = (n) => {
3
+ var t = (t) => {
4
+ if (!e.AST.isDeclaration(t) || t.encoding) return !1;
5
+ let n = t.annotations;
6
+ return n?.representation?.id === "effect/schema/Redacted" || n?.typeConstructor?._tag === "effect/Redacted";
7
+ }, n = (n) => {
4
8
  let r = n.ast, i = e.AST.isObjects(r) ? r : e.AST.isDeclaration(r) ? e.AST.toEncoded(r) : null;
5
9
  if (!i || !("propertySignatures" in i)) return n;
6
10
  let a = !1, o = {};
@@ -1,93 +1,105 @@
1
- import * as e from "effect-app/Option";
2
- import * as t from "effect-app/Schema";
1
+ import * as e from "effect-app/Schema";
3
2
  //#region src/components/OmegaForm/validation/localized.ts
4
- var n = (n) => ({
5
- leafHook: (r) => {
6
- let i = r.annotations?.message;
3
+ var t = (e) => {
4
+ let t = e.annotations?.representation;
5
+ return t && typeof t.id == "string" ? {
6
+ _tag: t.id.replace(/^effect\/schema\//, ""),
7
+ ...t.payload !== null && typeof t.payload == "object" ? t.payload : {}
8
+ } : e.annotations?.meta ?? {};
9
+ }, n = (t) => e.SchemaIssue.hasInput(t) ? t.input : void 0, r = (r) => ({
10
+ leafHook: (t) => {
11
+ let i = t.annotations?.message;
7
12
  if (i !== void 0) return String(i);
8
- switch (r._tag) {
9
- case "MissingKey": return n("validation.empty");
13
+ switch (t._tag) {
14
+ case "MissingKey": return r("validation.empty");
10
15
  case "InvalidType": {
11
- let i = r.ast;
12
- return e.isNone(r.actual) || e.isSome(r.actual) && r.actual.value === void 0 || t.AST.isString(i) ? n("validation.empty") : t.AST.isBoolean(i) ? n("validation.not_a_valid", { type: "boolean" }) : t.AST.isNumber(i) ? n("validation.number.expected", { actualValue: e.isSome(r.actual) ? String(r.actual.value) : "NaN" }) : n("validation.not_a_valid");
16
+ let i = t.ast, a = n(t);
17
+ return a === void 0 || e.AST.isString(i) ? r("validation.empty") : e.AST.isBoolean(i) ? r("validation.not_a_valid", { type: "boolean" }) : e.AST.isNumber(i) ? r("validation.number.expected", { actualValue: String(a) }) : r("validation.not_a_valid");
13
18
  }
14
- default: return n("validation.not_a_valid");
19
+ default: return r("validation.not_a_valid");
15
20
  }
16
21
  },
17
- checkHook: (e) => {
18
- if (e.filter.annotations?.identifier === "Email") return n("validation.email.invalid");
19
- let r = e.filter.annotations?.meta ?? {};
20
- switch (r._tag) {
21
- case "isMinLength": return r.minLength === 1 ? n("validation.empty") : n("validation.string.minLength", { minLength: r.minLength });
22
- case "isMaxLength": return n("validation.string.maxLength", { maxLength: r.maxLength });
23
- case "isInt": return n("validation.integer.expected", { actualValue: e.actual === void 0 ? "NaN" : String(e.actual) });
24
- case "isGreaterThanOrEqualTo": return n(r.minimum === 0 ? "validation.number.positive" : "validation.number.min", {
25
- minimum: r.minimum,
22
+ checkHook: (i) => {
23
+ if (i.filter.annotations?.identifier === "Email") return r("validation.email.invalid");
24
+ let a = t(i.filter);
25
+ switch (a._tag) {
26
+ case "isMinLength": return a.minLength === 1 ? r("validation.empty") : r("validation.string.minLength", { minLength: a.minLength });
27
+ case "isMaxLength": return r("validation.string.maxLength", { maxLength: a.maxLength });
28
+ case "isInt": {
29
+ let e = n(i);
30
+ return r("validation.integer.expected", { actualValue: e === void 0 ? "NaN" : String(e) });
31
+ }
32
+ case "isGreaterThanOrEqualTo": return r(a.minimum === 0 ? "validation.number.positive" : "validation.number.min", {
33
+ minimum: a.minimum,
26
34
  isExclusive: !0
27
35
  });
28
- case "isGreaterThan": return n(r.exclusiveMinimum === 0 ? "validation.number.positive" : "validation.number.min", {
29
- minimum: r.exclusiveMinimum,
36
+ case "isGreaterThan": return r(a.exclusiveMinimum === 0 ? "validation.number.positive" : "validation.number.min", {
37
+ minimum: a.exclusiveMinimum,
30
38
  isExclusive: !1
31
39
  });
32
- case "isLessThanOrEqualTo": return n("validation.number.max", {
33
- maximum: r.maximum,
40
+ case "isLessThanOrEqualTo": return r("validation.number.max", {
41
+ maximum: a.maximum,
34
42
  isExclusive: !0
35
43
  });
36
- case "isLessThan": return n("validation.number.max", {
37
- maximum: r.exclusiveMaximum,
44
+ case "isLessThan": return r("validation.number.max", {
45
+ maximum: a.exclusiveMaximum,
38
46
  isExclusive: !1
39
47
  });
40
- default: return t.SchemaIssue.defaultCheckHook(e);
48
+ default: return e.SchemaIssue.defaultCheckHook(i);
41
49
  }
42
50
  }
43
- }), r = (e, r) => {
44
- let { checkHook: i, leafHook: a } = n(r);
45
- return t.toStandardSchemaV1(e, {
51
+ }), i = (t, n) => {
52
+ let { checkHook: i, leafHook: a } = r(n);
53
+ return e.toStandardSchemaV1(t, {
46
54
  leafHook: a,
47
- checkHook: i
55
+ checkHook: i,
56
+ parseOptions: {
57
+ reportInput: !0,
58
+ errors: "all"
59
+ }
48
60
  });
49
- }, i = (e) => t.AST.isUnion(e) && e.types.every(t.AST.isLiteral), a = (e, n) => {
50
- if (i(e)) {
51
- if (e.annotations?.message !== void 0) return e;
52
- let r = e.types.map((e) => e.literal);
53
- return new t.AST.Union(e.types, e.mode, {
54
- ...e.annotations,
61
+ }, a = (t) => e.AST.isUnion(t) && t.types.every(e.AST.isLiteral), o = (t, n) => {
62
+ if (a(t)) {
63
+ if (t.annotations?.message !== void 0) return t;
64
+ let r = t.types.map((e) => e.literal);
65
+ return new e.AST.Union(t.types, t.mode, {
66
+ ...t.annotations,
55
67
  message: n("validation.not_a_valid", {
56
68
  type: "select",
57
69
  message: r.join(", ")
58
70
  })
59
- }, e.checks, e.encoding, e.context);
71
+ }, t.checks, t.encoding, t.context);
60
72
  }
61
- if (t.AST.isUnion(e)) {
62
- let r = e.types.map((e) => a(e, n));
63
- return r.some((t, n) => t !== e.types[n]) ? new t.AST.Union(r, e.mode, e.annotations, e.checks, e.encoding, e.context) : e;
73
+ if (e.AST.isUnion(t)) {
74
+ let r = t.types.map((e) => o(e, n));
75
+ return r.some((e, n) => e !== t.types[n]) ? new e.AST.Union(r, t.mode, t.annotations, t.checks, t.encoding, t.context) : t;
64
76
  }
65
- if (t.AST.isArrays(e)) {
66
- let r = e.rest.map((e) => a(e, n)), o = e.elements.map((e) => a(e, n)), s = e.annotations;
67
- if (e.annotations?.message === void 0 && e.rest.length === 1 && i(e.rest[0])) {
68
- let t = e.rest[0].types.map((e) => e.literal);
77
+ if (e.AST.isArrays(t)) {
78
+ let r = t.rest.map((e) => o(e, n)), i = t.elements.map((e) => o(e, n)), s = t.annotations;
79
+ if (t.annotations?.message === void 0 && t.rest.length === 1 && a(t.rest[0])) {
80
+ let e = t.rest[0].types.map((e) => e.literal);
69
81
  s = {
70
- ...e.annotations,
82
+ ...t.annotations,
71
83
  message: n("validation.not_a_valid", {
72
84
  type: "multiple",
73
- message: t.join(", ")
85
+ message: e.join(", ")
74
86
  })
75
87
  };
76
88
  }
77
- let c = r.some((t, n) => t !== e.rest[n]), l = o.some((t, n) => t !== e.elements[n]);
78
- return !c && !l && s === e.annotations ? e : new t.AST.Arrays(e.isMutable, o, r, s, e.checks, e.encoding, e.context);
89
+ let c = r.some((e, n) => e !== t.rest[n]), l = i.some((e, n) => e !== t.elements[n]);
90
+ return !c && !l && s === t.annotations ? t : new e.AST.Arrays(t.isMutable, i, r, s, t.checks, t.encoding, t.context);
79
91
  }
80
- if (t.AST.isObjects(e)) {
81
- let r = e.propertySignatures.map((e) => {
82
- let r = a(e.type, n);
83
- return r === e.type ? e : new t.AST.PropertySignature(e.name, r);
92
+ if (e.AST.isObjects(t)) {
93
+ let r = t.propertySignatures.map((t) => {
94
+ let r = o(t.type, n);
95
+ return r === t.type ? t : new e.AST.PropertySignature(t.name, r);
84
96
  });
85
- return r.some((t, n) => t !== e.propertySignatures[n]) ? new t.AST.Objects(r, e.indexSignatures, e.annotations, e.checks, e.encoding, e.context) : e;
97
+ return r.some((e, n) => e !== t.propertySignatures[n]) ? new e.AST.Objects(r, t.indexSignatures, t.annotations, t.checks, t.encoding, t.context) : t;
86
98
  }
87
- return e;
88
- }, o = (e, n) => {
89
- let r = a(e.ast, n);
90
- return r === e.ast ? e : t.make(r);
99
+ return t;
100
+ }, s = (t, n) => {
101
+ let r = o(t.ast, n);
102
+ return r === t.ast ? t : e.make(r);
91
103
  };
92
104
  //#endregion
93
- export { o as annotateLiteralUnionMessages, n as makeStandardSchemaV1Hooks, r as toLocalizedStandardSchemaV1 };
105
+ export { s as annotateLiteralUnionMessages, r as makeStandardSchemaV1Hooks, i as toLocalizedStandardSchemaV1 };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect-app/vue-components",
3
- "version": "4.0.0-beta.310",
3
+ "version": "4.0.0-beta.312",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/effect-app/libs.git",
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "peerDependencies": {
10
10
  "@mdi/js": "^7.4.47",
11
- "effect": "^4.0.0-beta.90",
11
+ "effect": "^4.0.0-beta.107",
12
12
  "intl-messageformat": "^11.2.7",
13
13
  "mdi-js": "^1.0.1",
14
14
  "primeflex": "^4.0.0",
@@ -62,8 +62,8 @@
62
62
  "highlight.js": "^11.11.1",
63
63
  "mitt": "^3.0.1",
64
64
  "vue3-highlightjs": "^1.0.5",
65
- "@effect-app/vue": "4.0.0-beta.310",
66
- "effect-app": "4.0.0-beta.310"
65
+ "@effect-app/vue": "4.0.0-beta.312",
66
+ "effect-app": "4.0.0-beta.312"
67
67
  },
68
68
  "scripts": {
69
69
  "check": "vue-tsc",
@@ -3,19 +3,41 @@ import * as S from "effect-app/Schema"
3
3
  import type * as Record from "effect/Record"
4
4
  import type { FieldMeta } from "./types"
5
5
 
6
+ /**
7
+ * Normalise a filter annotation into the meta shape used by field metadata
8
+ * extractors (`{ _tag: "isMinLength", minLength: n }`, …).
9
+ *
10
+ * Since effect beta.91+, filters expose `annotations.representation`
11
+ * (`{ id: "effect/schema/isMinLength", payload: { minLength } }`) instead of
12
+ * the older `annotations.meta` bag.
13
+ */
14
+ const metaFromFilter = (check: {
15
+ readonly annotations?: {
16
+ readonly meta?: unknown
17
+ readonly representation?: { readonly id?: string; readonly payload?: unknown }
18
+ }
19
+ }): Array<Record<string, any>> => {
20
+ const rep = check.annotations?.representation
21
+ if (rep && typeof rep.id === "string") {
22
+ const tag = rep.id.replace(/^effect\/schema\//, "")
23
+ const payload = rep.payload !== null && typeof rep.payload === "object"
24
+ ? rep.payload as Record<string, any>
25
+ : {}
26
+ return [{ _tag: tag, ...payload }]
27
+ }
28
+
29
+ const meta = check.annotations?.meta
30
+ return meta && typeof meta === "object" ? [meta as Record<string, any>] : []
31
+ }
32
+
6
33
  export const getCheckMetas = (property: S.AST.AST): Array<Record<string, any>> => {
7
34
  const checks = property.checks ?? []
8
35
 
9
36
  return checks.flatMap((check) => {
10
37
  if (check._tag === "FilterGroup") {
11
- return check.checks.flatMap((inner) => {
12
- const meta = inner.annotations?.meta
13
- return meta && typeof meta === "object" ? [meta as Record<string, any>] : []
14
- })
38
+ return check.checks.flatMap((inner) => metaFromFilter(inner))
15
39
  }
16
-
17
- const meta = check.annotations?.meta
18
- return meta && typeof meta === "object" ? [meta as Record<string, any>] : []
40
+ return metaFromFilter(check)
19
41
  })
20
42
  }
21
43
 
@@ -16,8 +16,9 @@ const extractDefaultFromLink = (link: any): unknown | undefined => {
16
16
  }
17
17
 
18
18
  const getDefaultFromAst = (property: S.AST.AST) => {
19
- // 1. Check withConstructorDefault (stored in context.defaultValue)
20
- const constructorLink = property.context?.defaultValue?.[0]
19
+ // 1. Check withConstructorDefault (context.constructorDefault is a single Link since beta.107;
20
+ // previously context.defaultValue was an Encoding tuple of Links)
21
+ const constructorLink = property.context?.constructorDefault
21
22
  const constructorDefault = extractDefaultFromLink(constructorLink)
22
23
  if (constructorDefault !== undefined) return constructorDefault
23
24
 
@@ -4,12 +4,17 @@ import * as S from "effect-app/Schema"
4
4
  * Checks if an AST node is a S.Redacted Declaration without encoding.
5
5
  * These need to be swapped to S.RedactedFromValue for form usage
6
6
  * because S.Redacted expects Redacted objects, not plain strings.
7
+ *
8
+ * Detection uses `annotations.representation.id` (beta.107+); the older
9
+ * `typeConstructor._tag === "effect/Redacted"` path is kept as a fallback.
7
10
  */
8
- const isRedactedWithoutEncoding = (ast: S.AST.AST): boolean =>
9
- S.AST.isDeclaration(ast)
11
+ const isRedactedWithoutEncoding = (ast: S.AST.AST): boolean => {
12
+ if (!S.AST.isDeclaration(ast) || ast.encoding) return false
10
13
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Effect Schema AST annotations are loosely typed
11
- && (ast.annotations as any)?.typeConstructor?._tag === "effect/Redacted"
12
- && !ast.encoding
14
+ const annotations = ast.annotations as any
15
+ return annotations?.representation?.id === "effect/schema/Redacted"
16
+ || annotations?.typeConstructor?._tag === "effect/Redacted"
17
+ }
13
18
 
14
19
  /*
15
20
  * Creates a form-compatible schema by replacing S.Redacted(X) with
@@ -1,6 +1,5 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
  import type { StandardSchemaV1 } from "@tanstack/vue-form"
3
- import * as Option from "effect-app/Option"
4
3
  import * as S from "effect-app/Schema"
5
4
  import type { useIntl } from "../../../utils"
6
5
 
@@ -16,6 +15,26 @@ type FilterMeta =
16
15
  | { readonly _tag: "isLessThan"; readonly exclusiveMaximum: number }
17
16
  | { readonly _tag?: undefined }
18
17
 
18
+ /** Map filter annotations (representation since beta.107, legacy meta before) to FilterMeta. */
19
+ const filterMetaOf = (filter: {
20
+ readonly annotations?: {
21
+ readonly meta?: unknown
22
+ readonly representation?: { readonly id?: string; readonly payload?: unknown }
23
+ }
24
+ }): FilterMeta => {
25
+ const rep = filter.annotations?.representation
26
+ if (rep && typeof rep.id === "string") {
27
+ const tag = rep.id.replace(/^effect\/schema\//, "")
28
+ const payload = rep.payload !== null && typeof rep.payload === "object"
29
+ ? rep.payload as Record<string, unknown>
30
+ : {}
31
+ return { _tag: tag, ...payload } as FilterMeta
32
+ }
33
+ return (filter.annotations?.meta ?? {})
34
+ }
35
+
36
+ const reportedInput = (issue: S.SchemaIssue.Issue): unknown => S.SchemaIssue.hasInput(issue) ? issue.input : undefined
37
+
19
38
  export const makeStandardSchemaV1Hooks = (
20
39
  trans: TransFn
21
40
  ): {
@@ -31,14 +50,13 @@ export const makeStandardSchemaV1Hooks = (
31
50
  case "InvalidType": {
32
51
  const ast = issue.ast
33
52
  // Detect undefined/missing actual values across required leaves and return a uniform empty message.
34
- const actualUndefined = Option.isNone(issue.actual)
35
- || (Option.isSome(issue.actual) && issue.actual.value === undefined)
53
+ const input = reportedInput(issue)
54
+ const actualUndefined = input === undefined
36
55
  if (actualUndefined) return trans("validation.empty")
37
56
  if (S.AST.isString(ast)) return trans("validation.empty")
38
57
  if (S.AST.isBoolean(ast)) return trans("validation.not_a_valid", { type: "boolean" })
39
58
  if (S.AST.isNumber(ast)) {
40
- const actual = Option.isSome(issue.actual) ? String(issue.actual.value) : "NaN"
41
- return trans("validation.number.expected", { actualValue: actual })
59
+ return trans("validation.number.expected", { actualValue: String(input) })
42
60
  }
43
61
  return trans("validation.not_a_valid")
44
62
  }
@@ -48,13 +66,13 @@ export const makeStandardSchemaV1Hooks = (
48
66
  }
49
67
 
50
68
  const checkHook: S.SchemaIssue.CheckHook = (issue) => {
51
- // S.Email's `refine(isValidEmail, ...)` has no `meta._tag` but carries
69
+ // S.Email's `refine(isValidEmail, ...)` has no representation meta but carries
52
70
  // `identifier: "Email"`. Localize it explicitly — otherwise the
53
71
  // formatter falls back to the generic "Expected <filter>, got <actual>".
54
72
  if (issue.filter.annotations?.identifier === "Email") {
55
73
  return trans("validation.email.invalid")
56
74
  }
57
- const meta = (issue.filter.annotations?.meta ?? {}) as FilterMeta
75
+ const meta = filterMetaOf(issue.filter)
58
76
  switch (meta._tag) {
59
77
  case "isMinLength":
60
78
  return meta.minLength === 1
@@ -63,7 +81,8 @@ export const makeStandardSchemaV1Hooks = (
63
81
  case "isMaxLength":
64
82
  return trans("validation.string.maxLength", { maxLength: meta.maxLength })
65
83
  case "isInt": {
66
- const actual = issue.actual !== undefined ? String(issue.actual) : "NaN"
84
+ const input = reportedInput(issue)
85
+ const actual = input !== undefined ? String(input) : "NaN"
67
86
  return trans("validation.integer.expected", { actualValue: actual })
68
87
  }
69
88
  case "isGreaterThanOrEqualTo":
@@ -97,7 +116,12 @@ export const toLocalizedStandardSchemaV1 = <To, From>(
97
116
  trans: TransFn
98
117
  ): StandardSchemaV1<From, To> => {
99
118
  const { checkHook, leafHook } = makeStandardSchemaV1Hooks(trans)
100
- return S.toStandardSchemaV1(schema, { leafHook, checkHook })
119
+ // reportInput so leaf/check hooks can include the rejected value in messages
120
+ return S.toStandardSchemaV1(schema, {
121
+ leafHook,
122
+ checkHook,
123
+ parseOptions: { reportInput: true, errors: "all" }
124
+ })
101
125
  }
102
126
 
103
127
  /*