effect-start 0.18.0 → 0.20.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 (203) hide show
  1. package/README.md +3 -3
  2. package/dist/Development.d.ts +8 -3
  3. package/dist/Development.js +14 -7
  4. package/dist/Effectify.d.ts +212 -0
  5. package/dist/Effectify.js +19 -0
  6. package/dist/FilePathPattern.d.ts +29 -0
  7. package/dist/FilePathPattern.js +86 -0
  8. package/dist/FileRouter.d.ts +39 -41
  9. package/dist/FileRouter.js +104 -158
  10. package/dist/FileRouterCodegen.d.ts +7 -8
  11. package/dist/FileRouterCodegen.js +97 -66
  12. package/dist/PlatformError.d.ts +46 -0
  13. package/dist/PlatformError.js +43 -0
  14. package/dist/PlatformRuntime.d.ts +27 -0
  15. package/dist/PlatformRuntime.js +51 -0
  16. package/dist/Route.d.ts +6 -2
  17. package/dist/Route.js +22 -0
  18. package/dist/RouteBody.d.ts +1 -1
  19. package/dist/RouteHttp.d.ts +1 -1
  20. package/dist/RouteHttp.js +12 -19
  21. package/dist/RouteMount.d.ts +2 -1
  22. package/dist/Start.d.ts +33 -6
  23. package/dist/Start.js +31 -13
  24. package/dist/Unique.d.ts +50 -0
  25. package/dist/Unique.js +187 -0
  26. package/dist/bun/BunHttpServer.js +5 -6
  27. package/dist/bun/BunPlatformHttpServer.d.ts +10 -0
  28. package/dist/bun/BunPlatformHttpServer.js +53 -0
  29. package/dist/bun/BunRoute.d.ts +4 -6
  30. package/dist/bun/BunRoute.js +10 -18
  31. package/dist/bun/BunRuntime.d.ts +2 -1
  32. package/dist/bun/BunRuntime.js +10 -5
  33. package/dist/bun/BunServer.d.ts +33 -0
  34. package/dist/bun/BunServer.js +133 -0
  35. package/dist/bun/BunServerRequest.d.ts +60 -0
  36. package/dist/bun/BunServerRequest.js +252 -0
  37. package/dist/bun/index.d.ts +1 -1
  38. package/dist/bun/index.js +1 -1
  39. package/dist/datastar/actions/fetch.d.ts +30 -0
  40. package/dist/datastar/actions/fetch.js +411 -0
  41. package/dist/datastar/actions/peek.d.ts +1 -0
  42. package/dist/datastar/actions/peek.js +14 -0
  43. package/dist/datastar/actions/setAll.d.ts +1 -0
  44. package/dist/datastar/actions/setAll.js +13 -0
  45. package/dist/datastar/actions/toggleAll.d.ts +1 -0
  46. package/dist/datastar/actions/toggleAll.js +13 -0
  47. package/dist/datastar/attributes/attr.d.ts +1 -0
  48. package/dist/datastar/attributes/attr.js +49 -0
  49. package/dist/datastar/attributes/bind.d.ts +1 -0
  50. package/dist/datastar/attributes/bind.js +183 -0
  51. package/dist/datastar/attributes/class.d.ts +1 -0
  52. package/dist/datastar/attributes/class.js +50 -0
  53. package/dist/datastar/attributes/computed.d.ts +1 -0
  54. package/dist/datastar/attributes/computed.js +27 -0
  55. package/dist/datastar/attributes/effect.d.ts +1 -0
  56. package/dist/datastar/attributes/effect.js +10 -0
  57. package/dist/datastar/attributes/indicator.d.ts +1 -0
  58. package/dist/datastar/attributes/indicator.js +32 -0
  59. package/dist/datastar/attributes/init.d.ts +1 -0
  60. package/dist/datastar/attributes/init.js +27 -0
  61. package/dist/datastar/attributes/jsonSignals.d.ts +1 -0
  62. package/dist/datastar/attributes/jsonSignals.js +31 -0
  63. package/dist/datastar/attributes/on.d.ts +1 -0
  64. package/dist/datastar/attributes/on.js +59 -0
  65. package/dist/datastar/attributes/onIntersect.d.ts +1 -0
  66. package/dist/datastar/attributes/onIntersect.js +54 -0
  67. package/dist/datastar/attributes/onInterval.d.ts +1 -0
  68. package/dist/datastar/attributes/onInterval.js +31 -0
  69. package/dist/datastar/attributes/onSignalPatch.d.ts +1 -0
  70. package/dist/datastar/attributes/onSignalPatch.js +44 -0
  71. package/dist/datastar/attributes/ref.d.ts +1 -0
  72. package/dist/datastar/attributes/ref.js +11 -0
  73. package/dist/datastar/attributes/show.d.ts +1 -0
  74. package/dist/datastar/attributes/show.js +32 -0
  75. package/dist/datastar/attributes/signals.d.ts +1 -0
  76. package/dist/datastar/attributes/signals.js +18 -0
  77. package/dist/datastar/attributes/style.d.ts +1 -0
  78. package/dist/datastar/attributes/style.js +56 -0
  79. package/dist/datastar/attributes/text.d.ts +1 -0
  80. package/dist/datastar/attributes/text.js +27 -0
  81. package/dist/datastar/engine.d.ts +156 -0
  82. package/dist/datastar/engine.js +971 -0
  83. package/dist/datastar/index.d.ts +24 -0
  84. package/dist/datastar/index.js +24 -0
  85. package/dist/datastar/load.d.ts +24 -0
  86. package/dist/datastar/load.js +24 -0
  87. package/dist/datastar/utils.d.ts +51 -0
  88. package/dist/datastar/utils.js +205 -0
  89. package/dist/datastar/watchers/patchElements.d.ts +1 -0
  90. package/dist/datastar/watchers/patchElements.js +420 -0
  91. package/dist/datastar/watchers/patchSignals.d.ts +1 -0
  92. package/dist/datastar/watchers/patchSignals.js +15 -0
  93. package/dist/index.d.ts +1 -0
  94. package/dist/index.js +1 -0
  95. package/dist/node/Effectify.d.ts +209 -0
  96. package/dist/node/Effectify.js +19 -0
  97. package/dist/node/FileSystem.d.ts +3 -5
  98. package/dist/node/FileSystem.js +42 -62
  99. package/dist/node/NodeFileSystem.d.ts +7 -0
  100. package/dist/node/NodeFileSystem.js +420 -0
  101. package/dist/node/NodeUtils.d.ts +2 -0
  102. package/dist/node/NodeUtils.js +20 -0
  103. package/dist/node/PlatformError.d.ts +46 -0
  104. package/dist/node/PlatformError.js +43 -0
  105. package/dist/testing/TestLogger.js +1 -1
  106. package/dist/x/tailwind/plugin.js +1 -1
  107. package/package.json +18 -7
  108. package/src/Development.ts +36 -40
  109. package/src/Effectify.ts +269 -0
  110. package/src/FilePathPattern.ts +115 -0
  111. package/src/FileRouter.ts +178 -255
  112. package/src/FileRouterCodegen.ts +135 -92
  113. package/src/PlatformError.ts +117 -0
  114. package/src/PlatformRuntime.ts +108 -0
  115. package/src/Route.ts +31 -2
  116. package/src/RouteBody.ts +1 -1
  117. package/src/RouteHttp.ts +15 -29
  118. package/src/RouteMount.ts +1 -1
  119. package/src/Start.ts +61 -27
  120. package/src/Unique.ts +232 -0
  121. package/src/bun/BunPlatformHttpServer.ts +88 -0
  122. package/src/bun/BunRoute.ts +14 -24
  123. package/src/bun/BunRuntime.ts +21 -5
  124. package/src/bun/BunServer.ts +228 -0
  125. package/src/bun/index.ts +1 -1
  126. package/src/datastar/README.md +18 -0
  127. package/src/datastar/actions/fetch.ts +609 -0
  128. package/src/datastar/actions/peek.ts +17 -0
  129. package/src/datastar/actions/setAll.ts +20 -0
  130. package/src/datastar/actions/toggleAll.ts +20 -0
  131. package/src/datastar/attributes/attr.ts +50 -0
  132. package/src/datastar/attributes/bind.ts +220 -0
  133. package/src/datastar/attributes/class.ts +57 -0
  134. package/src/datastar/attributes/computed.ts +33 -0
  135. package/src/datastar/attributes/effect.ts +11 -0
  136. package/src/datastar/attributes/indicator.ts +39 -0
  137. package/src/datastar/attributes/init.ts +35 -0
  138. package/src/datastar/attributes/jsonSignals.ts +38 -0
  139. package/src/datastar/attributes/on.ts +71 -0
  140. package/src/datastar/attributes/onIntersect.ts +65 -0
  141. package/src/datastar/attributes/onInterval.ts +39 -0
  142. package/src/datastar/attributes/onSignalPatch.ts +63 -0
  143. package/src/datastar/attributes/ref.ts +12 -0
  144. package/src/datastar/attributes/show.ts +33 -0
  145. package/src/datastar/attributes/signals.ts +22 -0
  146. package/src/datastar/attributes/style.ts +63 -0
  147. package/src/datastar/attributes/text.ts +30 -0
  148. package/src/datastar/engine.ts +1341 -0
  149. package/src/datastar/index.ts +25 -0
  150. package/src/datastar/utils.ts +286 -0
  151. package/src/datastar/watchers/patchElements.ts +554 -0
  152. package/src/datastar/watchers/patchSignals.ts +15 -0
  153. package/src/index.ts +1 -0
  154. package/src/node/{FileSystem.ts → NodeFileSystem.ts} +59 -97
  155. package/src/node/{Utils.ts → NodeUtils.ts} +2 -0
  156. package/src/testing/TestLogger.ts +1 -1
  157. package/src/x/tailwind/plugin.ts +1 -1
  158. package/dist/Random.d.ts +0 -5
  159. package/dist/Random.js +0 -49
  160. package/src/Commander.test.ts +0 -1639
  161. package/src/ContentNegotiation.test.ts +0 -603
  162. package/src/Development.test.ts +0 -119
  163. package/src/Entity.test.ts +0 -592
  164. package/src/FileRouterCodegen.todo.ts +0 -1133
  165. package/src/FileRouterPattern.test.ts +0 -147
  166. package/src/FileRouterPattern.ts +0 -59
  167. package/src/FileRouter_files.test.ts +0 -64
  168. package/src/FileRouter_path.test.ts +0 -145
  169. package/src/FileRouter_tree.test.ts +0 -132
  170. package/src/Http.test.ts +0 -319
  171. package/src/HttpAppExtra.test.ts +0 -103
  172. package/src/HttpUtils.test.ts +0 -85
  173. package/src/PathPattern.test.ts +0 -648
  174. package/src/Random.ts +0 -59
  175. package/src/RouteBody.test.ts +0 -232
  176. package/src/RouteHook.test.ts +0 -40
  177. package/src/RouteHttp.test.ts +0 -2909
  178. package/src/RouteMount.test.ts +0 -481
  179. package/src/RouteSchema.test.ts +0 -427
  180. package/src/RouteSse.test.ts +0 -249
  181. package/src/RouteTree.test.ts +0 -494
  182. package/src/RouteTrie.test.ts +0 -322
  183. package/src/RouterPattern.test.ts +0 -676
  184. package/src/RouterPattern.ts +0 -416
  185. package/src/StartApp.ts +0 -47
  186. package/src/Values.test.ts +0 -263
  187. package/src/bun/BunBundle.test.ts +0 -268
  188. package/src/bun/BunBundle_imports.test.ts +0 -48
  189. package/src/bun/BunHttpServer.test.ts +0 -251
  190. package/src/bun/BunHttpServer.ts +0 -306
  191. package/src/bun/BunImportTrackerPlugin.test.ts +0 -77
  192. package/src/bun/BunRoute.test.ts +0 -162
  193. package/src/bundler/BundleHttp.test.ts +0 -132
  194. package/src/effect/HttpRouter.test.ts +0 -548
  195. package/src/experimental/EncryptedCookies.test.ts +0 -488
  196. package/src/hyper/HyperHtml.test.ts +0 -209
  197. package/src/hyper/HyperRoute.test.tsx +0 -197
  198. package/src/middlewares/BasicAuthMiddleware.test.ts +0 -84
  199. package/src/testing/TestHttpClient.test.ts +0 -83
  200. package/src/testing/TestLogger.test.ts +0 -51
  201. package/src/x/datastar/Datastar.test.ts +0 -266
  202. package/src/x/tailwind/TailwindPlugin.test.ts +0 -333
  203. /package/src/bun/{BunHttpServer_web.ts → BunServerRequest.ts} +0 -0
