effect-start 0.25.0 → 0.27.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 (174) hide show
  1. package/package.json +20 -86
  2. package/src/Entity.ts +6 -6
  3. package/src/FileRouterCodegen.ts +4 -4
  4. package/src/FileSystem.ts +4 -8
  5. package/src/RouteHook.ts +1 -1
  6. package/src/RouteSse.ts +3 -3
  7. package/src/SqlIntrospect.ts +2 -2
  8. package/src/Start.ts +102 -2
  9. package/src/Values.ts +11 -0
  10. package/src/bun/BunRoute.ts +1 -1
  11. package/src/bun/BunRuntime.ts +5 -5
  12. package/src/hyper/HyperHtml.ts +11 -7
  13. package/src/hyper/jsx.d.ts +1 -1
  14. package/src/lint/plugin.js +174 -4
  15. package/src/sql/SqlClient.ts +355 -0
  16. package/src/sql/bun/index.ts +117 -50
  17. package/src/sql/index.ts +1 -1
  18. package/src/sql/libsql/index.ts +91 -77
  19. package/src/sql/libsql/libsql.d.ts +4 -1
  20. package/src/sql/mssql/index.ts +141 -108
  21. package/src/sql/mssql/mssql.d.ts +1 -0
  22. package/src/testing/TestLogger.ts +4 -4
  23. package/src/x/tailwind/compile.ts +6 -14
  24. package/dist/ChildProcess.js +0 -42
  25. package/dist/Commander.js +0 -410
  26. package/dist/ContentNegotiation.js +0 -465
  27. package/dist/Cookies.js +0 -371
  28. package/dist/Development.js +0 -94
  29. package/dist/Effectify.js +0 -27
  30. package/dist/Entity.js +0 -289
  31. package/dist/Fetch.js +0 -192
  32. package/dist/FilePathPattern.js +0 -97
  33. package/dist/FileRouter.js +0 -204
  34. package/dist/FileRouterCodegen.js +0 -298
  35. package/dist/FileSystem.js +0 -132
  36. package/dist/Http.js +0 -107
  37. package/dist/PathPattern.js +0 -451
  38. package/dist/PlatformError.js +0 -40
  39. package/dist/PlatformRuntime.js +0 -71
  40. package/dist/Route.js +0 -143
  41. package/dist/RouteBody.js +0 -92
  42. package/dist/RouteError.js +0 -76
  43. package/dist/RouteHook.js +0 -64
  44. package/dist/RouteHttp.js +0 -367
  45. package/dist/RouteHttpTracer.js +0 -90
  46. package/dist/RouteMount.js +0 -86
  47. package/dist/RouteSchema.js +0 -271
  48. package/dist/RouteSse.js +0 -94
  49. package/dist/RouteTree.js +0 -119
  50. package/dist/RouteTrie.js +0 -179
  51. package/dist/SchemaExtra.js +0 -99
  52. package/dist/Socket.js +0 -40
  53. package/dist/SqlIntrospect.js +0 -515
  54. package/dist/Start.js +0 -79
  55. package/dist/StartApp.js +0 -3
  56. package/dist/StreamExtra.js +0 -135
  57. package/dist/System.js +0 -38
  58. package/dist/TuplePathPattern.js +0 -74
  59. package/dist/Unique.js +0 -226
  60. package/dist/Values.js +0 -52
  61. package/dist/bun/BunBundle.js +0 -186
  62. package/dist/bun/BunChildProcessSpawner.js +0 -142
  63. package/dist/bun/BunImportTrackerPlugin.js +0 -91
  64. package/dist/bun/BunRoute.js +0 -157
  65. package/dist/bun/BunRuntime.js +0 -41
  66. package/dist/bun/BunServer.js +0 -285
  67. package/dist/bun/BunVirtualFilesPlugin.js +0 -54
  68. package/dist/bun/_BunEnhancedResolve.js +0 -127
  69. package/dist/bun/index.js +0 -5
  70. package/dist/bundler/Bundle.js +0 -92
  71. package/dist/bundler/BundleFiles.js +0 -154
  72. package/dist/bundler/BundleRoute.js +0 -62
  73. package/dist/client/Overlay.js +0 -33
  74. package/dist/client/ScrollState.js +0 -106
  75. package/dist/client/index.js +0 -97
  76. package/dist/console/Console.js +0 -42
  77. package/dist/console/ConsoleErrors.js +0 -211
  78. package/dist/console/ConsoleLogger.js +0 -56
  79. package/dist/console/ConsoleMetrics.js +0 -72
  80. package/dist/console/ConsoleProcess.js +0 -59
  81. package/dist/console/ConsoleStore.js +0 -72
  82. package/dist/console/ConsoleTracer.js +0 -107
  83. package/dist/console/Simulation.js +0 -784
  84. package/dist/console/index.js +0 -3
  85. package/dist/console/routes/tree.js +0 -30
  86. package/dist/datastar/actions/fetch.js +0 -536
  87. package/dist/datastar/actions/peek.js +0 -13
  88. package/dist/datastar/actions/setAll.js +0 -19
  89. package/dist/datastar/actions/toggleAll.js +0 -19
  90. package/dist/datastar/attributes/attr.js +0 -49
  91. package/dist/datastar/attributes/bind.js +0 -194
  92. package/dist/datastar/attributes/class.js +0 -54
  93. package/dist/datastar/attributes/computed.js +0 -25
  94. package/dist/datastar/attributes/effect.js +0 -10
  95. package/dist/datastar/attributes/indicator.js +0 -33
  96. package/dist/datastar/attributes/init.js +0 -27
  97. package/dist/datastar/attributes/jsonSignals.js +0 -33
  98. package/dist/datastar/attributes/on.js +0 -81
  99. package/dist/datastar/attributes/onIntersect.js +0 -53
  100. package/dist/datastar/attributes/onInterval.js +0 -31
  101. package/dist/datastar/attributes/onSignalPatch.js +0 -51
  102. package/dist/datastar/attributes/ref.js +0 -11
  103. package/dist/datastar/attributes/show.js +0 -32
  104. package/dist/datastar/attributes/signals.js +0 -18
  105. package/dist/datastar/attributes/style.js +0 -57
  106. package/dist/datastar/attributes/text.js +0 -29
  107. package/dist/datastar/engine.js +0 -1145
  108. package/dist/datastar/index.js +0 -25
  109. package/dist/datastar/utils.js +0 -250
  110. package/dist/datastar/watchers/patchElements.js +0 -486
  111. package/dist/datastar/watchers/patchSignals.js +0 -14
  112. package/dist/experimental/EncryptedCookies.js +0 -328
  113. package/dist/experimental/index.js +0 -1
  114. package/dist/hyper/Hyper.js +0 -28
  115. package/dist/hyper/HyperHtml.js +0 -165
  116. package/dist/hyper/HyperNode.js +0 -13
  117. package/dist/hyper/HyperRoute.js +0 -45
  118. package/dist/hyper/html.js +0 -30
  119. package/dist/hyper/index.js +0 -5
  120. package/dist/hyper/jsx-runtime.js +0 -14
  121. package/dist/index.js +0 -8
  122. package/dist/node/NodeFileSystem.js +0 -675
  123. package/dist/node/NodeUtils.js +0 -23
  124. package/dist/sql/Sql.js +0 -8
  125. package/dist/sql/bun/index.js +0 -142
  126. package/dist/sql/index.js +0 -1
  127. package/dist/sql/libsql/index.js +0 -156
  128. package/dist/sql/mssql/docker.js +0 -110
  129. package/dist/sql/mssql/index.js +0 -194
  130. package/dist/testing/TestLogger.js +0 -42
  131. package/dist/testing/index.js +0 -2
  132. package/dist/testing/utils.js +0 -61
  133. package/dist/x/cloudflare/CloudflareTunnel.js +0 -63
  134. package/dist/x/cloudflare/index.js +0 -1
  135. package/dist/x/tailscale/TailscaleTunnel.js +0 -94
  136. package/dist/x/tailscale/index.js +0 -1
  137. package/dist/x/tailwind/TailwindPlugin.js +0 -294
  138. package/dist/x/tailwind/compile.js +0 -210
  139. package/dist/x/tailwind/plugin.js +0 -17
  140. package/src/console/Console.ts +0 -42
  141. package/src/console/ConsoleErrors.ts +0 -213
  142. package/src/console/ConsoleLogger.ts +0 -56
  143. package/src/console/ConsoleMetrics.ts +0 -72
  144. package/src/console/ConsoleProcess.ts +0 -59
  145. package/src/console/ConsoleStore.ts +0 -187
  146. package/src/console/ConsoleTracer.ts +0 -107
  147. package/src/console/Simulation.ts +0 -814
  148. package/src/console/console.html +0 -340
  149. package/src/console/index.ts +0 -3
  150. package/src/console/routes/errors/route.tsx +0 -97
  151. package/src/console/routes/fiberDetail.tsx +0 -54
  152. package/src/console/routes/fibers/route.tsx +0 -45
  153. package/src/console/routes/git/route.tsx +0 -64
  154. package/src/console/routes/layout.tsx +0 -4
  155. package/src/console/routes/logs/route.tsx +0 -77
  156. package/src/console/routes/metrics/route.tsx +0 -36
  157. package/src/console/routes/route.tsx +0 -8
  158. package/src/console/routes/routes/route.tsx +0 -30
  159. package/src/console/routes/services/route.tsx +0 -21
  160. package/src/console/routes/system/route.tsx +0 -43
  161. package/src/console/routes/traceDetail.tsx +0 -22
  162. package/src/console/routes/traces/route.tsx +0 -81
  163. package/src/console/routes/tree.ts +0 -30
  164. package/src/console/ui/Errors.tsx +0 -76
  165. package/src/console/ui/Fibers.tsx +0 -321
  166. package/src/console/ui/Git.tsx +0 -182
  167. package/src/console/ui/Logs.tsx +0 -46
  168. package/src/console/ui/Metrics.tsx +0 -78
  169. package/src/console/ui/Routes.tsx +0 -125
  170. package/src/console/ui/Services.tsx +0 -273
  171. package/src/console/ui/Shell.tsx +0 -62
  172. package/src/console/ui/System.tsx +0 -131
  173. package/src/console/ui/Traces.tsx +0 -426
  174. package/src/sql/Sql.ts +0 -51
