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
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
import * as test from "bun:test"
|
|
2
|
-
import * as Effect from "effect/Effect"
|
|
3
|
-
import * as Layer from "effect/Layer"
|
|
4
|
-
import * as Route from "../Route.ts"
|
|
5
|
-
import * as BunHttpServer from "./BunHttpServer.ts"
|
|
6
|
-
|
|
7
|
-
test.describe("smart port selection", () => {
|
|
8
|
-
// Skip when running in TTY because the random port logic requires !isTTY && CLAUDECODE,
|
|
9
|
-
// and process.stdout.isTTY cannot be mocked
|
|
10
|
-
test.test.skipIf(process.stdout.isTTY)(
|
|
11
|
-
"uses random port when PORT not set, isTTY=false, CLAUDECODE set",
|
|
12
|
-
async () => {
|
|
13
|
-
const originalPort = process.env.PORT
|
|
14
|
-
const originalClaudeCode = process.env.CLAUDECODE
|
|
15
|
-
|
|
16
|
-
try {
|
|
17
|
-
delete process.env.PORT
|
|
18
|
-
process.env.CLAUDECODE = "1"
|
|
19
|
-
|
|
20
|
-
const port = await Effect.runPromise(
|
|
21
|
-
Effect.scoped(
|
|
22
|
-
Effect.gen(function*() {
|
|
23
|
-
const bunServer = yield* BunHttpServer.make({})
|
|
24
|
-
return bunServer.server.port
|
|
25
|
-
}),
|
|
26
|
-
),
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
test
|
|
30
|
-
.expect(port)
|
|
31
|
-
.not
|
|
32
|
-
.toBe(3000)
|
|
33
|
-
} finally {
|
|
34
|
-
if (originalPort !== undefined) {
|
|
35
|
-
process.env.PORT = originalPort
|
|
36
|
-
} else {
|
|
37
|
-
delete process.env.PORT
|
|
38
|
-
}
|
|
39
|
-
if (originalClaudeCode !== undefined) {
|
|
40
|
-
process.env.CLAUDECODE = originalClaudeCode
|
|
41
|
-
} else {
|
|
42
|
-
delete process.env.CLAUDECODE
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
)
|
|
47
|
-
|
|
48
|
-
test.test("uses explicit PORT even when CLAUDECODE is set", async () => {
|
|
49
|
-
const originalPort = process.env.PORT
|
|
50
|
-
const originalClaudeCode = process.env.CLAUDECODE
|
|
51
|
-
|
|
52
|
-
try {
|
|
53
|
-
process.env.PORT = "5678"
|
|
54
|
-
process.env.CLAUDECODE = "1"
|
|
55
|
-
|
|
56
|
-
const port = await Effect.runPromise(
|
|
57
|
-
Effect.scoped(
|
|
58
|
-
Effect.gen(function*() {
|
|
59
|
-
const bunServer = yield* BunHttpServer.make({})
|
|
60
|
-
return bunServer.server.port
|
|
61
|
-
}),
|
|
62
|
-
),
|
|
63
|
-
)
|
|
64
|
-
|
|
65
|
-
test
|
|
66
|
-
.expect(port)
|
|
67
|
-
.toBe(5678)
|
|
68
|
-
} finally {
|
|
69
|
-
if (originalPort !== undefined) {
|
|
70
|
-
process.env.PORT = originalPort
|
|
71
|
-
} else {
|
|
72
|
-
delete process.env.PORT
|
|
73
|
-
}
|
|
74
|
-
if (originalClaudeCode !== undefined) {
|
|
75
|
-
process.env.CLAUDECODE = originalClaudeCode
|
|
76
|
-
} else {
|
|
77
|
-
delete process.env.CLAUDECODE
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
})
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
const BunHttpServerTest = Layer.scoped(
|
|
84
|
-
BunHttpServer.BunHttpServer,
|
|
85
|
-
BunHttpServer.make({ port: 0 }),
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
const testLayer = (routes: ReturnType<typeof Route.tree>) =>
|
|
89
|
-
Layer.provideMerge(
|
|
90
|
-
BunHttpServer.layerRoutes(routes),
|
|
91
|
-
BunHttpServerTest,
|
|
92
|
-
)
|
|
93
|
-
|
|
94
|
-
test.describe("routes", () => {
|
|
95
|
-
test.test("serves static text route", async () => {
|
|
96
|
-
const routes = Route.tree({
|
|
97
|
-
"/": Route.get(Route.text("Hello, World!")),
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
const response = await Effect.runPromise(
|
|
101
|
-
Effect.scoped(
|
|
102
|
-
Effect
|
|
103
|
-
.gen(function*() {
|
|
104
|
-
const bunServer = yield* BunHttpServer.BunHttpServer
|
|
105
|
-
return yield* Effect.promise(() =>
|
|
106
|
-
fetch(`http://localhost:${bunServer.server.port}/`)
|
|
107
|
-
)
|
|
108
|
-
})
|
|
109
|
-
.pipe(Effect.provide(testLayer(routes))),
|
|
110
|
-
),
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
test.expect(response.status).toBe(200)
|
|
114
|
-
test.expect(await response.text()).toBe("Hello, World!")
|
|
115
|
-
})
|
|
116
|
-
|
|
117
|
-
test.test("serves JSON route", async () => {
|
|
118
|
-
const routes = Route.tree({
|
|
119
|
-
"/api/data": Route.get(Route.json({ message: "success", value: 42 })),
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
const response = await Effect.runPromise(
|
|
123
|
-
Effect.scoped(
|
|
124
|
-
Effect
|
|
125
|
-
.gen(function*() {
|
|
126
|
-
const bunServer = yield* BunHttpServer.BunHttpServer
|
|
127
|
-
return yield* Effect.promise(() =>
|
|
128
|
-
fetch(`http://localhost:${bunServer.server.port}/api/data`)
|
|
129
|
-
)
|
|
130
|
-
})
|
|
131
|
-
.pipe(Effect.provide(testLayer(routes))),
|
|
132
|
-
),
|
|
133
|
-
)
|
|
134
|
-
|
|
135
|
-
test.expect(response.status).toBe(200)
|
|
136
|
-
test.expect(response.headers.get("Content-Type")).toBe("application/json")
|
|
137
|
-
test.expect(await response.json()).toEqual({
|
|
138
|
-
message: "success",
|
|
139
|
-
value: 42,
|
|
140
|
-
})
|
|
141
|
-
})
|
|
142
|
-
|
|
143
|
-
test.test("returns 404 for unknown routes", async () => {
|
|
144
|
-
const routes = Route.tree({
|
|
145
|
-
"/": Route.get(Route.text("Home")),
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
const response = await Effect.runPromise(
|
|
149
|
-
Effect.scoped(
|
|
150
|
-
Effect
|
|
151
|
-
.gen(function*() {
|
|
152
|
-
const bunServer = yield* BunHttpServer.BunHttpServer
|
|
153
|
-
return yield* Effect.promise(() =>
|
|
154
|
-
fetch(`http://localhost:${bunServer.server.port}/unknown`)
|
|
155
|
-
)
|
|
156
|
-
})
|
|
157
|
-
.pipe(Effect.provide(testLayer(routes))),
|
|
158
|
-
),
|
|
159
|
-
)
|
|
160
|
-
|
|
161
|
-
test.expect(response.status).toBe(404)
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
test.test("handles content negotiation", async () => {
|
|
165
|
-
const routes = Route.tree({
|
|
166
|
-
"/data": Route
|
|
167
|
-
.get(Route.json({ type: "json" }))
|
|
168
|
-
.get(Route.html("<div>html</div>")),
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
const [jsonResponse, htmlResponse] = await Effect.runPromise(
|
|
172
|
-
Effect.scoped(
|
|
173
|
-
Effect
|
|
174
|
-
.gen(function*() {
|
|
175
|
-
const bunServer = yield* BunHttpServer.BunHttpServer
|
|
176
|
-
const baseUrl = `http://localhost:${bunServer.server.port}`
|
|
177
|
-
|
|
178
|
-
const json = yield* Effect.promise(() =>
|
|
179
|
-
fetch(`${baseUrl}/data`, {
|
|
180
|
-
headers: { Accept: "application/json" },
|
|
181
|
-
})
|
|
182
|
-
)
|
|
183
|
-
|
|
184
|
-
const html = yield* Effect.promise(() =>
|
|
185
|
-
fetch(`${baseUrl}/data`, {
|
|
186
|
-
headers: { Accept: "text/html" },
|
|
187
|
-
})
|
|
188
|
-
)
|
|
189
|
-
|
|
190
|
-
return [json, html] as const
|
|
191
|
-
})
|
|
192
|
-
.pipe(Effect.provide(testLayer(routes))),
|
|
193
|
-
),
|
|
194
|
-
)
|
|
195
|
-
|
|
196
|
-
test.expect(jsonResponse.headers.get("Content-Type")).toBe(
|
|
197
|
-
"application/json",
|
|
198
|
-
)
|
|
199
|
-
test.expect(await jsonResponse.json()).toEqual({ type: "json" })
|
|
200
|
-
|
|
201
|
-
test.expect(htmlResponse.headers.get("Content-Type")).toBe(
|
|
202
|
-
"text/html; charset=utf-8",
|
|
203
|
-
)
|
|
204
|
-
test.expect(await htmlResponse.text()).toBe("<div>html</div>")
|
|
205
|
-
})
|
|
206
|
-
|
|
207
|
-
test.test("returns 406 for unacceptable content type", async () => {
|
|
208
|
-
const routes = Route.tree({
|
|
209
|
-
"/data": Route.get(Route.json({ type: "json" })),
|
|
210
|
-
})
|
|
211
|
-
|
|
212
|
-
const response = await Effect.runPromise(
|
|
213
|
-
Effect.scoped(
|
|
214
|
-
Effect
|
|
215
|
-
.gen(function*() {
|
|
216
|
-
const bunServer = yield* BunHttpServer.BunHttpServer
|
|
217
|
-
return yield* Effect.promise(() =>
|
|
218
|
-
fetch(`http://localhost:${bunServer.server.port}/data`, {
|
|
219
|
-
headers: { Accept: "image/png" },
|
|
220
|
-
})
|
|
221
|
-
)
|
|
222
|
-
})
|
|
223
|
-
.pipe(Effect.provide(testLayer(routes))),
|
|
224
|
-
),
|
|
225
|
-
)
|
|
226
|
-
|
|
227
|
-
test.expect(response.status).toBe(406)
|
|
228
|
-
})
|
|
229
|
-
|
|
230
|
-
test.test("handles parameterized routes", async () => {
|
|
231
|
-
const routes = Route.tree({
|
|
232
|
-
"/users/:id": Route.get(Route.text("user")),
|
|
233
|
-
})
|
|
234
|
-
|
|
235
|
-
const response = await Effect.runPromise(
|
|
236
|
-
Effect.scoped(
|
|
237
|
-
Effect
|
|
238
|
-
.gen(function*() {
|
|
239
|
-
const bunServer = yield* BunHttpServer.BunHttpServer
|
|
240
|
-
return yield* Effect.promise(() =>
|
|
241
|
-
fetch(`http://localhost:${bunServer.server.port}/users/123`)
|
|
242
|
-
)
|
|
243
|
-
})
|
|
244
|
-
.pipe(Effect.provide(testLayer(routes))),
|
|
245
|
-
),
|
|
246
|
-
)
|
|
247
|
-
|
|
248
|
-
test.expect(response.status).toBe(200)
|
|
249
|
-
test.expect(await response.text()).toBe("user")
|
|
250
|
-
})
|
|
251
|
-
})
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import * as test from "bun:test"
|
|
2
|
-
import * as BunImportTrackerPlugin from "./BunImportTrackerPlugin.ts"
|
|
3
|
-
import * as BunVirtualFilesPlugin from "./BunVirtualFilesPlugin.ts"
|
|
4
|
-
|
|
5
|
-
const Files = {
|
|
6
|
-
"index.html": `
|
|
7
|
-
<!DOCTYPE html>
|
|
8
|
-
<html>
|
|
9
|
-
<head>
|
|
10
|
-
<title>Dashboard</title>
|
|
11
|
-
</head>
|
|
12
|
-
<body>
|
|
13
|
-
<div id="root"></div>
|
|
14
|
-
<script src="client.tsx" />
|
|
15
|
-
</body>
|
|
16
|
-
</html>
|
|
17
|
-
`,
|
|
18
|
-
|
|
19
|
-
"client.ts": `
|
|
20
|
-
import { message } from "./config.ts"
|
|
21
|
-
|
|
22
|
-
alert(message)
|
|
23
|
-
`,
|
|
24
|
-
|
|
25
|
-
".config.ts": `
|
|
26
|
-
export const message = "Hello, World!"
|
|
27
|
-
`,
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
test.it("virtual import", async () => {
|
|
31
|
-
const trackerPlugin = BunImportTrackerPlugin.make({
|
|
32
|
-
baseDir: Bun.fileURLToPath(import.meta.resolve("../..")),
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
await Bun.build({
|
|
36
|
-
target: "bun",
|
|
37
|
-
entrypoints: [
|
|
38
|
-
import.meta.path,
|
|
39
|
-
],
|
|
40
|
-
plugins: [
|
|
41
|
-
trackerPlugin,
|
|
42
|
-
],
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
test
|
|
46
|
-
.expect(
|
|
47
|
-
[...trackerPlugin.state.entries()],
|
|
48
|
-
)
|
|
49
|
-
.toEqual([
|
|
50
|
-
[
|
|
51
|
-
"src/bun/BunImportTrackerPlugin.test.ts",
|
|
52
|
-
[
|
|
53
|
-
{
|
|
54
|
-
kind: "import-statement",
|
|
55
|
-
path: "bun:test",
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
kind: "import-statement",
|
|
59
|
-
path: "src/bun/BunImportTrackerPlugin.ts",
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
kind: "import-statement",
|
|
63
|
-
path: "src/bun/BunVirtualFilesPlugin.ts",
|
|
64
|
-
},
|
|
65
|
-
],
|
|
66
|
-
],
|
|
67
|
-
[
|
|
68
|
-
"src/bun/BunImportTrackerPlugin.ts",
|
|
69
|
-
[
|
|
70
|
-
{
|
|
71
|
-
kind: "import-statement",
|
|
72
|
-
path: "node:path",
|
|
73
|
-
},
|
|
74
|
-
],
|
|
75
|
-
],
|
|
76
|
-
])
|
|
77
|
-
})
|
package/src/bun/BunRoute.test.ts
DELETED
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import * as test from "bun:test"
|
|
2
|
-
import * as Effect from "effect/Effect"
|
|
3
|
-
import * as Layer from "effect/Layer"
|
|
4
|
-
import * as Option from "effect/Option"
|
|
5
|
-
import * as Route from "../Route.ts"
|
|
6
|
-
import * as BunHttpServer from "./BunHttpServer.ts"
|
|
7
|
-
import * as BunRoute from "./BunRoute.ts"
|
|
8
|
-
|
|
9
|
-
const layerServer = Layer.scoped(
|
|
10
|
-
BunHttpServer.BunHttpServer,
|
|
11
|
-
BunHttpServer.make({ port: 0 }),
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
const testLayer = (routes: ReturnType<typeof Route.tree>) =>
|
|
15
|
-
Layer.provideMerge(
|
|
16
|
-
BunHttpServer.layerRoutes(routes),
|
|
17
|
-
layerServer,
|
|
18
|
-
)
|
|
19
|
-
|
|
20
|
-
test.describe(BunRoute.htmlBundle, () => {
|
|
21
|
-
test.test("wraps child content with layout", async () => {
|
|
22
|
-
const routes = Route.tree({
|
|
23
|
-
"/": Route.get(
|
|
24
|
-
BunRoute.htmlBundle(() => import("../../static/LayoutSlots.html")),
|
|
25
|
-
Route.html("<p>Hello World</p>"),
|
|
26
|
-
),
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
const response = await Effect.runPromise(
|
|
30
|
-
Effect.scoped(
|
|
31
|
-
Effect
|
|
32
|
-
.gen(function*() {
|
|
33
|
-
const bunServer = yield* BunHttpServer.BunHttpServer
|
|
34
|
-
return yield* Effect.promise(() =>
|
|
35
|
-
fetch(`http://localhost:${bunServer.server.port}/`)
|
|
36
|
-
)
|
|
37
|
-
})
|
|
38
|
-
.pipe(Effect.provide(testLayer(routes))),
|
|
39
|
-
),
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
test.expect(response.status).toBe(200)
|
|
43
|
-
const html = await response.text()
|
|
44
|
-
test.expect(html).toContain("<p>Hello World</p>")
|
|
45
|
-
test.expect(html).toContain("<body>")
|
|
46
|
-
test.expect(html).toContain("</body>")
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
test.test("replaces %yield% with child content", async () => {
|
|
50
|
-
const routes = Route.tree({
|
|
51
|
-
"/page": Route.get(
|
|
52
|
-
BunRoute.htmlBundle(() => import("../../static/LayoutSlots.html")),
|
|
53
|
-
Route.html("<div>Page Content</div>"),
|
|
54
|
-
),
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
const response = await Effect.runPromise(
|
|
58
|
-
Effect.scoped(
|
|
59
|
-
Effect
|
|
60
|
-
.gen(function*() {
|
|
61
|
-
const bunServer = yield* BunHttpServer.BunHttpServer
|
|
62
|
-
return yield* Effect.promise(() =>
|
|
63
|
-
fetch(`http://localhost:${bunServer.server.port}/page`)
|
|
64
|
-
)
|
|
65
|
-
})
|
|
66
|
-
.pipe(Effect.provide(testLayer(routes))),
|
|
67
|
-
),
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
const html = await response.text()
|
|
71
|
-
test.expect(html).toContain("<div>Page Content</div>")
|
|
72
|
-
test.expect(html).not.toContain("%children%")
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
test.test("works with use() for wildcard routes", async () => {
|
|
76
|
-
const routes = Route.tree({
|
|
77
|
-
"*": Route.use(
|
|
78
|
-
BunRoute.htmlBundle(() => import("../../static/LayoutSlots.html")),
|
|
79
|
-
),
|
|
80
|
-
"/:path*": Route.get(Route.html("<section>Catch All</section>")),
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
const response = await Effect.runPromise(
|
|
84
|
-
Effect.scoped(
|
|
85
|
-
Effect
|
|
86
|
-
.gen(function*() {
|
|
87
|
-
const bunServer = yield* BunHttpServer.BunHttpServer
|
|
88
|
-
return yield* Effect.promise(() =>
|
|
89
|
-
fetch(`http://localhost:${bunServer.server.port}/any/path`)
|
|
90
|
-
)
|
|
91
|
-
})
|
|
92
|
-
.pipe(Effect.provide(testLayer(routes))),
|
|
93
|
-
),
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
test.expect(response.status).toBe(200)
|
|
97
|
-
const html = await response.text()
|
|
98
|
-
test.expect(html).toContain("<section>Catch All</section>")
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
test.test("has format: html descriptor", async () => {
|
|
102
|
-
const routes = Route.tree({
|
|
103
|
-
"/": Route.get(
|
|
104
|
-
BunRoute.htmlBundle(() => import("../../static/LayoutSlots.html")),
|
|
105
|
-
Route.html("<p>content</p>"),
|
|
106
|
-
),
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
const response = await Effect.runPromise(
|
|
110
|
-
Effect.scoped(
|
|
111
|
-
Effect
|
|
112
|
-
.gen(function*() {
|
|
113
|
-
const bunServer = yield* BunHttpServer.BunHttpServer
|
|
114
|
-
return yield* Effect.promise(() =>
|
|
115
|
-
fetch(`http://localhost:${bunServer.server.port}/`)
|
|
116
|
-
)
|
|
117
|
-
})
|
|
118
|
-
.pipe(Effect.provide(testLayer(routes))),
|
|
119
|
-
),
|
|
120
|
-
)
|
|
121
|
-
|
|
122
|
-
test.expect(response.status).toBe(200)
|
|
123
|
-
const contentType = response.headers.get("content-type")
|
|
124
|
-
test.expect(contentType).toContain("text/html")
|
|
125
|
-
})
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
test.describe(BunRoute.validateBunPattern, () => {
|
|
129
|
-
test.test("returns none for valid patterns", () => {
|
|
130
|
-
test
|
|
131
|
-
.expect(Option.isNone(BunRoute.validateBunPattern("/users")))
|
|
132
|
-
.toBe(true)
|
|
133
|
-
test
|
|
134
|
-
.expect(Option.isNone(BunRoute.validateBunPattern("/users/[id]")))
|
|
135
|
-
.toBe(true)
|
|
136
|
-
test
|
|
137
|
-
.expect(Option.isNone(BunRoute.validateBunPattern("/[...rest]")))
|
|
138
|
-
.toBe(true)
|
|
139
|
-
})
|
|
140
|
-
|
|
141
|
-
test.test("returns error for prefixed params", () => {
|
|
142
|
-
const result = BunRoute.validateBunPattern("/pk_[id]")
|
|
143
|
-
test.expect(Option.isSome(result)).toBe(true)
|
|
144
|
-
})
|
|
145
|
-
|
|
146
|
-
test.test("returns error for suffixed params", () => {
|
|
147
|
-
const result = BunRoute.validateBunPattern("/[id]_suffix")
|
|
148
|
-
test.expect(Option.isSome(result)).toBe(true)
|
|
149
|
-
})
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
test.describe(BunRoute.isHtmlBundle, () => {
|
|
153
|
-
test.test("returns false for non-objects", () => {
|
|
154
|
-
test.expect(BunRoute.isHtmlBundle(null)).toBe(false)
|
|
155
|
-
test.expect(BunRoute.isHtmlBundle(undefined)).toBe(false)
|
|
156
|
-
test.expect(BunRoute.isHtmlBundle("string")).toBe(false)
|
|
157
|
-
})
|
|
158
|
-
|
|
159
|
-
test.test("returns true for object with index property", () => {
|
|
160
|
-
test.expect(BunRoute.isHtmlBundle({ index: "index.html" })).toBe(true)
|
|
161
|
-
})
|
|
162
|
-
})
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import * as HttpRouter from "@effect/platform/HttpRouter"
|
|
2
|
-
import * as HttpServerResponse from "@effect/platform/HttpServerResponse"
|
|
3
|
-
import * as test from "bun:test"
|
|
4
|
-
import * as Effect from "effect/Effect"
|
|
5
|
-
import * as Layer from "effect/Layer"
|
|
6
|
-
import IndexHtml from "../../static/react-dashboard.html" with { type: "file" }
|
|
7
|
-
import * as BunBundle from "../bun/BunBundle.ts"
|
|
8
|
-
import { effectFn } from "../testing"
|
|
9
|
-
import * as TestHttpClient from "../testing/TestHttpClient.ts"
|
|
10
|
-
import * as Bundle from "./Bundle.ts"
|
|
11
|
-
import * as BundleHttp from "./BundleHttp.ts"
|
|
12
|
-
|
|
13
|
-
const effect = effectFn(
|
|
14
|
-
Layer.effect(
|
|
15
|
-
Bundle.ClientBundle,
|
|
16
|
-
BunBundle.buildClient(IndexHtml as any),
|
|
17
|
-
),
|
|
18
|
-
)
|
|
19
|
-
|
|
20
|
-
test.it("entrypoint with specific uri", () =>
|
|
21
|
-
effect(function*() {
|
|
22
|
-
const App = HttpRouter.empty.pipe(
|
|
23
|
-
HttpRouter.get(
|
|
24
|
-
"/react-dashboard",
|
|
25
|
-
BundleHttp.entrypoint("../static/react-dashboard.html"),
|
|
26
|
-
),
|
|
27
|
-
)
|
|
28
|
-
const Client = TestHttpClient.make(App)
|
|
29
|
-
|
|
30
|
-
const dashboardRes = yield* Client.get("/react-dashboard")
|
|
31
|
-
test
|
|
32
|
-
.expect(dashboardRes.status)
|
|
33
|
-
.toBe(200)
|
|
34
|
-
test
|
|
35
|
-
.expect(yield* dashboardRes.text)
|
|
36
|
-
.toStartWith("<!DOCTYPE html>")
|
|
37
|
-
}))
|
|
38
|
-
|
|
39
|
-
test.it("entrypoint without uri parameter", () =>
|
|
40
|
-
effect(function*() {
|
|
41
|
-
const App = HttpRouter.empty.pipe(
|
|
42
|
-
HttpRouter.get(
|
|
43
|
-
"/",
|
|
44
|
-
BundleHttp.entrypoint(),
|
|
45
|
-
),
|
|
46
|
-
HttpRouter.get(
|
|
47
|
-
"/index",
|
|
48
|
-
BundleHttp.entrypoint(),
|
|
49
|
-
),
|
|
50
|
-
HttpRouter.get(
|
|
51
|
-
"/react-dashboard",
|
|
52
|
-
BundleHttp.entrypoint(),
|
|
53
|
-
),
|
|
54
|
-
HttpRouter.get(
|
|
55
|
-
"/nonexistent",
|
|
56
|
-
BundleHttp.entrypoint(),
|
|
57
|
-
),
|
|
58
|
-
)
|
|
59
|
-
const Client = TestHttpClient.make(App)
|
|
60
|
-
|
|
61
|
-
const indexRes = yield* Client.get("/").pipe(
|
|
62
|
-
Effect.catchTag(
|
|
63
|
-
"RouteNotFound",
|
|
64
|
-
() => HttpServerResponse.empty({ status: 404 }),
|
|
65
|
-
),
|
|
66
|
-
)
|
|
67
|
-
test
|
|
68
|
-
.expect(indexRes.status)
|
|
69
|
-
.toBe(404)
|
|
70
|
-
|
|
71
|
-
const indexPathRes = yield* Client.get("/index").pipe(
|
|
72
|
-
Effect.catchTag(
|
|
73
|
-
"RouteNotFound",
|
|
74
|
-
() => HttpServerResponse.empty({ status: 404 }),
|
|
75
|
-
),
|
|
76
|
-
)
|
|
77
|
-
test
|
|
78
|
-
.expect(indexPathRes.status)
|
|
79
|
-
.toBe(404)
|
|
80
|
-
|
|
81
|
-
const dashboardRes = yield* Client.get("/react-dashboard")
|
|
82
|
-
test
|
|
83
|
-
.expect(dashboardRes.status)
|
|
84
|
-
.toBe(200)
|
|
85
|
-
test
|
|
86
|
-
.expect(yield* dashboardRes.text)
|
|
87
|
-
.toStartWith("<!DOCTYPE html>")
|
|
88
|
-
|
|
89
|
-
const nonexistentRes = yield* Client.get("/nonexistent").pipe(
|
|
90
|
-
Effect.catchTag(
|
|
91
|
-
"RouteNotFound",
|
|
92
|
-
() => HttpServerResponse.empty({ status: 404 }),
|
|
93
|
-
),
|
|
94
|
-
)
|
|
95
|
-
test
|
|
96
|
-
.expect(nonexistentRes.status)
|
|
97
|
-
.toBe(404)
|
|
98
|
-
}))
|
|
99
|
-
|
|
100
|
-
test.it("withEntrypoints middleware", () =>
|
|
101
|
-
effect(function*() {
|
|
102
|
-
const fallbackApp = Effect.succeed(
|
|
103
|
-
HttpServerResponse.text("Fallback", { status: 404 }),
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
const App = BundleHttp.withEntrypoints()(fallbackApp)
|
|
107
|
-
const Client = TestHttpClient.make(App)
|
|
108
|
-
|
|
109
|
-
const rootRes = yield* Client.get("/")
|
|
110
|
-
test
|
|
111
|
-
.expect(rootRes.status)
|
|
112
|
-
.toBe(404)
|
|
113
|
-
test
|
|
114
|
-
.expect(yield* rootRes.text)
|
|
115
|
-
.toBe("Fallback")
|
|
116
|
-
|
|
117
|
-
const dashboardRes = yield* Client.get("/react-dashboard")
|
|
118
|
-
test
|
|
119
|
-
.expect(dashboardRes.status)
|
|
120
|
-
.toBe(200)
|
|
121
|
-
test
|
|
122
|
-
.expect(yield* dashboardRes.text)
|
|
123
|
-
.toStartWith("<!DOCTYPE html>")
|
|
124
|
-
|
|
125
|
-
const nonexistentRes = yield* Client.get("/nonexistent")
|
|
126
|
-
test
|
|
127
|
-
.expect(nonexistentRes.status)
|
|
128
|
-
.toBe(404)
|
|
129
|
-
test
|
|
130
|
-
.expect(yield* nonexistentRes.text)
|
|
131
|
-
.toBe("Fallback")
|
|
132
|
-
}))
|