@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.
- package/admin-build/.gitkeep +0 -0
- package/admin-build/_app/env.js +1 -0
- package/admin-build/_app/immutable/assets/0.Bm6cF078.css +1 -0
- package/admin-build/_app/immutable/assets/1.BfW3pUNa.css +1 -0
- package/admin-build/_app/immutable/assets/11.CVmQOewb.css +1 -0
- package/admin-build/_app/immutable/assets/12.B1EhbRZT.css +1 -0
- package/admin-build/_app/immutable/assets/13.BvwYeuwE.css +1 -0
- package/admin-build/_app/immutable/assets/14.CdVfcO0R.css +1 -0
- package/admin-build/_app/immutable/assets/15.2yeZ66b-.css +1 -0
- package/admin-build/_app/immutable/assets/17.BVg0JEVu.css +1 -0
- package/admin-build/_app/immutable/assets/18.Rwnl3x_i.css +1 -0
- package/admin-build/_app/immutable/assets/20.DsPWA9AV.css +1 -0
- package/admin-build/_app/immutable/assets/21.Dz2RJ56c.css +1 -0
- package/admin-build/_app/immutable/assets/22.DwNLk5Ai.css +1 -0
- package/admin-build/_app/immutable/assets/23.CFpu0gOO.css +1 -0
- package/admin-build/_app/immutable/assets/24.Cy5LBeoJ.css +1 -0
- package/admin-build/_app/immutable/assets/25.pUyLVf-h.css +1 -0
- package/admin-build/_app/immutable/assets/26.DBcGrlXa.css +1 -0
- package/admin-build/_app/immutable/assets/27.BswYyAJD.css +1 -0
- package/admin-build/_app/immutable/assets/28.B4ueB1Kf.css +1 -0
- package/admin-build/_app/immutable/assets/29.B-qU6PdF.css +1 -0
- package/admin-build/_app/immutable/assets/3.Dg81Pgmd.css +1 -0
- package/admin-build/_app/immutable/assets/30.CsdWum94.css +1 -0
- package/admin-build/_app/immutable/assets/31.U6OwIp50.css +1 -0
- package/admin-build/_app/immutable/assets/4.CyawCCux.css +1 -0
- package/admin-build/_app/immutable/assets/5.C0YO2HTk.css +1 -0
- package/admin-build/_app/immutable/assets/8.Br5jd6kD.css +1 -0
- package/admin-build/_app/immutable/assets/Badge.EMYLHBxE.css +1 -0
- package/admin-build/_app/immutable/assets/Button.DpzMRTjK.css +1 -0
- package/admin-build/_app/immutable/assets/ConfirmDialog.DAnaWRRk.css +1 -0
- package/admin-build/_app/immutable/assets/EmptyState.CwKsu57Y.css +1 -0
- package/admin-build/_app/immutable/assets/Input.BDUSenmU.css +1 -0
- package/admin-build/_app/immutable/assets/Modal.Dm5B0Xie.css +1 -0
- package/admin-build/_app/immutable/assets/PageShell.CmU-Xh-b.css +1 -0
- package/admin-build/_app/immutable/assets/SchemaFieldEditor.g4NsCdno.css +1 -0
- package/admin-build/_app/immutable/assets/Select.BW4Keufm.css +1 -0
- package/admin-build/_app/immutable/assets/Skeleton.KWUulTKJ.css +1 -0
- package/admin-build/_app/immutable/assets/Tabs.CniGYb67.css +1 -0
- package/admin-build/_app/immutable/assets/TimeChart.BTCDAvmT.css +1 -0
- package/admin-build/_app/immutable/assets/Toggle.Cy_K12OM.css +1 -0
- package/admin-build/_app/immutable/assets/TopList.ClFzmPlA.css +1 -0
- package/admin-build/_app/immutable/chunks/7B47DvSx.js +1 -0
- package/admin-build/_app/immutable/chunks/7f08Id8e.js +1 -0
- package/admin-build/_app/immutable/chunks/8wJeQ7LN.js +1 -0
- package/admin-build/_app/immutable/chunks/B-h2afW5.js +1 -0
- package/admin-build/_app/immutable/chunks/B8vJP3wz.js +1 -0
- package/admin-build/_app/immutable/chunks/BR_fL5Yv.js +1 -0
- package/admin-build/_app/immutable/chunks/BY92tFS2.js +1 -0
- package/admin-build/_app/immutable/chunks/BcR-Rdj9.js +1 -0
- package/admin-build/_app/immutable/chunks/BdrwyZv8.js +1 -0
- package/admin-build/_app/immutable/chunks/Bh56EfQ_.js +1 -0
- package/admin-build/_app/immutable/chunks/BkrCkgYp.js +1 -0
- package/admin-build/_app/immutable/chunks/BmRjiP5k.js +1 -0
- package/admin-build/_app/immutable/chunks/BsokvhWC.js +1 -0
- package/admin-build/_app/immutable/chunks/C4D51vTW.js +1 -0
- package/admin-build/_app/immutable/chunks/C6puvcoR.js +2 -0
- package/admin-build/_app/immutable/chunks/CCKNu7m7.js +1 -0
- package/admin-build/_app/immutable/chunks/CWj6FrbW.js +1 -0
- package/admin-build/_app/immutable/chunks/Ce-ngf4p.js +5 -0
- package/admin-build/_app/immutable/chunks/Cs0GwzJA.js +1 -0
- package/admin-build/_app/immutable/chunks/CwROoZK0.js +1 -0
- package/admin-build/_app/immutable/chunks/CxCPv_Ut.js +1 -0
- package/admin-build/_app/immutable/chunks/CxbRue-5.js +1 -0
- package/admin-build/_app/immutable/chunks/CyqB6g-D.js +1 -0
- package/admin-build/_app/immutable/chunks/D5h5A1cc.js +2 -0
- package/admin-build/_app/immutable/chunks/DnyL7Zq-.js +1 -0
- package/admin-build/_app/immutable/chunks/DoPXzH7F.js +1 -0
- package/admin-build/_app/immutable/chunks/DrQSgw-f.js +1 -0
- package/admin-build/_app/immutable/chunks/DttM2zNO.js +1 -0
- package/admin-build/_app/immutable/chunks/DuXuUBWN.js +1 -0
- package/admin-build/_app/immutable/chunks/MdeqaOQx.js +10 -0
- package/admin-build/_app/immutable/chunks/NuUjtcO2.js +1 -0
- package/admin-build/_app/immutable/chunks/Q2nPFxS6.js +1 -0
- package/admin-build/_app/immutable/chunks/R6arueIl.js +1 -0
- package/admin-build/_app/immutable/chunks/UUazaC_N.js +1 -0
- package/admin-build/_app/immutable/chunks/cOYbrQxx.js +1 -0
- package/admin-build/_app/immutable/chunks/eFQHTGwA.js +1 -0
- package/admin-build/_app/immutable/chunks/ehbppgYb.js +1 -0
- package/admin-build/_app/immutable/chunks/glwixJlP.js +1 -0
- package/admin-build/_app/immutable/chunks/vApWTCBs.js +1 -0
- package/admin-build/_app/immutable/chunks/w89G9Xpi.js +1 -0
- package/admin-build/_app/immutable/chunks/wJsUhbfZ.js +1 -0
- package/admin-build/_app/immutable/chunks/zfauFM8P.js +1 -0
- package/admin-build/_app/immutable/entry/app.CcO-Uos3.js +2 -0
- package/admin-build/_app/immutable/entry/start.COebYq3I.js +1 -0
- package/admin-build/_app/immutable/nodes/0.CjtHKU-6.js +1 -0
- package/admin-build/_app/immutable/nodes/1.DEisjlM0.js +1 -0
- package/admin-build/_app/immutable/nodes/10.CvhdyWVB.js +1 -0
- package/admin-build/_app/immutable/nodes/11.DjHqcOvy.js +1 -0
- package/admin-build/_app/immutable/nodes/12.mQLz4Mj_.js +1 -0
- package/admin-build/_app/immutable/nodes/13.CBonZZyP.js +110 -0
- package/admin-build/_app/immutable/nodes/14.d-oiZL0j.js +3 -0
- package/admin-build/_app/immutable/nodes/15.CKPQsUYF.js +1 -0
- package/admin-build/_app/immutable/nodes/16.wPzAPQGx.js +1 -0
- package/admin-build/_app/immutable/nodes/17.DayhKyEZ.js +1 -0
- package/admin-build/_app/immutable/nodes/18.DKwS0Ir0.js +1 -0
- package/admin-build/_app/immutable/nodes/19.wPzAPQGx.js +1 -0
- package/admin-build/_app/immutable/nodes/2.BKoKrw1i.js +1 -0
- package/admin-build/_app/immutable/nodes/20.BvIkkkrW.js +1 -0
- package/admin-build/_app/immutable/nodes/21.DMaFhdHk.js +128 -0
- package/admin-build/_app/immutable/nodes/22.3xdgwuK1.js +1 -0
- package/admin-build/_app/immutable/nodes/23.8Bvgjbsl.js +112 -0
- package/admin-build/_app/immutable/nodes/24.DzSSzRhG.js +2 -0
- package/admin-build/_app/immutable/nodes/25.9KKYBnAE.js +2 -0
- package/admin-build/_app/immutable/nodes/26.Bhn9dfhY.js +1 -0
- package/admin-build/_app/immutable/nodes/27.kRLiC24G.js +1 -0
- package/admin-build/_app/immutable/nodes/28.BVIN1-7N.js +1 -0
- package/admin-build/_app/immutable/nodes/29.3yabZWj4.js +1 -0
- package/admin-build/_app/immutable/nodes/3.BFtSOkX7.js +2 -0
- package/admin-build/_app/immutable/nodes/30.CyCQlwaP.js +1 -0
- package/admin-build/_app/immutable/nodes/31.C4LDXjES.js +1 -0
- package/admin-build/_app/immutable/nodes/4.CvbiMlCa.js +1 -0
- package/admin-build/_app/immutable/nodes/5.C6BLv2eM.js +1 -0
- package/admin-build/_app/immutable/nodes/6.BcXvfl2P.js +1 -0
- package/admin-build/_app/immutable/nodes/7.CIuqhPiK.js +1 -0
- package/admin-build/_app/immutable/nodes/8.BQOR_JfO.js +1 -0
- package/admin-build/_app/immutable/nodes/9.NZqXQxPy.js +1 -0
- package/admin-build/_app/version.json +1 -0
- package/admin-build/favicon.svg +26 -0
- package/admin-build/index.html +45 -0
- package/openapi.json +19543 -0
- package/package.json +66 -0
- package/src/__tests__/admin-assets.test.ts +55 -0
- package/src/__tests__/admin-data-routes.test.ts +488 -0
- package/src/__tests__/admin-db-target.test.ts +103 -0
- package/src/__tests__/admin-routing.test.ts +31 -0
- package/src/__tests__/admin-user-management.test.ts +311 -0
- package/src/__tests__/analytics-query.test.ts +75 -0
- package/src/__tests__/auth-d1.test.ts +749 -0
- package/src/__tests__/auth-db-adapter.test.ts +73 -0
- package/src/__tests__/auth-jwt.test.ts +440 -0
- package/src/__tests__/auth-oauth.test.ts +389 -0
- package/src/__tests__/auth-password.test.ts +367 -0
- package/src/__tests__/auth-redirect.test.ts +87 -0
- package/src/__tests__/backup-restore.test.ts +711 -0
- package/src/__tests__/broadcast.test.ts +128 -0
- package/src/__tests__/cli.test.ts +178 -0
- package/src/__tests__/cloudflare-realtime.test.ts +113 -0
- package/src/__tests__/config.test.ts +469 -0
- package/src/__tests__/cors.test.ts +154 -0
- package/src/__tests__/cron.test.ts +302 -0
- package/src/__tests__/d1-handler.test.ts +402 -0
- package/src/__tests__/d1-sql.test.ts +120 -0
- package/src/__tests__/database-live-config.test.ts +42 -0
- package/src/__tests__/database-live-emitter.test.ts +56 -0
- package/src/__tests__/database-live-filters.test.ts +63 -0
- package/src/__tests__/database-live-route.test.ts +113 -0
- package/src/__tests__/db-sql.test.ts +163 -0
- package/src/__tests__/do-lifecycle.test.ts +263 -0
- package/src/__tests__/do-router.test.ts +729 -0
- package/src/__tests__/email-provider.test.ts +128 -0
- package/src/__tests__/email-templates.test.ts +528 -0
- package/src/__tests__/error-format.test.ts +250 -0
- package/src/__tests__/field-ops.test.ts +242 -0
- package/src/__tests__/functions-context.test.ts +334 -0
- package/src/__tests__/functions-d1-proxy.test.ts +229 -0
- package/src/__tests__/functions-registry-runtime-config.test.ts +17 -0
- package/src/__tests__/functions-route.test.ts +139 -0
- package/src/__tests__/internal-request.test.ts +77 -0
- package/src/__tests__/log-writer.test.ts +44 -0
- package/src/__tests__/logger.test.ts +58 -0
- package/src/__tests__/meta-admin-proxy.test.ts +48 -0
- package/src/__tests__/meta-export-coverage.test.ts +191 -0
- package/src/__tests__/meta-route-registration.test.ts +47 -0
- package/src/__tests__/namespace-dump.test.ts +28 -0
- package/src/__tests__/oauth-providers.test.ts +337 -0
- package/src/__tests__/openapi-coverage.test.ts +144 -0
- package/src/__tests__/pagination.test.ts +59 -0
- package/src/__tests__/password-policy.test.ts +191 -0
- package/src/__tests__/plugin-migrations.test.ts +379 -0
- package/src/__tests__/postgres-batch-compat.test.ts +133 -0
- package/src/__tests__/postgres-dialect.test.ts +328 -0
- package/src/__tests__/postgres-executor.test.ts +79 -0
- package/src/__tests__/postgres-field-ops-compat.test.ts +222 -0
- package/src/__tests__/postgres-schema-init.test.ts +105 -0
- package/src/__tests__/postgres-table-utils.test.ts +107 -0
- package/src/__tests__/presence.test.ts +199 -0
- package/src/__tests__/provider.test.ts +550 -0
- package/src/__tests__/public-user-profile.test.ts +339 -0
- package/src/__tests__/push-handlers.test.ts +179 -0
- package/src/__tests__/push-provider.test.ts +80 -0
- package/src/__tests__/push-token.test.ts +418 -0
- package/src/__tests__/query.test.ts +771 -0
- package/src/__tests__/rate-limit.test.ts +260 -0
- package/src/__tests__/room-access-policy.test.ts +101 -0
- package/src/__tests__/room-handler-context.test.ts +130 -0
- package/src/__tests__/room-monitoring.test.ts +138 -0
- package/src/__tests__/room-runtime-routing.test.ts +222 -0
- package/src/__tests__/room.test.ts +254 -0
- package/src/__tests__/route-parser.test.ts +490 -0
- package/src/__tests__/rules.test.ts +234 -0
- package/src/__tests__/runtime-surface-accounting.test.ts +120 -0
- package/src/__tests__/scheduled.test.ts +80 -0
- package/src/__tests__/schema.test.ts +1273 -0
- package/src/__tests__/security-hardening.test.ts +312 -0
- package/src/__tests__/server.unit.test.ts +333 -0
- package/src/__tests__/service-key-db-proxy.test.ts +650 -0
- package/src/__tests__/service-key-provider-bypass.test.ts +138 -0
- package/src/__tests__/service-key.test.ts +757 -0
- package/src/__tests__/smoke-skip-report.test.ts +72 -0
- package/src/__tests__/sms-provider.test.ts +39 -0
- package/src/__tests__/sql-route.test.ts +218 -0
- package/src/__tests__/storage-hook-context.test.ts +115 -0
- package/src/__tests__/totp.test.ts +200 -0
- package/src/__tests__/uuid.test.ts +144 -0
- package/src/__tests__/validation.test.ts +773 -0
- package/src/__tests__/websocket-pending.test.ts +163 -0
- package/src/_functions-registry.ts +51 -0
- package/src/bench-entry.ts +9 -0
- package/src/cloudflare-test.d.ts +1 -0
- package/src/durable-objects/auth-do.ts +49 -0
- package/src/durable-objects/database-do.ts +2240 -0
- package/src/durable-objects/database-live-do.ts +949 -0
- package/src/durable-objects/logs-do.ts +1200 -0
- package/src/durable-objects/room-runtime-base.ts +1604 -0
- package/src/durable-objects/rooms-do.ts +2191 -0
- package/src/generated-config.ts +6 -0
- package/src/index.ts +382 -0
- package/src/lib/admin-assets.ts +54 -0
- package/src/lib/admin-db-target.ts +301 -0
- package/src/lib/admin-routing.ts +35 -0
- package/src/lib/admin-user-management.ts +464 -0
- package/src/lib/analytics-adapter.ts +103 -0
- package/src/lib/analytics-query.ts +579 -0
- package/src/lib/auth-d1-service.ts +1193 -0
- package/src/lib/auth-d1.ts +1056 -0
- package/src/lib/auth-db-adapter.ts +289 -0
- package/src/lib/auth-redirect.ts +116 -0
- package/src/lib/cidr.ts +115 -0
- package/src/lib/client-ip.ts +51 -0
- package/src/lib/cloudflare-realtime.ts +251 -0
- package/src/lib/control-db.ts +36 -0
- package/src/lib/cron.ts +163 -0
- package/src/lib/d1-handler.ts +1425 -0
- package/src/lib/d1-schema-init.ts +255 -0
- package/src/lib/d1-sql.ts +33 -0
- package/src/lib/database-live-config.ts +24 -0
- package/src/lib/database-live-emitter.ts +111 -0
- package/src/lib/db-sql.ts +66 -0
- package/src/lib/do-retry.ts +36 -0
- package/src/lib/do-router.ts +270 -0
- package/src/lib/do-sql.ts +73 -0
- package/src/lib/email-provider.ts +379 -0
- package/src/lib/email-templates.ts +285 -0
- package/src/lib/email-translations.ts +422 -0
- package/src/lib/errors.ts +151 -0
- package/src/lib/functions.ts +2091 -0
- package/src/lib/hono.ts +56 -0
- package/src/lib/internal-request.ts +56 -0
- package/src/lib/jwt.ts +354 -0
- package/src/lib/log-writer.ts +272 -0
- package/src/lib/namespace-dump.ts +125 -0
- package/src/lib/oauth-providers.ts +1225 -0
- package/src/lib/op-parser.ts +99 -0
- package/src/lib/openapi.ts +146 -0
- package/src/lib/pagination.ts +19 -0
- package/src/lib/password-policy.ts +102 -0
- package/src/lib/password.ts +145 -0
- package/src/lib/plugin-migrations.ts +612 -0
- package/src/lib/postgres-executor.ts +203 -0
- package/src/lib/postgres-handler.ts +1102 -0
- package/src/lib/postgres-schema-init.ts +341 -0
- package/src/lib/postgres-table-utils.ts +87 -0
- package/src/lib/public-user-profile.ts +187 -0
- package/src/lib/push-provider.ts +409 -0
- package/src/lib/push-token.ts +294 -0
- package/src/lib/query-engine.ts +768 -0
- package/src/lib/room-monitoring.ts +97 -0
- package/src/lib/room-runtime.ts +14 -0
- package/src/lib/route-parser.ts +434 -0
- package/src/lib/schema.ts +538 -0
- package/src/lib/schemas.ts +152 -0
- package/src/lib/service-key.ts +419 -0
- package/src/lib/sms-provider.ts +230 -0
- package/src/lib/startup-config.ts +99 -0
- package/src/lib/totp.ts +242 -0
- package/src/lib/uuid.ts +87 -0
- package/src/lib/validation.ts +205 -0
- package/src/lib/version.ts +2 -0
- package/src/lib/websocket-pending.ts +40 -0
- package/src/middleware/auth.ts +169 -0
- package/src/middleware/captcha-verify.ts +217 -0
- package/src/middleware/cors.ts +159 -0
- package/src/middleware/error-handler.ts +54 -0
- package/src/middleware/internal-guard.ts +26 -0
- package/src/middleware/logger.ts +126 -0
- package/src/middleware/rate-limit.ts +283 -0
- package/src/middleware/rules.ts +475 -0
- package/src/routes/admin-auth.ts +447 -0
- package/src/routes/admin.ts +3501 -0
- package/src/routes/analytics-api.ts +290 -0
- package/src/routes/auth.ts +4222 -0
- package/src/routes/backup.ts +1466 -0
- package/src/routes/config.ts +53 -0
- package/src/routes/d1.ts +109 -0
- package/src/routes/database-live.ts +281 -0
- package/src/routes/functions.ts +155 -0
- package/src/routes/health.ts +32 -0
- package/src/routes/kv.ts +167 -0
- package/src/routes/oauth.ts +1055 -0
- package/src/routes/push.ts +1465 -0
- package/src/routes/room.ts +639 -0
- package/src/routes/schema-endpoint.ts +76 -0
- package/src/routes/sql.ts +176 -0
- package/src/routes/storage.ts +1674 -0
- package/src/routes/tables.ts +699 -0
- package/src/routes/users.ts +21 -0
- package/src/routes/vectorize.ts +372 -0
- package/src/types.ts +99 -0
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
|
+
}
|