effect-start 0.17.2 → 0.19.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/dist/Development.d.ts +7 -2
- package/dist/Development.js +12 -6
- package/dist/PlatformRuntime.d.ts +4 -0
- package/dist/PlatformRuntime.js +9 -0
- package/dist/Route.d.ts +6 -2
- package/dist/Route.js +22 -0
- package/dist/RouteHttp.d.ts +1 -1
- package/dist/RouteHttp.js +12 -19
- package/dist/RouteMount.d.ts +2 -1
- package/dist/Start.d.ts +1 -5
- package/dist/Start.js +1 -8
- package/dist/Unique.d.ts +50 -0
- package/dist/Unique.js +187 -0
- package/dist/bun/BunHttpServer.js +5 -6
- package/dist/bun/BunRoute.d.ts +1 -1
- package/dist/bun/BunRoute.js +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/node/Effectify.d.ts +209 -0
- package/dist/node/Effectify.js +19 -0
- package/dist/node/FileSystem.d.ts +3 -5
- package/dist/node/FileSystem.js +42 -62
- package/dist/node/PlatformError.d.ts +46 -0
- package/dist/node/PlatformError.js +43 -0
- package/dist/testing/TestLogger.js +1 -1
- package/package.json +10 -5
- package/src/Development.ts +13 -18
- package/src/PlatformRuntime.ts +11 -0
- package/src/Route.ts +31 -2
- package/src/RouteHttp.ts +15 -31
- package/src/RouteMount.ts +1 -1
- package/src/Start.ts +1 -15
- package/src/Unique.ts +232 -0
- package/src/bun/BunHttpServer.ts +6 -9
- package/src/bun/BunRoute.ts +3 -3
- package/src/index.ts +1 -0
- package/src/node/Effectify.ts +262 -0
- package/src/node/FileSystem.ts +59 -97
- package/src/node/PlatformError.ts +102 -0
- package/src/testing/TestLogger.ts +1 -1
- package/dist/Random.d.ts +0 -5
- package/dist/Random.js +0 -49
- package/src/Commander.test.ts +0 -1639
- package/src/ContentNegotiation.test.ts +0 -603
- package/src/Development.test.ts +0 -119
- package/src/Entity.test.ts +0 -592
- package/src/FileRouterPattern.test.ts +0 -147
- package/src/FileRouter_files.test.ts +0 -64
- package/src/FileRouter_path.test.ts +0 -145
- package/src/FileRouter_tree.test.ts +0 -132
- package/src/Http.test.ts +0 -319
- package/src/HttpAppExtra.test.ts +0 -103
- package/src/HttpUtils.test.ts +0 -85
- package/src/PathPattern.test.ts +0 -648
- package/src/Random.ts +0 -59
- package/src/RouteBody.test.ts +0 -232
- package/src/RouteHook.test.ts +0 -40
- package/src/RouteHttp.test.ts +0 -2909
- package/src/RouteMount.test.ts +0 -481
- package/src/RouteSchema.test.ts +0 -427
- package/src/RouteSse.test.ts +0 -249
- package/src/RouteTree.test.ts +0 -494
- package/src/RouteTrie.test.ts +0 -322
- package/src/RouterPattern.test.ts +0 -676
- package/src/Values.test.ts +0 -263
- package/src/bun/BunBundle.test.ts +0 -268
- package/src/bun/BunBundle_imports.test.ts +0 -48
- package/src/bun/BunHttpServer.test.ts +0 -251
- package/src/bun/BunImportTrackerPlugin.test.ts +0 -77
- package/src/bun/BunRoute.test.ts +0 -162
- package/src/bundler/BundleHttp.test.ts +0 -132
- package/src/effect/HttpRouter.test.ts +0 -548
- package/src/experimental/EncryptedCookies.test.ts +0 -488
- package/src/hyper/HyperHtml.test.ts +0 -209
- package/src/hyper/HyperRoute.test.tsx +0 -197
- package/src/middlewares/BasicAuthMiddleware.test.ts +0 -84
- package/src/testing/TestHttpClient.test.ts +0 -83
- package/src/testing/TestLogger.test.ts +0 -51
- package/src/x/datastar/Datastar.test.ts +0 -266
- package/src/x/tailwind/TailwindPlugin.test.ts +0 -333
package/src/Development.test.ts
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import * as FileSystem from "@effect/platform/FileSystem"
|
|
2
|
-
import * as test from "bun:test"
|
|
3
|
-
import { MemoryFileSystem } from "effect-memfs"
|
|
4
|
-
import * as Chunk from "effect/Chunk"
|
|
5
|
-
import * as Effect from "effect/Effect"
|
|
6
|
-
import * as Fiber from "effect/Fiber"
|
|
7
|
-
import * as Layer from "effect/Layer"
|
|
8
|
-
import * as Stream from "effect/Stream"
|
|
9
|
-
import * as Development from "./Development.ts"
|
|
10
|
-
|
|
11
|
-
test.beforeEach(() => {
|
|
12
|
-
Development._resetForTesting()
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
test.describe("watch", () => {
|
|
16
|
-
test.it("creates pubsub and publishes file events", () =>
|
|
17
|
-
Effect
|
|
18
|
-
.gen(function*() {
|
|
19
|
-
const fs = yield* FileSystem.FileSystem
|
|
20
|
-
const watchDir = "/dev-watch"
|
|
21
|
-
|
|
22
|
-
const dev = yield* Development.watch({ path: watchDir })
|
|
23
|
-
|
|
24
|
-
const subFiber = yield* Effect.fork(
|
|
25
|
-
Stream.runCollect(
|
|
26
|
-
Stream.take(Stream.fromPubSub(dev.events), 1),
|
|
27
|
-
),
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
yield* Effect.sleep(1)
|
|
31
|
-
yield* fs.writeFileString(`${watchDir}/test.ts`, "const x = 1")
|
|
32
|
-
|
|
33
|
-
const events = yield* Fiber.join(subFiber)
|
|
34
|
-
|
|
35
|
-
test
|
|
36
|
-
.expect(Chunk.size(events))
|
|
37
|
-
.toBe(1)
|
|
38
|
-
const first = Chunk.unsafeGet(events, 0)
|
|
39
|
-
test
|
|
40
|
-
.expect("path" in first && first.path)
|
|
41
|
-
.toContain("test.ts")
|
|
42
|
-
})
|
|
43
|
-
.pipe(
|
|
44
|
-
Effect.scoped,
|
|
45
|
-
Effect.provide(
|
|
46
|
-
MemoryFileSystem.layerWith({ "/dev-watch/.gitkeep": "" }),
|
|
47
|
-
),
|
|
48
|
-
Effect.runPromise,
|
|
49
|
-
))
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
test.describe("layerWatch", () => {
|
|
53
|
-
test.it("provides Development service", () =>
|
|
54
|
-
Effect
|
|
55
|
-
.gen(function*() {
|
|
56
|
-
const dev = yield* Development.Development
|
|
57
|
-
|
|
58
|
-
test
|
|
59
|
-
.expect(dev.events)
|
|
60
|
-
.toBeDefined()
|
|
61
|
-
})
|
|
62
|
-
.pipe(
|
|
63
|
-
Effect.scoped,
|
|
64
|
-
Effect.provide(Development.layerWatch({ path: "/layer-test" })),
|
|
65
|
-
Effect.provide(
|
|
66
|
-
MemoryFileSystem.layerWith({ "/layer-test/.gitkeep": "" }),
|
|
67
|
-
),
|
|
68
|
-
Effect.runPromise,
|
|
69
|
-
))
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
test.describe("stream", () => {
|
|
73
|
-
test.it("returns stream from pubsub when Development is available", () =>
|
|
74
|
-
Effect
|
|
75
|
-
.gen(function*() {
|
|
76
|
-
const fs = yield* FileSystem.FileSystem
|
|
77
|
-
const watchDir = "/events-test"
|
|
78
|
-
|
|
79
|
-
const collectFiber = yield* Effect.fork(
|
|
80
|
-
Stream.runCollect(Stream.take(Development.stream(), 1)),
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
yield* Effect.sleep(1)
|
|
84
|
-
yield* fs.writeFileString(`${watchDir}/file.ts`, "content")
|
|
85
|
-
|
|
86
|
-
const collected = yield* Fiber.join(collectFiber)
|
|
87
|
-
|
|
88
|
-
test
|
|
89
|
-
.expect(Chunk.size(collected))
|
|
90
|
-
.toBe(1)
|
|
91
|
-
const first = Chunk.unsafeGet(collected, 0)
|
|
92
|
-
test
|
|
93
|
-
.expect("path" in first && first.path)
|
|
94
|
-
.toContain("file.ts")
|
|
95
|
-
})
|
|
96
|
-
.pipe(
|
|
97
|
-
Effect.scoped,
|
|
98
|
-
Effect.provide(Development.layerWatch({ path: "/events-test" })),
|
|
99
|
-
Effect.provide(
|
|
100
|
-
MemoryFileSystem.layerWith({ "/events-test/.gitkeep": "" }),
|
|
101
|
-
),
|
|
102
|
-
Effect.runPromise,
|
|
103
|
-
))
|
|
104
|
-
|
|
105
|
-
test.it("returns empty stream when Development is not available", () =>
|
|
106
|
-
Effect
|
|
107
|
-
.gen(function*() {
|
|
108
|
-
const collected = yield* Stream.runCollect(Development.stream())
|
|
109
|
-
|
|
110
|
-
test
|
|
111
|
-
.expect(Chunk.size(collected))
|
|
112
|
-
.toBe(0)
|
|
113
|
-
})
|
|
114
|
-
.pipe(
|
|
115
|
-
Effect.scoped,
|
|
116
|
-
Effect.provide(Layer.empty),
|
|
117
|
-
Effect.runPromise,
|
|
118
|
-
))
|
|
119
|
-
})
|
package/src/Entity.test.ts
DELETED
|
@@ -1,592 +0,0 @@
|
|
|
1
|
-
import * as test from "bun:test"
|
|
2
|
-
import * as Data from "effect/Data"
|
|
3
|
-
import * as Effect from "effect/Effect"
|
|
4
|
-
import * as ParseResult from "effect/ParseResult"
|
|
5
|
-
import * as Schema from "effect/Schema"
|
|
6
|
-
import * as Stream from "effect/Stream"
|
|
7
|
-
import * as Entity from "./Entity.ts"
|
|
8
|
-
|
|
9
|
-
test.describe(Entity.make, () => {
|
|
10
|
-
test.it("creates entity with string body", () => {
|
|
11
|
-
const entity = Entity.make("hello")
|
|
12
|
-
|
|
13
|
-
test
|
|
14
|
-
.expect(entity.body)
|
|
15
|
-
.toBe("hello")
|
|
16
|
-
test
|
|
17
|
-
.expect(entity.headers)
|
|
18
|
-
.toEqual({})
|
|
19
|
-
test
|
|
20
|
-
.expect(entity.url)
|
|
21
|
-
.toBeUndefined()
|
|
22
|
-
test
|
|
23
|
-
.expect(entity.status)
|
|
24
|
-
.toBeUndefined()
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
test.it("creates entity with all options", () => {
|
|
28
|
-
const entity = Entity.make("hello", {
|
|
29
|
-
headers: { "content-type": "text/plain" },
|
|
30
|
-
url: "https://example.com",
|
|
31
|
-
status: 200,
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
test
|
|
35
|
-
.expect(entity.body)
|
|
36
|
-
.toBe("hello")
|
|
37
|
-
test
|
|
38
|
-
.expect(entity.headers)
|
|
39
|
-
.toEqual({ "content-type": "text/plain" })
|
|
40
|
-
test
|
|
41
|
-
.expect(entity.url)
|
|
42
|
-
.toBe("https://example.com")
|
|
43
|
-
test
|
|
44
|
-
.expect(entity.status)
|
|
45
|
-
.toBe(200)
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
test.it("creates entity with object body", () => {
|
|
49
|
-
const data = { key: "value" }
|
|
50
|
-
const entity = Entity.make(data)
|
|
51
|
-
|
|
52
|
-
test
|
|
53
|
-
.expect(entity.body)
|
|
54
|
-
.toBe(data)
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
test.it("creates entity with Uint8Array body", () => {
|
|
58
|
-
const bytes = new Uint8Array([1, 2, 3])
|
|
59
|
-
const entity = Entity.make(bytes)
|
|
60
|
-
|
|
61
|
-
test
|
|
62
|
-
.expect(entity.body)
|
|
63
|
-
.toBe(bytes)
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
test.it("creates entity with ArrayBuffer body", () => {
|
|
67
|
-
const buffer = new ArrayBuffer(8)
|
|
68
|
-
const entity = Entity.make(buffer)
|
|
69
|
-
|
|
70
|
-
test
|
|
71
|
-
.expect(entity.body)
|
|
72
|
-
.toBe(buffer)
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
test.it("creates entity with Stream body", () => {
|
|
76
|
-
const stream = Stream.make(new Uint8Array([1, 2, 3]))
|
|
77
|
-
const entity = Entity.make(stream)
|
|
78
|
-
|
|
79
|
-
test
|
|
80
|
-
.expect(entity.body)
|
|
81
|
-
.toBe(stream)
|
|
82
|
-
})
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
test.describe(Entity.type, () => {
|
|
86
|
-
test.it("returns content-type from headers if present", () => {
|
|
87
|
-
const entity = Entity.make("hello", {
|
|
88
|
-
headers: { "content-type": "application/xml" },
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
test
|
|
92
|
-
.expect(Entity.type(entity))
|
|
93
|
-
.toBe("application/xml")
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
test.it("infers text/plain for string body", () => {
|
|
97
|
-
const entity = Entity.make("hello")
|
|
98
|
-
|
|
99
|
-
test
|
|
100
|
-
.expect(Entity.type(entity))
|
|
101
|
-
.toBe("text/plain")
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
test.it("infers application/octet-stream for Uint8Array body", () => {
|
|
105
|
-
const entity = Entity.make(new Uint8Array([1, 2, 3]))
|
|
106
|
-
|
|
107
|
-
test
|
|
108
|
-
.expect(Entity.type(entity))
|
|
109
|
-
.toBe("application/octet-stream")
|
|
110
|
-
})
|
|
111
|
-
|
|
112
|
-
test.it("infers application/octet-stream for ArrayBuffer body", () => {
|
|
113
|
-
const entity = Entity.make(new ArrayBuffer(8))
|
|
114
|
-
|
|
115
|
-
test
|
|
116
|
-
.expect(Entity.type(entity))
|
|
117
|
-
.toBe("application/octet-stream")
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
test.it("infers application/json for object body", () => {
|
|
121
|
-
const entity = Entity.make({ key: "value" })
|
|
122
|
-
|
|
123
|
-
test
|
|
124
|
-
.expect(Entity.type(entity))
|
|
125
|
-
.toBe("application/json")
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
test.it("returns application/octet-stream for unknown body types", () => {
|
|
129
|
-
const entity = Entity.make(null as any)
|
|
130
|
-
|
|
131
|
-
test
|
|
132
|
-
.expect(Entity.type(entity))
|
|
133
|
-
.toBe("application/octet-stream")
|
|
134
|
-
})
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
test.describe(Entity.length, () => {
|
|
138
|
-
test.it("returns content-length from headers if present", () => {
|
|
139
|
-
const entity = Entity.make("hello", {
|
|
140
|
-
headers: { "content-length": "42" },
|
|
141
|
-
})
|
|
142
|
-
|
|
143
|
-
test
|
|
144
|
-
.expect(Entity.length(entity))
|
|
145
|
-
.toBe(42)
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
test.it("calculates length for string body", () => {
|
|
149
|
-
const entity = Entity.make("hello")
|
|
150
|
-
|
|
151
|
-
test
|
|
152
|
-
.expect(Entity.length(entity))
|
|
153
|
-
.toBe(5)
|
|
154
|
-
})
|
|
155
|
-
|
|
156
|
-
test.it("calculates length for multi-byte string", () => {
|
|
157
|
-
const entity = Entity.make("héllo")
|
|
158
|
-
|
|
159
|
-
test
|
|
160
|
-
.expect(Entity.length(entity))
|
|
161
|
-
.toBe(6)
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
test.it("returns byteLength for Uint8Array body", () => {
|
|
165
|
-
const entity = Entity.make(new Uint8Array([1, 2, 3, 4, 5]))
|
|
166
|
-
|
|
167
|
-
test
|
|
168
|
-
.expect(Entity.length(entity))
|
|
169
|
-
.toBe(5)
|
|
170
|
-
})
|
|
171
|
-
|
|
172
|
-
test.it("returns byteLength for ArrayBuffer body", () => {
|
|
173
|
-
const entity = Entity.make(new ArrayBuffer(8))
|
|
174
|
-
|
|
175
|
-
test
|
|
176
|
-
.expect(Entity.length(entity))
|
|
177
|
-
.toBe(8)
|
|
178
|
-
})
|
|
179
|
-
|
|
180
|
-
test.it("returns undefined for object body", () => {
|
|
181
|
-
const entity = Entity.make({ a: 1 })
|
|
182
|
-
|
|
183
|
-
test
|
|
184
|
-
.expect(Entity.length(entity))
|
|
185
|
-
.toBeUndefined()
|
|
186
|
-
})
|
|
187
|
-
})
|
|
188
|
-
|
|
189
|
-
test.describe("text", () => {
|
|
190
|
-
test.it("returns string body directly", async () => {
|
|
191
|
-
const entity = Entity.make("hello world")
|
|
192
|
-
const result = await Effect.runPromise(entity.text)
|
|
193
|
-
|
|
194
|
-
test
|
|
195
|
-
.expect(result)
|
|
196
|
-
.toBe("hello world")
|
|
197
|
-
})
|
|
198
|
-
|
|
199
|
-
test.it("decodes Uint8Array body to string", async () => {
|
|
200
|
-
const bytes = new TextEncoder().encode("hello world")
|
|
201
|
-
const entity = Entity.make(bytes)
|
|
202
|
-
const result = await Effect.runPromise(entity.text)
|
|
203
|
-
|
|
204
|
-
test
|
|
205
|
-
.expect(result)
|
|
206
|
-
.toBe("hello world")
|
|
207
|
-
})
|
|
208
|
-
|
|
209
|
-
test.it("decodes ArrayBuffer body to string", async () => {
|
|
210
|
-
const bytes = new TextEncoder().encode("hello world")
|
|
211
|
-
const buffer = bytes.buffer.slice(
|
|
212
|
-
bytes.byteOffset,
|
|
213
|
-
bytes.byteOffset + bytes.byteLength,
|
|
214
|
-
)
|
|
215
|
-
const entity = Entity.make(buffer)
|
|
216
|
-
const result = await Effect.runPromise(entity.text)
|
|
217
|
-
|
|
218
|
-
test
|
|
219
|
-
.expect(result)
|
|
220
|
-
.toBe("hello world")
|
|
221
|
-
})
|
|
222
|
-
|
|
223
|
-
test.it("decodes Stream body to string", async () => {
|
|
224
|
-
const bytes1 = new TextEncoder().encode("hello ")
|
|
225
|
-
const bytes2 = new TextEncoder().encode("world")
|
|
226
|
-
const stream = Stream.make(bytes1, bytes2)
|
|
227
|
-
const entity = Entity.make(stream)
|
|
228
|
-
const result = await Effect.runPromise(entity.text)
|
|
229
|
-
|
|
230
|
-
test
|
|
231
|
-
.expect(result)
|
|
232
|
-
.toBe("hello world")
|
|
233
|
-
})
|
|
234
|
-
|
|
235
|
-
test.it("fails for unsupported body types", async () => {
|
|
236
|
-
const entity = Entity.make(42 as any)
|
|
237
|
-
const result = await Effect.runPromiseExit(entity.text)
|
|
238
|
-
|
|
239
|
-
test
|
|
240
|
-
.expect(result._tag)
|
|
241
|
-
.toBe("Failure")
|
|
242
|
-
})
|
|
243
|
-
})
|
|
244
|
-
|
|
245
|
-
test.describe("json", () => {
|
|
246
|
-
test.it("returns object body directly", async () => {
|
|
247
|
-
const data = { key: "value", num: 42 }
|
|
248
|
-
const entity = Entity.make(data)
|
|
249
|
-
const result = await Effect.runPromise(entity.json)
|
|
250
|
-
|
|
251
|
-
test
|
|
252
|
-
.expect(result)
|
|
253
|
-
.toEqual(data)
|
|
254
|
-
})
|
|
255
|
-
|
|
256
|
-
test.it("parses string body as JSON", async () => {
|
|
257
|
-
const entity = Entity.make("{\"key\":\"value\"}")
|
|
258
|
-
const result = await Effect.runPromise(entity.json)
|
|
259
|
-
|
|
260
|
-
test
|
|
261
|
-
.expect(result)
|
|
262
|
-
.toEqual({ key: "value" })
|
|
263
|
-
})
|
|
264
|
-
|
|
265
|
-
test.it("parses Uint8Array body as JSON", async () => {
|
|
266
|
-
const bytes = new TextEncoder().encode("{\"key\":\"value\"}")
|
|
267
|
-
const entity = Entity.make(bytes)
|
|
268
|
-
const result = await Effect.runPromise(entity.json)
|
|
269
|
-
|
|
270
|
-
test
|
|
271
|
-
.expect(result)
|
|
272
|
-
.toEqual({ key: "value" })
|
|
273
|
-
})
|
|
274
|
-
|
|
275
|
-
test.it("parses ArrayBuffer body as JSON", async () => {
|
|
276
|
-
const bytes = new TextEncoder().encode("{\"key\":\"value\"}")
|
|
277
|
-
const buffer = bytes.buffer.slice(
|
|
278
|
-
bytes.byteOffset,
|
|
279
|
-
bytes.byteOffset + bytes.byteLength,
|
|
280
|
-
)
|
|
281
|
-
const entity = Entity.make(buffer)
|
|
282
|
-
const result = await Effect.runPromise(entity.json)
|
|
283
|
-
|
|
284
|
-
test
|
|
285
|
-
.expect(result)
|
|
286
|
-
.toEqual({ key: "value" })
|
|
287
|
-
})
|
|
288
|
-
|
|
289
|
-
test.it("parses Stream body as JSON", async () => {
|
|
290
|
-
const bytes = new TextEncoder().encode("{\"key\":\"value\"}")
|
|
291
|
-
const stream = Stream.make(bytes)
|
|
292
|
-
const entity = Entity.make(stream)
|
|
293
|
-
const result = await Effect.runPromise(entity.json)
|
|
294
|
-
|
|
295
|
-
test
|
|
296
|
-
.expect(result)
|
|
297
|
-
.toEqual({ key: "value" })
|
|
298
|
-
})
|
|
299
|
-
|
|
300
|
-
test.it("fails for invalid JSON string", async () => {
|
|
301
|
-
const entity = Entity.make("not valid json")
|
|
302
|
-
const result = await Effect.runPromiseExit(entity.json)
|
|
303
|
-
|
|
304
|
-
test
|
|
305
|
-
.expect(result._tag)
|
|
306
|
-
.toBe("Failure")
|
|
307
|
-
})
|
|
308
|
-
|
|
309
|
-
test.it("fails for unsupported body types", async () => {
|
|
310
|
-
const entity = Entity.make(42 as any)
|
|
311
|
-
const result = await Effect.runPromiseExit(entity.json)
|
|
312
|
-
|
|
313
|
-
test
|
|
314
|
-
.expect(result._tag)
|
|
315
|
-
.toBe("Failure")
|
|
316
|
-
})
|
|
317
|
-
})
|
|
318
|
-
|
|
319
|
-
test.describe("bytes", () => {
|
|
320
|
-
test.it("returns Uint8Array body directly", async () => {
|
|
321
|
-
const bytes = new Uint8Array([1, 2, 3])
|
|
322
|
-
const entity = Entity.make(bytes)
|
|
323
|
-
const result = await Effect.runPromise(entity.bytes)
|
|
324
|
-
|
|
325
|
-
test
|
|
326
|
-
.expect(result)
|
|
327
|
-
.toBe(bytes)
|
|
328
|
-
})
|
|
329
|
-
|
|
330
|
-
test.it("converts ArrayBuffer body to Uint8Array", async () => {
|
|
331
|
-
const buffer = new ArrayBuffer(4)
|
|
332
|
-
new Uint8Array(buffer).set([1, 2, 3, 4])
|
|
333
|
-
const entity = Entity.make(buffer)
|
|
334
|
-
const result = await Effect.runPromise(entity.bytes)
|
|
335
|
-
|
|
336
|
-
test
|
|
337
|
-
.expect(result)
|
|
338
|
-
.toEqual(new Uint8Array([1, 2, 3, 4]))
|
|
339
|
-
})
|
|
340
|
-
|
|
341
|
-
test.it("encodes string body to Uint8Array", async () => {
|
|
342
|
-
const entity = Entity.make("hello")
|
|
343
|
-
const result = await Effect.runPromise(entity.bytes)
|
|
344
|
-
|
|
345
|
-
test
|
|
346
|
-
.expect(result)
|
|
347
|
-
.toEqual(new TextEncoder().encode("hello"))
|
|
348
|
-
})
|
|
349
|
-
|
|
350
|
-
test.it("collects Stream body to Uint8Array", async () => {
|
|
351
|
-
const chunk1 = new Uint8Array([1, 2])
|
|
352
|
-
const chunk2 = new Uint8Array([3, 4])
|
|
353
|
-
const stream = Stream.make(chunk1, chunk2)
|
|
354
|
-
const entity = Entity.make(stream)
|
|
355
|
-
const result = await Effect.runPromise(entity.bytes)
|
|
356
|
-
|
|
357
|
-
test
|
|
358
|
-
.expect(result)
|
|
359
|
-
.toEqual(new Uint8Array([1, 2, 3, 4]))
|
|
360
|
-
})
|
|
361
|
-
|
|
362
|
-
test.it("serializes objects to JSON bytes", async () => {
|
|
363
|
-
const entity = Entity.make({ key: "value" })
|
|
364
|
-
const result = await Effect.runPromise(entity.bytes)
|
|
365
|
-
const text = new TextDecoder().decode(result)
|
|
366
|
-
|
|
367
|
-
test
|
|
368
|
-
.expect(text)
|
|
369
|
-
.toBe("{\"key\":\"value\"}")
|
|
370
|
-
})
|
|
371
|
-
})
|
|
372
|
-
|
|
373
|
-
test.describe("stream", () => {
|
|
374
|
-
test.it("returns Stream body content", async () => {
|
|
375
|
-
const bytes = new Uint8Array([1, 2, 3])
|
|
376
|
-
const entity = Entity.make(Stream.make(bytes))
|
|
377
|
-
const chunks = await Effect.runPromise(Stream.runCollect(entity.stream))
|
|
378
|
-
|
|
379
|
-
test
|
|
380
|
-
.expect(Array.from(chunks))
|
|
381
|
-
.toEqual([bytes])
|
|
382
|
-
})
|
|
383
|
-
|
|
384
|
-
test.it("converts Uint8Array body to stream", async () => {
|
|
385
|
-
const bytes = new Uint8Array([1, 2, 3])
|
|
386
|
-
const entity = Entity.make(bytes)
|
|
387
|
-
const chunks = await Effect.runPromise(Stream.runCollect(entity.stream))
|
|
388
|
-
|
|
389
|
-
test
|
|
390
|
-
.expect(Array.from(chunks))
|
|
391
|
-
.toEqual([bytes])
|
|
392
|
-
})
|
|
393
|
-
|
|
394
|
-
test.it("converts ArrayBuffer body to stream", async () => {
|
|
395
|
-
const buffer = new ArrayBuffer(3)
|
|
396
|
-
new Uint8Array(buffer).set([1, 2, 3])
|
|
397
|
-
const entity = Entity.make(buffer)
|
|
398
|
-
const chunks = await Effect.runPromise(Stream.runCollect(entity.stream))
|
|
399
|
-
|
|
400
|
-
test
|
|
401
|
-
.expect(Array.from(chunks))
|
|
402
|
-
.toEqual([new Uint8Array([1, 2, 3])])
|
|
403
|
-
})
|
|
404
|
-
|
|
405
|
-
test.it("converts string body to stream", async () => {
|
|
406
|
-
const entity = Entity.make("hello")
|
|
407
|
-
const chunks = await Effect.runPromise(Stream.runCollect(entity.stream))
|
|
408
|
-
|
|
409
|
-
test
|
|
410
|
-
.expect(Array.from(chunks))
|
|
411
|
-
.toEqual([new TextEncoder().encode("hello")])
|
|
412
|
-
})
|
|
413
|
-
})
|
|
414
|
-
|
|
415
|
-
test.describe("Effect body", () => {
|
|
416
|
-
test.it("executes lazily on accessor access", async () => {
|
|
417
|
-
let count = 0
|
|
418
|
-
const entity = Entity.make(
|
|
419
|
-
Effect.sync(() => {
|
|
420
|
-
count++
|
|
421
|
-
return "hello"
|
|
422
|
-
}),
|
|
423
|
-
)
|
|
424
|
-
|
|
425
|
-
test.expect(count).toBe(0)
|
|
426
|
-
|
|
427
|
-
await Effect.runPromise(entity.text)
|
|
428
|
-
test.expect(count).toBe(1)
|
|
429
|
-
})
|
|
430
|
-
|
|
431
|
-
test.it("propagates Effect errors", async () => {
|
|
432
|
-
const error = new ParseResult.ParseError({
|
|
433
|
-
issue: new ParseResult.Type(Schema.String.ast, 123),
|
|
434
|
-
})
|
|
435
|
-
const effect = Effect.fail(error)
|
|
436
|
-
const entity = Entity.make(effect)
|
|
437
|
-
const result = await Effect.runPromiseExit(entity.text)
|
|
438
|
-
|
|
439
|
-
test
|
|
440
|
-
.expect(result._tag)
|
|
441
|
-
.toBe("Failure")
|
|
442
|
-
})
|
|
443
|
-
|
|
444
|
-
test.it("tracks error type in Entity accessors", () => {
|
|
445
|
-
class CustomError extends Data.TaggedError("CustomError")<{
|
|
446
|
-
readonly reason: string
|
|
447
|
-
}> {}
|
|
448
|
-
|
|
449
|
-
const entity = Entity.make(Effect.fail(new CustomError({ reason: "test" })))
|
|
450
|
-
|
|
451
|
-
test
|
|
452
|
-
.expectTypeOf<
|
|
453
|
-
CustomError extends Effect.Effect.Error<typeof entity.text> ? true
|
|
454
|
-
: false
|
|
455
|
-
>()
|
|
456
|
-
.toEqualTypeOf<true>()
|
|
457
|
-
})
|
|
458
|
-
|
|
459
|
-
test.it("text decodes Effect<Uint8Array> to string", async () => {
|
|
460
|
-
const bytes = new TextEncoder().encode("hello world")
|
|
461
|
-
const effect = Effect.succeed(bytes)
|
|
462
|
-
const entity = Entity.make(effect)
|
|
463
|
-
const result = await Effect.runPromise(entity.text)
|
|
464
|
-
|
|
465
|
-
test
|
|
466
|
-
.expect(result)
|
|
467
|
-
.toBe("hello world")
|
|
468
|
-
})
|
|
469
|
-
|
|
470
|
-
test.it("json parses Effect<string> as JSON", async () => {
|
|
471
|
-
const effect = Effect.succeed("{\"key\":\"value\"}")
|
|
472
|
-
const entity = Entity.make(effect)
|
|
473
|
-
const result = await Effect.runPromise(entity.json)
|
|
474
|
-
|
|
475
|
-
test
|
|
476
|
-
.expect(result)
|
|
477
|
-
.toEqual({ key: "value" })
|
|
478
|
-
})
|
|
479
|
-
|
|
480
|
-
test.it("bytes encodes Effect<string> to Uint8Array", async () => {
|
|
481
|
-
const effect = Effect.succeed("hello")
|
|
482
|
-
const entity = Entity.make(effect)
|
|
483
|
-
const result = await Effect.runPromise(entity.bytes)
|
|
484
|
-
|
|
485
|
-
test
|
|
486
|
-
.expect(result)
|
|
487
|
-
.toEqual(new TextEncoder().encode("hello"))
|
|
488
|
-
})
|
|
489
|
-
})
|
|
490
|
-
|
|
491
|
-
test.describe("Pipeable interface", () => {
|
|
492
|
-
test.it("supports piping", () => {
|
|
493
|
-
const entity = Entity.make("hello")
|
|
494
|
-
const piped = entity.pipe((e) => Entity.type(e))
|
|
495
|
-
|
|
496
|
-
test
|
|
497
|
-
.expect(piped)
|
|
498
|
-
.toBe("text/plain")
|
|
499
|
-
})
|
|
500
|
-
})
|
|
501
|
-
|
|
502
|
-
test.describe("Proto getters", () => {
|
|
503
|
-
test.it("entity.text returns text", async () => {
|
|
504
|
-
const entity = Entity.make("hello")
|
|
505
|
-
const result = await Effect.runPromise(entity.text)
|
|
506
|
-
|
|
507
|
-
test
|
|
508
|
-
.expect(result)
|
|
509
|
-
.toBe("hello")
|
|
510
|
-
})
|
|
511
|
-
|
|
512
|
-
test.it("entity.json returns json", async () => {
|
|
513
|
-
const data = { key: "value" }
|
|
514
|
-
const entity = Entity.make(data)
|
|
515
|
-
const result = await Effect.runPromise(entity.json)
|
|
516
|
-
|
|
517
|
-
test
|
|
518
|
-
.expect(result)
|
|
519
|
-
.toEqual(data)
|
|
520
|
-
})
|
|
521
|
-
|
|
522
|
-
test.it("entity.bytes returns bytes", async () => {
|
|
523
|
-
const bytes = new Uint8Array([1, 2, 3])
|
|
524
|
-
const entity = Entity.make(bytes)
|
|
525
|
-
const result = await Effect.runPromise(entity.bytes)
|
|
526
|
-
|
|
527
|
-
test
|
|
528
|
-
.expect(result)
|
|
529
|
-
.toBe(bytes)
|
|
530
|
-
})
|
|
531
|
-
|
|
532
|
-
test.it("entity.stream returns stream", async () => {
|
|
533
|
-
const bytes = new Uint8Array([1, 2, 3])
|
|
534
|
-
const entity = Entity.make(bytes)
|
|
535
|
-
const chunks = await Effect.runPromise(Stream.runCollect(entity.stream))
|
|
536
|
-
|
|
537
|
-
test
|
|
538
|
-
.expect(Array.from(chunks))
|
|
539
|
-
.toEqual([bytes])
|
|
540
|
-
})
|
|
541
|
-
})
|
|
542
|
-
|
|
543
|
-
test.describe("type inference", () => {
|
|
544
|
-
test.it("infers correct body type from make()", () => {
|
|
545
|
-
const stringEntity = Entity.make("hello")
|
|
546
|
-
test
|
|
547
|
-
.expectTypeOf(stringEntity.body)
|
|
548
|
-
.toEqualTypeOf<string>()
|
|
549
|
-
|
|
550
|
-
const objectEntity = Entity.make({ key: "value" })
|
|
551
|
-
test
|
|
552
|
-
.expectTypeOf(objectEntity.body)
|
|
553
|
-
.toEqualTypeOf<{ key: string }>()
|
|
554
|
-
|
|
555
|
-
const bytesEntity = Entity.make(new Uint8Array([1, 2, 3]))
|
|
556
|
-
test
|
|
557
|
-
.expect(bytesEntity.body instanceof Uint8Array)
|
|
558
|
-
.toBe(true)
|
|
559
|
-
})
|
|
560
|
-
|
|
561
|
-
test.it("text returns string for string body", () => {
|
|
562
|
-
const entity = Entity.make("hello")
|
|
563
|
-
|
|
564
|
-
test
|
|
565
|
-
.expectTypeOf<Effect.Effect.Success<typeof entity.text>>()
|
|
566
|
-
.toEqualTypeOf<string>()
|
|
567
|
-
})
|
|
568
|
-
|
|
569
|
-
test.it("json returns T for object body", () => {
|
|
570
|
-
const entity = Entity.make({ key: "value" })
|
|
571
|
-
|
|
572
|
-
test
|
|
573
|
-
.expectTypeOf<Effect.Effect.Success<typeof entity.json>>()
|
|
574
|
-
.toEqualTypeOf<{ key: string }>()
|
|
575
|
-
})
|
|
576
|
-
|
|
577
|
-
test.it("bytes returns Uint8Array for string body", () => {
|
|
578
|
-
const entity = Entity.make("hello")
|
|
579
|
-
|
|
580
|
-
test
|
|
581
|
-
.expectTypeOf<Effect.Effect.Success<typeof entity.bytes>>()
|
|
582
|
-
.toEqualTypeOf<Uint8Array>()
|
|
583
|
-
})
|
|
584
|
-
|
|
585
|
-
test.it("stream returns Stream for string body", () => {
|
|
586
|
-
const entity = Entity.make("hello")
|
|
587
|
-
|
|
588
|
-
test
|
|
589
|
-
.expectTypeOf<Stream.Stream.Success<typeof entity.stream>>()
|
|
590
|
-
.toEqualTypeOf<Uint8Array>()
|
|
591
|
-
})
|
|
592
|
-
})
|