@effect-app/vue 2.93.8 → 2.94.0
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/CHANGELOG.md +11 -0
- package/package.json +19 -19
- package/test/dist/stubs.d.ts +1 -1
- package/test/form-validation-errors.test.ts +102 -43
- package/tsconfig.json +3 -1
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect-app/vue",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.94.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"homepage": "https://github.com/effect-ts-app/libs/tree/main/packages/vue",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@formatjs/intl": "^
|
|
8
|
+
"@formatjs/intl": "^4.1.0",
|
|
9
9
|
"@tanstack/query-core": "5.83.1",
|
|
10
10
|
"@tanstack/vue-query": "5.83.1",
|
|
11
|
-
"@vueuse/core": "^14.
|
|
11
|
+
"@vueuse/core": "^14.1.0",
|
|
12
12
|
"change-case": "^5.4.4",
|
|
13
13
|
"query-string": "^9.3.1",
|
|
14
|
-
"effect-app": "3.
|
|
14
|
+
"effect-app": "3.16.0"
|
|
15
15
|
},
|
|
16
16
|
"peerDependencies": {
|
|
17
|
-
"@effect-atom/atom": "^0.4.
|
|
18
|
-
"@effect-atom/atom-vue": "^0.4.
|
|
19
|
-
"@effect/platform": "^0.
|
|
20
|
-
"@effect/platform-browser": "^0.
|
|
21
|
-
"@sentry/browser": "^10.
|
|
22
|
-
"effect": "^3.19.
|
|
23
|
-
"vue": "^3.5.
|
|
17
|
+
"@effect-atom/atom": "^0.4.13",
|
|
18
|
+
"@effect-atom/atom-vue": "^0.4.5",
|
|
19
|
+
"@effect/platform": "^0.94.1",
|
|
20
|
+
"@effect/platform-browser": "^0.74.0",
|
|
21
|
+
"@sentry/browser": "^10.34.0",
|
|
22
|
+
"effect": "^3.19.14",
|
|
23
|
+
"vue": "^3.5.26"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@effect/vitest": "^0.27.0",
|
|
27
|
-
"@formatjs/icu-messageformat-parser": "^
|
|
28
|
-
"@types/node": "
|
|
29
|
-
"@vitejs/plugin-vue": "^6.0.
|
|
30
|
-
"intl-messageformat": "^
|
|
27
|
+
"@formatjs/icu-messageformat-parser": "^3.4.0",
|
|
28
|
+
"@types/node": "25.0.8",
|
|
29
|
+
"@vitejs/plugin-vue": "^6.0.3",
|
|
30
|
+
"intl-messageformat": "^11.1.0",
|
|
31
31
|
"json5": "^2.2.3",
|
|
32
32
|
"typescript": "~5.9.3",
|
|
33
|
-
"vite": "^7.
|
|
34
|
-
"vitest": "^4.0.
|
|
35
|
-
"@effect-app/eslint-shared-config": "0.
|
|
33
|
+
"vite": "^7.3.1",
|
|
34
|
+
"vitest": "^4.0.17",
|
|
35
|
+
"@effect-app/eslint-shared-config": "0.5.0"
|
|
36
36
|
},
|
|
37
37
|
"typesVersions": {
|
|
38
38
|
"*": {
|
|
@@ -139,6 +139,6 @@
|
|
|
139
139
|
"testsuite": "pnpm lint && pnpm circular && pnpm run test:run",
|
|
140
140
|
"ncu": "ncu",
|
|
141
141
|
"pub": "pnpm prepublish && npm publish --access public",
|
|
142
|
-
"prepublish": "
|
|
142
|
+
"prepublish": "cp -f ./tsconfig.json ./tsconfig.json.bak && node ../../scripts/mergeTsConfig.mjs ./tsconfig.json"
|
|
143
143
|
}
|
|
144
144
|
}
|
package/test/dist/stubs.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export declare const fakeIntlLayer: (messages?: Record<string, string> | Record<
|
|
|
13
13
|
export declare const useExperimental: (options?: {
|
|
14
14
|
messages?: Record<string, string> | Record<string, MessageFormatElement[]>;
|
|
15
15
|
toasts: any[];
|
|
16
|
-
}) => import("../src/experimental/makeUseCommand.js").CommanderResolved<Toast.Toast | I18n
|
|
16
|
+
}) => import("../src/experimental/makeUseCommand.js").CommanderResolved<WithToast | Toast.Toast | I18n, never>;
|
|
17
17
|
declare const RequestContextMap_base: (new () => {
|
|
18
18
|
readonly config: {};
|
|
19
19
|
}) & {
|
|
@@ -8,74 +8,133 @@ class TestSchema extends S.Class<TestSchema>("TestSchema")({
|
|
|
8
8
|
stringField: S.String
|
|
9
9
|
}) {}
|
|
10
10
|
|
|
11
|
-
//
|
|
11
|
+
// translation dictionaries
|
|
12
|
+
const translations: Record<string, Record<string, string>> = {
|
|
13
|
+
en: {
|
|
14
|
+
"validation.integer.expected": "Expected an integer, actual {actualValue}",
|
|
15
|
+
"validation.number.expected": "Expected a number, actual {actualValue}"
|
|
16
|
+
},
|
|
17
|
+
de: {
|
|
18
|
+
"validation.integer.expected": "Es wird eine ganze Zahl erwartet, tatsächlich: {actualValue}",
|
|
19
|
+
"validation.number.expected": "Es wird eine Zahl erwartet, tatsächlich: {actualValue}"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// mock translate function to capture translation calls and return actual translated string
|
|
12
24
|
const translationCalls: Array<{ id: string; defaultMessage: string; params?: any }> = []
|
|
25
|
+
let currentLocale = "en"
|
|
26
|
+
|
|
13
27
|
const mockTranslate = (msg: { id: string; defaultMessage: string }, params?: any) => {
|
|
14
28
|
translationCalls.push({ id: msg.id, defaultMessage: msg.defaultMessage, params })
|
|
15
|
-
|
|
16
|
-
|
|
29
|
+
|
|
30
|
+
// get the translation template
|
|
31
|
+
const template = translations[currentLocale]?.[msg.id] || msg.defaultMessage
|
|
32
|
+
|
|
33
|
+
// replace parameters in the template
|
|
34
|
+
if (params) {
|
|
35
|
+
return Object.entries(params).reduce((result, [key, value]) => {
|
|
36
|
+
return result.replace(`{${key}}`, String(value))
|
|
37
|
+
}, template)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return template
|
|
17
41
|
}
|
|
18
42
|
|
|
19
43
|
beforeEach(() => {
|
|
20
44
|
translationCalls.length = 0
|
|
45
|
+
currentLocale = "en"
|
|
21
46
|
translate.value = mockTranslate as any
|
|
22
47
|
})
|
|
23
48
|
|
|
24
|
-
it("validates integer field with decimal value", () =>
|
|
25
|
-
Effect
|
|
26
|
-
|
|
27
|
-
|
|
49
|
+
it("validates integer field with decimal value (English)", () =>
|
|
50
|
+
Effect
|
|
51
|
+
.gen(function*() {
|
|
52
|
+
currentLocale = "en"
|
|
53
|
+
const fieldInfo = buildFieldInfoFromFieldsRoot(TestSchema)
|
|
54
|
+
const integerFieldInfo = fieldInfo.fields.integerField
|
|
55
|
+
|
|
56
|
+
expect(integerFieldInfo._tag).toBe("FieldInfo")
|
|
57
|
+
expect(integerFieldInfo.type).toBe("int")
|
|
58
|
+
|
|
59
|
+
// test validation rules with a decimal value
|
|
60
|
+
const result = integerFieldInfo.rules[1] ? integerFieldInfo.rules[1]("59.5") : undefined
|
|
61
|
+
|
|
62
|
+
console.log("Validation result (EN):", result)
|
|
63
|
+
console.log("Translation calls:", translationCalls)
|
|
64
|
+
|
|
65
|
+
// the validation should fail
|
|
66
|
+
expect(result).not.toBe(true)
|
|
67
|
+
expect(typeof result).toBe("string")
|
|
68
|
+
|
|
69
|
+
// check if the correct translation key was called
|
|
70
|
+
const integerErrorCall = translationCalls.find((call) => call.id === "validation.integer.expected")
|
|
71
|
+
expect(integerErrorCall).toBeDefined()
|
|
72
|
+
expect(integerErrorCall?.params).toHaveProperty("actualValue")
|
|
73
|
+
expect(integerErrorCall?.params.actualValue).toBe("59.5")
|
|
74
|
+
|
|
75
|
+
// MOST IMPORTANT: verify the actual translated string returned
|
|
76
|
+
expect(result).toBe("Expected an integer, actual 59.5")
|
|
77
|
+
})
|
|
78
|
+
.pipe(Effect.runPromise))
|
|
79
|
+
|
|
80
|
+
it("validates integer field with decimal value (German)", () =>
|
|
81
|
+
Effect
|
|
82
|
+
.gen(function*() {
|
|
83
|
+
currentLocale = "de"
|
|
84
|
+
const fieldInfo = buildFieldInfoFromFieldsRoot(TestSchema)
|
|
85
|
+
const integerFieldInfo = fieldInfo.fields.integerField
|
|
28
86
|
|
|
29
|
-
|
|
30
|
-
|
|
87
|
+
expect(integerFieldInfo._tag).toBe("FieldInfo")
|
|
88
|
+
expect(integerFieldInfo.type).toBe("int")
|
|
31
89
|
|
|
32
|
-
|
|
33
|
-
|
|
90
|
+
// test validation rules with a decimal value
|
|
91
|
+
const result = integerFieldInfo.rules[1] ? integerFieldInfo.rules[1]("59.5") : undefined
|
|
34
92
|
|
|
35
|
-
|
|
36
|
-
console.log("Translation calls:", translationCalls)
|
|
93
|
+
console.log("Validation result (DE):", result)
|
|
37
94
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
95
|
+
// the validation should fail
|
|
96
|
+
expect(result).not.toBe(true)
|
|
97
|
+
expect(typeof result).toBe("string")
|
|
41
98
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
expect(integerErrorCall?.params.actualValue).toBe("59.5")
|
|
47
|
-
}).pipe(Effect.runPromise))
|
|
99
|
+
// MOST IMPORTANT: verify the actual German translated string returned
|
|
100
|
+
expect(result).toBe("Es wird eine ganze Zahl erwartet, tatsächlich: 59.5")
|
|
101
|
+
})
|
|
102
|
+
.pipe(Effect.runPromise))
|
|
48
103
|
|
|
49
104
|
it("validates string field parsed as number", () =>
|
|
50
|
-
Effect
|
|
51
|
-
|
|
52
|
-
|
|
105
|
+
Effect
|
|
106
|
+
.gen(function*() {
|
|
107
|
+
const fieldInfo = buildFieldInfoFromFieldsRoot(TestSchema)
|
|
108
|
+
const stringFieldInfo = fieldInfo.fields.stringField
|
|
53
109
|
|
|
54
|
-
|
|
55
|
-
|
|
110
|
+
expect(stringFieldInfo._tag).toBe("FieldInfo")
|
|
111
|
+
expect(stringFieldInfo.type).toBe("text")
|
|
56
112
|
|
|
57
|
-
|
|
58
|
-
|
|
113
|
+
// test validation rules with a number that should fail string validation
|
|
114
|
+
const result = stringFieldInfo.rules[0] ? stringFieldInfo.rules[0]("123") : undefined
|
|
59
115
|
|
|
60
|
-
|
|
116
|
+
console.log("Validation result for string field:", result)
|
|
61
117
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
118
|
+
// string field should accept "123" as a valid string
|
|
119
|
+
expect(result).toBe(true)
|
|
120
|
+
})
|
|
121
|
+
.pipe(Effect.runPromise))
|
|
65
122
|
|
|
66
123
|
it("validates integer field with valid integer", () =>
|
|
67
|
-
Effect
|
|
68
|
-
|
|
69
|
-
|
|
124
|
+
Effect
|
|
125
|
+
.gen(function*() {
|
|
126
|
+
const fieldInfo = buildFieldInfoFromFieldsRoot(TestSchema)
|
|
127
|
+
const integerFieldInfo = fieldInfo.fields.integerField
|
|
70
128
|
|
|
71
|
-
|
|
72
|
-
|
|
129
|
+
// test validation rules with a valid integer
|
|
130
|
+
const result = integerFieldInfo.rules[1] ? integerFieldInfo.rules[1]("42") : undefined
|
|
73
131
|
|
|
74
|
-
|
|
132
|
+
console.log("Validation result for valid integer:", result)
|
|
75
133
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
134
|
+
// the validation should pass
|
|
135
|
+
expect(result).toBe(true)
|
|
136
|
+
})
|
|
137
|
+
.pipe(Effect.runPromise))
|
|
79
138
|
|
|
80
139
|
it("error message format matches regex pattern", () => {
|
|
81
140
|
// test the actual error message format from Effect Schema
|
|
@@ -95,5 +154,5 @@ it("error message format matches regex pattern", () => {
|
|
|
95
154
|
|
|
96
155
|
const numberMatch = numberErrorMessage.match(/Expected.*number.*actual\s+(.+)/i)
|
|
97
156
|
expect(numberMatch).toBeTruthy()
|
|
98
|
-
expect(numberMatch![1]).toBe(
|
|
157
|
+
expect(numberMatch![1]).toBe("\"not-a-number\"")
|
|
99
158
|
})
|
package/tsconfig.json
CHANGED
|
@@ -35,7 +35,9 @@
|
|
|
35
35
|
{
|
|
36
36
|
"name": "@effect/language-service",
|
|
37
37
|
"diagnosticSeverity": {
|
|
38
|
-
"missingEffectServiceDependency": "error"
|
|
38
|
+
"missingEffectServiceDependency": "error",
|
|
39
|
+
"effectFnOpportunity": "warning",
|
|
40
|
+
"globalErrorInEffectFailure": "warning"
|
|
39
41
|
}
|
|
40
42
|
}
|
|
41
43
|
],
|