gorsee 0.2.4 → 0.2.6

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 (532) hide show
  1. package/README.md +283 -212
  2. package/dist-pkg/ai/artifact-lifecycle.d.ts +25 -0
  3. package/dist-pkg/ai/artifact-lifecycle.js +98 -0
  4. package/dist-pkg/ai/bridge.d.ts +26 -0
  5. package/dist-pkg/ai/bridge.js +82 -0
  6. package/dist-pkg/ai/bundle.d.ts +46 -0
  7. package/dist-pkg/ai/bundle.js +247 -0
  8. package/dist-pkg/ai/contracts.d.ts +1 -0
  9. package/dist-pkg/ai/contracts.js +1 -0
  10. package/dist-pkg/ai/ide.d.ts +37 -0
  11. package/dist-pkg/ai/ide.js +56 -0
  12. package/dist-pkg/ai/index.d.ts +85 -0
  13. package/dist-pkg/ai/index.js +267 -0
  14. package/dist-pkg/ai/json.d.ts +6 -0
  15. package/dist-pkg/ai/json.js +14 -0
  16. package/dist-pkg/ai/mcp.d.ts +28 -0
  17. package/dist-pkg/ai/mcp.js +173 -0
  18. package/dist-pkg/ai/session-pack.d.ts +28 -0
  19. package/dist-pkg/ai/session-pack.js +57 -0
  20. package/dist-pkg/ai/store.d.ts +67 -0
  21. package/dist-pkg/ai/store.js +174 -0
  22. package/dist-pkg/ai/summary.d.ts +57 -0
  23. package/dist-pkg/ai/summary.js +148 -0
  24. package/dist-pkg/ai/watch.d.ts +15 -0
  25. package/dist-pkg/ai/watch.js +66 -0
  26. package/dist-pkg/auth/action-tokens.d.ts +50 -0
  27. package/dist-pkg/auth/action-tokens.js +79 -0
  28. package/dist-pkg/auth/index.d.ts +70 -0
  29. package/dist-pkg/auth/index.js +199 -0
  30. package/dist-pkg/auth/redis-session-store.d.ts +7 -0
  31. package/dist-pkg/auth/redis-session-store.js +42 -0
  32. package/dist-pkg/auth/signing.d.ts +4 -0
  33. package/dist-pkg/auth/signing.js +33 -0
  34. package/dist-pkg/auth/sqlite-session-store.d.ts +12 -0
  35. package/dist-pkg/auth/sqlite-session-store.js +83 -0
  36. package/dist-pkg/auth/store-utils.d.ts +2 -0
  37. package/dist-pkg/auth/store-utils.js +20 -0
  38. package/dist-pkg/bin/gorsee.js +2 -0
  39. package/dist-pkg/build/backends/experimental-rolldown.d.ts +6 -0
  40. package/dist-pkg/build/backends/experimental-rolldown.js +9 -0
  41. package/dist-pkg/build/backends/register.d.ts +7 -0
  42. package/dist-pkg/build/backends/register.js +24 -0
  43. package/dist-pkg/build/backends/rolldown.d.ts +16 -0
  44. package/dist-pkg/build/backends/rolldown.js +176 -0
  45. package/dist-pkg/build/client-backend.d.ts +31 -0
  46. package/dist-pkg/build/client-backend.js +97 -0
  47. package/dist-pkg/build/client.d.ts +12 -0
  48. package/dist-pkg/build/client.js +93 -0
  49. package/dist-pkg/build/css-modules.d.ts +10 -0
  50. package/dist-pkg/build/css-modules.js +51 -0
  51. package/dist-pkg/build/devalue-parse.d.ts +1 -0
  52. package/dist-pkg/build/devalue-parse.js +1 -0
  53. package/dist-pkg/build/diagnostics.d.ts +20 -0
  54. package/dist-pkg/build/diagnostics.js +35 -0
  55. package/dist-pkg/build/fixtures.d.ts +7 -0
  56. package/dist-pkg/build/fixtures.js +60 -0
  57. package/dist-pkg/build/framework-imports.d.ts +4 -0
  58. package/dist-pkg/build/framework-imports.js +58 -0
  59. package/dist-pkg/build/init.d.ts +1 -0
  60. package/dist-pkg/build/init.js +6 -0
  61. package/dist-pkg/build/manifest.d.ts +3 -0
  62. package/dist-pkg/build/manifest.js +23 -0
  63. package/dist-pkg/build/parity.d.ts +32 -0
  64. package/dist-pkg/build/parity.js +71 -0
  65. package/dist-pkg/build/plugin.d.ts +11 -0
  66. package/dist-pkg/build/plugin.js +8 -0
  67. package/dist-pkg/build/readiness.d.ts +11 -0
  68. package/dist-pkg/build/readiness.js +18 -0
  69. package/dist-pkg/build/route-client-transform.d.ts +17 -0
  70. package/dist-pkg/build/route-client-transform.js +48 -0
  71. package/dist-pkg/build/route-metadata.d.ts +6 -0
  72. package/dist-pkg/build/route-metadata.js +8 -0
  73. package/dist-pkg/build/rpc-transform.d.ts +1 -0
  74. package/dist-pkg/build/rpc-transform.js +44 -0
  75. package/dist-pkg/build/server-bundle.d.ts +4 -0
  76. package/dist-pkg/build/server-bundle.js +261 -0
  77. package/dist-pkg/build/server-strip.d.ts +2 -0
  78. package/dist-pkg/build/server-strip.js +32 -0
  79. package/dist-pkg/build/ssg.d.ts +12 -0
  80. package/dist-pkg/build/ssg.js +36 -0
  81. package/dist-pkg/cli/bun-plugin.d.ts +2 -0
  82. package/dist-pkg/cli/bun-plugin.js +14 -0
  83. package/dist-pkg/cli/canonical-import-rewrite.d.ts +18 -0
  84. package/dist-pkg/cli/canonical-import-rewrite.js +94 -0
  85. package/dist-pkg/cli/canonical-imports.d.ts +8 -0
  86. package/dist-pkg/cli/canonical-imports.js +131 -0
  87. package/dist-pkg/cli/check-ast.d.ts +20 -0
  88. package/dist-pkg/cli/check-ast.js +126 -0
  89. package/dist-pkg/cli/cmd-ai.d.ts +4 -0
  90. package/dist-pkg/cli/cmd-ai.js +290 -0
  91. package/dist-pkg/cli/cmd-build.d.ts +12 -0
  92. package/dist-pkg/cli/cmd-build.js +198 -0
  93. package/dist-pkg/cli/cmd-check.d.ts +25 -0
  94. package/dist-pkg/cli/cmd-check.js +573 -0
  95. package/dist-pkg/cli/cmd-create.d.ts +6 -0
  96. package/dist-pkg/cli/cmd-create.js +600 -0
  97. package/dist-pkg/cli/cmd-deploy.d.ts +6 -0
  98. package/dist-pkg/cli/cmd-deploy.js +381 -0
  99. package/dist-pkg/cli/cmd-dev.d.ts +5 -0
  100. package/dist-pkg/cli/cmd-dev.js +5 -0
  101. package/dist-pkg/cli/cmd-docs.d.ts +50 -0
  102. package/dist-pkg/cli/cmd-docs.js +122 -0
  103. package/dist-pkg/cli/cmd-generate.d.ts +12 -0
  104. package/dist-pkg/cli/cmd-generate.js +320 -0
  105. package/dist-pkg/cli/cmd-migrate.d.ts +7 -0
  106. package/dist-pkg/cli/cmd-migrate.js +42 -0
  107. package/dist-pkg/cli/cmd-routes.d.ts +6 -0
  108. package/dist-pkg/cli/cmd-routes.js +24 -0
  109. package/dist-pkg/cli/cmd-start.d.ts +13 -0
  110. package/dist-pkg/cli/cmd-start.js +32 -0
  111. package/dist-pkg/cli/cmd-test.d.ts +20 -0
  112. package/dist-pkg/cli/cmd-test.js +103 -0
  113. package/dist-pkg/cli/cmd-typegen.d.ts +7 -0
  114. package/dist-pkg/cli/cmd-typegen.js +66 -0
  115. package/dist-pkg/cli/cmd-upgrade.d.ts +38 -0
  116. package/dist-pkg/cli/cmd-upgrade.js +232 -0
  117. package/dist-pkg/cli/context.d.ts +4 -0
  118. package/dist-pkg/cli/context.js +4 -0
  119. package/dist-pkg/cli/framework-md.d.ts +1 -0
  120. package/dist-pkg/cli/framework-md.js +391 -0
  121. package/dist-pkg/cli/index.d.ts +6 -0
  122. package/dist-pkg/cli/index.js +106 -0
  123. package/dist-pkg/cli/release-version.d.ts +2 -0
  124. package/dist-pkg/cli/release-version.js +33 -0
  125. package/dist-pkg/client.d.ts +16 -0
  126. package/dist-pkg/client.js +71 -0
  127. package/dist-pkg/compat.d.ts +1 -0
  128. package/dist-pkg/compat.js +1 -0
  129. package/dist-pkg/compiler/analysis-backend.d.ts +20 -0
  130. package/dist-pkg/compiler/analysis-backend.js +164 -0
  131. package/dist-pkg/compiler/backends/experimental-oxc.d.ts +6 -0
  132. package/dist-pkg/compiler/backends/experimental-oxc.js +9 -0
  133. package/dist-pkg/compiler/backends/oxc.d.ts +16 -0
  134. package/dist-pkg/compiler/backends/oxc.js +198 -0
  135. package/dist-pkg/compiler/backends/register.d.ts +7 -0
  136. package/dist-pkg/compiler/backends/register.js +22 -0
  137. package/dist-pkg/compiler/fixtures.d.ts +2 -0
  138. package/dist-pkg/compiler/fixtures.js +118 -0
  139. package/dist-pkg/compiler/init.d.ts +1 -0
  140. package/dist-pkg/compiler/init.js +6 -0
  141. package/dist-pkg/compiler/module-analysis.d.ts +13 -0
  142. package/dist-pkg/compiler/module-analysis.js +50 -0
  143. package/dist-pkg/compiler/parity.d.ts +35 -0
  144. package/dist-pkg/compiler/parity.js +89 -0
  145. package/dist-pkg/compiler/readiness.d.ts +11 -0
  146. package/dist-pkg/compiler/readiness.js +18 -0
  147. package/dist-pkg/compiler/route-facts.d.ts +34 -0
  148. package/dist-pkg/compiler/route-facts.js +75 -0
  149. package/dist-pkg/content/index.d.ts +27 -0
  150. package/dist-pkg/content/index.js +287 -0
  151. package/dist-pkg/db/index.d.ts +3 -0
  152. package/dist-pkg/db/index.js +6 -0
  153. package/dist-pkg/db/migrate.d.ts +7 -0
  154. package/dist-pkg/db/migrate.js +53 -0
  155. package/dist-pkg/db/postgres.d.ts +29 -0
  156. package/dist-pkg/db/postgres.js +59 -0
  157. package/dist-pkg/db/sqlite.d.ts +10 -0
  158. package/dist-pkg/db/sqlite.js +22 -0
  159. package/dist-pkg/deploy/cloudflare.d.ts +8 -0
  160. package/{src/deploy/cloudflare.ts → dist-pkg/deploy/cloudflare.js} +44 -28
  161. package/dist-pkg/deploy/conformance.d.ts +21 -0
  162. package/dist-pkg/deploy/conformance.js +98 -0
  163. package/dist-pkg/deploy/dockerfile.d.ts +3 -0
  164. package/{src/deploy/dockerfile.ts → dist-pkg/deploy/dockerfile.js} +8 -10
  165. package/dist-pkg/deploy/fly.d.ts +3 -0
  166. package/{src/deploy/fly.ts → dist-pkg/deploy/fly.js} +11 -12
  167. package/dist-pkg/deploy/index.d.ts +6 -0
  168. package/dist-pkg/deploy/index.js +26 -0
  169. package/dist-pkg/deploy/netlify.d.ts +2 -0
  170. package/{src/deploy/netlify.ts → dist-pkg/deploy/netlify.js} +17 -11
  171. package/dist-pkg/deploy/runtime.d.ts +2 -0
  172. package/dist-pkg/deploy/runtime.js +3 -0
  173. package/dist-pkg/deploy/vercel.d.ts +22 -0
  174. package/dist-pkg/deploy/vercel.js +53 -0
  175. package/dist-pkg/dev/error-overlay.d.ts +1 -0
  176. package/{src/dev/error-overlay.ts → dist-pkg/dev/error-overlay.js} +13 -23
  177. package/dist-pkg/dev/hmr.d.ts +30 -0
  178. package/dist-pkg/dev/hmr.js +86 -0
  179. package/dist-pkg/dev/partial-handler.d.ts +9 -0
  180. package/dist-pkg/dev/partial-handler.js +24 -0
  181. package/dist-pkg/dev/request-handler.d.ts +30 -0
  182. package/dist-pkg/dev/request-handler.js +67 -0
  183. package/dist-pkg/dev/watcher.d.ts +6 -0
  184. package/dist-pkg/dev/watcher.js +34 -0
  185. package/dist-pkg/dev.d.ts +11 -0
  186. package/dist-pkg/dev.js +268 -0
  187. package/dist-pkg/env/index.d.ts +3 -0
  188. package/dist-pkg/env/index.js +57 -0
  189. package/dist-pkg/errors/catalog.d.ts +9 -0
  190. package/{src/errors/catalog.ts → dist-pkg/errors/catalog.js} +8 -24
  191. package/dist-pkg/errors/formatter.d.ts +22 -0
  192. package/dist-pkg/errors/formatter.js +43 -0
  193. package/dist-pkg/errors/index.d.ts +2 -0
  194. package/dist-pkg/errors/index.js +2 -0
  195. package/dist-pkg/forms/action.d.ts +15 -0
  196. package/dist-pkg/forms/action.js +20 -0
  197. package/dist-pkg/forms/index.d.ts +4 -0
  198. package/dist-pkg/forms/index.js +12 -0
  199. package/dist-pkg/i18n/index.d.ts +61 -0
  200. package/dist-pkg/i18n/index.js +147 -0
  201. package/dist-pkg/index-client.d.ts +1 -0
  202. package/dist-pkg/index-client.js +1 -0
  203. package/dist-pkg/index.d.ts +32 -0
  204. package/dist-pkg/index.js +79 -0
  205. package/dist-pkg/jsx-runtime-client.d.ts +8 -0
  206. package/dist-pkg/jsx-runtime-client.js +1 -0
  207. package/dist-pkg/jsx-runtime.d.ts +13 -0
  208. package/dist-pkg/jsx-runtime.js +5 -0
  209. package/dist-pkg/jsx-types-html.d.ts +221 -0
  210. package/dist-pkg/jsx-types-html.js +0 -0
  211. package/dist-pkg/log/index.d.ts +8 -0
  212. package/dist-pkg/log/index.js +55 -0
  213. package/dist-pkg/plugins/drizzle.d.ts +16 -0
  214. package/dist-pkg/plugins/drizzle.js +53 -0
  215. package/dist-pkg/plugins/index.d.ts +62 -0
  216. package/dist-pkg/plugins/index.js +159 -0
  217. package/dist-pkg/plugins/lucia.d.ts +26 -0
  218. package/dist-pkg/plugins/lucia.js +63 -0
  219. package/dist-pkg/plugins/prisma.d.ts +14 -0
  220. package/dist-pkg/plugins/prisma.js +60 -0
  221. package/dist-pkg/plugins/resend.d.ts +21 -0
  222. package/dist-pkg/plugins/resend.js +45 -0
  223. package/dist-pkg/plugins/s3.d.ts +18 -0
  224. package/dist-pkg/plugins/s3.js +63 -0
  225. package/dist-pkg/plugins/stripe.d.ts +32 -0
  226. package/dist-pkg/plugins/stripe.js +69 -0
  227. package/dist-pkg/plugins/tailwind.d.ts +15 -0
  228. package/dist-pkg/plugins/tailwind.js +58 -0
  229. package/dist-pkg/prod.d.ts +21 -0
  230. package/dist-pkg/prod.js +347 -0
  231. package/dist-pkg/reactive/computed.d.ts +3 -0
  232. package/dist-pkg/reactive/computed.js +15 -0
  233. package/dist-pkg/reactive/data.d.ts +25 -0
  234. package/dist-pkg/reactive/data.js +56 -0
  235. package/dist-pkg/reactive/diagnostics.d.ts +100 -0
  236. package/dist-pkg/reactive/diagnostics.js +363 -0
  237. package/dist-pkg/reactive/effect.d.ts +3 -0
  238. package/dist-pkg/reactive/effect.js +6 -0
  239. package/dist-pkg/reactive/index.d.ts +9 -0
  240. package/dist-pkg/reactive/index.js +18 -0
  241. package/dist-pkg/reactive/live.d.ts +15 -0
  242. package/dist-pkg/reactive/live.js +70 -0
  243. package/dist-pkg/reactive/optimistic.d.ts +20 -0
  244. package/dist-pkg/reactive/optimistic.js +67 -0
  245. package/dist-pkg/reactive/resource.d.ts +25 -0
  246. package/dist-pkg/reactive/resource.js +153 -0
  247. package/dist-pkg/reactive/signal.d.ts +4 -0
  248. package/dist-pkg/reactive/signal.js +17 -0
  249. package/dist-pkg/reactive/store.d.ts +6 -0
  250. package/dist-pkg/reactive/store.js +19 -0
  251. package/dist-pkg/router/index.d.ts +2 -0
  252. package/dist-pkg/router/index.js +2 -0
  253. package/dist-pkg/router/matcher.d.ts +7 -0
  254. package/dist-pkg/router/matcher.js +40 -0
  255. package/dist-pkg/router/scanner.d.ts +14 -0
  256. package/dist-pkg/router/scanner.js +141 -0
  257. package/dist-pkg/routes/index.d.ts +1 -0
  258. package/dist-pkg/routes/index.js +10 -0
  259. package/dist-pkg/runtime/app-config.d.ts +26 -0
  260. package/dist-pkg/runtime/app-config.js +69 -0
  261. package/dist-pkg/runtime/client.d.ts +3 -0
  262. package/dist-pkg/runtime/client.js +42 -0
  263. package/dist-pkg/runtime/devtools.d.ts +64 -0
  264. package/dist-pkg/runtime/devtools.js +132 -0
  265. package/dist-pkg/runtime/error-boundary.d.ts +6 -0
  266. package/dist-pkg/runtime/error-boundary.js +17 -0
  267. package/dist-pkg/runtime/event-replay.d.ts +3 -0
  268. package/{src/runtime/event-replay.ts → dist-pkg/runtime/event-replay.js} +20 -22
  269. package/dist-pkg/runtime/event-source.d.ts +7 -0
  270. package/dist-pkg/runtime/event-source.js +24 -0
  271. package/dist-pkg/runtime/form.d.ts +24 -0
  272. package/dist-pkg/runtime/form.js +65 -0
  273. package/dist-pkg/runtime/head.d.ts +7 -0
  274. package/dist-pkg/runtime/head.js +90 -0
  275. package/dist-pkg/runtime/html-escape.d.ts +7 -0
  276. package/dist-pkg/runtime/html-escape.js +39 -0
  277. package/dist-pkg/runtime/hydration.d.ts +15 -0
  278. package/dist-pkg/runtime/hydration.js +103 -0
  279. package/dist-pkg/runtime/image.d.ts +49 -0
  280. package/dist-pkg/runtime/image.js +144 -0
  281. package/dist-pkg/runtime/index.d.ts +17 -0
  282. package/dist-pkg/runtime/index.js +59 -0
  283. package/dist-pkg/runtime/island-hydrator.d.ts +12 -0
  284. package/dist-pkg/runtime/island-hydrator.js +74 -0
  285. package/dist-pkg/runtime/island.d.ts +19 -0
  286. package/dist-pkg/runtime/island.js +36 -0
  287. package/dist-pkg/runtime/jsx-runtime.d.ts +12 -0
  288. package/dist-pkg/runtime/jsx-runtime.js +176 -0
  289. package/dist-pkg/runtime/link.d.ts +16 -0
  290. package/dist-pkg/runtime/link.js +47 -0
  291. package/dist-pkg/runtime/project.d.ts +37 -0
  292. package/dist-pkg/runtime/project.js +36 -0
  293. package/dist-pkg/runtime/renderable.d.ts +6 -0
  294. package/dist-pkg/runtime/renderable.js +0 -0
  295. package/dist-pkg/runtime/router.d.ts +47 -0
  296. package/dist-pkg/runtime/router.js +487 -0
  297. package/dist-pkg/runtime/server.d.ts +8 -0
  298. package/dist-pkg/runtime/server.js +71 -0
  299. package/dist-pkg/runtime/stream.d.ts +29 -0
  300. package/dist-pkg/runtime/stream.js +106 -0
  301. package/dist-pkg/runtime/suspense.d.ts +6 -0
  302. package/dist-pkg/runtime/suspense.js +16 -0
  303. package/dist-pkg/runtime/typed-routes.d.ts +24 -0
  304. package/dist-pkg/runtime/typed-routes.js +77 -0
  305. package/dist-pkg/runtime/validated-form.d.ts +40 -0
  306. package/dist-pkg/runtime/validated-form.js +120 -0
  307. package/dist-pkg/security/cors.d.ts +10 -0
  308. package/dist-pkg/security/cors.js +56 -0
  309. package/dist-pkg/security/csrf.d.ts +9 -0
  310. package/dist-pkg/security/csrf.js +53 -0
  311. package/dist-pkg/security/headers.d.ts +11 -0
  312. package/dist-pkg/security/headers.js +31 -0
  313. package/dist-pkg/security/index.d.ts +5 -0
  314. package/dist-pkg/security/index.js +5 -0
  315. package/dist-pkg/security/rate-limit.d.ts +10 -0
  316. package/dist-pkg/security/rate-limit.js +49 -0
  317. package/dist-pkg/security/redis-rate-limit.d.ts +14 -0
  318. package/dist-pkg/security/redis-rate-limit.js +23 -0
  319. package/dist-pkg/server/action.d.ts +21 -0
  320. package/dist-pkg/server/action.js +64 -0
  321. package/dist-pkg/server/cache-utils.d.ts +2 -0
  322. package/dist-pkg/server/cache-utils.js +26 -0
  323. package/dist-pkg/server/cache.d.ts +33 -0
  324. package/dist-pkg/server/cache.js +236 -0
  325. package/dist-pkg/server/compress.d.ts +2 -0
  326. package/dist-pkg/server/compress.js +77 -0
  327. package/dist-pkg/server/endpoint-execution.d.ts +28 -0
  328. package/dist-pkg/server/endpoint-execution.js +37 -0
  329. package/dist-pkg/server/etag.d.ts +3 -0
  330. package/dist-pkg/server/etag.js +18 -0
  331. package/dist-pkg/server/guard.d.ts +16 -0
  332. package/dist-pkg/server/guard.js +45 -0
  333. package/dist-pkg/server/html-shell.d.ts +12 -0
  334. package/dist-pkg/server/html-shell.js +52 -0
  335. package/dist-pkg/server/index.d.ts +36 -0
  336. package/dist-pkg/server/index.js +170 -0
  337. package/dist-pkg/server/jobs.d.ts +41 -0
  338. package/dist-pkg/server/jobs.js +83 -0
  339. package/dist-pkg/server/manifest.d.ts +19 -0
  340. package/dist-pkg/server/manifest.js +36 -0
  341. package/dist-pkg/server/middleware.d.ts +39 -0
  342. package/dist-pkg/server/middleware.js +127 -0
  343. package/dist-pkg/server/mime.d.ts +1 -0
  344. package/{src/server/mime.ts → dist-pkg/server/mime.js} +6 -17
  345. package/dist-pkg/server/not-found.d.ts +6 -0
  346. package/dist-pkg/server/not-found.js +27 -0
  347. package/dist-pkg/server/page-render.d.ts +29 -0
  348. package/dist-pkg/server/page-render.js +70 -0
  349. package/dist-pkg/server/partial-navigation.d.ts +4 -0
  350. package/dist-pkg/server/partial-navigation.js +16 -0
  351. package/dist-pkg/server/pipe.d.ts +9 -0
  352. package/dist-pkg/server/pipe.js +32 -0
  353. package/dist-pkg/server/redis-cache-store.d.ts +10 -0
  354. package/dist-pkg/server/redis-cache-store.js +73 -0
  355. package/dist-pkg/server/redis-client.d.ts +37 -0
  356. package/dist-pkg/server/redis-client.js +37 -0
  357. package/dist-pkg/server/request-policy.d.ts +55 -0
  358. package/dist-pkg/server/request-policy.js +216 -0
  359. package/dist-pkg/server/request-preflight.d.ts +23 -0
  360. package/dist-pkg/server/request-preflight.js +46 -0
  361. package/dist-pkg/server/request-security-policy.d.ts +17 -0
  362. package/dist-pkg/server/request-security-policy.js +34 -0
  363. package/dist-pkg/server/request-surface.d.ts +8 -0
  364. package/dist-pkg/server/request-surface.js +19 -0
  365. package/dist-pkg/server/route-request.d.ts +31 -0
  366. package/dist-pkg/server/route-request.js +112 -0
  367. package/dist-pkg/server/route-response.d.ts +22 -0
  368. package/dist-pkg/server/route-response.js +61 -0
  369. package/dist-pkg/server/rpc-hash.d.ts +2 -0
  370. package/dist-pkg/server/rpc-hash.js +7 -0
  371. package/dist-pkg/server/rpc-protocol.d.ts +22 -0
  372. package/dist-pkg/server/rpc-protocol.js +28 -0
  373. package/dist-pkg/server/rpc-utils.d.ts +2 -0
  374. package/dist-pkg/server/rpc-utils.js +26 -0
  375. package/dist-pkg/server/rpc.d.ts +20 -0
  376. package/dist-pkg/server/rpc.js +147 -0
  377. package/dist-pkg/server/runtime-dispatch.d.ts +19 -0
  378. package/dist-pkg/server/runtime-dispatch.js +67 -0
  379. package/dist-pkg/server/server-execution.d.ts +22 -0
  380. package/dist-pkg/server/server-execution.js +53 -0
  381. package/dist-pkg/server/sqlite-cache-store.d.ts +13 -0
  382. package/dist-pkg/server/sqlite-cache-store.js +88 -0
  383. package/dist-pkg/server/sse.d.ts +9 -0
  384. package/dist-pkg/server/sse.js +34 -0
  385. package/dist-pkg/server/static-file.d.ts +9 -0
  386. package/dist-pkg/server/static-file.js +43 -0
  387. package/dist-pkg/server/ws.d.ts +18 -0
  388. package/dist-pkg/server/ws.js +40 -0
  389. package/dist-pkg/server-entry.d.ts +19 -0
  390. package/dist-pkg/server-entry.js +93 -0
  391. package/dist-pkg/testing/index.d.ts +98 -0
  392. package/dist-pkg/testing/index.js +257 -0
  393. package/dist-pkg/types/index.d.ts +4 -0
  394. package/dist-pkg/types/index.js +4 -0
  395. package/dist-pkg/types/safe-html.d.ts +7 -0
  396. package/dist-pkg/types/safe-html.js +19 -0
  397. package/dist-pkg/types/safe-sql.d.ts +8 -0
  398. package/dist-pkg/types/safe-sql.js +14 -0
  399. package/dist-pkg/types/safe-url.d.ts +7 -0
  400. package/dist-pkg/types/safe-url.js +20 -0
  401. package/dist-pkg/types/user-input.d.ts +9 -0
  402. package/dist-pkg/types/user-input.js +3 -0
  403. package/dist-pkg/unsafe/index.d.ts +12 -0
  404. package/dist-pkg/unsafe/index.js +6 -0
  405. package/package.json +110 -45
  406. package/bin/gorsee.js +0 -2
  407. package/src/auth/index.ts +0 -178
  408. package/src/auth/redis-session-store.ts +0 -46
  409. package/src/auth/sqlite-session-store.ts +0 -98
  410. package/src/auth/store-utils.ts +0 -21
  411. package/src/build/client.ts +0 -139
  412. package/src/build/css-modules.ts +0 -69
  413. package/src/build/devalue-parse.ts +0 -2
  414. package/src/build/manifest.ts +0 -34
  415. package/src/build/route-metadata.ts +0 -12
  416. package/src/build/rpc-transform.ts +0 -62
  417. package/src/build/server-strip.ts +0 -87
  418. package/src/build/ssg.ts +0 -70
  419. package/src/cli/bun-plugin.ts +0 -58
  420. package/src/cli/cmd-build.ts +0 -153
  421. package/src/cli/cmd-check.ts +0 -239
  422. package/src/cli/cmd-create.ts +0 -328
  423. package/src/cli/cmd-deploy.ts +0 -149
  424. package/src/cli/cmd-dev.ts +0 -13
  425. package/src/cli/cmd-docs.ts +0 -152
  426. package/src/cli/cmd-generate.ts +0 -155
  427. package/src/cli/cmd-migrate.ts +0 -53
  428. package/src/cli/cmd-routes.ts +0 -36
  429. package/src/cli/cmd-start.ts +0 -30
  430. package/src/cli/cmd-test.ts +0 -129
  431. package/src/cli/cmd-typegen.ts +0 -93
  432. package/src/cli/cmd-upgrade.ts +0 -143
  433. package/src/cli/context.ts +0 -12
  434. package/src/cli/framework-md.ts +0 -223
  435. package/src/cli/index.ts +0 -107
  436. package/src/client.ts +0 -26
  437. package/src/db/index.ts +0 -2
  438. package/src/db/migrate.ts +0 -89
  439. package/src/db/sqlite.ts +0 -40
  440. package/src/deploy/index.ts +0 -31
  441. package/src/deploy/vercel.ts +0 -94
  442. package/src/dev/hmr.ts +0 -31
  443. package/src/dev/partial-handler.ts +0 -52
  444. package/src/dev/request-handler.ts +0 -127
  445. package/src/dev/watcher.ts +0 -48
  446. package/src/dev.ts +0 -208
  447. package/src/env/index.ts +0 -74
  448. package/src/errors/formatter.ts +0 -63
  449. package/src/errors/index.ts +0 -2
  450. package/src/i18n/index.ts +0 -72
  451. package/src/index-client.ts +0 -4
  452. package/src/index.ts +0 -43
  453. package/src/jsx-runtime-client.ts +0 -13
  454. package/src/jsx-runtime.ts +0 -20
  455. package/src/jsx-types-html.ts +0 -242
  456. package/src/log/index.ts +0 -44
  457. package/src/plugins/drizzle.ts +0 -84
  458. package/src/plugins/index.ts +0 -86
  459. package/src/plugins/lucia.ts +0 -111
  460. package/src/plugins/prisma.ts +0 -85
  461. package/src/plugins/resend.ts +0 -78
  462. package/src/plugins/s3.ts +0 -102
  463. package/src/plugins/stripe.ts +0 -133
  464. package/src/plugins/tailwind.ts +0 -92
  465. package/src/prod.ts +0 -252
  466. package/src/reactive/computed.ts +0 -7
  467. package/src/reactive/effect.ts +0 -7
  468. package/src/reactive/index.ts +0 -7
  469. package/src/reactive/live.ts +0 -97
  470. package/src/reactive/optimistic.ts +0 -83
  471. package/src/reactive/resource.ts +0 -138
  472. package/src/reactive/signal.ts +0 -20
  473. package/src/reactive/store.ts +0 -36
  474. package/src/router/index.ts +0 -2
  475. package/src/router/matcher.ts +0 -53
  476. package/src/router/scanner.ts +0 -206
  477. package/src/runtime/client.ts +0 -28
  478. package/src/runtime/error-boundary.ts +0 -35
  479. package/src/runtime/form.ts +0 -49
  480. package/src/runtime/head.ts +0 -113
  481. package/src/runtime/html-escape.ts +0 -30
  482. package/src/runtime/hydration.ts +0 -95
  483. package/src/runtime/image.ts +0 -48
  484. package/src/runtime/index.ts +0 -12
  485. package/src/runtime/island-hydrator.ts +0 -84
  486. package/src/runtime/island.ts +0 -88
  487. package/src/runtime/jsx-runtime.ts +0 -167
  488. package/src/runtime/link.ts +0 -45
  489. package/src/runtime/project.ts +0 -73
  490. package/src/runtime/router.ts +0 -224
  491. package/src/runtime/server.ts +0 -102
  492. package/src/runtime/stream.ts +0 -182
  493. package/src/runtime/suspense.ts +0 -37
  494. package/src/runtime/typed-routes.ts +0 -26
  495. package/src/runtime/validated-form.ts +0 -106
  496. package/src/security/cors.ts +0 -80
  497. package/src/security/csrf.ts +0 -85
  498. package/src/security/headers.ts +0 -50
  499. package/src/security/index.ts +0 -4
  500. package/src/security/rate-limit.ts +0 -80
  501. package/src/server/action.ts +0 -48
  502. package/src/server/cache-utils.ts +0 -23
  503. package/src/server/cache.ts +0 -125
  504. package/src/server/compress.ts +0 -60
  505. package/src/server/etag.ts +0 -23
  506. package/src/server/guard.ts +0 -69
  507. package/src/server/html-shell.ts +0 -69
  508. package/src/server/index.ts +0 -57
  509. package/src/server/manifest.ts +0 -36
  510. package/src/server/middleware.ts +0 -159
  511. package/src/server/not-found.ts +0 -35
  512. package/src/server/page-render.ts +0 -123
  513. package/src/server/pipe.ts +0 -46
  514. package/src/server/redis-cache-store.ts +0 -87
  515. package/src/server/redis-client.ts +0 -71
  516. package/src/server/request-preflight.ts +0 -45
  517. package/src/server/route-request.ts +0 -72
  518. package/src/server/rpc-hash.ts +0 -17
  519. package/src/server/rpc-utils.ts +0 -27
  520. package/src/server/rpc.ts +0 -177
  521. package/src/server/sqlite-cache-store.ts +0 -109
  522. package/src/server/sse.ts +0 -96
  523. package/src/server/static-file.ts +0 -63
  524. package/src/server/ws.ts +0 -56
  525. package/src/server-entry.ts +0 -36
  526. package/src/testing/index.ts +0 -74
  527. package/src/types/index.ts +0 -4
  528. package/src/types/safe-html.ts +0 -32
  529. package/src/types/safe-sql.ts +0 -28
  530. package/src/types/safe-url.ts +0 -40
  531. package/src/types/user-input.ts +0 -12
  532. package/src/unsafe/index.ts +0 -18
