effect-start 0.14.0 → 0.16.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.
Files changed (87) hide show
  1. package/package.json +8 -9
  2. package/src/Commander.test.ts +507 -245
  3. package/src/ContentNegotiation.test.ts +603 -0
  4. package/src/ContentNegotiation.ts +542 -0
  5. package/src/Entity.test.ts +592 -0
  6. package/src/Entity.ts +362 -0
  7. package/src/FileRouter.ts +16 -12
  8. package/src/{FileRouterCodegen.test.ts → FileRouterCodegen.todo.ts} +384 -219
  9. package/src/FileRouterCodegen.ts +6 -6
  10. package/src/FileRouterPattern.test.ts +93 -62
  11. package/src/FileRouter_files.test.ts +5 -5
  12. package/src/FileRouter_path.test.ts +121 -69
  13. package/src/FileRouter_tree.test.ts +62 -56
  14. package/src/FileSystemExtra.test.ts +46 -30
  15. package/src/Http.test.ts +319 -0
  16. package/src/Http.ts +167 -0
  17. package/src/HttpAppExtra.test.ts +39 -20
  18. package/src/HttpAppExtra.ts +0 -1
  19. package/src/HttpUtils.test.ts +35 -18
  20. package/src/HttpUtils.ts +2 -0
  21. package/src/PathPattern.test.ts +648 -0
  22. package/src/PathPattern.ts +485 -0
  23. package/src/Route.ts +266 -1069
  24. package/src/RouteBody.test.ts +234 -0
  25. package/src/RouteBody.ts +193 -0
  26. package/src/RouteHook.test.ts +40 -0
  27. package/src/RouteHook.ts +106 -0
  28. package/src/RouteHttp.test.ts +2906 -0
  29. package/src/RouteHttp.ts +427 -0
  30. package/src/RouteHttpTracer.ts +92 -0
  31. package/src/RouteMount.test.ts +481 -0
  32. package/src/RouteMount.ts +470 -0
  33. package/src/RouteSchema.test.ts +427 -0
  34. package/src/RouteSchema.ts +423 -0
  35. package/src/RouteTree.test.ts +494 -0
  36. package/src/RouteTree.ts +219 -0
  37. package/src/RouteTrie.test.ts +322 -0
  38. package/src/RouteTrie.ts +224 -0
  39. package/src/RouterPattern.test.ts +569 -548
  40. package/src/RouterPattern.ts +7 -7
  41. package/src/Start.ts +3 -3
  42. package/src/StreamExtra.ts +21 -1
  43. package/src/TuplePathPattern.ts +64 -0
  44. package/src/Values.test.ts +263 -0
  45. package/src/Values.ts +76 -0
  46. package/src/bun/BunBundle.test.ts +36 -42
  47. package/src/bun/BunBundle.ts +2 -2
  48. package/src/bun/BunBundle_imports.test.ts +4 -6
  49. package/src/bun/BunHttpServer.test.ts +183 -6
  50. package/src/bun/BunHttpServer.ts +72 -32
  51. package/src/bun/BunHttpServer_web.ts +18 -6
  52. package/src/bun/BunImportTrackerPlugin.test.ts +3 -3
  53. package/src/bun/BunRoute.test.ts +124 -442
  54. package/src/bun/BunRoute.ts +146 -286
  55. package/src/{BundleHttp.test.ts → bundler/BundleHttp.test.ts} +34 -60
  56. package/src/{BundleHttp.ts → bundler/BundleHttp.ts} +1 -2
  57. package/src/client/index.ts +1 -1
  58. package/src/{Effect_HttpRouter.test.ts → effect/HttpRouter.test.ts} +69 -90
  59. package/src/experimental/EncryptedCookies.test.ts +125 -64
  60. package/src/experimental/SseHttpResponse.ts +0 -1
  61. package/src/hyper/Hyper.ts +89 -0
  62. package/src/{HyperHtml.test.ts → hyper/HyperHtml.test.ts} +13 -13
  63. package/src/{HyperHtml.ts → hyper/HyperHtml.ts} +2 -2
  64. package/src/{jsx.d.ts → hyper/jsx.d.ts} +1 -1
  65. package/src/index.ts +3 -4
  66. package/src/middlewares/BasicAuthMiddleware.test.ts +29 -19
  67. package/src/{NodeFileSystem.ts → node/FileSystem.ts} +6 -2
  68. package/src/testing/TestHttpClient.test.ts +26 -26
  69. package/src/testing/TestLogger.test.ts +27 -14
  70. package/src/testing/TestLogger.ts +15 -9
  71. package/src/x/datastar/Datastar.test.ts +47 -48
  72. package/src/x/datastar/Datastar.ts +1 -1
  73. package/src/x/tailwind/TailwindPlugin.test.ts +56 -58
  74. package/src/x/tailwind/plugin.ts +1 -1
  75. package/src/FileHttpRouter.test.ts +0 -239
  76. package/src/FileHttpRouter.ts +0 -194
  77. package/src/Hyper.ts +0 -194
  78. package/src/Route.test.ts +0 -1370
  79. package/src/RouteRender.ts +0 -40
  80. package/src/Router.test.ts +0 -375
  81. package/src/Router.ts +0 -255
  82. package/src/bun/BunRoute_bundles.test.ts +0 -219
  83. /package/src/{Bundle.ts → bundler/Bundle.ts} +0 -0
  84. /package/src/{BundleFiles.ts → bundler/BundleFiles.ts} +0 -0
  85. /package/src/{HyperNode.ts → hyper/HyperNode.ts} +0 -0
  86. /package/src/{jsx-runtime.ts → hyper/jsx-runtime.ts} +0 -0
  87. /package/src/{NodeUtils.ts → node/Utils.ts} +0 -0
@@ -1,18 +1,17 @@
1
1
  import * as Error from "@effect/platform/Error"
2
2
  import * as FileSystem from "@effect/platform/FileSystem"
3
- import * as t from "bun:test"
3
+ import * as test from "bun:test"
4
4
  import * as Effect from "effect/Effect"
5
5
  import * as Schema from "effect/Schema"
6
6
  import * as Scope from "effect/Scope"
7
7
  import * as path from "node:path"
8
+ import * as NodeFileSystem from "../node/FileSystem.ts"
9
+ import * as SchemaExtra from "../SchemaExtra.ts"
10
+ import * as TestLogger from "../testing/TestLogger.ts"
8
11
  import * as FileRouter from "./FileRouter.ts"