@@ -1,147 +0,0 @@
1
- import * as test from "bun:test"
2
- import * as FileRouterPattern from "./FileRouterPattern.ts"
3
-
4
- test.it("empty path", () => {
5
- test
6
- .expect(FileRouterPattern.parse(""))
7
- .toEqual([])
8
- test
9
- .expect(FileRouterPattern.parse("/"))
10
- .toEqual([])
11
- })
12
-
13
- test.it("groups", () => {
14
- test
15
- .expect(FileRouterPattern.parse("(admin)"))
16
- .toEqual([
17
- { _tag: "GroupSegment", name: "admin" },
18
- ])
19
- test
20
- .expect(FileRouterPattern.parse("/(admin)/users"))
21
- .toEqual([
22
- { _tag: "GroupSegment", name: "admin" },
23
- { _tag: "LiteralSegment", value: "users" },
24
- ])
25
- test
26
- .expect(FileRouterPattern.parse("(auth)/login/(step1)"))
27
- .toEqual([
28
- { _tag: "GroupSegment", name: "auth" },
29
- { _tag: "LiteralSegment", value: "login" },
30
- { _tag: "GroupSegment", name: "step1" },
31
- ])
32
- })
33
-
34
- test.it("handle files parsed as Literal", () => {
35
- test
36
- .expect(FileRouterPattern.parse("route.ts"))
37
- .toEqual([
38
- { _tag: "LiteralSegment", value: "route.ts" },
39
- ])
40
- test
41
- .expect(FileRouterPattern.parse("/api/route.js"))
42
- .toEqual([
43
- { _tag: "LiteralSegment", value: "api" },
44
- { _tag: "LiteralSegment", value: "route.js" },
45
- ])
46
- test
47
- .expect(FileRouterPattern.parse("layer.tsx"))
48
- .toEqual([
49
- { _tag: "LiteralSegment", value: "layer.tsx" },
50
- ])
51
- test
52
- .expect(FileRouterPattern.parse("/blog/layer.jsx"))
53
- .toEqual([
54
- { _tag: "LiteralSegment", value: "blog" },
55
- { _tag: "LiteralSegment", value: "layer.jsx" },
56
- ])
57
- })
58
-
59
- test.it("params and rest", () => {
60
- test
61
- .expect(FileRouterPattern.parse("users/[userId]/posts"))
62
- .toEqual([
63
- { _tag: "LiteralSegment", value: "users" },
64
- { _tag: "ParamSegment", name: "userId" },
65
- { _tag: "LiteralSegment", value: "posts" },
66
- ])
67
- test
68
- .expect(FileRouterPattern.parse("api/[[...path]]"))
69
- .toEqual([
70
- { _tag: "LiteralSegment", value: "api" },
71
- { _tag: "RestSegment", name: "path", optional: true },
72
- ])
73
- })
74
-
75
- test.it("invalid paths", () => {
76
- test
77
- .expect(() => FileRouterPattern.parse("$..."))
78
- .toThrow()
79
- test
80
- .expect(() => FileRouterPattern.parse("invalid%char"))
81
- .toThrow()
82
- test
83
- .expect(() => FileRouterPattern.parse("path with spaces"))
84
- .toThrow()
85
- })
86
-
87
- test.it("segments with extensions (literal with dots)", () => {
88
- test
89
- .expect(FileRouterPattern.parse("events.json/route.ts"))
90
- .toEqual([
91
- { _tag: "LiteralSegment", value: "events.json" },
92
- { _tag: "LiteralSegment", value: "route.ts" },
93
- ])
94
- })
95
-
96
- test.it("formatSegment", () => {
97
- test
98
- .expect(
99
- FileRouterPattern.formatSegment({
100
- _tag: "LiteralSegment",
101
- value: "users",
102
- }),
103
- )
104
- .toBe("users")
105
- test
106
- .expect(
107
- FileRouterPattern.formatSegment({ _tag: "ParamSegment", name: "id" }),
108
- )
109
- .toBe("[id]")
110
- test
111
- .expect(
112
- FileRouterPattern.formatSegment({ _tag: "GroupSegment", name: "admin" }),
113
- )
114
- .toBe("(admin)")
115
- test
116
- .expect(
117
- FileRouterPattern.formatSegment({ _tag: "RestSegment", name: "path" }),
118
- )
119
- .toBe("[...path]")
120
- })
121
-
122
- test.it("format", () => {
123
- test
124
- .expect(FileRouterPattern.format([]))
125
- .toBe("/")
126
- test
127
- .expect(
128
- FileRouterPattern.format([{ _tag: "LiteralSegment", value: "users" }]),
129
- )
130
- .toBe("/users")
131
- test
132
- .expect(
133
- FileRouterPattern.format([
134
- { _tag: "GroupSegment", name: "admin" },
135
- { _tag: "LiteralSegment", value: "users" },
136
- ]),
137
- )
138
- .toBe("/(admin)/users")
139
- test
140
- .expect(
141
- FileRouterPattern.format([
142
- { _tag: "LiteralSegment", value: "users" },
143
- { _tag: "ParamSegment", name: "id" },
144
- ]),
145
- )
146
- .toBe("/users/[id]")
147
- })
@@ -1,59 +0,0 @@
1
- import * as RouterPattern from "./RouterPattern.ts"
2
-
3
- export type GroupSegment<
4
- Name extends string = string,
5
- > = {
6
- _tag: "GroupSegment"
7
- name: Name
8
- }
9
-
10
- export type Segment =
11
- | RouterPattern.Segment
12
- | GroupSegment
13
-
14
- export function parse(pattern: string): Segment[] {
15
- const trimmedPath = pattern.replace(/(^\/)|(\/$)/g, "")
16
-
17
- if (trimmedPath === "") {
18
- return []
19
- }
20
-
21
- const segmentStrings = trimmedPath
22
- .split("/")
23
- .filter(s => s !== "")
24
-
25
- if (segmentStrings.length === 0) {
26
- return []
27
- }
28
-
29
- const segments: (Segment | null)[] = segmentStrings.map(
30
- (s): Segment | null => {
31
- // (group) - Groups (FileRouter-specific)
32
- const groupMatch = s.match(/^\((\w+)\)$/)
33
- if (groupMatch) {
34
- return { _tag: "GroupSegment", name: groupMatch[1] }
35
- }
36
-
37
- // Delegate to RouterPattern for all other segment types
38
- return RouterPattern.parseSegment(s)
39
- },
40
- )
41
-
42
- if (segments.some((seg) => seg === null)) {
43
- throw new Error(
44
- `Invalid path segment in "${pattern}": contains invalid characters or format`,
45
- )
46
- }
47
-
48
- return segments as Segment[]
49
- }
50
-
51
- export function formatSegment(seg: Segment): string {
52
- if (seg._tag === "GroupSegment") return `(${seg.name})`
53
- return RouterPattern.formatSegment(seg)
54
- }
55
-
56
- export function format(segments: Segment[]): `/${string}` {
57
- const joined = segments.map(formatSegment).join("/")
58
- return (joined ? `/${joined}` : "/") as `/${string}`
59
- }
@@ -1,64 +0,0 @@
1
- import * as test from "bun:test"
2
- import { MemoryFileSystem } from "effect-memfs"
3
- import * as Effect from "effect/Effect"
4
- import * as FileRouter from "./FileRouter.ts"
5
- import { effectFn } from "./testing"
6
-
7
- const Files = {
8
- "/routes/about/layer.tsx": "",
9
- "/routes/about/route.tsx": "",
10
- "/routes/users/route.tsx": "",
11
- "/routes/users/layer.tsx": "",
12
- "/routes/users/[userId]/route.tsx": "",
13
- "/routes/layer.tsx": "",
14
- }
15
-
16
- const effect = effectFn()
17
-
18
- test.it("walks routes", () =>
19
- effect(function*() {
20
- const files = yield* FileRouter.walkRoutesDirectory("/routes").pipe(
21
- Effect.provide(MemoryFileSystem.layerWith(Files)),
22
- )
23
-
24
- test
25
- .expect(
26
- files.map(v => v.modulePath),
27
- )
28
- .toEqual([
29
- "layer.tsx",
30
- "about/layer.tsx",
31
- "about/route.tsx",
32
- "users/layer.tsx",
33
- "users/route.tsx",
34
- "users/[userId]/route.tsx",
35
- ])
36
- }))
37
-
38
- test.it("walks routes with rest", () =>
39
- effect(function*() {
40
- const files = yield* FileRouter.walkRoutesDirectory("/routes").pipe(
41
- Effect.provide(
42
- MemoryFileSystem.layerWith({
43
- ...Files,
44
- "/routes/[[...rest]]/route.tsx": "",
45
- "/routes/users/[...path]/route.tsx": "",
46
- }),
47
- ),
48
- )
49
-
50
- test
51
- .expect(
52
- files.map(v => v.modulePath),
53
- )
54
- .toEqual([
55
- "layer.tsx",
56
- "about/layer.tsx",
57
- "about/route.tsx",
58
- "users/layer.tsx",
59
- "users/route.tsx",
60
- "users/[userId]/route.tsx",
61
- "users/[...path]/route.tsx",
62
- "[[...rest]]/route.tsx",
63
- ])
64
- }))
@@ -1,145 +0,0 @@
1
- import * as test from "bun:test"
2
- import * as FileRouter from "./FileRouter.ts"
3
-
4
- test.it("empty path", () => {
5
- test
6
- .expect(FileRouter.parse(""))
7
- .toEqual([])
8
- test
9
- .expect(FileRouter.parse("/"))
10
- .toEqual([])
11
- })
12
-
13
- test.it("groups", () => {
14
- test
15
- .expect(FileRouter.parse("(admin)"))
16
- .toEqual([
17
- { _tag: "GroupSegment", name: "admin" },
18
- ])
19
- test
20
- .expect(FileRouter.parse("/(admin)/users"))
21
- .toEqual([
22
- { _tag: "GroupSegment", name: "admin" },
23
- { _tag: "LiteralSegment", value: "users" },
24
- ])
25
- test
26
- .expect(FileRouter.parse("(auth)/login/(step1)"))
27
- .toEqual([
28
- { _tag: "GroupSegment", name: "auth" },
29
- { _tag: "LiteralSegment", value: "login" },
30
- { _tag: "GroupSegment", name: "step1" },
31
- ])
32
- })
33
-
34
- test.it("handle files parsed as Literal", () => {
35
- test
36
- .expect(FileRouter.parse("route.ts"))
37
- .toEqual([
38
- { _tag: "LiteralSegment", value: "route.ts" },
39
- ])
40
- test
41
- .expect(FileRouter.parse("/api/route.js"))
42
- .toEqual([
43
- { _tag: "LiteralSegment", value: "api" },
44
- { _tag: "LiteralSegment", value: "route.js" },
45
- ])
46
- test
47
- .expect(FileRouter.parse("layer.tsx"))
48
- .toEqual([
49
- { _tag: "LiteralSegment", value: "layer.tsx" },
50
- ])
51
- test
52
- .expect(FileRouter.parse("/blog/layer.jsx"))
53
- .toEqual([
54
- { _tag: "LiteralSegment", value: "blog" },
55
- { _tag: "LiteralSegment", value: "layer.jsx" },
56
- ])
57
- })
58
-
59
- test.it("parseRoute extracts handle from Literal", () => {
60
- const route = FileRouter.parseRoute("users/route.tsx")
61
- test
62
- .expect(route.handle)
63
- .toBe("route")
64
- test
65
- .expect(route.routePath)
66
- .toBe("/users")
67
- test
68
- .expect(route.segments)
69
- .toEqual([
70
- { _tag: "LiteralSegment", value: "users" },
71
- ])
72
-
73
- const layer = FileRouter.parseRoute("api/layer.ts")
74
- test
75
- .expect(layer.handle)
76
- .toBe("layer")
77
- test
78
- .expect(layer.routePath)
79
- .toBe("/api")
80
- })
81
-
82
- test.it("parseRoute with groups", () => {
83
- const route = FileRouter.parseRoute("(admin)/users/route.tsx")
84
- test
85
- .expect(route.handle)
86
- .toBe("route")
87
- test
88
- .expect(route.routePath)
89
- .toBe("/users")
90
- test
91
- .expect(route.segments)
92
- .toEqual([
93
- { _tag: "GroupSegment", name: "admin" },
94
- { _tag: "LiteralSegment", value: "users" },
95
- ])
96
- })
97
-
98
- test.it("parseRoute with params and rest", () => {
99
- const route = FileRouter.parseRoute("users/[userId]/posts/route.tsx")
100
- test
101
- .expect(route.handle)
102
- .toBe("route")
103
- test
104
- .expect(route.routePath)
105
- .toBe("/users/[userId]/posts")
106
- test
107
- .expect(route.segments)
108
- .toEqual([
109
- { _tag: "LiteralSegment", value: "users" },
110
- { _tag: "ParamSegment", name: "userId" },
111
- { _tag: "LiteralSegment", value: "posts" },
112
- ])
113
-
114
- const rest = FileRouter.parseRoute("api/[[...path]]/route.ts")
115
- test
116
- .expect(rest.handle)
117
- .toBe("route")
118
- test
119
- .expect(rest.segments)
120
- .toEqual([
121
- { _tag: "LiteralSegment", value: "api" },
122
- { _tag: "RestSegment", name: "path", optional: true },
123
- ])
124
- })
125
-
126
- test.it("invalid paths", () => {
127
- test
128
- .expect(() => FileRouter.parse("$..."))
129
- .toThrow()
130
- test
131
- .expect(() => FileRouter.parse("invalid%char"))
132
- .toThrow()
133
- test
134
- .expect(() => FileRouter.parse("path with spaces"))
135
- .toThrow()
136
- })
137
-
138
- test.it("segments with extensions (literal with dots)", () => {
139
- test
140
- .expect(FileRouter.parse("events.json/route.ts"))
141
- .toEqual([
142
- { _tag: "LiteralSegment", value: "events.json" },
143
- { _tag: "LiteralSegment", value: "route.ts" },
144
- ])
145
- })
@@ -1,132 +0,0 @@
1
- import * as test from "bun:test"
2
- import * as FileRouter from "./FileRouter.ts"
3
-
4
- test.it("tree with root only", () => {
5
- const handles = [
6
- "route.tsx",
7
- "layer.tsx",
8
- ]
9
- .map(FileRouter.parseRoute)
10
- const tree = FileRouter.treeFromRouteHandles(handles)
11
-
12
- test
13
- .expect(tree)
14
- .toEqual({
15
- path: "/",
16
- handles: [
17
- test.expect.objectContaining({
18
- handle: "route",
19
- }),
20
- test.expect.objectContaining({
21
- handle: "layer",
22
- }),
23
- ],
24
- })
25
- })
26
-
27
- test.it("tree without root", () => {
28
- const handles = []
29
- .map(FileRouter.parseRoute)
30
- const tree = FileRouter.treeFromRouteHandles(handles)
31
-
32
- test
33
- .expect(tree)
34
- .toEqual({
35
- path: "/",
36
- handles: [],
37
- })
38
- })
39
-
40
- test.it("deep tree", () => {
41
- const handles = [
42
- "users/route.tsx",
43
- "users/layer.tsx",
44
- "users/[userId]/route.tsx",
45
- "layer.tsx",
46
- ]
47
- .map(FileRouter.parseRoute)
48
- const tree = FileRouter.treeFromRouteHandles(handles)
49
-
50
- test
51
- .expect(tree)
52
- .toEqual({
53
- path: "/",
54
- handles: [
55
- test.expect.objectContaining({
56
- handle: "layer",
57
- }),
58
- ],
59
- children: [
60
- {
61
- path: "/users",
62
- handles: [
63
- test.expect.objectContaining({
64
- handle: "route",
65
- }),
66
- test.expect.objectContaining({
67
- handle: "layer",
68
- }),
69
- ],
70
- children: [
71
- {
72
- path: "/[userId]",
73
- handles: [
74
- test.expect.objectContaining({
75
- handle: "route",
76
- }),
77
- ],
78
- },
79
- ],
80
- },
81
- ],
82
- })
83
- })
84
-
85
- test.it("throws on overlapping routes from groups", () => {
86
- test
87
- .expect(() => {
88
- const handles = [
89
- "(admin)/users/route.tsx",
90
- "users/route.tsx",
91
- ]
92
- .map(FileRouter.parseRoute)
93
-
94
- FileRouter.getRouteHandlesFromPaths(
95
- handles.map(h => h.modulePath),
96
- )
97
- })
98
- .toThrow("Conflicting routes detected at path /users")
99
- })
100
-
101
- test.it("throws on overlapping routes with same path", () => {
102
- test
103
- .expect(() => {
104
- const handles = [
105
- "about/route.tsx",
106
- "about/route.ts",
107
- ]
108
- .map(FileRouter.parseRoute)
109
-
110
- FileRouter.getRouteHandlesFromPaths(
111
- handles.map(h => h.modulePath),
112
- )
113
- })
114
- .toThrow("Conflicting routes detected at path /about")
115
- })
116
-
117
- test.it("allows route and layer at same path", () => {
118
- test
119
- .expect(() => {
120
- const handles = [
121
- "users/route.tsx",
122
- "users/layer.tsx",
123
- ]
124
- .map(FileRouter.parseRoute)
125
-
126
- FileRouter.getRouteHandlesFromPaths(
127
- handles.map(h => h.modulePath),
128
- )
129
- })
130
- .not
131
- .toThrow()
132
- })