@@ -1,182 +0,0 @@
1
- export interface GitFileEntry {
2
- readonly status: string
3
- readonly path: string
4
- }
5
-
6
- export interface GitStatus {
7
- readonly oid: string
8
- readonly head: string
9
- readonly upstream: string | undefined
10
- readonly ahead: number
11
- readonly behind: number
12
- readonly tag: string | undefined
13
- readonly tagDistance: number
14
- readonly staged: Array<GitFileEntry>
15
- readonly unstaged: Array<GitFileEntry>
16
- readonly untracked: Array<string>
17
- }
18
-
19
- const xyToLabel: Record<string, string> = {
20
- M: "modified",
21
- A: "new file",
22
- D: "deleted",
23
- R: "renamed",
24
- C: "copied",
25
- T: "typechange",
26
- U: "unmerged",
27
- }
28
-
29
- function statusLabel(code: string): string {
30
- return xyToLabel[code] ?? code
31
- }
32
-
33
- function gitStatusColor(code: string): string {
34
- if (code === "D") return "#ef4444"
35
- if (code === "A") return "#4ade80"
36
- if (code === "R" || code === "C") return "#60a5fa"
37
- if (code === "M") return "#fbbf24"
38
- return "#94a3b8"
39
- }
40
-
41
- export function parseGitStatus(porcelain: string, tagLine: string): GitStatus {
42
- const lines = porcelain.split("\n")
43
- let oid = ""
44
- let head = ""
45
- let upstream: string | undefined
46
- let ahead = 0
47
- let behind = 0
48
- const staged: Array<GitFileEntry> = []
49
- const unstaged: Array<GitFileEntry> = []
50
- const untracked: Array<string> = []
51
-
52
- for (const line of lines) {
53
- if (line.startsWith("# branch.oid ")) {
54
- oid = line.slice("# branch.oid ".length, "# branch.oid ".length + 7)
55
- } else if (line.startsWith("# branch.head ")) {
56
- head = line.slice("# branch.head ".length)
57
- } else if (line.startsWith("# branch.upstream ")) {
58
- upstream = line.slice("# branch.upstream ".length)
59
- } else if (line.startsWith("# branch.ab ")) {
60
- const parts = line.slice("# branch.ab ".length).split(" ")
61
- ahead = parseInt(parts[0]?.slice(1) ?? "0", 10)
62
- behind = parseInt(parts[1]?.slice(1) ?? "0", 10)
63
- } else if (line.startsWith("1 ") || line.startsWith("2 ")) {
64
- const xy = line.slice(2, 4)
65
- const x = xy[0]
66
- const y = xy[1]
67
- const parts = line.split("\t")
68
- const firstParts = parts[0].split(" ")
69
- const path = parts.length > 1 ? parts[1] : firstParts[firstParts.length - 1]
70
- if (x !== "." && x !== "?") staged.push({ status: x, path })
71
- if (y !== "." && y !== "?") unstaged.push({ status: y, path })
72
- } else if (line.startsWith("u ")) {
73
- const parts = line.split("\t")
74
- const path = parts.length > 1 ? parts[1] : line.split(" ").pop()!
75
- staged.push({ status: "U", path })
76
- } else if (line.startsWith("? ")) {
77
- untracked.push(line.slice(2))
78
- }
79
- }
80
-
81
- let tag: string | undefined
82
- let tagDistance = 0
83
- const tagParts = tagLine.trim().split("\n")
84
- if (tagParts[0] && !tagParts[0].startsWith("fatal")) {
85
- tag = tagParts[0]
86
- tagDistance = parseInt(tagParts[1] ?? "0", 10)
87
- }
88
-
89
- return { oid, head, upstream, ahead, behind, tag, tagDistance, staged, unstaged, untracked }
90
- }
91
-
92
- function GitKV({ label, children }: { label: string; children: any }) {
93
- return (
94
- <div style="display:flex;gap:8px;padding:3px 0;font-size:13px;font-family:monospace">
95
- <span style="color:#6b7280;min-width:80px">{label}</span>
96
- <span style="color:#e5e7eb">{children}</span>
97
- </div>
98
- )
99
- }
100
-
101
- function GitFileRow({ entry }: { entry: GitFileEntry }) {
102
- const label = statusLabel(entry.status)
103
- const color = gitStatusColor(entry.status)
104
- return (
105
- <div style="display:flex;gap:12px;padding:2px 0;font-size:13px;font-family:monospace">
106
- <span style={`color:${color};font-style:italic;min-width:80px`}>{label}</span>
107
- <span style="color:#d1d5db">{entry.path}</span>
108
- </div>
109
- )
110
- }
111
-
112
- function SectionHeader({ title, count }: { title: string; count: number }) {
113
- return (
114
- <div style="color:#fbbf24;font-size:14px;font-weight:600;padding:16px 0 6px;font-family:monospace">
115
- {title} ({count})
116
- </div>
117
- )
118
- }
119
-
120
- export function GitStatusView({ status }: { status: GitStatus }) {
121
- return (
122
- <div style="padding:12px 16px">
123
- <GitKV label="Head:">
124
- <span style="color:#94a3b8;font-style:italic">{status.oid}</span>{" "}
125
- <span style="color:#4ade80;font-weight:600">{status.head}</span>
126
- </GitKV>
127
- {status.upstream && (
128
- <GitKV label="Upstream:">
129
- <span style="color:#94a3b8;font-style:italic">{status.oid}</span>{" "}
130
- <span style="color:#60a5fa;font-weight:600">{status.upstream}</span>
131
- {(status.ahead > 0 || status.behind > 0) && (
132
- <span style="color:#94a3b8">
133
- {status.ahead > 0 ? ` +${status.ahead}` : ""}
134
- {status.behind > 0 ? ` -${status.behind}` : ""}
135
- </span>
136
- )}
137
- </GitKV>
138
- )}
139
- {status.tag && (
140
- <GitKV label="Tag:">
141
- <span style="color:#e5e7eb">{status.tag}</span>
142
- {status.tagDistance > 0 && <span style="color:#60a5fa"> ({status.tagDistance})</span>}
143
- </GitKV>
144
- )}
145
-
146
- {status.untracked.length > 0 && (
147
- <>
148
- <SectionHeader title="Untracked files" count={status.untracked.length} />
149
- {status.untracked.map((f) => (
150
- <div style="padding:2px 0;font-size:13px;font-family:monospace;color:#d1d5db">{f}</div>
151
- ))}
152
- </>
153
- )}
154
-
155
- {status.unstaged.length > 0 && (
156
- <>
157
- <SectionHeader title="Unstaged changes" count={status.unstaged.length} />
158
- {status.unstaged.map((e) => (
159
- <GitFileRow entry={e} />
160
- ))}
161
- </>
162
- )}
163
-
164
- {status.staged.length > 0 && (
165
- <>
166
- <SectionHeader title="Staged changes" count={status.staged.length} />
167
- {status.staged.map((e) => (
168
- <GitFileRow entry={e} />
169
- ))}
170
- </>
171
- )}
172
-
173
- {status.untracked.length === 0 &&
174
- status.unstaged.length === 0 &&
175
- status.staged.length === 0 && (
176
- <div style="color:#4ade80;font-size:13px;font-family:monospace;padding:16px 0">
177
- Clean working tree
178
- </div>
179
- )}
180
- </div>
181
- )
182
- }
@@ -1,46 +0,0 @@
1
- import * as ConsoleStore from "../ConsoleStore.ts"
2
-
3
- function levelColor(level: string): string {
4
- if (level === "DEBUG") return "#94a3b8"
5
- if (level === "INFO") return "#60a5fa"
6
- if (level === "WARNING") return "#fbbf24"
7
- if (level === "ERROR") return "#ef4444"
8
- if (level === "FATAL") return "#dc2626"
9
- return "#e5e7eb"
10
- }
11
-
12
- export function LogLine({ log }: { log: ConsoleStore.ConsoleLog }) {
13
- const color = levelColor(log.level)
14
- const time = log.date.toLocaleTimeString("en", {
15
- hour12: false,
16
- hour: "2-digit",
17
- minute: "2-digit",
18
- second: "2-digit",
19
- })
20
-
21
- return (
22
- <div
23
- id={`log-${log.id}`}
24
- style="padding:3px 8px;border-bottom:1px solid #1f2937;font-family:monospace;font-size:12px;display:flex;align-items:baseline"
25
- >
26
- <span style="color:#6b7280;white-space:nowrap">{time}</span>
27
- <span style={`color:${color};font-weight:600;width:56px;text-align:center;flex-shrink:0`}>
28
- {log.level}
29
- </span>
30
- <span style="color:#e5e7eb;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis">
31
- {log.message}
32
- </span>
33
- <a
34
- href={`${ConsoleStore.store.prefix}/fibers/${log.fiberId.replace("#", "")}`}
35
- style="color:#6b7280;white-space:nowrap;margin-left:8px;text-decoration:none"
36
- >
37
- {log.fiberId}
38
- </a>
39
- {log.cause && (
40
- <div style="color:#ef4444;font-size:11px;padding:2px 0 0 0;white-space:pre-wrap;width:100%">
41
- {log.cause}
42
- </div>
43
- )}
44
- </div>
45
- )
46
- }
@@ -1,78 +0,0 @@
1
- import type * as ConsoleStore from "../ConsoleStore.ts"
2
-
3
- function MetricValue({ metric }: { metric: ConsoleStore.ConsoleMetricSnapshot }) {
4
- if (metric.type === "counter" || metric.type === "gauge") {
5
- return (
6
- <div style="font-size:32px;font-weight:700;color:#e5e7eb;font-family:monospace;line-height:1.1">
7
- {String(metric.value)}
8
- </div>
9
- )
10
- }
11
- if (metric.type === "histogram") {
12
- const h = metric.value as { count: number; sum: number; min: number; max: number }
13
- return (
14
- <div style="display:grid;grid-template-columns:auto auto;gap:2px 12px;font-size:12px;font-family:monospace">
15
- <span style="color:#6b7280">count</span>
16
- <span style="color:#e5e7eb">{h.count}</span>
17
- <span style="color:#6b7280">sum</span>
18
- <span style="color:#e5e7eb">{h.sum.toFixed(2)}</span>
19
- <span style="color:#6b7280">min</span>
20
- <span style="color:#e5e7eb">{h.min.toFixed(2)}</span>
21
- <span style="color:#6b7280">max</span>
22
- <span style="color:#e5e7eb">{h.max.toFixed(2)}</span>
23
- </div>
24
- )
25
- }
26
- if (metric.type === "frequency") {
27
- const occ = metric.value as Record<string, number>
28
- return (
29
- <div style="display:grid;grid-template-columns:auto auto;gap:2px 12px;font-size:12px;font-family:monospace">
30
- {Object.entries(occ)
31
- .slice(0, 10)
32
- .map(([k, v]) => (
33
- <>
34
- <span style="color:#6b7280">{k}</span>
35
- <span style="color:#e5e7eb">{v}</span>
36
- </>
37
- ))}
38
- </div>
39
- )
40
- }
41
- return (
42
- <pre style="font-size:11px;color:#9ca3af;margin:0;white-space:pre-wrap">
43
- {JSON.stringify(metric.value, null, 2)}
44
- </pre>
45
- )
46
- }
47
-
48
- function MetricCard({ metric }: { metric: ConsoleStore.ConsoleMetricSnapshot }) {
49
- return (
50
- <div style="background:#111827;border:1px solid #374151;border-radius:6px;padding:12px;min-width:200px">
51
- <div style="display:flex;align-items:center;gap:8px;margin-bottom:8px">
52
- <span style="color:#d1d5db;font-size:13px;font-weight:600">{metric.name}</span>
53
- <span style="font-size:10px;padding:1px 6px;border-radius:4px;background:#1e3a5f;color:#60a5fa">
54
- {metric.type}
55
- </span>
56
- </div>
57
- <MetricValue metric={metric} />
58
- {metric.tags.length > 0 && (
59
- <div style="font-size:10px;color:#6b7280;margin-top:4px">
60
- {metric.tags.map((t) => `${t.key}=${t.value}`).join(" ")}
61
- </div>
62
- )}
63
- </div>
64
- )
65
- }
66
-
67
- export function MetricsGrid({ metrics }: { metrics: Array<ConsoleStore.ConsoleMetricSnapshot> }) {
68
- if (metrics.length === 0) {
69
- return <div class="empty">Waiting for metrics...</div>
70
- }
71
- return (
72
- <>
73
- {metrics.map((m) => (
74
- <MetricCard metric={m} />
75
- ))}
76
- </>
77
- )
78
- }
@@ -1,125 +0,0 @@
1
- export interface RouteInfo {
2
- readonly method: string
3
- readonly path: string
4
- readonly format: string | undefined
5
- }
6
-
7
- function groupByPath(routes: Array<RouteInfo>): Array<{ path: string; routes: Array<RouteInfo> }> {
8
- const byPath = new Map<string, Array<RouteInfo>>()
9
- for (const r of routes) {
10
- let group = byPath.get(r.path)
11
- if (!group) {
12
- group = []
13
- byPath.set(r.path, group)
14
- }
15
- group.push(r)
16
- }
17
- return Array.from(byPath, ([path, routes]) => ({
18
- path,
19
- routes: routes.sort((a, b) => methodOrder.indexOf(a.method) - methodOrder.indexOf(b.method)),
20
- })).sort((a, b) => a.path.localeCompare(b.path))
21
- }
22
-
23
- function methodColor(method: string): string {
24
- if (method === "GET") return "#22c55e"
25
- if (method === "POST") return "#3b82f6"
26
- if (method === "PUT") return "#f59e0b"
27
- if (method === "DELETE") return "#ef4444"
28
- if (method === "PATCH") return "#a855f7"
29
- if (method === "*") return "#6b7280"
30
- return "#94a3b8"
31
- }
32
-
33
- function methodBg(method: string): string {
34
- if (method === "GET") return "#052e16"
35
- if (method === "POST") return "#172554"
36
- if (method === "PUT") return "#422006"
37
- if (method === "DELETE") return "#450a0a"
38
- if (method === "PATCH") return "#3b0764"
39
- return "#1e293b"
40
- }
41
-
42
- const methodOrder = ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS", "*"]
43
-
44
- function MethodBadge({ method }: { method: string }) {
45
- return (
46
- <span
47
- style={`font-size:10px;font-weight:700;font-family:monospace;padding:2px 6px;border-radius:3px;background:${methodBg(method)};color:${methodColor(method)};min-width:48px;text-align:center;display:inline-block`}
48
- >
49
- {method}
50
- </span>
51
- )
52
- }
53
-
54
- function FormatBadge({ format }: { format: string }) {
55
- return (
56
- <span style="font-size:10px;padding:1px 6px;border-radius:3px;background:#1e3a5f;color:#60a5fa">
57
- {format}
58
- </span>
59
- )
60
- }
61
-
62
- function ColoredPath({ path }: { path: string }) {
63
- const segments = path.split("/").filter(Boolean)
64
- return (
65
- <span style="font-family:monospace;font-size:13px">
66
- {segments.length === 0 ? (
67
- <span style="color:#e2e8f0">/</span>
68
- ) : (
69
- segments.map((seg) => {
70
- const isParam = seg.startsWith(":")
71
- return (
72
- <>
73
- <span style="color:#475569">/</span>
74
- <span style={isParam ? "color:#c084fc" : "color:#e2e8f0"}>{seg}</span>
75
- </>
76
- )
77
- })
78
- )}
79
- </span>
80
- )
81
- }
82
-
83
- function PathGroup({ path, routes }: { path: string; routes: Array<RouteInfo> }) {
84
- return (
85
- <div style="padding:8px 12px;border-bottom:1px solid #1e293b">
86
- <div style="margin-bottom:4px">
87
- <ColoredPath path={path} />
88
- </div>
89
- <div style="display:flex;flex-wrap:wrap;gap:4px">
90
- {routes.map((r) => (
91
- <div style="display:flex;align-items:center;gap:6px">
92
- <MethodBadge method={r.method} />
93
- {r.format && <FormatBadge format={r.format} />}
94
- </div>
95
- ))}
96
- </div>
97
- </div>
98
- )
99
- }
100
-
101
- export function RouteList({ routes }: { routes: Array<RouteInfo> }) {
102
- if (routes.length === 0) {
103
- return <div class="empty">No routes registered</div>
104
- }
105
-
106
- const groups = groupByPath(routes)
107
- const routeCount = routes.length
108
- const pathCount = groups.length
109
-
110
- return (
111
- <>
112
- <div style="padding:8px 12px;border-bottom:1px solid #1e293b;display:flex;gap:16px;font-size:12px;color:#64748b">
113
- <span>
114
- {pathCount} path{pathCount !== 1 ? "s" : ""}
115
- </span>
116
- <span>
117
- {routeCount} route{routeCount !== 1 ? "s" : ""}
118
- </span>
119
- </div>
120
- {groups.map((g) => (
121
- <PathGroup path={g.path} routes={g.routes} />
122
- ))}
123
- </>
124
- )
125
- }