9
12
  import { parseRoute } from "./FileRouter.ts"
10
13
  import type { RouteHandle } from "./FileRouter.ts"
11
14
  import * as FileRouterCodegen from "./FileRouterCodegen.ts"
12
- import * as NodeFileSystem from "./NodeFileSystem.ts"
13
- import * as Route from "./Route.ts"
14
- import * as SchemaExtra from "./SchemaExtra.ts"
15
- import * as TestLogger from "./testing/TestLogger.ts"
16
15
 
17
16
  function createTempDirWithFiles(
18
17
  files: Record<string, string>,
@@ -37,7 +36,7 @@ function createTempDirWithFiles(
37
36
  })
38
37
  }
39
38
 
40
- t.it("generates code for routes only", () => {
39
+ test.it("generates code for routes only", () => {
41
40
  const handles: RouteHandle[] = [
42
41
  parseRoute("route.tsx"),
43
42
  parseRoute("about/route.tsx"),
@@ -49,8 +48,6 @@ t.it("generates code for routes only", () => {
49
48
  * Auto-generated by effect-start.
50
49
  */
51
50
 
52
- import type { Router } from "effect-start"
53
-
54
51
  export const routes = [
55
52
  {
56
53
  path: "/",
@@ -63,10 +60,12 @@ export const routes = [
63
60
  ] as const
64
61
  `
65
62
 
66
- t.expect(code).toBe(expected)
63
+ test
64
+ .expect(code)
65
+ .toBe(expected)
67
66
  })
68
67
 
69
- t.it("generates code with layers", () => {
68
+ test.it("generates code with layers", () => {
70
69
  const handles: RouteHandle[] = [
71
70
  parseRoute("layer.tsx"),
72
71
  parseRoute("route.tsx"),
@@ -79,8 +78,6 @@ t.it("generates code with layers", () => {
79
78
  * Auto-generated by effect-start.
80
79
  */
81
80
 
82
- import type { Router } from "effect-start"
83
-
84
81
  export const routes = [
85
82
  {
86
83
  path: "/",
@@ -99,10 +96,12 @@ export const routes = [
99
96
  ] as const
100
97
  `
101
98
 
102
- t.expect(code).toBe(expected)
99
+ test
100
+ .expect(code)
101
+ .toBe(expected)
103
102
  })
104
103
 
105
- t.it("generates code with nested layers", () => {
104
+ test.it("generates code with nested layers", () => {
106
105
  const handles: RouteHandle[] = [
107
106
  parseRoute("layer.tsx"),
108
107
  parseRoute("dashboard/layer.tsx"),
@@ -116,8 +115,6 @@ t.it("generates code with nested layers", () => {
116
115
  * Auto-generated by effect-start.
117
116
  */
118
117
 
119
- import type { Router } from "effect-start"
120
-
121
118
  export const routes = [
122
119
  {
123
120
  path: "/dashboard",
@@ -138,10 +135,12 @@ export const routes = [
138
135
  ] as const
139
136
  `
140
137
 
141
- t.expect(code).toBe(expected)
138
+ test
139
+ .expect(code)
140
+ .toBe(expected)
142
141
  })
143
142
 
144
- t.it("only includes group layers for routes in that group", () => {
143
+ test.it("only includes group layers for routes in that group", () => {
145
144
  const handles: RouteHandle[] = [
146
145
  parseRoute("layer.tsx"),
147
146
  parseRoute("(admin)/layer.ts"),
@@ -151,16 +150,19 @@ t.it("only includes group layers for routes in that group", () => {
151
150
 
152
151
  const code = FileRouterCodegen.generateCode(handles)
153
152
 
154
- t.expect(code).toContain("path: \"/users\"")
155
-
156
- t.expect(code).toContain("path: \"/movies\"")
153
+ test
154
+ .expect(code)
155
+ .toContain("path: \"/users\"")
156
+ test
157
+ .expect(code)
158
+ .toContain("path: \"/movies\"")
159
+ test
160
+ .expect(code)
161
+ .toContain("() => import(\"./layer.tsx\")")
162
+ test
163
+ .expect(code)
164
+ .toContain("() => import(\"./(admin)/layer.ts\")")
157
165
 
158
- // /users should have both root layer and (admin) layer
159
- t.expect(code).toContain("() => import(\"./layer.tsx\")")
160
-
161
- t.expect(code).toContain("() => import(\"./(admin)/layer.ts\")")
162
-
163
- // /movies should only have root layer, not (admin) layer
164
166
  const expectedMovies = ` {
165
167
  path: "/movies",
166
168
  load: () => import("./movies/route.tsx"),
@@ -169,10 +171,12 @@ t.it("only includes group layers for routes in that group", () => {
169
171
  ],
170
172
  },`
171
173
 
172
- t.expect(code).toContain(expectedMovies)
174
+ test
175
+ .expect(code)
176
+ .toContain(expectedMovies)
173
177
  })
174
178
 
175
- t.it("handles dynamic routes with params", () => {
179
+ test.it("handles dynamic routes with params", () => {
176
180
  const handles: RouteHandle[] = [
177
181
  parseRoute("users/route.tsx"),
178
182
  parseRoute("users/[userId]/route.tsx"),
@@ -181,12 +185,18 @@ t.it("handles dynamic routes with params", () => {
181
185
 
182
186
  const code = FileRouterCodegen.generateCode(handles)
183
187
 
184
- t.expect(code).toContain("path: \"/users\"")
185
- t.expect(code).toContain("path: \"/users/[userId]\"")
186
- t.expect(code).toContain("path: \"/posts/[postId]/comments/[commentId]\"")
188
+ test
189
+ .expect(code)
190
+ .toContain("path: \"/users\"")
191
+ test
192
+ .expect(code)
193
+ .toContain("path: \"/users/[userId]\"")
194
+ test
195
+ .expect(code)
196
+ .toContain("path: \"/posts/[postId]/comments/[commentId]\"")
187
197
  })
188
198
 
189
- t.it("handles rest parameters", () => {
199
+ test.it("handles rest parameters", () => {
190
200
  const handles: RouteHandle[] = [
191
201
  parseRoute("docs/[[...slug]]/route.tsx"),
192
202
  parseRoute("api/[...path]/route.tsx"),
@@ -194,11 +204,15 @@ t.it("handles rest parameters", () => {
194
204
 
195
205
  const code = FileRouterCodegen.generateCode(handles)
196
206
 
197
- t.expect(code).toContain("path: \"/docs/[[...slug]]\"")
198
- t.expect(code).toContain("path: \"/api/[...path]\"")
207
+ test
208
+ .expect(code)
209
+ .toContain("path: \"/docs/[[...slug]]\"")
210
+ test
211
+ .expect(code)
212
+ .toContain("path: \"/api/[...path]\"")
199
213
  })
200
214
 
201
- t.it("handles groups in path", () => {
215
+ test.it("handles groups in path", () => {
202
216
  const handles: RouteHandle[] = [
203
217
  parseRoute("(admin)/users/route.tsx"),
204
218
  parseRoute("(admin)/layer.tsx"),
@@ -206,23 +220,29 @@ t.it("handles groups in path", () => {
206
220
 
207
221
  const code = FileRouterCodegen.generateCode(handles)
208
222
 
209
- t.expect(code).toContain("path: \"/users\"") // groups stripped from URL
210
- t.expect(code).toContain(
211
- "layers: [\n () => import(\"./(admin)/layer.tsx\"),\n ]",
212
- )
223
+ test
224
+ .expect(code)
225
+ .toContain("path: \"/users\"")
226
+ test
227
+ .expect(code)
228
+ .toContain(
229
+ "layers: [\n () => import(\"./(admin)/layer.tsx\"),\n ]",
230
+ )
213
231
  })
214
232
 
215
- t.it("generates correct variable names for root routes", () => {
233
+ test.it("generates correct variable names for root routes", () => {
216
234
  const handles: RouteHandle[] = [
217
235
  parseRoute("route.tsx"),
218
236
  ]
219
237
 
220
238
  const code = FileRouterCodegen.generateCode(handles)
221
239
 
222
- t.expect(code).toContain("path: \"/\"")
240
+ test
241
+ .expect(code)
242
+ .toContain("path: \"/\"")
223
243
  })
224
244
 
225
- t.it("handles routes with dots in path segments", () => {
245
+ test.it("handles routes with dots in path segments", () => {
226
246
  const handles: RouteHandle[] = [
227
247
  parseRoute("events.json/route.ts"),
228
248
  parseRoute("config.yaml.backup/route.ts"),
@@ -230,29 +250,33 @@ t.it("handles routes with dots in path segments", () => {
230
250
 
231
251
  const code = FileRouterCodegen.generateCode(handles)
232
252
 
233
- t.expect(code).toContain("path: \"/events.json\"")
234
- t.expect(code).toContain("path: \"/config.yaml.backup\"")
253
+ test
254
+ .expect(code)
255
+ .toContain("path: \"/events.json\"")
256
+ test
257
+ .expect(code)
258
+ .toContain("path: \"/config.yaml.backup\"")
235
259
  })
236
260
 
237
- t.it("uses default module identifier", () => {
261
+ test.it("uses default module identifier", () => {
238
262
  const handles: RouteHandle[] = [
239
263
  parseRoute("route.tsx"),
240
264
  ]
241
265
 
242
266
  const code = FileRouterCodegen.generateCode(handles)
243
-
244
- t.expect(code).toContain("import type { Router } from \"effect-start\"")
245
267
  })
246
268
 
247
- t.it("generates empty routes array when no handles provided", () => {
269
+ test.it("generates empty routes array when no handles provided", () => {
248
270
  const handles: RouteHandle[] = []
249
271
 
250
272
  const code = FileRouterCodegen.generateCode(handles)
251
273
 
252
- t.expect(code).toContain("export const routes = [] as const")
274
+ test
275
+ .expect(code)
276
+ .toContain("export const routes = [] as const")
253
277
  })
254
278
 
255
- t.it("only includes routes, not layers", () => {
279
+ test.it("only includes routes, not layers", () => {
256
280
  const handles: RouteHandle[] = [
257
281
  parseRoute("layer.tsx"),
258
282
  parseRoute("users/layer.tsx"),
@@ -260,10 +284,12 @@ t.it("only includes routes, not layers", () => {
260
284
 
261
285
  const code = FileRouterCodegen.generateCode(handles)
262
286
 
263
- t.expect(code).toContain("export const routes = [] as const")
287
+ test
288
+ .expect(code)
289
+ .toContain("export const routes = [] as const")
264
290
  })
265
291
 
266
- t.it("complex nested routes with multiple layers", () => {
292
+ test.it("complex nested routes with multiple layers", () => {
267
293
  const handles: RouteHandle[] = [
268
294
  parseRoute("layer.tsx"),
269
295
  parseRoute("(auth)/layer.tsx"),
@@ -276,18 +302,30 @@ t.it("complex nested routes with multiple layers", () => {
276
302
 
277
303
  const code = FileRouterCodegen.generateCode(handles)
278
304
 
279
- t.expect(code).toContain("path: \"/login\"") // group stripped
280
- t.expect(code).toContain("path: \"/signup\"") // group stripped
281
- t.expect(code).toContain("path: \"/dashboard\"")
282
- t.expect(code).toContain("path: \"/dashboard/settings\"")
283
-
284
- // Check layers are properly inherited
285
- t.expect(code).toContain("() => import(\"./layer.tsx\")")
286
- t.expect(code).toContain("() => import(\"./(auth)/layer.tsx\")")
287
- t.expect(code).toContain("() => import(\"./dashboard/layer.tsx\")")
305
+ test
306
+ .expect(code)
307
+ .toContain("path: \"/login\"")
308
+ test
309
+ .expect(code)
310
+ .toContain("path: \"/signup\"")
311
+ test
312
+ .expect(code)
313
+ .toContain("path: \"/dashboard\"")
314
+ test
315
+ .expect(code)
316
+ .toContain("path: \"/dashboard/settings\"")
317
+ test
318
+ .expect(code)
319
+ .toContain("() => import(\"./layer.tsx\")")
320
+ test
321
+ .expect(code)
322
+ .toContain("() => import(\"./(auth)/layer.tsx\")")
323
+ test
324
+ .expect(code)
325
+ .toContain("() => import(\"./dashboard/layer.tsx\")")
288
326
  })
289
327
 
290
- t.it("handles routes with hyphens and underscores in path segments", () => {
328
+ test.it("handles routes with hyphens and underscores in path segments", () => {
291
329
  const handles: RouteHandle[] = [
292
330
  parseRoute("api-v1/route.ts"),
293
331
  parseRoute("my_resource/route.ts"),
@@ -295,66 +333,55 @@ t.it("handles routes with hyphens and underscores in path segments", () => {
295
333
 
296
334
  const code = FileRouterCodegen.generateCode(handles)
297
335
 
298
- t.expect(code).toContain("path: \"/api-v1\"")
299
- t.expect(code).toContain("path: \"/my_resource\"")
336
+ test
337
+ .expect(code)
338
+ .toContain("path: \"/api-v1\"")
339
+ test
340
+ .expect(code)
341
+ .toContain("path: \"/my_resource\"")
300
342
  })
301
343
 
302
- t.it("validateRouteModule returns true for valid modules", () => {
303
- const validRoute = Route.text("Hello")
304
-
305
- t
306
- .expect(FileRouterCodegen.validateRouteModule({ default: validRoute }))
307
- .toBe(true)
308
-
309
- t
310
- .expect(FileRouterCodegen.validateRouteModule({
311
- default: Route.html(Effect.succeed("<div>Hello</div>")),
312
- }))
313
- .toBe(true)
314
-
315
- t
316
- .expect(FileRouterCodegen.validateRouteModule({
317
- default: Route.json({ message: "Hello" }),
318
- }))
319
- .toBe(true)
320
- })
321
-
322
- t.it("validateRouteModule returns false for invalid modules", () => {
323
- t.expect(FileRouterCodegen.validateRouteModule({})).toBe(false)
324
-
325
- t
344
+ test.it.skip("validateRouteModule returns false for invalid modules", () => {
345
+ test
346
+ .expect(FileRouterCodegen.validateRouteModule({}))
347
+ .toBe(false)
348
+ test
326
349
  .expect(FileRouterCodegen.validateRouteModule({ default: {} }))
327
350
  .toBe(false)
328
-
329
- t
351
+ test
330
352
  .expect(FileRouterCodegen.validateRouteModule({ default: "not a route" }))
331
353
  .toBe(false)
332
-
333
- t
354
+ test
334
355
  .expect(FileRouterCodegen.validateRouteModule({ foo: "bar" }))
335
356
  .toBe(false)
336
-
337
- t.expect(FileRouterCodegen.validateRouteModule(null)).toBe(false)
338
-
339
- t.expect(FileRouterCodegen.validateRouteModule(undefined)).toBe(false)
340
-
341
- t.expect(FileRouterCodegen.validateRouteModule("string")).toBe(false)
342
-
343
- t.expect(FileRouterCodegen.validateRouteModule(42)).toBe(false)
357
+ test
358
+ .expect(FileRouterCodegen.validateRouteModule(null))
359
+ .toBe(false)
360
+ test
361
+ .expect(FileRouterCodegen.validateRouteModule(undefined))
362
+ .toBe(false)
363
+ test
364
+ .expect(FileRouterCodegen.validateRouteModule("string"))
365
+ .toBe(false)
366
+ test
367
+ .expect(FileRouterCodegen.validateRouteModule(42))
368
+ .toBe(false)
344
369
  })
345
370
 
346
- t.it("mixed params and rest in same route", () => {
371
+ test.it("mixed params and rest in same route", () => {
347
372
  const handles: RouteHandle[] = [
348
373
  parseRoute("users/[userId]/files/[...path]/route.tsx"),
349
374
  ]
350
375
 
351
376
  const code = FileRouterCodegen.generateCode(handles)
352
377
 
353
- t.expect(code).toContain("path: \"/users/[userId]/files/[...path]\"")
378
+ test
379
+ .expect(code)
380
+ .toContain("path: \"/users/[userId]/files/[...path]\"")
354
381
  })
355
382
 
356
- t.describe("layerMatchesRoute", () => {
357
- t.it("layer in dynamic param dir only applies to routes in that dir", () => {
383
+ test.describe("layerMatchesRoute", () => {
384
+ test.it("layer in dynamic param dir only applies to routes in that dir", () => {
358
385
  const handles: RouteHandle[] = [
359
386
  parseRoute("[userId]/layer.tsx"),
360
387
  parseRoute("[userId]/posts/route.tsx"),
@@ -371,17 +398,21 @@ t.describe("layerMatchesRoute", () => {
371
398
  ],
372
399
  },`
373
400
 
374
- t.expect(code).toContain(expectedUserIdPosts)
401
+ test
402
+ .expect(code)
403
+ .toContain(expectedUserIdPosts)
375
404
 
376
405
  const expectedOtherId = ` {
377
406
  path: "/[otherId]",
378
407
  load: () => import("./[otherId]/route.tsx"),
379
408
  },`
380
409
 
381
- t.expect(code).toContain(expectedOtherId)
410
+ test
411
+ .expect(code)
412
+ .toContain(expectedOtherId)
382
413
  })
383
414
 
384
- t.it("nested groups only apply to routes in those groups", () => {
415
+ test.it("nested groups only apply to routes in those groups", () => {
385
416
  const handles: RouteHandle[] = [
386
417
  parseRoute("layer.tsx"),
387
418
  parseRoute("(admin)/(dashboard)/layer.tsx"),
@@ -401,7 +432,9 @@ t.describe("layerMatchesRoute", () => {
401
432
  ],
402
433
  },`
403
434
 
404
- t.expect(code).toContain(expectedAdminDashboardUsers)
435
+ test
436
+ .expect(code)
437
+ .toContain(expectedAdminDashboardUsers)
405
438
 
406
439
  const expectedAdminSettings = ` {
407
440
  path: "/settings",
@@ -411,7 +444,9 @@ t.describe("layerMatchesRoute", () => {
411
444
  ],
412
445
  },`
413
446
 
414
- t.expect(code).toContain(expectedAdminSettings)
447
+ test
448
+ .expect(code)
449
+ .toContain(expectedAdminSettings)
415
450
 
416
451
  const expectedOtherDashboard = ` {
417
452
  path: "/",
@@ -421,10 +456,12 @@ t.describe("layerMatchesRoute", () => {
421
456
  ],
422
457
  },`
423
458
 
424
- t.expect(code).toContain(expectedOtherDashboard)
459
+ test
460
+ .expect(code)
461
+ .toContain(expectedOtherDashboard)
425
462
  })
426
463
 
427
- t.it("similar directory names do not match (user vs users)", () => {
464
+ test.it("similar directory names do not match (user vs users)", () => {
428
465
  const handles: RouteHandle[] = [
429
466
  parseRoute("user/layer.tsx"),
430
467
  parseRoute("user/route.tsx"),
@@ -441,17 +478,21 @@ t.describe("layerMatchesRoute", () => {
441
478
  ],
442
479
  },`
443
480
 
444
- t.expect(code).toContain(expectedUser)
481
+ test
482
+ .expect(code)
483
+ .toContain(expectedUser)
445
484
 
446
485
  const expectedUsers = ` {
447
486
  path: "/users",
448
487
  load: () => import("./users/route.tsx"),
449
488
  },`
450
489
 
451
- t.expect(code).toContain(expectedUsers)
490
+ test
491
+ .expect(code)
492
+ .toContain(expectedUsers)
452
493
  })
453
494
 
454
- t.it("mixed groups and literals layer matching", () => {
495
+ test.it("mixed groups and literals layer matching", () => {
455
496
  const handles: RouteHandle[] = [
456
497
  parseRoute("(admin)/users/layer.tsx"),
457
498
  parseRoute("(admin)/users/[userId]/route.tsx"),
@@ -469,24 +510,30 @@ t.describe("layerMatchesRoute", () => {
469
510
  ],
470
511
  },`
471
512
 
472
- t.expect(code).toContain(expectedAdminUsersId)
513
+ test
514
+ .expect(code)
515
+ .toContain(expectedAdminUsersId)
473
516
 
474
517
  const expectedUsers = ` {
475
518
  path: "/users",
476
519
  load: () => import("./users/route.tsx"),
477
520
  },`
478
521
 
479
- t.expect(code).toContain(expectedUsers)
522
+ test
523
+ .expect(code)
524
+ .toContain(expectedUsers)
480
525
 
481
526
  const expectedAdminPosts = ` {
482
527
  path: "/posts",
483
528
  load: () => import("./(admin)/posts/route.tsx"),
484
529
  },`
485
530
 
486
- t.expect(code).toContain(expectedAdminPosts)
531
+ test
532
+ .expect(code)
533
+ .toContain(expectedAdminPosts)
487
534
  })
488
535
 
489
- t.it("param directory layer only applies to routes in that dir", () => {
536
+ test.it("param directory layer only applies to routes in that dir", () => {
490
537
  const handles: RouteHandle[] = [
491
538
  parseRoute("[tenantId]/layer.tsx"),
492
539
  parseRoute("[tenantId]/settings/route.tsx"),
@@ -503,17 +550,21 @@ t.describe("layerMatchesRoute", () => {
503
550
  ],
504
551
  },`
505
552
 
506
- t.expect(code).toContain(expectedTenantSettings)
553
+ test
554
+ .expect(code)
555
+ .toContain(expectedTenantSettings)
507
556
 
508
557
  const expectedOther = ` {
509
558
  path: "/other",
510
559
  load: () => import("./other/route.tsx"),
511
560
  },`
512
561
 
513
- t.expect(code).toContain(expectedOther)
562
+ test
563
+ .expect(code)
564
+ .toContain(expectedOther)
514
565
  })
515
566
 
516
- t.it(
567
+ test.it(
517
568
  "optional param directory layer only applies to routes in that dir",
518
569
  () => {
519
570
  const handles: RouteHandle[] = [
@@ -532,18 +583,22 @@ t.describe("layerMatchesRoute", () => {
532
583
  ],
533
584
  },`
534
585
 
535
- t.expect(code).toContain(expectedIdSettings)
586
+ test
587
+ .expect(code)
588
+ .toContain(expectedIdSettings)
536
589
 
537
590
  const expectedOther = ` {
538
591
  path: "/other",
539
592
  load: () => import("./other/route.tsx"),
540
593
  },`
541
594
 
542
- t.expect(code).toContain(expectedOther)
595
+ test
596
+ .expect(code)
597
+ .toContain(expectedOther)
543
598
  },
544
599
  )
545
600
 
546
- t.it("layer and route at same directory level", () => {
601
+ test.it("layer and route at same directory level", () => {
547
602
  const handles: RouteHandle[] = [
548
603
  parseRoute("users/layer.tsx"),
549
604
  parseRoute("users/route.tsx"),
@@ -559,7 +614,9 @@ t.describe("layerMatchesRoute", () => {
559
614
  ],
560
615
  },`
561
616
 
562
- t.expect(code).toContain(expected)
617
+ test
618
+ .expect(code)
619
+ .toContain(expected)
563
620
  })
564
621
  })
565
622
 
@@ -569,7 +626,7 @@ const simpleRouteContent = `import * as Route from "${
569
626
  export default Route.text("Hello")
570
627
  `
571
628
 
572
- t.it("update() > writes file", () =>
629
+ test.it("update() > writes file", () =>
573
630
  Effect
574
631
  .gen(function*() {
575
632
  const fs = yield* FileSystem.FileSystem
@@ -585,7 +642,9 @@ t.it("update() > writes file", () =>
585
642
  path.join(routesPath, "manifest.ts"),
586
643
  )
587
644
 
588
- t.expect(content).toContain("export const routes =")
645
+ test
646
+ .expect(content)
647
+ .toContain("export const routes =")
589
648
  })
590
649
  .pipe(
591
650
  Effect.scoped,
@@ -593,7 +652,7 @@ t.it("update() > writes file", () =>
593
652
  Effect.runPromise,
594
653
  ))
595
654
 
596
- t.it("update() > writes only when it changes", () =>
655
+ test.it("update() > writes only when it changes", () =>
597
656
  Effect
598
657
  .gen(function*() {
599
658
  const fs = yield* FileSystem.FileSystem
@@ -615,8 +674,13 @@ t.it("update() > writes only when it changes", () =>
615
674
  path.join(routesPath, "manifest.ts"),
616
675
  )
617
676
 
618
- t.expect(content2).not.toBe("")
619
- t.expect(content2).toBe(content)
677
+ test
678
+ .expect(content2)
679
+ .not
680
+ .toBe("")
681
+ test
682
+ .expect(content2)
683
+ .toBe(content)
620
684
  })
621
685
  .pipe(
622
686
  Effect.scoped,
@@ -624,7 +688,7 @@ t.it("update() > writes only when it changes", () =>
624
688
  Effect.runPromise,
625
689
  ))
626
690
 
627
- t.it(
691
+ test.it(
628
692
  "update() > removes deleted routes from manifest",
629
693
  () =>
630
694
  Effect
@@ -642,8 +706,12 @@ t.it(
642
706
  path.join(routesPath, "manifest.ts"),
643
707
  )
644
708
 
645
- t.expect(content).toContain("path: \"/\"")
646
- t.expect(content).toContain("path: \"/about\"")
709
+ test
710
+ .expect(content)
711
+ .toContain("path: \"/\"")
712
+ test
713
+ .expect(content)
714
+ .toContain("path: \"/about\"")
647
715
 
648
716
  yield* fs.remove(path.join(routesPath, "about/route.tsx"))
649
717
 
@@ -653,8 +721,13 @@ t.it(
653
721
  path.join(routesPath, "manifest.ts"),
654
722
  )
655
723
 
656
- t.expect(content2).toContain("path: \"/\"")
657
- t.expect(content2).not.toContain("path: \"/about\"")
724
+ test
725
+ .expect(content2)
726
+ .toContain("path: \"/\"")
727
+ test
728
+ .expect(content2)
729
+ .not
730
+ .toContain("path: \"/about\"")
658
731
  })
659
732
  .pipe(
660
733
  Effect.scoped,
@@ -663,7 +736,7 @@ t.it(
663
736
  ),
664
737
  )
665
738
 
666
- t.it(
739
+ test.it(
667
740
  "update() > removes routes when entire directory is deleted",
668
741
  () =>
669
742
  Effect
@@ -682,9 +755,15 @@ t.it(
682
755
  path.join(routesPath, "manifest.ts"),
683
756
  )
684
757
 
685
- t.expect(content).toContain("path: \"/\"")
686
- t.expect(content).toContain("path: \"/about\"")
687
- t.expect(content).toContain("path: \"/users\"")
758
+ test
759
+ .expect(content)
760
+ .toContain("path: \"/\"")
761
+ test
762
+ .expect(content)
763
+ .toContain("path: \"/about\"")
764
+ test
765
+ .expect(content)
766
+ .toContain("path: \"/users\"")
688
767
 
689
768
  yield* fs.remove(path.join(routesPath, "users"), {
690
769
  recursive: true,
@@ -696,9 +775,16 @@ t.it(
696
775
  path.join(routesPath, "manifest.ts"),
697
776
  )
698
777
 
699
- t.expect(content2).toContain("path: \"/\"")
700
- t.expect(content2).toContain("path: \"/about\"")
701
- t.expect(content2).not.toContain("path: \"/users\"")
778
+ test
779
+ .expect(content2)
780
+ .toContain("path: \"/\"")
781
+ test
782
+ .expect(content2)
783
+ .toContain("path: \"/about\"")
784
+ test
785
+ .expect(content2)
786
+ .not
787
+ .toContain("path: \"/users\"")
702
788
  })
703
789
  .pipe(
704
790
  Effect.scoped,
@@ -707,121 +793,176 @@ t.it(
707
793
  ),
708
794
  )
709
795
 
710
- t.describe("PathParams schema generation and validation", () => {
711
- t.describe("generatePathParamsSchema", () => {
712
- t.it("returns null for routes with no params", () => {
796
+ test.describe("PathParams schema generation and validation", () => {
797
+ test.describe("generatePathParamsSchema", () => {
798
+ test.it("returns null for routes with no params", () => {
713
799
  const handle = parseRoute("users/route.tsx")
714
800
  const schema = FileRouterCodegen.generatePathParamsSchema(handle.segments)
715
- t.expect(schema).toBe(null)
801
+ test
802
+ .expect(schema)
803
+ .toBe(null)
716
804
  })
717
805
 
718
- t.it("generates schema for single required param", () => {
806
+ test.it("generates schema for single required param", () => {
719
807
  const handle = parseRoute("users/[id]/route.tsx")
720
808
  const schema = FileRouterCodegen.generatePathParamsSchema(handle.segments)
721
- t.expect(schema).not.toBe(null)
722
- t.expect(Object.keys(schema!.fields)).toEqual(["id"])
809
+ test
810
+ .expect(schema)
811
+ .not
812
+ .toBe(null)
813
+ test
814
+ .expect(Object.keys(schema!.fields))
815
+ .toEqual(["id"])
723
816
  })
724
817
 
725
- t.it("generates schema for single optional param", () => {
818
+ test.it("generates schema for single optional param", () => {
726
819
  const handle = parseRoute("about/[[section]]/route.tsx")
727
820
  const schema = FileRouterCodegen.generatePathParamsSchema(handle.segments)
728
- t.expect(schema).not.toBe(null)
729
- t.expect(Object.keys(schema!.fields)).toEqual(["section"])
821
+ test
822
+ .expect(schema)
823
+ .not
824
+ .toBe(null)
825
+ test
826
+ .expect(Object.keys(schema!.fields))
827
+ .toEqual(["section"])
730
828
  })
731
829
 
732
- t.it("generates schema for rest segment", () => {
830
+ test.it("generates schema for rest segment", () => {
733
831
  const handle = parseRoute("docs/[...path]/route.tsx")
734
832
  const schema = FileRouterCodegen.generatePathParamsSchema(handle.segments)
735
- t.expect(schema).not.toBe(null)
736
- t.expect(Object.keys(schema!.fields)).toEqual(["path"])
833
+ test
834
+ .expect(schema)
835
+ .not
836
+ .toBe(null)
837
+ test
838
+ .expect(Object.keys(schema!.fields))
839
+ .toEqual(["path"])
737
840
  })
738
841
 
739
- t.it("rest segment should capture path starting with /", () => {
842
+ test.it("rest segment should capture path starting with /", () => {
740
843
  const handle = parseRoute("docs/[...path]/route.tsx")
741
844
  const schema = FileRouterCodegen.generatePathParamsSchema(handle.segments)
742
- t.expect(schema).not.toBe(null)
845
+ test
846
+ .expect(schema)
847
+ .not
848
+ .toBe(null)
743
849
 
744
- // Rest segments capture remaining path as string
745
- // For route /docs/[...path] matching /docs/guide/getting-started
746
- // The path param should be: "/guide/getting-started" (with leading /)
747
850
  const formatted = SchemaExtra.formatSchemaCode(schema!)
748
- t.expect(formatted).toBe("{ path: Schema.String }")
851
+ test
852
+ .expect(formatted)
853
+ .toBe("{ path: Schema.String }")
749
854
  })
750
855
 
751
- t.it("generates schema for optional rest segment", () => {
856
+ test.it("generates schema for optional rest segment", () => {
752
857
  const handle = parseRoute("docs/[[...slug]]/route.tsx")
753
858
  const schema = FileRouterCodegen.generatePathParamsSchema(handle.segments)
754
- t.expect(schema).not.toBe(null)
755
- t.expect(Object.keys(schema!.fields)).toEqual(["slug"])
859
+ test
860
+ .expect(schema)
861
+ .not
862
+ .toBe(null)
863
+ test
864
+ .expect(Object.keys(schema!.fields))
865
+ .toEqual(["slug"])
756
866
  })
757
867
 
758
- t.it("generates schema for multiple params", () => {
868
+ test.it("generates schema for multiple params", () => {
759
869
  const handle = parseRoute("posts/[postId]/comments/[commentId]/route.tsx")
760
870
  const schema = FileRouterCodegen.generatePathParamsSchema(handle.segments)
761
- t.expect(schema).not.toBe(null)
762
- t.expect(Object.keys(schema!.fields).sort()).toEqual([
763
- "commentId",
764
- "postId",
765
- ])
871
+ test
872
+ .expect(schema)
873
+ .not
874
+ .toBe(null)
875
+ test
876
+ .expect(Object.keys(schema!.fields).sort())
877
+ .toEqual([
878
+ "commentId",
879
+ "postId",
880
+ ])
766
881
  })
767
882
 
768
- t.it("generates schema for mixed required and optional params", () => {
883
+ test.it("generates schema for mixed required and optional params", () => {
769
884
  const handle = parseRoute("users/[userId]/posts/[[postId]]/route.tsx")
770
885
  const schema = FileRouterCodegen.generatePathParamsSchema(handle.segments)
771
- t.expect(schema).not.toBe(null)
772
- t.expect(Object.keys(schema!.fields).sort()).toEqual(["postId", "userId"])
886
+ test
887
+ .expect(schema)
888
+ .not
889
+ .toBe(null)
890
+ test
891
+ .expect(Object.keys(schema!.fields).sort())
892
+ .toEqual(["postId", "userId"])
773
893
  })
774
894
 
775
- t.it("ignores group segments", () => {
895
+ test.it("ignores group segments", () => {
776
896
  const handle = parseRoute("(admin)/users/[id]/route.tsx")
777
897
  const schema = FileRouterCodegen.generatePathParamsSchema(handle.segments)
778
- t.expect(schema).not.toBe(null)
779
- t.expect(Object.keys(schema!.fields)).toEqual(["id"])
898
+ test
899
+ .expect(schema)
900
+ .not
901
+ .toBe(null)
902
+ test
903
+ .expect(Object.keys(schema!.fields))
904
+ .toEqual(["id"])
780
905
  })
781
906
  })
782
907
 
783
- t.describe("schemaEqual", () => {
784
- t.it("returns true when both schemas are undefined/null", () => {
785
- t.expect(SchemaExtra.schemaEqual(undefined, null)).toBe(true)
908
+ test.describe("schemaEqual", () => {
909
+ test.it("returns true when both schemas are undefined/null", () => {
910
+ test
911
+ .expect(SchemaExtra.schemaEqual(undefined, null))
912
+ .toBe(true)
786
913
  })
787
914
 
788
- t.it("returns false when only one schema is undefined", () => {
915
+ test.it("returns false when only one schema is undefined", () => {
789
916
  const schema = Schema.Struct({ id: Schema.String })
790
- t.expect(SchemaExtra.schemaEqual(undefined, schema)).toBe(false)
791
- t.expect(SchemaExtra.schemaEqual(schema, null)).toBe(false)
917
+ test
918
+ .expect(SchemaExtra.schemaEqual(undefined, schema))
919
+ .toBe(false)
920
+ test
921
+ .expect(SchemaExtra.schemaEqual(schema, null))
922
+ .toBe(false)
792
923
  })
793
924
 
794
- t.it("returns true for exact matches", () => {
925
+ test.it("returns true for exact matches", () => {
795
926
  const schema1 = Schema.Struct({ id: Schema.String })
796
927
  const schema2 = Schema.Struct({ id: Schema.String })
797
- t.expect(SchemaExtra.schemaEqual(schema1, schema2)).toBe(true)
928
+ test
929
+ .expect(SchemaExtra.schemaEqual(schema1, schema2))
930
+ .toBe(true)
798
931
  })
799
932
 
800
- t.it("returns true for refinement matches (UUID = String)", () => {
933
+ test.it("returns true for refinement matches (UUID = String)", () => {
801
934
  const userSchema = Schema.Struct({ id: Schema.UUID })
802
935
  const expectedSchema = Schema.Struct({ id: Schema.String })
803
- t.expect(SchemaExtra.schemaEqual(userSchema, expectedSchema)).toBe(true)
936
+ test
937
+ .expect(SchemaExtra.schemaEqual(userSchema, expectedSchema))
938
+ .toBe(true)
804
939
  })
805
940
 
806
- t.it("returns false for type mismatches", () => {
941
+ test.it("returns false for type mismatches", () => {
807
942
  const schema1 = Schema.Struct({ id: Schema.String })
808
943
  const schema2 = Schema.Struct({ id: Schema.Number })
809
- t.expect(SchemaExtra.schemaEqual(schema1, schema2)).toBe(false)
944
+ test
945
+ .expect(SchemaExtra.schemaEqual(schema1, schema2))
946
+ .toBe(false)
810
947
  })
811
948
 
812
- t.it("returns false for field name mismatches", () => {
949
+ test.it("returns false for field name mismatches", () => {
813
950
  const schema1 = Schema.Struct({ id: Schema.String })
814
951
  const schema2 = Schema.Struct({ userId: Schema.String })
815
- t.expect(SchemaExtra.schemaEqual(schema1, schema2)).toBe(false)
952
+ test
953
+ .expect(SchemaExtra.schemaEqual(schema1, schema2))
954
+ .toBe(false)
816
955
  })
817
956
 
818
- t.it("returns false for field count mismatches", () => {
957
+ test.it("returns false for field count mismatches", () => {
819
958
  const schema1 = Schema.Struct({ id: Schema.String })
820
959
  const schema2 = Schema.Struct({ id: Schema.String, name: Schema.String })
821
- t.expect(SchemaExtra.schemaEqual(schema1, schema2)).toBe(false)
960
+ test
961
+ .expect(SchemaExtra.schemaEqual(schema1, schema2))
962
+ .toBe(false)
822
963
  })
823
964
 
824
- t.it("returns true for multiple fields with UUID refinement", () => {
965
+ test.it("returns true for multiple fields with UUID refinement", () => {
825
966
  const userSchema = Schema.Struct({
826
967
  id: Schema.UUID,
827
968
  name: Schema.String,
@@ -830,10 +971,12 @@ t.describe("PathParams schema generation and validation", () => {
830
971
  id: Schema.String,
831
972
  name: Schema.String,
832
973
  })
833
- t.expect(SchemaExtra.schemaEqual(userSchema, expectedSchema)).toBe(true)
974
+ test
975
+ .expect(SchemaExtra.schemaEqual(userSchema, expectedSchema))
976
+ .toBe(true)
834
977
  })
835
978
 
836
- t.it("handles optional fields correctly", () => {
979
+ test.it("handles optional fields correctly", () => {
837
980
  const schema1 = Schema.Struct({
838
981
  id: Schema.String,
839
982
  name: Schema.optional(Schema.String),
@@ -842,48 +985,62 @@ t.describe("PathParams schema generation and validation", () => {
842
985
  id: Schema.String,
843
986
  name: Schema.optional(Schema.String),
844
987
  })
845
- t.expect(SchemaExtra.schemaEqual(schema1, schema2)).toBe(true)
988
+ test
989
+ .expect(SchemaExtra.schemaEqual(schema1, schema2))
990
+ .toBe(true)
846
991
  })
847
992
  })
848
993
 
849
- t.describe("formatSchemaCode", () => {
850
- t.it("formats single required field", () => {
994
+ test.describe("formatSchemaCode", () => {
995
+ test.it("formats single required field", () => {
851
996
  const schema = Schema.Struct({ id: Schema.String })
852
997
  const formatted = SchemaExtra.formatSchemaCode(schema)
853
- t.expect(formatted).toBe("{ id: Schema.String }")
998
+ test
999
+ .expect(formatted)
1000
+ .toBe("{ id: Schema.String }")
854
1001
  })
855
1002
 
856
- t.it("formats multiple fields", () => {
1003
+ test.it("formats multiple fields", () => {
857
1004
  const schema = Schema.Struct({
858
1005
  id: Schema.String,
859
1006
  count: Schema.Number,
860
1007
  })
861
1008
  const formatted = SchemaExtra.formatSchemaCode(schema)
862
- t.expect(formatted).toContain("id: Schema.String")
863
- t.expect(formatted).toContain("count: Schema.Number")
1009
+ test
1010
+ .expect(formatted)
1011
+ .toContain("id: Schema.String")
1012
+ test
1013
+ .expect(formatted)
1014
+ .toContain("count: Schema.Number")
864
1015
  })
865
1016
 
866
- t.it("formats optional fields with ? marker", () => {
1017
+ test.it("formats optional fields with ? marker", () => {
867
1018
  const schema = Schema.Struct({
868
1019
  id: Schema.String,
869
1020
  name: Schema.optional(Schema.String),
870
1021
  })
871
1022
  const formatted = SchemaExtra.formatSchemaCode(schema)
872
- t.expect(formatted).toContain("id: Schema.String")
873
- t.expect(formatted).toContain("name")
1023
+ test
1024
+ .expect(formatted)
1025
+ .toContain("id: Schema.String")
1026
+ test
1027
+ .expect(formatted)
1028
+ .toContain("name")
874
1029
  })
875
1030
 
876
- t.it("formats boolean fields", () => {
1031
+ test.it("formats boolean fields", () => {
877
1032
  const schema = Schema.Struct({
878
1033
  active: Schema.Boolean,
879
1034
  })
880
1035
  const formatted = SchemaExtra.formatSchemaCode(schema)
881
- t.expect(formatted).toBe("{ active: Schema.Boolean }")
1036
+ test
1037
+ .expect(formatted)
1038
+ .toBe("{ active: Schema.Boolean }")
882
1039
  })
883
1040
  })
884
1041
 
885
- t.describe("validateRouteModules", () => {
886
- t.it(
1042
+ test.describe("validateRouteModules", () => {
1043
+ test.it(
887
1044
  "does not log when PathParams schema is missing",
888
1045
  () =>
889
1046
  Effect
@@ -906,9 +1063,10 @@ export default Route.text("User")
906
1063
 
907
1064
  yield* FileRouterCodegen.validateRouteModules(routesPath, handles)
908
1065
 
909
- // Verify no logs were created
910
1066
  const messages = yield* TestLogger.messages
911
- t.expect(messages).toHaveLength(0)
1067
+ test
1068
+ .expect(messages)
1069
+ .toHaveLength(0)
912
1070
  })
913
1071
  .pipe(
914
1072
  Effect.scoped,
@@ -920,7 +1078,7 @@ export default Route.text("User")
920
1078
  ),
921
1079
  )
922
1080
 
923
- t.it(
1081
+ test.it(
924
1082
  "logs error when PathParams schema is incorrect",
925
1083
  () =>
926
1084
  Effect
@@ -928,7 +1086,7 @@ export default Route.text("User")
928
1086
  const fs = yield* FileSystem.FileSystem
929
1087
  const schemaPath = path.resolve(
930
1088
  import.meta.dirname,
931
- "../node_modules/effect/Schema",
1089
+ "../../node_modules/effect/Schema",
932
1090
  )
933
1091
  const routeContent = `import * as Route from "${
934
1092
  path.resolve(import.meta.dirname, "./Route.ts")
@@ -948,12 +1106,19 @@ export default Route.text("User").schemaPathParams({ userId: Schema.String })
948
1106
 
949
1107
  yield* FileRouterCodegen.validateRouteModules(routesPath, handles)
950
1108
 
951
- // Verify error was logged
952
1109
  const messages = yield* TestLogger.messages
953
- t.expect(messages).toHaveLength(1)
954
- t.expect(messages[0]).toContain("[Error]")
955
- t.expect(messages[0]).toContain("incorrect PathParams schema")
956
- t.expect(messages[0]).toContain("expected schemaPathParams")
1110
+ test
1111
+ .expect(messages)
1112
+ .toHaveLength(1)
1113
+ test
1114
+ .expect(messages[0])
1115
+ .toContain("[Error]")
1116
+ test
1117
+ .expect(messages[0])
1118
+ .toContain("incorrect PathParams schema")
1119
+ test
1120
+ .expect(messages[0])
1121
+ .toContain("expected schemaPathParams")
957
1122
  })
958
1123
  .pipe(
959
1124
  Effect.scoped,