@@ -1,106 +0,0 @@
1
- // Type-safe validated forms with branded types
2
- // Combines client-side validation with server-side action safety
3
-
4
- export interface FieldRule {
5
- required?: boolean
6
- minLength?: number
7
- maxLength?: number
8
- pattern?: RegExp
9
- min?: number
10
- max?: number
11
- custom?: (value: string) => string | null // return error message or null
12
- }
13
-
14
- export interface FormField {
15
- name: string
16
- rules: FieldRule
17
- label?: string
18
- }
19
-
20
- export interface FormSchema {
21
- fields: FormField[]
22
- }
23
-
24
- export interface ValidationError {
25
- field: string
26
- message: string
27
- }
28
-
29
- export interface ValidationResult<T> {
30
- valid: boolean
31
- data: T | null
32
- errors: ValidationError[]
33
- }
34
-
35
- /** Define a form schema for validation */
36
- export function defineForm(fields: FormField[]): FormSchema {
37
- return { fields }
38
- }
39
-
40
- function validateField(value: string | undefined, field: FormField): string | null {
41
- const { rules, label } = field
42
- const name = label ?? field.name
43
- const v = value ?? ""
44
-
45
- if (rules.required && !v.trim()) return `${name} is required`
46
- if (!v && !rules.required) return null
47
- if (rules.minLength !== undefined && v.length < rules.minLength)
48
- return `${name} must be at least ${rules.minLength} characters`
49
- if (rules.maxLength !== undefined && v.length > rules.maxLength)
50
- return `${name} must be at most ${rules.maxLength} characters`
51
- if (rules.pattern && !rules.pattern.test(v)) return `${name} format is invalid`
52
- if (rules.min !== undefined && Number(v) < rules.min) return `${name} must be at least ${rules.min}`
53
- if (rules.max !== undefined && Number(v) > rules.max) return `${name} must be at most ${rules.max}`
54
- if (rules.custom) return rules.custom(v)
55
- return null
56
- }
57
-
58
- /** Validate form data against schema */
59
- export function validateForm<T extends Record<string, string>>(
60
- data: Record<string, string>,
61
- schema: FormSchema,
62
- ): ValidationResult<T> {
63
- const errors: ValidationError[] = []
64
-
65
- for (const field of schema.fields) {
66
- const error = validateField(data[field.name], field)
67
- if (error) errors.push({ field: field.name, message: error })
68
- }
69
-
70
- return {
71
- valid: errors.length === 0,
72
- data: errors.length === 0 ? (data as T) : null,
73
- errors,
74
- }
75
- }
76
-
77
- /** Server action helper: parse request and validate */
78
- export async function validateAction<T extends Record<string, string>>(
79
- request: Request,
80
- schema: FormSchema,
81
- ): Promise<ValidationResult<T>> {
82
- const contentType = request.headers.get("content-type") ?? ""
83
- let data: Record<string, string>
84
-
85
- if (contentType.includes("application/json")) {
86
- data = await request.json()
87
- } else {
88
- const formData = await request.formData()
89
- data = {}
90
- formData.forEach((v, k) => { data[k] = String(v) })
91
- }
92
-
93
- return validateForm<T>(data, schema)
94
- }
95
-
96
- /** Generate client-side validation attributes for HTML inputs */
97
- export function fieldAttrs(field: FormField): Record<string, unknown> {
98
- const attrs: Record<string, unknown> = { name: field.name }
99
- if (field.rules.required) attrs.required = true
100
- if (field.rules.minLength !== undefined) attrs.minlength = field.rules.minLength
101
- if (field.rules.maxLength !== undefined) attrs.maxlength = field.rules.maxLength
102
- if (field.rules.pattern) attrs.pattern = field.rules.pattern.source
103
- if (field.rules.min !== undefined) attrs.min = field.rules.min
104
- if (field.rules.max !== undefined) attrs.max = field.rules.max
105
- return attrs
106
- }
@@ -1,80 +0,0 @@
1
- // CORS middleware — configurable Cross-Origin Resource Sharing
2
-
3
- import type { MiddlewareFn } from "../server/middleware.ts"
4
-
5
- export interface CORSOptions {
6
- origin?: string | string[] | ((origin: string) => boolean)
7
- methods?: string[]
8
- allowHeaders?: string[]
9
- exposeHeaders?: string[]
10
- credentials?: boolean
11
- maxAge?: number
12
- }
13
-
14
- const DEFAULT_METHODS = ["GET", "HEAD", "PUT", "PATCH", "POST", "DELETE"]
15
- const DEFAULT_HEADERS = ["Content-Type", "Authorization", "X-Requested-With"]
16
-
17
- function isOriginAllowed(origin: string, allowed: CORSOptions["origin"]): boolean {
18
- if (!allowed) return false
19
- if (allowed === "*") return true
20
- if (typeof allowed === "string") return origin === allowed
21
- if (Array.isArray(allowed)) return allowed.includes(origin)
22
- if (typeof allowed === "function") return allowed(origin)
23
- return false
24
- }
25
-
26
- export function cors(options: CORSOptions = {}): MiddlewareFn {
27
- const {
28
- origin = "*",
29
- methods = DEFAULT_METHODS,
30
- allowHeaders = DEFAULT_HEADERS,
31
- exposeHeaders = [],
32
- credentials = false,
33
- maxAge = 86400,
34
- } = options
35
-
36
- return async (ctx, next) => {
37
- const requestOrigin = ctx.request.headers.get("origin") ?? ""
38
-
39
- // Preflight
40
- if (ctx.request.method === "OPTIONS") {
41
- const headers = new Headers()
42
-
43
- if (origin === "*" && !credentials) {
44
- headers.set("Access-Control-Allow-Origin", "*")
45
- } else if (isOriginAllowed(requestOrigin, origin)) {
46
- headers.set("Access-Control-Allow-Origin", requestOrigin)
47
- headers.set("Vary", "Origin")
48
- }
49
-
50
- headers.set("Access-Control-Allow-Methods", methods.join(", "))
51
- headers.set("Access-Control-Allow-Headers", allowHeaders.join(", "))
52
- if (exposeHeaders.length > 0) {
53
- headers.set("Access-Control-Expose-Headers", exposeHeaders.join(", "))
54
- }
55
- if (credentials) headers.set("Access-Control-Allow-Credentials", "true")
56
- headers.set("Access-Control-Max-Age", String(maxAge))
57
-
58
- return new Response(null, { status: 204, headers })
59
- }
60
-
61
- // Actual request
62
- const response = await next()
63
-
64
- if (origin === "*" && !credentials) {
65
- response.headers.set("Access-Control-Allow-Origin", "*")
66
- } else if (isOriginAllowed(requestOrigin, origin)) {
67
- response.headers.set("Access-Control-Allow-Origin", requestOrigin)
68
- response.headers.append("Vary", "Origin")
69
- }
70
-
71
- if (credentials) {
72
- response.headers.set("Access-Control-Allow-Credentials", "true")
73
- }
74
- if (exposeHeaders.length > 0) {
75
- response.headers.set("Access-Control-Expose-Headers", exposeHeaders.join(", "))
76
- }
77
-
78
- return response
79
- }
80
- }
@@ -1,85 +0,0 @@
1
- // CSRF protection using Signed Double-Submit Cookie pattern
2
- // Works for both SSR (token in HTML) and SPA (cookie-based)
3
-
4
- import { timingSafeEqual } from "node:crypto"
5
-
6
- const CSRF_COOKIE = "__gorsee_csrf"
7
- const CSRF_HEADER = "x-gorsee-csrf"
8
- const TOKEN_LENGTH = 32
9
-
10
- function randomBytes(length: number): string {
11
- const bytes = new Uint8Array(length)
12
- crypto.getRandomValues(bytes)
13
- return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("")
14
- }
15
-
16
- async function hmacSign(token: string, secret: string): Promise<string> {
17
- const key = await crypto.subtle.importKey(
18
- "raw",
19
- new TextEncoder().encode(secret),
20
- { name: "HMAC", hash: "SHA-256" },
21
- false,
22
- ["sign"]
23
- )
24
- const sig = await crypto.subtle.sign(
25
- "HMAC",
26
- key,
27
- new TextEncoder().encode(token)
28
- )
29
- return Array.from(new Uint8Array(sig), (b) => b.toString(16).padStart(2, "0")).join("")
30
- }
31
-
32
- export function generateCSRFToken(): string {
33
- return randomBytes(TOKEN_LENGTH)
34
- }
35
-
36
- export async function validateCSRFToken(
37
- request: Request,
38
- secret: string
39
- ): Promise<boolean> {
40
- // Skip safe methods
41
- if (["GET", "HEAD", "OPTIONS"].includes(request.method)) return true
42
-
43
- const cookieHeader = request.headers.get("cookie") ?? ""
44
- const headerToken = request.headers.get(CSRF_HEADER) ?? ""
45
-
46
- // Parse cookie
47
- let cookieToken = ""
48
- for (const pair of cookieHeader.split(";")) {
49
- const [key, ...rest] = pair.trim().split("=")
50
- if (key === CSRF_COOKIE) {
51
- cookieToken = rest.join("=")
52
- break
53
- }
54
- }
55
-
56
- if (!cookieToken || !headerToken) return false
57
-
58
- // Verify: cookie contains "token.signature", header contains "token"
59
- const [token, signature] = cookieToken.split(".")
60
- if (!token || !signature) return false
61
-
62
- // Header must match token part of cookie
63
- if (headerToken !== token) return false
64
-
65
- // Verify HMAC signature (timing-safe comparison)
66
- const expectedSig = await hmacSign(token, secret)
67
- if (signature.length !== expectedSig.length) return false
68
- return timingSafeEqual(Buffer.from(signature), Buffer.from(expectedSig))
69
- }
70
-
71
- export async function csrfProtection(secret: string): Promise<{
72
- token: string
73
- cookie: string
74
- headerName: string
75
- }> {
76
- const token = generateCSRFToken()
77
- const signature = await hmacSign(token, secret)
78
- const cookieValue = `${token}.${signature}`
79
-
80
- return {
81
- token,
82
- cookie: `${CSRF_COOKIE}=${cookieValue}; Path=/; SameSite=Lax; Secure`,
83
- headerName: CSRF_HEADER,
84
- }
85
- }
@@ -1,50 +0,0 @@
1
- export interface SecurityConfig {
2
- csp: boolean
3
- hsts: boolean
4
- csrf: boolean
5
- rateLimit: { requests: number; window: string } | false
6
- nonce?: string
7
- }
8
-
9
- const DEFAULT_CONFIG: SecurityConfig = {
10
- csp: true,
11
- hsts: true,
12
- csrf: true,
13
- rateLimit: { requests: 100, window: "1m" },
14
- }
15
-
16
- export function securityHeaders(
17
- config: Partial<SecurityConfig> = {},
18
- nonce?: string
19
- ): Record<string, string> {
20
- const cfg = { ...DEFAULT_CONFIG, ...config }
21
- const headers: Record<string, string> = {}
22
-
23
- if (cfg.csp) {
24
- const scriptSrc = nonce ? `'nonce-${nonce}'` : "'self'"
25
- headers["Content-Security-Policy"] = [
26
- "default-src 'self'",
27
- `script-src ${scriptSrc}`,
28
- "style-src 'self' 'unsafe-inline'",
29
- "img-src 'self' data: https:",
30
- "font-src 'self'",
31
- "connect-src 'self' ws: wss:",
32
- "frame-ancestors 'none'",
33
- "base-uri 'self'",
34
- "form-action 'self'",
35
- ].join("; ")
36
- }
37
-
38
- if (cfg.hsts) {
39
- headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains; preload"
40
- }
41
-
42
- // Always set these
43
- headers["X-Content-Type-Options"] = "nosniff"
44
- headers["X-Frame-Options"] = "DENY"
45
- headers["Referrer-Policy"] = "strict-origin-when-cross-origin"
46
- headers["X-XSS-Protection"] = "0" // Modern browsers: CSP is better
47
- headers["Permissions-Policy"] = "camera=(), microphone=(), geolocation=()"
48
-
49
- return headers
50
- }
@@ -1,4 +0,0 @@
1
- export { securityHeaders, type SecurityConfig } from "./headers.ts"
2
- export { csrfProtection, generateCSRFToken, validateCSRFToken } from "./csrf.ts"
3
- export { createRateLimiter, type RateLimiter } from "./rate-limit.ts"
4
- export { cors, type CORSOptions } from "./cors.ts"
@@ -1,80 +0,0 @@
1
- // In-memory token bucket rate limiter (for Bun runtime)
2
- // For Cloudflare Workers: use Durable Objects adapter (future)
3
-
4
- export interface RateLimiter {
5
- check(key: string): { allowed: boolean; remaining: number; resetAt: number }
6
- reset(key: string): void
7
- }
8
-
9
- interface Bucket {
10
- tokens: number
11
- lastRefill: number
12
- }
13
-
14
- function parseWindow(window: string): number {
15
- const match = window.match(/^(\d+)(s|m|h)$/)
16
- if (!match) throw new Error(`Invalid rate limit window: "${window}"`)
17
- const value = Number(match[1])
18
- switch (match[2]) {
19
- case "s": return value * 1000
20
- case "m": return value * 60_000
21
- case "h": return value * 3_600_000
22
- default: throw new Error(`Invalid unit: ${match[2]}`)
23
- }
24
- }
25
-
26
- export function createRateLimiter(
27
- maxRequests: number,
28
- window: string
29
- ): RateLimiter {
30
- const windowMs = parseWindow(window)
31
- const buckets = new Map<string, Bucket>()
32
-
33
- // Cleanup old entries periodically
34
- const CLEANUP_INTERVAL = Math.max(windowMs * 2, 60_000)
35
- const cleanup = setInterval(() => {
36
- const now = Date.now()
37
- for (const [key, bucket] of buckets) {
38
- if (now - bucket.lastRefill > windowMs * 2) {
39
- buckets.delete(key)
40
- }
41
- }
42
- }, CLEANUP_INTERVAL)
43
-
44
- // Don't prevent process from exiting
45
- if (typeof cleanup === "object" && "unref" in cleanup) {
46
- (cleanup as NodeJS.Timeout).unref()
47
- }
48
-
49
- return {
50
- check(key: string): { allowed: boolean; remaining: number; resetAt: number } {
51
- const now = Date.now()
52
- let bucket = buckets.get(key)
53
-
54
- if (!bucket) {
55
- bucket = { tokens: maxRequests, lastRefill: now }
56
- buckets.set(key, bucket)
57
- }
58
-
59
- // Refill tokens based on elapsed time
60
- const elapsed = now - bucket.lastRefill
61
- if (elapsed >= windowMs) {
62
- bucket.tokens = maxRequests
63
- bucket.lastRefill = now
64
- }
65
-
66
- const resetAt = bucket.lastRefill + windowMs
67
-
68
- if (bucket.tokens > 0) {
69
- bucket.tokens--
70
- return { allowed: true, remaining: bucket.tokens, resetAt }
71
- }
72
-
73
- return { allowed: false, remaining: 0, resetAt }
74
- },
75
-
76
- reset(key: string): void {
77
- buckets.delete(key)
78
- },
79
- }
80
- }
@@ -1,48 +0,0 @@
1
- // Server Actions -- form mutations with progressive enhancement
2
- // Usage in route:
3
- // export const action = defineAction(async (ctx) => { ... })
4
- //
5
- // Client-side: submits via fetch, returns result
6
- // SSR: handles POST form submissions with redirect
7
-
8
- import type { Context } from "./middleware.ts"
9
-
10
- export type ActionFn<T = unknown> = (ctx: Context) => Promise<T | Response>
11
-
12
- export interface ActionResult<T = unknown> {
13
- data?: T
14
- error?: string
15
- status: number
16
- }
17
-
18
- export function defineAction<T = unknown>(fn: ActionFn<T>): ActionFn<T> {
19
- return fn
20
- }
21
-
22
- export async function handleAction<T>(
23
- actionFn: ActionFn<T>,
24
- ctx: Context,
25
- ): Promise<ActionResult<T>> {
26
- try {
27
- const result = await actionFn(ctx)
28
- if (result instanceof Response) {
29
- return { status: result.status }
30
- }
31
- return { data: result, status: 200 }
32
- } catch (err) {
33
- const message = err instanceof Error ? err.message : String(err)
34
- return { error: message, status: 500 }
35
- }
36
- }
37
-
38
- // Parse form data from request into a typed object
39
- export async function parseFormData(request: Request): Promise<Record<string, string>> {
40
- const formData = await request.formData()
41
- const result: Record<string, string> = {}
42
- for (const [key, value] of formData.entries()) {
43
- if (typeof value === "string") {
44
- result[key] = value
45
- }
46
- }
47
- return result
48
- }
@@ -1,23 +0,0 @@
1
- import type { CacheEntry, CacheStore } from "./cache.ts"
2
-
3
- export function createNamespacedCacheStore(store: CacheStore, namespace: string): CacheStore {
4
- const prefix = `${namespace}:`
5
- return {
6
- get: (key) => store.get(prefix + key),
7
- set: async (key, entry) => { await store.set(prefix + key, entry) },
8
- delete: async (key) => { await store.delete(prefix + key) },
9
- clear: async () => {
10
- const keys = await store.keys()
11
- for await (const key of keys) {
12
- if (key.startsWith(prefix)) await store.delete(key)
13
- }
14
- },
15
- keys: async function* () {
16
- const keys = await store.keys()
17
- for await (const key of keys) {
18
- if (!key.startsWith(prefix)) continue
19
- yield key.slice(prefix.length)
20
- }
21
- },
22
- }
23
- }
@@ -1,125 +0,0 @@
1
- // Route-level response cache with stale-while-revalidate
2
- // Usage: export const cache = { maxAge: 60, staleWhileRevalidate: 300 }
3
-
4
- import type { MiddlewareFn } from "./middleware.ts"
5
-
6
- export interface CacheOptions {
7
- maxAge: number // fresh cache TTL in seconds
8
- staleWhileRevalidate?: number // serve stale while revalidating (seconds)
9
- vary?: string[] // cache key varies by these headers
10
- key?: (url: URL) => string // custom cache key generator
11
- store?: CacheStore
12
- }
13
-
14
- type Awaitable<T> = T | Promise<T>
15
-
16
- export interface CacheEntry {
17
- body: string
18
- headers: Record<string, string>
19
- status: number
20
- createdAt: number
21
- revalidating?: boolean
22
- }
23
-
24
- export interface CacheStore {
25
- get(key: string): Awaitable<CacheEntry | undefined>
26
- set(key: string, entry: CacheEntry): Awaitable<void>
27
- delete(key: string): Awaitable<void>
28
- clear(): Awaitable<void>
29
- keys(): Awaitable<Iterable<string> | AsyncIterable<string>>
30
- }
31
-
32
- export function createMemoryCacheStore(): CacheStore {
33
- const store = new Map<string, CacheEntry>()
34
- return {
35
- get: (key) => store.get(key),
36
- set: (key, entry) => { store.set(key, entry) },
37
- delete: (key) => { store.delete(key) },
38
- clear: () => { store.clear() },
39
- keys: () => store.keys(),
40
- }
41
- }
42
-
43
- const defaultCacheStore = createMemoryCacheStore()
44
-
45
- function buildKey(url: URL, vary: string[], request: Request, customKey?: (url: URL) => string): string {
46
- const base = customKey ? customKey(url) : url.pathname + url.search
47
- if (vary.length === 0) return base
48
- const varyParts = vary.map((h) => `${h}=${request.headers.get(h) ?? ""}`).join("&")
49
- return `${base}?__vary=${varyParts}`
50
- }
51
-
52
- export function routeCache(options: CacheOptions): MiddlewareFn {
53
- const { maxAge, staleWhileRevalidate = 0, vary = [], key: customKey, store = defaultCacheStore } = options
54
-
55
- return async (ctx, next) => {
56
- if (ctx.request.method !== "GET") return next()
57
-
58
- const cacheKey = buildKey(ctx.url, vary, ctx.request, customKey)
59
- const entry = await store.get(cacheKey)
60
- const now = Date.now()
61
-
62
- if (entry) {
63
- const age = (now - entry.createdAt) / 1000
64
- // Fresh — serve from cache
65
- if (age < maxAge) {
66
- return new Response(entry.body, {
67
- status: entry.status,
68
- headers: { ...entry.headers, "X-Cache": "HIT", "Age": String(Math.floor(age)) },
69
- })
70
- }
71
- // Stale but within revalidation window — serve stale, revalidate in background
72
- if (age < maxAge + staleWhileRevalidate && !entry.revalidating) {
73
- entry.revalidating = true
74
- revalidate(cacheKey, store, next)
75
- return new Response(entry.body, {
76
- status: entry.status,
77
- headers: { ...entry.headers, "X-Cache": "STALE", "Age": String(Math.floor(age)) },
78
- })
79
- }
80
- }
81
-
82
- // Miss — fetch and cache
83
- const response = await next()
84
- if (response.status === 200) {
85
- const body = await response.text()
86
- const headers: Record<string, string> = {}
87
- response.headers.forEach((v, k) => { headers[k] = v })
88
- await store.set(cacheKey, { body, headers, status: response.status, createdAt: now })
89
- return new Response(body, {
90
- status: response.status,
91
- headers: { ...headers, "X-Cache": "MISS" },
92
- })
93
- }
94
- return response
95
- }
96
- }
97
-
98
- async function revalidate(key: string, store: CacheStore, next: () => Promise<Response>): Promise<void> {
99
- try {
100
- const response = await next()
101
- if (response.status === 200) {
102
- const body = await response.text()
103
- const headers: Record<string, string> = {}
104
- response.headers.forEach((v, k) => { headers[k] = v })
105
- await store.set(key, { body, headers, status: response.status, createdAt: Date.now() })
106
- }
107
- } catch {
108
- // revalidation failed, stale entry stays
109
- const entry = await store.get(key)
110
- if (entry) entry.revalidating = false
111
- }
112
- }
113
-
114
- /** Invalidate cached entry by path */
115
- export async function invalidateCache(path: string): Promise<void> {
116
- const keys = await defaultCacheStore.keys()
117
- for await (const key of keys) {
118
- if (key.startsWith(path)) await defaultCacheStore.delete(key)
119
- }
120
- }
121
-
122
- /** Clear all cached entries */
123
- export async function clearCache(): Promise<void> {
124
- await defaultCacheStore.clear()
125
- }
@@ -1,60 +0,0 @@
1
- // Response compression middleware — gzip/deflate
2
- // Uses Web Streams API (native in Bun)
3
-
4
- import type { MiddlewareFn } from "./middleware.ts"
5
-
6
- const COMPRESSIBLE_TYPES = new Set([
7
- "text/html",
8
- "text/css",
9
- "text/javascript",
10
- "application/javascript",
11
- "application/json",
12
- "text/xml",
13
- "application/xml",
14
- "image/svg+xml",
15
- ])
16
-
17
- function isCompressible(contentType: string | null): boolean {
18
- if (!contentType) return false
19
- const type = contentType.split(";")[0]!.trim()
20
- return COMPRESSIBLE_TYPES.has(type)
21
- }
22
-
23
- export function compress(): MiddlewareFn {
24
- return async (_ctx, next) => {
25
- const response = await next()
26
- const contentType = response.headers.get("content-type")
27
-
28
- if (!isCompressible(contentType)) return response
29
- if (response.headers.has("content-encoding")) return response
30
- if (!response.body) return response
31
-
32
- const acceptEncoding = _ctx.request.headers.get("accept-encoding") ?? ""
33
-
34
- if (acceptEncoding.includes("gzip")) {
35
- const compressed = response.body.pipeThrough(new CompressionStream("gzip"))
36
- const headers = new Headers(response.headers)
37
- headers.set("Content-Encoding", "gzip")
38
- headers.delete("Content-Length")
39
- return new Response(compressed, {
40
- status: response.status,
41
- statusText: response.statusText,
42
- headers,
43
- })
44
- }
45
-
46
- if (acceptEncoding.includes("deflate")) {
47
- const compressed = response.body.pipeThrough(new CompressionStream("deflate"))
48
- const headers = new Headers(response.headers)
49
- headers.set("Content-Encoding", "deflate")
50
- headers.delete("Content-Length")
51
- return new Response(compressed, {
52
- status: response.status,
53
- statusText: response.statusText,
54
- headers,
55
- })
56
- }
57
-
58
- return response
59
- }
60
- }
@@ -1,23 +0,0 @@
1
- // ETag support for static file serving
2
- // Generates weak ETags based on file size + modification time
3
-
4
- import { stat } from "node:fs/promises"
5
-
6
- export function generateETag(size: number, mtimeMs: number): string {
7
- return `W/"${size.toString(16)}-${Math.floor(mtimeMs).toString(16)}"`
8
- }
9
-
10
- export async function fileETag(filePath: string): Promise<string | null> {
11
- try {
12
- const s = await stat(filePath)
13
- return generateETag(s.size, s.mtimeMs)
14
- } catch {
15
- return null
16
- }
17
- }
18
-
19
- export function isNotModified(request: Request, etag: string): boolean {
20
- const ifNoneMatch = request.headers.get("if-none-match")
21
- if (!ifNoneMatch) return false
22
- return ifNoneMatch.split(",").some((t) => t.trim() === etag)
23
- }