@edge-base/server 0.1.1

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 (309) hide show
  1. package/admin-build/.gitkeep +0 -0
  2. package/admin-build/_app/env.js +1 -0
  3. package/admin-build/_app/immutable/assets/0.Bm6cF078.css +1 -0
  4. package/admin-build/_app/immutable/assets/1.BfW3pUNa.css +1 -0
  5. package/admin-build/_app/immutable/assets/11.CVmQOewb.css +1 -0
  6. package/admin-build/_app/immutable/assets/12.B1EhbRZT.css +1 -0
  7. package/admin-build/_app/immutable/assets/13.BvwYeuwE.css +1 -0
  8. package/admin-build/_app/immutable/assets/14.CdVfcO0R.css +1 -0
  9. package/admin-build/_app/immutable/assets/15.2yeZ66b-.css +1 -0
  10. package/admin-build/_app/immutable/assets/17.BVg0JEVu.css +1 -0
  11. package/admin-build/_app/immutable/assets/18.Rwnl3x_i.css +1 -0
  12. package/admin-build/_app/immutable/assets/20.DsPWA9AV.css +1 -0
  13. package/admin-build/_app/immutable/assets/21.Dz2RJ56c.css +1 -0
  14. package/admin-build/_app/immutable/assets/22.DwNLk5Ai.css +1 -0
  15. package/admin-build/_app/immutable/assets/23.CFpu0gOO.css +1 -0
  16. package/admin-build/_app/immutable/assets/24.Cy5LBeoJ.css +1 -0
  17. package/admin-build/_app/immutable/assets/25.pUyLVf-h.css +1 -0
  18. package/admin-build/_app/immutable/assets/26.DBcGrlXa.css +1 -0
  19. package/admin-build/_app/immutable/assets/27.BswYyAJD.css +1 -0
  20. package/admin-build/_app/immutable/assets/28.B4ueB1Kf.css +1 -0
  21. package/admin-build/_app/immutable/assets/29.B-qU6PdF.css +1 -0
  22. package/admin-build/_app/immutable/assets/3.Dg81Pgmd.css +1 -0
  23. package/admin-build/_app/immutable/assets/30.CsdWum94.css +1 -0
  24. package/admin-build/_app/immutable/assets/31.U6OwIp50.css +1 -0
  25. package/admin-build/_app/immutable/assets/4.CyawCCux.css +1 -0
  26. package/admin-build/_app/immutable/assets/5.C0YO2HTk.css +1 -0
  27. package/admin-build/_app/immutable/assets/8.Br5jd6kD.css +1 -0
  28. package/admin-build/_app/immutable/assets/Badge.EMYLHBxE.css +1 -0
  29. package/admin-build/_app/immutable/assets/Button.DpzMRTjK.css +1 -0
  30. package/admin-build/_app/immutable/assets/ConfirmDialog.DAnaWRRk.css +1 -0
  31. package/admin-build/_app/immutable/assets/EmptyState.CwKsu57Y.css +1 -0
  32. package/admin-build/_app/immutable/assets/Input.BDUSenmU.css +1 -0
  33. package/admin-build/_app/immutable/assets/Modal.Dm5B0Xie.css +1 -0
  34. package/admin-build/_app/immutable/assets/PageShell.CmU-Xh-b.css +1 -0
  35. package/admin-build/_app/immutable/assets/SchemaFieldEditor.g4NsCdno.css +1 -0
  36. package/admin-build/_app/immutable/assets/Select.BW4Keufm.css +1 -0
  37. package/admin-build/_app/immutable/assets/Skeleton.KWUulTKJ.css +1 -0
  38. package/admin-build/_app/immutable/assets/Tabs.CniGYb67.css +1 -0
  39. package/admin-build/_app/immutable/assets/TimeChart.BTCDAvmT.css +1 -0
  40. package/admin-build/_app/immutable/assets/Toggle.Cy_K12OM.css +1 -0
  41. package/admin-build/_app/immutable/assets/TopList.ClFzmPlA.css +1 -0
  42. package/admin-build/_app/immutable/chunks/7B47DvSx.js +1 -0
  43. package/admin-build/_app/immutable/chunks/7f08Id8e.js +1 -0
  44. package/admin-build/_app/immutable/chunks/8wJeQ7LN.js +1 -0
  45. package/admin-build/_app/immutable/chunks/B-h2afW5.js +1 -0
  46. package/admin-build/_app/immutable/chunks/B8vJP3wz.js +1 -0
  47. package/admin-build/_app/immutable/chunks/BR_fL5Yv.js +1 -0
  48. package/admin-build/_app/immutable/chunks/BY92tFS2.js +1 -0
  49. package/admin-build/_app/immutable/chunks/BcR-Rdj9.js +1 -0
  50. package/admin-build/_app/immutable/chunks/BdrwyZv8.js +1 -0
  51. package/admin-build/_app/immutable/chunks/Bh56EfQ_.js +1 -0
  52. package/admin-build/_app/immutable/chunks/BkrCkgYp.js +1 -0
  53. package/admin-build/_app/immutable/chunks/BmRjiP5k.js +1 -0
  54. package/admin-build/_app/immutable/chunks/BsokvhWC.js +1 -0
  55. package/admin-build/_app/immutable/chunks/C4D51vTW.js +1 -0
  56. package/admin-build/_app/immutable/chunks/C6puvcoR.js +2 -0
  57. package/admin-build/_app/immutable/chunks/CCKNu7m7.js +1 -0
  58. package/admin-build/_app/immutable/chunks/CWj6FrbW.js +1 -0
  59. package/admin-build/_app/immutable/chunks/Ce-ngf4p.js +5 -0
  60. package/admin-build/_app/immutable/chunks/Cs0GwzJA.js +1 -0
  61. package/admin-build/_app/immutable/chunks/CwROoZK0.js +1 -0
  62. package/admin-build/_app/immutable/chunks/CxCPv_Ut.js +1 -0
  63. package/admin-build/_app/immutable/chunks/CxbRue-5.js +1 -0
  64. package/admin-build/_app/immutable/chunks/CyqB6g-D.js +1 -0
  65. package/admin-build/_app/immutable/chunks/D5h5A1cc.js +2 -0
  66. package/admin-build/_app/immutable/chunks/DnyL7Zq-.js +1 -0
  67. package/admin-build/_app/immutable/chunks/DoPXzH7F.js +1 -0
  68. package/admin-build/_app/immutable/chunks/DrQSgw-f.js +1 -0
  69. package/admin-build/_app/immutable/chunks/DttM2zNO.js +1 -0
  70. package/admin-build/_app/immutable/chunks/DuXuUBWN.js +1 -0
  71. package/admin-build/_app/immutable/chunks/MdeqaOQx.js +10 -0
  72. package/admin-build/_app/immutable/chunks/NuUjtcO2.js +1 -0
  73. package/admin-build/_app/immutable/chunks/Q2nPFxS6.js +1 -0
  74. package/admin-build/_app/immutable/chunks/R6arueIl.js +1 -0
  75. package/admin-build/_app/immutable/chunks/UUazaC_N.js +1 -0
  76. package/admin-build/_app/immutable/chunks/cOYbrQxx.js +1 -0
  77. package/admin-build/_app/immutable/chunks/eFQHTGwA.js +1 -0
  78. package/admin-build/_app/immutable/chunks/ehbppgYb.js +1 -0
  79. package/admin-build/_app/immutable/chunks/glwixJlP.js +1 -0
  80. package/admin-build/_app/immutable/chunks/vApWTCBs.js +1 -0
  81. package/admin-build/_app/immutable/chunks/w89G9Xpi.js +1 -0
  82. package/admin-build/_app/immutable/chunks/wJsUhbfZ.js +1 -0
  83. package/admin-build/_app/immutable/chunks/zfauFM8P.js +1 -0
  84. package/admin-build/_app/immutable/entry/app.CcO-Uos3.js +2 -0
  85. package/admin-build/_app/immutable/entry/start.COebYq3I.js +1 -0
  86. package/admin-build/_app/immutable/nodes/0.CjtHKU-6.js +1 -0
  87. package/admin-build/_app/immutable/nodes/1.DEisjlM0.js +1 -0
  88. package/admin-build/_app/immutable/nodes/10.CvhdyWVB.js +1 -0
  89. package/admin-build/_app/immutable/nodes/11.DjHqcOvy.js +1 -0
  90. package/admin-build/_app/immutable/nodes/12.mQLz4Mj_.js +1 -0
  91. package/admin-build/_app/immutable/nodes/13.CBonZZyP.js +110 -0
  92. package/admin-build/_app/immutable/nodes/14.d-oiZL0j.js +3 -0
  93. package/admin-build/_app/immutable/nodes/15.CKPQsUYF.js +1 -0
  94. package/admin-build/_app/immutable/nodes/16.wPzAPQGx.js +1 -0
  95. package/admin-build/_app/immutable/nodes/17.DayhKyEZ.js +1 -0
  96. package/admin-build/_app/immutable/nodes/18.DKwS0Ir0.js +1 -0
  97. package/admin-build/_app/immutable/nodes/19.wPzAPQGx.js +1 -0
  98. package/admin-build/_app/immutable/nodes/2.BKoKrw1i.js +1 -0
  99. package/admin-build/_app/immutable/nodes/20.BvIkkkrW.js +1 -0
  100. package/admin-build/_app/immutable/nodes/21.DMaFhdHk.js +128 -0
  101. package/admin-build/_app/immutable/nodes/22.3xdgwuK1.js +1 -0
  102. package/admin-build/_app/immutable/nodes/23.8Bvgjbsl.js +112 -0
  103. package/admin-build/_app/immutable/nodes/24.DzSSzRhG.js +2 -0
  104. package/admin-build/_app/immutable/nodes/25.9KKYBnAE.js +2 -0
  105. package/admin-build/_app/immutable/nodes/26.Bhn9dfhY.js +1 -0
  106. package/admin-build/_app/immutable/nodes/27.kRLiC24G.js +1 -0
  107. package/admin-build/_app/immutable/nodes/28.BVIN1-7N.js +1 -0
  108. package/admin-build/_app/immutable/nodes/29.3yabZWj4.js +1 -0
  109. package/admin-build/_app/immutable/nodes/3.BFtSOkX7.js +2 -0
  110. package/admin-build/_app/immutable/nodes/30.CyCQlwaP.js +1 -0
  111. package/admin-build/_app/immutable/nodes/31.C4LDXjES.js +1 -0
  112. package/admin-build/_app/immutable/nodes/4.CvbiMlCa.js +1 -0
  113. package/admin-build/_app/immutable/nodes/5.C6BLv2eM.js +1 -0
  114. package/admin-build/_app/immutable/nodes/6.BcXvfl2P.js +1 -0
  115. package/admin-build/_app/immutable/nodes/7.CIuqhPiK.js +1 -0
  116. package/admin-build/_app/immutable/nodes/8.BQOR_JfO.js +1 -0
  117. package/admin-build/_app/immutable/nodes/9.NZqXQxPy.js +1 -0
  118. package/admin-build/_app/version.json +1 -0
  119. package/admin-build/favicon.svg +26 -0
  120. package/admin-build/index.html +45 -0
  121. package/openapi.json +19543 -0
  122. package/package.json +66 -0
  123. package/src/__tests__/admin-assets.test.ts +55 -0
  124. package/src/__tests__/admin-data-routes.test.ts +488 -0
  125. package/src/__tests__/admin-db-target.test.ts +103 -0
  126. package/src/__tests__/admin-routing.test.ts +31 -0
  127. package/src/__tests__/admin-user-management.test.ts +311 -0
  128. package/src/__tests__/analytics-query.test.ts +75 -0
  129. package/src/__tests__/auth-d1.test.ts +749 -0
  130. package/src/__tests__/auth-db-adapter.test.ts +73 -0
  131. package/src/__tests__/auth-jwt.test.ts +440 -0
  132. package/src/__tests__/auth-oauth.test.ts +389 -0
  133. package/src/__tests__/auth-password.test.ts +367 -0
  134. package/src/__tests__/auth-redirect.test.ts +87 -0
  135. package/src/__tests__/backup-restore.test.ts +711 -0
  136. package/src/__tests__/broadcast.test.ts +128 -0
  137. package/src/__tests__/cli.test.ts +178 -0
  138. package/src/__tests__/cloudflare-realtime.test.ts +113 -0
  139. package/src/__tests__/config.test.ts +469 -0
  140. package/src/__tests__/cors.test.ts +154 -0
  141. package/src/__tests__/cron.test.ts +302 -0
  142. package/src/__tests__/d1-handler.test.ts +402 -0
  143. package/src/__tests__/d1-sql.test.ts +120 -0
  144. package/src/__tests__/database-live-config.test.ts +42 -0
  145. package/src/__tests__/database-live-emitter.test.ts +56 -0
  146. package/src/__tests__/database-live-filters.test.ts +63 -0
  147. package/src/__tests__/database-live-route.test.ts +113 -0
  148. package/src/__tests__/db-sql.test.ts +163 -0
  149. package/src/__tests__/do-lifecycle.test.ts +263 -0
  150. package/src/__tests__/do-router.test.ts +729 -0
  151. package/src/__tests__/email-provider.test.ts +128 -0
  152. package/src/__tests__/email-templates.test.ts +528 -0
  153. package/src/__tests__/error-format.test.ts +250 -0
  154. package/src/__tests__/field-ops.test.ts +242 -0
  155. package/src/__tests__/functions-context.test.ts +334 -0
  156. package/src/__tests__/functions-d1-proxy.test.ts +229 -0
  157. package/src/__tests__/functions-registry-runtime-config.test.ts +17 -0
  158. package/src/__tests__/functions-route.test.ts +139 -0
  159. package/src/__tests__/internal-request.test.ts +77 -0
  160. package/src/__tests__/log-writer.test.ts +44 -0
  161. package/src/__tests__/logger.test.ts +58 -0
  162. package/src/__tests__/meta-admin-proxy.test.ts +48 -0
  163. package/src/__tests__/meta-export-coverage.test.ts +191 -0
  164. package/src/__tests__/meta-route-registration.test.ts +47 -0
  165. package/src/__tests__/namespace-dump.test.ts +28 -0
  166. package/src/__tests__/oauth-providers.test.ts +337 -0
  167. package/src/__tests__/openapi-coverage.test.ts +144 -0
  168. package/src/__tests__/pagination.test.ts +59 -0
  169. package/src/__tests__/password-policy.test.ts +191 -0
  170. package/src/__tests__/plugin-migrations.test.ts +379 -0
  171. package/src/__tests__/postgres-batch-compat.test.ts +133 -0
  172. package/src/__tests__/postgres-dialect.test.ts +328 -0
  173. package/src/__tests__/postgres-executor.test.ts +79 -0
  174. package/src/__tests__/postgres-field-ops-compat.test.ts +222 -0
  175. package/src/__tests__/postgres-schema-init.test.ts +105 -0
  176. package/src/__tests__/postgres-table-utils.test.ts +107 -0
  177. package/src/__tests__/presence.test.ts +199 -0
  178. package/src/__tests__/provider.test.ts +550 -0
  179. package/src/__tests__/public-user-profile.test.ts +339 -0
  180. package/src/__tests__/push-handlers.test.ts +179 -0
  181. package/src/__tests__/push-provider.test.ts +80 -0
  182. package/src/__tests__/push-token.test.ts +418 -0
  183. package/src/__tests__/query.test.ts +771 -0
  184. package/src/__tests__/rate-limit.test.ts +260 -0
  185. package/src/__tests__/room-access-policy.test.ts +101 -0
  186. package/src/__tests__/room-handler-context.test.ts +130 -0
  187. package/src/__tests__/room-monitoring.test.ts +138 -0
  188. package/src/__tests__/room-runtime-routing.test.ts +222 -0
  189. package/src/__tests__/room.test.ts +254 -0
  190. package/src/__tests__/route-parser.test.ts +490 -0
  191. package/src/__tests__/rules.test.ts +234 -0
  192. package/src/__tests__/runtime-surface-accounting.test.ts +120 -0
  193. package/src/__tests__/scheduled.test.ts +80 -0
  194. package/src/__tests__/schema.test.ts +1273 -0
  195. package/src/__tests__/security-hardening.test.ts +312 -0
  196. package/src/__tests__/server.unit.test.ts +333 -0
  197. package/src/__tests__/service-key-db-proxy.test.ts +650 -0
  198. package/src/__tests__/service-key-provider-bypass.test.ts +138 -0
  199. package/src/__tests__/service-key.test.ts +757 -0
  200. package/src/__tests__/smoke-skip-report.test.ts +72 -0
  201. package/src/__tests__/sms-provider.test.ts +39 -0
  202. package/src/__tests__/sql-route.test.ts +218 -0
  203. package/src/__tests__/storage-hook-context.test.ts +115 -0
  204. package/src/__tests__/totp.test.ts +200 -0
  205. package/src/__tests__/uuid.test.ts +144 -0
  206. package/src/__tests__/validation.test.ts +773 -0
  207. package/src/__tests__/websocket-pending.test.ts +163 -0
  208. package/src/_functions-registry.ts +51 -0
  209. package/src/bench-entry.ts +9 -0
  210. package/src/cloudflare-test.d.ts +1 -0
  211. package/src/durable-objects/auth-do.ts +49 -0
  212. package/src/durable-objects/database-do.ts +2240 -0
  213. package/src/durable-objects/database-live-do.ts +949 -0
  214. package/src/durable-objects/logs-do.ts +1200 -0
  215. package/src/durable-objects/room-runtime-base.ts +1604 -0
  216. package/src/durable-objects/rooms-do.ts +2191 -0
  217. package/src/generated-config.ts +6 -0
  218. package/src/index.ts +382 -0
  219. package/src/lib/admin-assets.ts +54 -0
  220. package/src/lib/admin-db-target.ts +301 -0
  221. package/src/lib/admin-routing.ts +35 -0
  222. package/src/lib/admin-user-management.ts +464 -0
  223. package/src/lib/analytics-adapter.ts +103 -0
  224. package/src/lib/analytics-query.ts +579 -0
  225. package/src/lib/auth-d1-service.ts +1193 -0
  226. package/src/lib/auth-d1.ts +1056 -0
  227. package/src/lib/auth-db-adapter.ts +289 -0
  228. package/src/lib/auth-redirect.ts +116 -0
  229. package/src/lib/cidr.ts +115 -0
  230. package/src/lib/client-ip.ts +51 -0
  231. package/src/lib/cloudflare-realtime.ts +251 -0
  232. package/src/lib/control-db.ts +36 -0
  233. package/src/lib/cron.ts +163 -0
  234. package/src/lib/d1-handler.ts +1425 -0
  235. package/src/lib/d1-schema-init.ts +255 -0
  236. package/src/lib/d1-sql.ts +33 -0
  237. package/src/lib/database-live-config.ts +24 -0
  238. package/src/lib/database-live-emitter.ts +111 -0
  239. package/src/lib/db-sql.ts +66 -0
  240. package/src/lib/do-retry.ts +36 -0
  241. package/src/lib/do-router.ts +270 -0
  242. package/src/lib/do-sql.ts +73 -0
  243. package/src/lib/email-provider.ts +379 -0
  244. package/src/lib/email-templates.ts +285 -0
  245. package/src/lib/email-translations.ts +422 -0
  246. package/src/lib/errors.ts +151 -0
  247. package/src/lib/functions.ts +2091 -0
  248. package/src/lib/hono.ts +56 -0
  249. package/src/lib/internal-request.ts +56 -0
  250. package/src/lib/jwt.ts +354 -0
  251. package/src/lib/log-writer.ts +272 -0
  252. package/src/lib/namespace-dump.ts +125 -0
  253. package/src/lib/oauth-providers.ts +1225 -0
  254. package/src/lib/op-parser.ts +99 -0
  255. package/src/lib/openapi.ts +146 -0
  256. package/src/lib/pagination.ts +19 -0
  257. package/src/lib/password-policy.ts +102 -0
  258. package/src/lib/password.ts +145 -0
  259. package/src/lib/plugin-migrations.ts +612 -0
  260. package/src/lib/postgres-executor.ts +203 -0
  261. package/src/lib/postgres-handler.ts +1102 -0
  262. package/src/lib/postgres-schema-init.ts +341 -0
  263. package/src/lib/postgres-table-utils.ts +87 -0
  264. package/src/lib/public-user-profile.ts +187 -0
  265. package/src/lib/push-provider.ts +409 -0
  266. package/src/lib/push-token.ts +294 -0
  267. package/src/lib/query-engine.ts +768 -0
  268. package/src/lib/room-monitoring.ts +97 -0
  269. package/src/lib/room-runtime.ts +14 -0
  270. package/src/lib/route-parser.ts +434 -0
  271. package/src/lib/schema.ts +538 -0
  272. package/src/lib/schemas.ts +152 -0
  273. package/src/lib/service-key.ts +419 -0
  274. package/src/lib/sms-provider.ts +230 -0
  275. package/src/lib/startup-config.ts +99 -0
  276. package/src/lib/totp.ts +242 -0
  277. package/src/lib/uuid.ts +87 -0
  278. package/src/lib/validation.ts +205 -0
  279. package/src/lib/version.ts +2 -0
  280. package/src/lib/websocket-pending.ts +40 -0
  281. package/src/middleware/auth.ts +169 -0
  282. package/src/middleware/captcha-verify.ts +217 -0
  283. package/src/middleware/cors.ts +159 -0
  284. package/src/middleware/error-handler.ts +54 -0
  285. package/src/middleware/internal-guard.ts +26 -0
  286. package/src/middleware/logger.ts +126 -0
  287. package/src/middleware/rate-limit.ts +283 -0
  288. package/src/middleware/rules.ts +475 -0
  289. package/src/routes/admin-auth.ts +447 -0
  290. package/src/routes/admin.ts +3501 -0
  291. package/src/routes/analytics-api.ts +290 -0
  292. package/src/routes/auth.ts +4222 -0
  293. package/src/routes/backup.ts +1466 -0
  294. package/src/routes/config.ts +53 -0
  295. package/src/routes/d1.ts +109 -0
  296. package/src/routes/database-live.ts +281 -0
  297. package/src/routes/functions.ts +155 -0
  298. package/src/routes/health.ts +32 -0
  299. package/src/routes/kv.ts +167 -0
  300. package/src/routes/oauth.ts +1055 -0
  301. package/src/routes/push.ts +1465 -0
  302. package/src/routes/room.ts +639 -0
  303. package/src/routes/schema-endpoint.ts +76 -0
  304. package/src/routes/sql.ts +176 -0
  305. package/src/routes/storage.ts +1674 -0
  306. package/src/routes/tables.ts +699 -0
  307. package/src/routes/users.ts +21 -0
  308. package/src/routes/vectorize.ts +372 -0
  309. package/src/types.ts +99 -0
