@effect-app/infra 4.0.0-beta.325 → 4.0.0-beta.326
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 +21 -0
- package/dist/Store/Cosmos.d.ts.map +1 -1
- package/dist/Store/Cosmos.js +5 -3
- package/dist/Store/Disk.d.ts.map +1 -1
- package/dist/Store/Disk.js +13 -7
- package/dist/Store/Memory.d.ts +1 -1
- package/dist/Store/Memory.d.ts.map +1 -1
- package/dist/Store/Memory.js +7 -6
- package/dist/Store/SQL/Pg.d.ts.map +1 -1
- package/dist/Store/SQL/Pg.js +7 -5
- package/dist/Store/SQL.d.ts.map +1 -1
- package/dist/Store/SQL.js +12 -8
- package/dist/Store/jsonDocument.d.ts +32 -1
- package/dist/Store/jsonDocument.d.ts.map +1 -1
- package/dist/Store/jsonDocument.js +43 -1
- package/package.json +2 -2
- package/src/Store/Cosmos.ts +4 -2
- package/src/Store/Disk.ts +15 -6
- package/src/Store/Memory.ts +17 -5
- package/src/Store/SQL/Pg.ts +6 -4
- package/src/Store/SQL.ts +11 -7
- package/src/Store/jsonDocument.ts +46 -1
- package/test/dist/repository-legacy-document.test.d.ts.map +1 -0
- package/test/repository-legacy-document.test.ts +329 -0
- package/test/validateSample.test.ts +45 -29
|
@@ -4,6 +4,7 @@ import { makeRepo, ValidationError, ValidationResult } from "effect-app/Model/Re
|
|
|
4
4
|
import { RepositoryRegistryLive } from "effect-app/Model/Repository/Registry"
|
|
5
5
|
import * as S from "effect-app/Schema"
|
|
6
6
|
import { setupRequestContextFromCurrent } from "effect-app/setupRequest"
|
|
7
|
+
import type { JsonRecord } from "effect-app/Store"
|
|
7
8
|
import { describe, expect, it } from "vitest"
|
|
8
9
|
import { MemoryStoreLive } from "../src/Store/Memory.js"
|
|
9
10
|
|
|
@@ -16,6 +17,26 @@ class SimpleItem extends S.Class<SimpleItem>("SimpleItem")({
|
|
|
16
17
|
count: S.NonNegativeInt
|
|
17
18
|
}) {}
|
|
18
19
|
|
|
20
|
+
/**
|
|
21
|
+
* `count` is stored as a *string*, so its Encoded shape accepts anything the
|
|
22
|
+
* JSON document happens to hold while the domain decode still demands a finite
|
|
23
|
+
* number.
|
|
24
|
+
*
|
|
25
|
+
* That split is what `validateSample` exists for, and it is the only way to
|
|
26
|
+
* observe a repository-level validation error now that `jitM` runs at the store
|
|
27
|
+
* boundary: the store's `toCodecJson(toEncoded(schema))` decode is strict, so a
|
|
28
|
+
* `jitM` that produced a value the *Encoded* shape rejects would fail loudly in
|
|
29
|
+
* the store instead of ever reaching the repository.
|
|
30
|
+
*/
|
|
31
|
+
class LooseCountItem extends S.Class<LooseCountItem>("LooseCountItem")({
|
|
32
|
+
id: S.String,
|
|
33
|
+
name: S.NonEmptyString255,
|
|
34
|
+
count: S.FiniteFromString
|
|
35
|
+
}) {}
|
|
36
|
+
|
|
37
|
+
/** build a `LooseCountItem` from its encoded (stored) form */
|
|
38
|
+
const looseItem = (id: string, name: string, count: string) => S.decodeSync(LooseCountItem)({ id, name, count })
|
|
39
|
+
|
|
19
40
|
describe("validateSample", () => {
|
|
20
41
|
it("returns success when all items pass validation", () =>
|
|
21
42
|
Effect
|
|
@@ -43,23 +64,23 @@ describe("validateSample", () => {
|
|
|
43
64
|
Effect.runPromise
|
|
44
65
|
))
|
|
45
66
|
|
|
46
|
-
it("returns errors when jitM produces
|
|
67
|
+
it("returns errors when jitM produces data the domain schema rejects", () =>
|
|
47
68
|
Effect
|
|
48
69
|
.gen(function*() {
|
|
49
|
-
// jitM that corrupts
|
|
50
|
-
const corruptingJitM = (
|
|
51
|
-
if (
|
|
52
|
-
return { ...
|
|
70
|
+
// jitM that corrupts two specific items' count into a non-numeric string
|
|
71
|
+
const corruptingJitM = (json: JsonRecord): JsonRecord => {
|
|
72
|
+
if (json["id"] === "2" || json["id"] === "3") {
|
|
73
|
+
return { ...json, count: "not-a-number" } // still a string, so the store decode is happy
|
|
53
74
|
}
|
|
54
|
-
return
|
|
75
|
+
return json
|
|
55
76
|
}
|
|
56
77
|
|
|
57
|
-
const repo = yield* makeRepo("CorruptItem",
|
|
78
|
+
const repo = yield* makeRepo("CorruptItem", LooseCountItem, {
|
|
58
79
|
jitM: corruptingJitM,
|
|
59
80
|
makeInitial: Effect.succeed([
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
81
|
+
looseItem("1", "Valid", "10"),
|
|
82
|
+
looseItem("2", "WillBeInvalid1", "20"),
|
|
83
|
+
looseItem("3", "WillBeInvalid2", "30")
|
|
63
84
|
])
|
|
64
85
|
})
|
|
65
86
|
|
|
@@ -152,9 +173,9 @@ describe("validateSample", () => {
|
|
|
152
173
|
|
|
153
174
|
// jitM that adds default status for items
|
|
154
175
|
const repo = yield* makeRepo("ItemWithStatus", ItemWithStatus, {
|
|
155
|
-
jitM: (
|
|
156
|
-
...
|
|
157
|
-
status:
|
|
176
|
+
jitM: (json) => ({
|
|
177
|
+
...json,
|
|
178
|
+
status: json["status"] ?? "active" // default to active if missing
|
|
158
179
|
}),
|
|
159
180
|
makeInitial: Effect.succeed([
|
|
160
181
|
new ItemWithStatus({ id: "1", status: "active" }),
|
|
@@ -180,16 +201,14 @@ describe("validateSample", () => {
|
|
|
180
201
|
Effect
|
|
181
202
|
.gen(function*() {
|
|
182
203
|
// jitM that corrupts the data
|
|
183
|
-
const corruptingJitM = (
|
|
184
|
-
...
|
|
185
|
-
count: -
|
|
204
|
+
const corruptingJitM = (json: JsonRecord): JsonRecord => ({
|
|
205
|
+
...json,
|
|
206
|
+
count: "not-a-number" // always corrupt count
|
|
186
207
|
})
|
|
187
208
|
|
|
188
|
-
const repo = yield* makeRepo("ContextErrorTest",
|
|
209
|
+
const repo = yield* makeRepo("ContextErrorTest", LooseCountItem, {
|
|
189
210
|
jitM: corruptingJitM,
|
|
190
|
-
makeInitial: Effect.succeed([
|
|
191
|
-
new SimpleItem({ id: "bad-item", name: S.NonEmptyString255("Test"), count: S.NonNegativeInt(100) })
|
|
192
|
-
])
|
|
211
|
+
makeInitial: Effect.succeed([looseItem("bad-item", "Test", "100")])
|
|
193
212
|
})
|
|
194
213
|
|
|
195
214
|
const result = yield* repo.validateSample({ percentage: 1.0 })
|
|
@@ -199,23 +218,20 @@ describe("validateSample", () => {
|
|
|
199
218
|
const error = result.errors[0]!
|
|
200
219
|
expect(error.id).toBe("bad-item")
|
|
201
220
|
|
|
202
|
-
// rawData
|
|
221
|
+
// rawData is what the store returned: jitM already ran at the store
|
|
222
|
+
// boundary, so the corrupted count is what the repository decoded
|
|
203
223
|
expect(error.rawData).toMatchObject({
|
|
204
224
|
id: "bad-item",
|
|
205
225
|
name: "Test",
|
|
206
|
-
count:
|
|
226
|
+
count: "not-a-number"
|
|
207
227
|
})
|
|
208
228
|
|
|
209
|
-
// jitMResult
|
|
210
|
-
expect(error.jitMResult).
|
|
211
|
-
id: "bad-item",
|
|
212
|
-
name: "Test",
|
|
213
|
-
count: -999
|
|
214
|
-
})
|
|
229
|
+
// jitMResult is kept for compatibility and is identical to rawData
|
|
230
|
+
expect(error.jitMResult).toEqual(error.rawData)
|
|
215
231
|
|
|
216
232
|
// error should be a SchemaError
|
|
217
233
|
expect(error.error).toBeDefined()
|
|
218
|
-
expect((error.error as
|
|
234
|
+
expect((error.error as { _tag?: string })._tag).toBe("SchemaError")
|
|
219
235
|
})
|
|
220
236
|
.pipe(
|
|
221
237
|
Effect.provide(TestStoreLive),
|