@@ -0,0 +1,6 @@
1
+ // Auto-generated fallback shim for repository/runtime builds.
2
+ // The open-source repo does not commit a project-local edgebase.config.ts,
3
+ // so packaged builds must stay importable without that private file.
4
+ const config = {};
5
+
6
+ export default config;
package/src/index.ts ADDED
@@ -0,0 +1,382 @@
1
+ import { OpenAPIHono, type HonoEnv } from './lib/hono.js';
2
+ import { HTTPException } from 'hono/http-exception';
3
+ import { initFunctionRegistry } from './_functions-registry.js';
4
+ import { corsMiddleware } from './middleware/cors.js';
5
+ import { rateLimitMiddleware } from './middleware/rate-limit.js';
6
+ import { errorHandlerMiddleware } from './middleware/error-handler.js';
7
+ import { internalGuardMiddleware } from './middleware/internal-guard.js';
8
+ import { authMiddleware } from './middleware/auth.js';
9
+ import { rulesMiddleware } from './middleware/rules.js';
10
+
11
+ import { loggerMiddleware } from './middleware/logger.js';
12
+ import { EdgeBaseError } from '@edge-base/shared';
13
+ import { SERVER_VERSION } from './lib/version.js';
14
+ import { healthRoute } from './routes/health.js';
15
+ import { tablesRoute } from './routes/tables.js';
16
+ import { schemaRoute } from './routes/schema-endpoint.js';
17
+ import { authRoute } from './routes/auth.js';
18
+ import { adminAuthRoute } from './routes/admin-auth.js';
19
+ import { oauthRoute } from './routes/oauth.js';
20
+ import { databaseLiveRoute } from './routes/database-live.js';
21
+ import { storageRoute } from './routes/storage.js';
22
+ import { functionsRoute } from './routes/functions.js';
23
+ import { adminRoute } from './routes/admin.js';
24
+ import { backupRoute } from './routes/backup.js';
25
+ import { sqlRoute } from './routes/sql.js';
26
+ import { kvRoute } from './routes/kv.js';
27
+ import { d1Route } from './routes/d1.js';
28
+ import { vectorizeRoute } from './routes/vectorize.js';
29
+ import { configRoute } from './routes/config.js';
30
+ import { pushRoute } from './routes/push.js';
31
+ import { roomRoute } from './routes/room.js';
32
+ import { analyticsApi } from './routes/analytics-api.js';
33
+ import { parseConfig, setConfig } from './lib/do-router.js';
34
+ import { createAdminAssetRequest } from './lib/admin-assets.js';
35
+ import { resolveAdminFaviconTarget, resolveAdminRedirectTarget } from './lib/admin-routing.js';
36
+ import { zodDefaultHook } from './lib/schemas.js';
37
+ import { executePluginMigrations } from './lib/plugin-migrations.js';
38
+ import { getFunctionsByTrigger, buildFunctionContext, getWorkerUrl } from './lib/functions.js';
39
+ import { parseCron, matchesCron } from './lib/cron.js';
40
+ import { parseDuration } from './lib/jwt.js';
41
+ import { resolveStartupConfig } from './lib/startup-config.js';
42
+ import * as authService from './lib/auth-d1-service.js';
43
+ import { ensureAuthSchema, deleteAnon } from './lib/auth-d1.js';
44
+ import { resolveAuthDb } from './lib/auth-db-adapter.js';
45
+ import { resolveRootServiceKey } from './lib/service-key.js';
46
+ import { normalizeOpenApiDocument, type OpenApiSpec } from './lib/openapi.js';
47
+ import generatedConfig from './generated-config.js';
48
+ import type { Env } from './types.js';
49
+
50
+ // Compile-time constant — injected by wrangler [define] in wrangler.test.toml
51
+ declare const EDGEBASE_TEST_BUILD: boolean | undefined;
52
+
53
+ // ─── DO Re-exports (wrangler needs exports from main entry) ───
54
+ export { DatabaseDO } from './durable-objects/database-do.js';
55
+ export { DatabaseLiveDO } from './durable-objects/database-live-do.js';
56
+ export { AuthDO } from './durable-objects/auth-do.js';
57
+ export { RoomsDO } from './durable-objects/rooms-do.js';
58
+ export { LogsDO } from './durable-objects/logs-do.js';
59
+
60
+ try {
61
+ const processEnv = typeof process !== 'undefined' ? process.env : undefined;
62
+ // EDGEBASE_TEST_BUILD is a compile-time constant injected by wrangler [define]
63
+ // in wrangler.test.toml. typeof is safe for undefined identifiers.
64
+ const isTestBuild = typeof EDGEBASE_TEST_BUILD !== 'undefined';
65
+ const preferTestConfig = await detectWorkersTestRuntime() || isTestBuild;
66
+ const resolvedConfig = await resolveStartupConfig(
67
+ generatedConfig,
68
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
69
+ async () => import('../edgebase.test.config.ts' as any),
70
+ processEnv,
71
+ { preferTestConfig },
72
+ );
73
+
74
+ if (resolvedConfig) {
75
+ setConfig(resolvedConfig);
76
+ }
77
+ } catch (err) {
78
+ console.error('[EdgeBase] Failed to initialize config at startup:', err);
79
+ throw err;
80
+ }
81
+
82
+ async function detectWorkersTestRuntime(): Promise<boolean> {
83
+ try {
84
+ await import('cloudflare:test');
85
+ return true;
86
+ } catch {
87
+ return false;
88
+ }
89
+ }
90
+
91
+ initFunctionRegistry();
92
+
93
+ const app = new OpenAPIHono<HonoEnv>({ defaultHook: zodDefaultHook });
94
+
95
+ // ─── Global Middleware Chain ───
96
+ // Order: Error Handler → Logger → CORS → Strip Internal Header → Rate Limit → Auth → Context → Rules
97
+
98
+ app.use('*', errorHandlerMiddleware);
99
+ app.use('*', loggerMiddleware);
100
+ app.use('*', corsMiddleware);
101
+
102
+ // NOTE: X-EdgeBase-Internal header stripping via c.req.raw.headers.delete() is NOT
103
+ // possible in Workers — Request.headers are immutable. Instead, the internal guard
104
+ // middleware below rejects any request with this header unless it comes via internal
105
+ // stub.fetch (which is allowed by the x-internal whitelist). No stripping needed.
106
+
107
+ // Plugin migration middleware — lazy, runs once per cold-start
108
+ app.use('*', async (c, next) => {
109
+ const config = parseConfig(c.env);
110
+ const requestPath = new URL(c.req.url).pathname;
111
+ const shouldSkipPluginMigrations =
112
+ requestPath.startsWith('/admin/api/backup/') ||
113
+ requestPath.startsWith('/admin/api/data/backup/') ||
114
+ requestPath.startsWith('/internal/backup/');
115
+ if (!shouldSkipPluginMigrations && config?.plugins?.length) {
116
+ await executePluginMigrations(config.plugins, c.env, config, getWorkerUrl(c.req.url, c.env));
117
+ }
118
+ return next();
119
+ });
120
+
121
+ app.use('*', rateLimitMiddleware);
122
+
123
+ // Auth middleware — JWT verification + auth context injection (M3)
124
+ app.use('/api/*', authMiddleware);
125
+
126
+ // Context middleware removed — DB-level access rules (§4,) handle multi-tenancy.
127
+
128
+ // Rules middleware — access rules evaluation (M4,)
129
+ app.use('/api/db/*', rulesMiddleware);
130
+
131
+ // ─── Internal Guard ───
132
+ app.use('/internal/*', internalGuardMiddleware);
133
+
134
+ // ─── Routes ───
135
+ app.route('/api', healthRoute);
136
+ app.route('/api/auth', authRoute);
137
+ app.route('/api/auth/admin', adminAuthRoute);
138
+ app.route('/api/auth/oauth', oauthRoute);
139
+ app.route('/api/db', tablesRoute);
140
+ app.route('/api/db', databaseLiveRoute);
141
+ app.route('/api/schema', schemaRoute);
142
+ app.route('/api/storage', storageRoute);
143
+ app.route('/api/functions', functionsRoute);
144
+ app.route('/api/sql', sqlRoute);
145
+ app.route('/api/kv', kvRoute);
146
+ app.route('/api/d1', d1Route);
147
+ app.route('/api/vectorize', vectorizeRoute);
148
+ app.route('/api/config', configRoute);
149
+ app.route('/api/push', pushRoute);
150
+ app.route('/api/room', roomRoute);
151
+ app.route('/api/analytics', analyticsApi);
152
+ // ─── Admin Dashboard (M12,) ───
153
+ app.route('/admin/api', adminRoute);
154
+ app.route('/admin/api/backup', backupRoute);
155
+
156
+ app.get('/', (c) => {
157
+ const externalAdminUrl = resolveAdminRedirectTarget(c.req.url, c.env.ADMIN_ORIGIN);
158
+ if (externalAdminUrl) {
159
+ return c.redirect(externalAdminUrl, 302);
160
+ }
161
+ if (c.env.ASSETS) {
162
+ return c.redirect('/admin', 302);
163
+ }
164
+ return c.json({
165
+ name: 'EdgeBase API',
166
+ docs: '/openapi.json',
167
+ admin: null,
168
+ });
169
+ });
170
+
171
+ // Admin static assets — SvelteKit SPA served via Workers Static Assets
172
+ app.get('/favicon.ico', async (c) => {
173
+ const externalFaviconUrl = resolveAdminFaviconTarget(c.env.ADMIN_ORIGIN);
174
+ if (externalFaviconUrl) {
175
+ return c.redirect(externalFaviconUrl, 302);
176
+ }
177
+
178
+ if (!c.env.ASSETS) {
179
+ return c.json({ code: 404, message: 'Admin dashboard not deployed.' }, 404);
180
+ }
181
+
182
+ const url = new URL(c.req.url);
183
+ url.pathname = '/admin/favicon.svg';
184
+ return c.env.ASSETS.fetch(createAdminAssetRequest(new Request(url.toString(), c.req.raw)));
185
+ });
186
+
187
+ app.get('/favicon.svg', async (c) => {
188
+ const externalFaviconUrl = resolveAdminFaviconTarget(c.env.ADMIN_ORIGIN);
189
+ if (externalFaviconUrl) {
190
+ return c.redirect(externalFaviconUrl, 302);
191
+ }
192
+
193
+ if (c.env.ASSETS) {
194
+ return c.env.ASSETS.fetch(c.req.raw);
195
+ }
196
+
197
+ return c.json({ code: 404, message: 'Admin dashboard not deployed.' }, 404);
198
+ });
199
+
200
+ app.get('/_app/*', async (c) => {
201
+ if (c.env.ASSETS) {
202
+ return c.env.ASSETS.fetch(c.req.raw);
203
+ }
204
+
205
+ return c.json({ code: 404, message: 'Admin dashboard not deployed.' }, 404);
206
+ });
207
+
208
+ app.get('/admin/*', async (c) => {
209
+ const externalAdminUrl = resolveAdminRedirectTarget(c.req.url, c.env.ADMIN_ORIGIN);
210
+ if (externalAdminUrl) {
211
+ return c.redirect(externalAdminUrl, 302);
212
+ }
213
+ if (c.env.ASSETS) {
214
+ return c.env.ASSETS.fetch(createAdminAssetRequest(c.req.raw));
215
+ }
216
+ return c.json({ code: 404, message: 'Admin dashboard not deployed.' }, 404);
217
+ });
218
+ app.get('/admin', async (c) => {
219
+ const externalAdminUrl = resolveAdminRedirectTarget(c.req.url, c.env.ADMIN_ORIGIN);
220
+ if (externalAdminUrl) {
221
+ return c.redirect(externalAdminUrl, 302);
222
+ }
223
+ if (c.env.ASSETS) {
224
+ return c.env.ASSETS.fetch(createAdminAssetRequest(c.req.raw));
225
+ }
226
+ return c.json({ code: 404, message: 'Admin dashboard not deployed.' }, 404);
227
+ });
228
+
229
+ app.get('/harness', (c) => {
230
+ return c.redirect('/harness/', 302);
231
+ });
232
+ app.get('/harness/', async (c) => {
233
+ if (c.env.ASSETS) {
234
+ return c.env.ASSETS.fetch(c.req.raw);
235
+ }
236
+ return c.json({ code: 404, message: 'Harness assets not deployed.' }, 404);
237
+ });
238
+ app.get('/harness/assets/*', async (c) => {
239
+ if (c.env.ASSETS) {
240
+ return c.env.ASSETS.fetch(c.req.raw);
241
+ }
242
+ return c.json({ code: 404, message: 'Harness assets not deployed.' }, 404);
243
+ });
244
+ app.get('/harness/*', (c) => {
245
+ return c.redirect('/harness/', 302);
246
+ });
247
+
248
+ // ─── OpenAPI Spec ───
249
+ app.get('/openapi.json', (c) => {
250
+ const spec = app.getOpenAPI31Document({
251
+ openapi: '3.1.0',
252
+ info: { title: 'EdgeBase API', version: SERVER_VERSION },
253
+ });
254
+
255
+ return c.json(normalizeOpenApiDocument(spec as OpenApiSpec, new URL(c.req.url).origin));
256
+ });
257
+
258
+ // ─── 404 Fallback ───
259
+ app.notFound((c) => {
260
+ return c.json({ code: 404, message: 'Not found.' }, 404);
261
+ });
262
+
263
+ // ─── Hono-level onError (safety net for Workers cross-module instanceof issues) ───
264
+ app.onError((err, c) => {
265
+ if (err instanceof SyntaxError) {
266
+ return c.json(
267
+ {
268
+ code: 400,
269
+ message: 'Invalid JSON payload. Please ensure your request body is valid JSON.',
270
+ },
271
+ 400,
272
+ );
273
+ }
274
+ if (err instanceof EdgeBaseError) {
275
+ return c.json(err.toJSON(), err.code as 400);
276
+ }
277
+ // Hono HTTPException (thrown by @hono/zod-openapi validators on malformed JSON, etc.)
278
+ if (err instanceof HTTPException) {
279
+ return c.json({ code: err.status, message: err.message }, err.status as 400);
280
+ }
281
+ // Duck-type fallback
282
+ const e = err as unknown as Record<string, unknown>;
283
+ if (
284
+ typeof e.code === 'number' &&
285
+ e.code >= 400 &&
286
+ e.code < 600 &&
287
+ typeof e.message === 'string'
288
+ ) {
289
+ const body: { code: number; message: string; data?: unknown } = {
290
+ code: e.code as number,
291
+ message: e.message as string,
292
+ };
293
+ if (e.data) body.data = e.data;
294
+ return c.json(body, e.code as number as 400);
295
+ }
296
+ console.error('Unhandled error:', err);
297
+ return c.json({ code: 500, message: 'Internal server error.' }, 500);
298
+ });
299
+
300
+ export default {
301
+ fetch: app.fetch,
302
+
303
+ /**
304
+ * Cloudflare Cron Triggers — replaces db:_system alarm-based scheduling.
305
+ * CLI generates [triggers] section in wrangler.toml from config schedule functions.
306
+ */
307
+ async scheduled(event: ScheduledEvent, env: Env, ctx: ExecutionContext): Promise<void> {
308
+ const config = parseConfig(env);
309
+ const scheduleFns = getFunctionsByTrigger('schedule');
310
+
311
+ const now = new Date(event.scheduledTime);
312
+
313
+ // Schedule function timeout (default: 10s)
314
+ const timeoutStr = config.functions?.scheduleFunctionTimeout ?? '10s';
315
+ const timeoutMs = parseDuration(timeoutStr) * 1000;
316
+
317
+ // ── System cron: session cleanup + anonymous account cleanup ──
318
+ ctx.waitUntil(
319
+ (async () => {
320
+ try {
321
+ const authDb = resolveAuthDb(env as unknown as Record<string, unknown>);
322
+ await ensureAuthSchema(authDb);
323
+ // Clean expired sessions
324
+ await authService.cleanExpiredSessions(authDb);
325
+ // Clean stale anonymous accounts
326
+ if (config?.auth?.anonymousAuth) {
327
+ const retentionDays = config.auth.anonymousRetentionDays ?? 30;
328
+ const deletedIds = await authService.cleanStaleAnonymousAccounts(authDb, retentionDays);
329
+ for (const id of deletedIds) {
330
+ await deleteAnon(authDb, id).catch(() => {});
331
+ }
332
+ }
333
+ } catch (err) {
334
+ console.error('[EdgeBase] Session/anonymous cleanup failed:', err);
335
+ }
336
+ })(),
337
+ );
338
+
339
+ if (scheduleFns.length === 0) return;
340
+
341
+ for (const { name, definition } of scheduleFns) {
342
+ const trigger = definition.trigger as { type: 'schedule'; cron: string };
343
+ try {
344
+ const schedule = parseCron(trigger.cron);
345
+ if (!matchesCron(now, schedule)) continue;
346
+
347
+ const fnCtx = buildFunctionContext({
348
+ request: new Request('http://internal/schedule/' + name),
349
+ auth: null,
350
+ databaseNamespace: env.DATABASE,
351
+ authNamespace: env.AUTH,
352
+ d1Database: env.AUTH_DB,
353
+ kvNamespace: env.KV,
354
+ env: env as never,
355
+ executionCtx: ctx as never,
356
+ config,
357
+ serviceKey: resolveRootServiceKey(config, env),
358
+ data: {
359
+ before: undefined,
360
+ after: { scheduledTime: now.toISOString(), cron: trigger.cron },
361
+ },
362
+ });
363
+
364
+ ctx.waitUntil(
365
+ Promise.race([
366
+ definition.handler(fnCtx),
367
+ new Promise((_, reject) =>
368
+ setTimeout(
369
+ () => reject(new Error(`Schedule function '${name}' timed out (${timeoutStr})`)),
370
+ timeoutMs,
371
+ ),
372
+ ),
373
+ ]).catch((err) => {
374
+ console.error(`[EdgeBase] Schedule function '${name}' failed:`, err);
375
+ }),
376
+ );
377
+ } catch (err) {
378
+ console.error(`[EdgeBase] Schedule function '${name}' failed:`, err);
379
+ }
380
+ }
381
+ },
382
+ };
@@ -0,0 +1,54 @@
1
+ export function resolveAdminAssetPath(pathname: string): string {
2
+ if (pathname === '/admin' || pathname === '/admin/') {
3
+ return '/';
4
+ }
5
+
6
+ if (!pathname.startsWith('/admin/')) {
7
+ return pathname;
8
+ }
9
+
10
+ const assetPath = pathname.slice('/admin'.length) || '/';
11
+ if (assetPath === '/' || assetPath === '') {
12
+ return '/';
13
+ }
14
+
15
+ if (assetPath.startsWith('/_app/')) {
16
+ return assetPath;
17
+ }
18
+
19
+ const lastSegment = assetPath.split('/').pop() ?? '';
20
+ if (lastSegment.includes('.')) {
21
+ return assetPath;
22
+ }
23
+
24
+ return '/';
25
+ }
26
+
27
+ export function createAdminAssetRequest(request: Request): Request {
28
+ const url = new URL(request.url);
29
+ url.pathname = resolveAdminAssetPath(url.pathname);
30
+ return new Request(url.toString(), request);
31
+ }
32
+
33
+ export function resolveHarnessAssetPath(pathname: string): string {
34
+ if (pathname === '/harness' || pathname === '/harness/') {
35
+ return '/harness.html';
36
+ }
37
+
38
+ if (!pathname.startsWith('/harness/')) {
39
+ return '/harness.html';
40
+ }
41
+
42
+ const lastSegment = pathname.split('/').pop() ?? '';
43
+ if (lastSegment.includes('.')) {
44
+ return pathname;
45
+ }
46
+
47
+ return '/harness.html';
48
+ }
49
+
50
+ export function createHarnessAssetRequest(request: Request): Request {
51
+ const url = new URL(request.url);
52
+ url.pathname = resolveHarnessAssetPath(url.pathname);
53
+ return new Request(url.toString(), request);
54
+ }