@syncular/server 0.0.6-96 → 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/README.md +1 -2
- package/dist/auth-leases.d.ts +85 -0
- package/dist/auth-leases.d.ts.map +1 -0
- package/dist/auth-leases.js +368 -0
- package/dist/auth-leases.js.map +1 -0
- package/dist/better-sqlite3.d.ts +22 -0
- package/dist/better-sqlite3.d.ts.map +1 -0
- package/dist/better-sqlite3.js +16 -0
- package/dist/better-sqlite3.js.map +1 -0
- package/dist/blobs/access.d.ts +35 -0
- package/dist/blobs/access.d.ts.map +1 -0
- package/dist/blobs/access.js +149 -0
- package/dist/blobs/access.js.map +1 -0
- package/dist/blobs/adapters/database.d.ts +26 -9
- package/dist/blobs/adapters/database.d.ts.map +1 -1
- package/dist/blobs/adapters/database.js +68 -23
- package/dist/blobs/adapters/database.js.map +1 -1
- package/dist/blobs/index.d.ts +1 -0
- package/dist/blobs/index.d.ts.map +1 -1
- package/dist/blobs/index.js +1 -0
- package/dist/blobs/index.js.map +1 -1
- package/dist/blobs/manager.d.ts +69 -44
- package/dist/blobs/manager.d.ts.map +1 -1
- package/dist/blobs/manager.js +250 -65
- package/dist/blobs/manager.js.map +1 -1
- package/dist/blobs/migrate.d.ts.map +1 -1
- package/dist/blobs/migrate.js +16 -8
- package/dist/blobs/migrate.js.map +1 -1
- package/dist/blobs/types.d.ts +4 -0
- package/dist/blobs/types.d.ts.map +1 -1
- package/dist/bun-sqlite.d.ts +19 -0
- package/dist/bun-sqlite.d.ts.map +1 -0
- package/dist/bun-sqlite.js +19 -0
- package/dist/bun-sqlite.js.map +1 -0
- package/dist/clients.d.ts +1 -0
- package/dist/clients.d.ts.map +1 -1
- package/dist/clients.js.map +1 -1
- package/dist/cloudflare/durable-object.d.ts +93 -0
- package/dist/cloudflare/durable-object.d.ts.map +1 -0
- package/dist/cloudflare/durable-object.js +210 -0
- package/dist/cloudflare/durable-object.js.map +1 -0
- package/dist/cloudflare/index.d.ts +22 -0
- package/dist/cloudflare/index.d.ts.map +1 -0
- package/dist/cloudflare/index.js +22 -0
- package/dist/cloudflare/index.js.map +1 -0
- package/dist/cloudflare/r2.d.ts +180 -0
- package/dist/cloudflare/r2.d.ts.map +1 -0
- package/dist/cloudflare/r2.js +258 -0
- package/dist/cloudflare/r2.js.map +1 -0
- package/dist/cloudflare/scope-cache.d.ts +54 -0
- package/dist/cloudflare/scope-cache.d.ts.map +1 -0
- package/dist/cloudflare/scope-cache.js +223 -0
- package/dist/cloudflare/scope-cache.js.map +1 -0
- package/dist/cloudflare/sentry.d.ts +47 -0
- package/dist/cloudflare/sentry.d.ts.map +1 -0
- package/dist/cloudflare/sentry.js +163 -0
- package/dist/cloudflare/sentry.js.map +1 -0
- package/dist/cloudflare/worker.d.ts +46 -0
- package/dist/cloudflare/worker.d.ts.map +1 -0
- package/dist/cloudflare/worker.js +63 -0
- package/dist/cloudflare/worker.js.map +1 -0
- package/dist/commit-integrity.d.ts +38 -0
- package/dist/commit-integrity.d.ts.map +1 -0
- package/dist/commit-integrity.js +260 -0
- package/dist/commit-integrity.js.map +1 -0
- package/dist/compaction.js.map +1 -1
- package/dist/crdt-yjs/index.d.ts +99 -0
- package/dist/crdt-yjs/index.d.ts.map +1 -0
- package/dist/crdt-yjs/index.js +629 -0
- package/dist/crdt-yjs/index.js.map +1 -0
- package/dist/d1.d.ts +13 -0
- package/dist/d1.d.ts.map +1 -0
- package/dist/d1.js +14 -0
- package/dist/d1.js.map +1 -0
- package/dist/dialect/base.d.ts +11 -1
- package/dist/dialect/base.d.ts.map +1 -1
- package/dist/dialect/base.js +42 -5
- package/dist/dialect/base.js.map +1 -1
- package/dist/dialect/helpers.d.ts +6 -0
- package/dist/dialect/helpers.d.ts.map +1 -1
- package/dist/dialect/helpers.js +24 -0
- package/dist/dialect/helpers.js.map +1 -1
- package/dist/dialect/types.d.ts +40 -0
- package/dist/dialect/types.d.ts.map +1 -1
- package/dist/encrypted-crdt.d.ts +67 -0
- package/dist/encrypted-crdt.d.ts.map +1 -0
- package/dist/encrypted-crdt.js +426 -0
- package/dist/encrypted-crdt.js.map +1 -0
- package/dist/errors.d.ts +10 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +13 -0
- package/dist/errors.js.map +1 -0
- package/dist/filesystem/index.d.ts +44 -0
- package/dist/filesystem/index.d.ts.map +1 -0
- package/dist/filesystem/index.js +164 -0
- package/dist/filesystem/index.js.map +1 -0
- package/dist/handlers/collection.d.ts +11 -3
- package/dist/handlers/collection.d.ts.map +1 -1
- package/dist/handlers/collection.js +34 -56
- package/dist/handlers/collection.js.map +1 -1
- package/dist/handlers/create-handler.d.ts +31 -7
- package/dist/handlers/create-handler.d.ts.map +1 -1
- package/dist/handlers/create-handler.js +332 -115
- package/dist/handlers/create-handler.js.map +1 -1
- package/dist/handlers/types.d.ts +86 -1
- package/dist/handlers/types.d.ts.map +1 -1
- package/dist/helpers/conflict.js.map +1 -1
- package/dist/helpers/emitted-change.js.map +1 -1
- package/dist/helpers/index.d.ts +2 -0
- package/dist/helpers/index.d.ts.map +1 -1
- package/dist/helpers/index.js +2 -0
- package/dist/helpers/index.js.map +1 -1
- package/dist/helpers/paginate.js.map +1 -1
- package/dist/helpers/scope-authorization.d.ts +7 -0
- package/dist/helpers/scope-authorization.d.ts.map +1 -0
- package/dist/helpers/scope-authorization.js +19 -0
- package/dist/helpers/scope-authorization.js.map +1 -0
- package/dist/helpers/scope-commit-index.d.ts +12 -0
- package/dist/helpers/scope-commit-index.d.ts.map +1 -0
- package/dist/helpers/scope-commit-index.js +35 -0
- package/dist/helpers/scope-commit-index.js.map +1 -0
- package/dist/helpers/scope-strings.js.map +1 -1
- package/dist/hono/api-key-auth.d.ts +49 -0
- package/dist/hono/api-key-auth.d.ts.map +1 -0
- package/dist/hono/api-key-auth.js +108 -0
- package/dist/hono/api-key-auth.js.map +1 -0
- package/dist/hono/audit-redaction.d.ts +20 -0
- package/dist/hono/audit-redaction.d.ts.map +1 -0
- package/dist/hono/audit-redaction.js +85 -0
- package/dist/hono/audit-redaction.js.map +1 -0
- package/dist/hono/blobs.d.ts +75 -0
- package/dist/hono/blobs.d.ts.map +1 -0
- package/dist/hono/blobs.js +586 -0
- package/dist/hono/blobs.js.map +1 -0
- package/dist/hono/console/gateway.d.ts +42 -0
- package/dist/hono/console/gateway.d.ts.map +1 -0
- package/dist/hono/console/gateway.js +2158 -0
- package/dist/hono/console/gateway.js.map +1 -0
- package/dist/hono/console/live-auth.d.ts +7 -0
- package/dist/hono/console/live-auth.d.ts.map +1 -0
- package/dist/hono/console/live-auth.js +39 -0
- package/dist/hono/console/live-auth.js.map +1 -0
- package/dist/hono/console/route-descriptor.d.ts +6 -0
- package/dist/hono/console/route-descriptor.d.ts.map +1 -0
- package/dist/hono/console/route-descriptor.js +16 -0
- package/dist/hono/console/route-descriptor.js.map +1 -0
- package/dist/hono/console/routes/api-keys.d.ts +8 -0
- package/dist/hono/console/routes/api-keys.d.ts.map +1 -0
- package/dist/hono/console/routes/api-keys.js +575 -0
- package/dist/hono/console/routes/api-keys.js.map +1 -0
- package/dist/hono/console/routes/clients.d.ts +8 -0
- package/dist/hono/console/routes/clients.d.ts.map +1 -0
- package/dist/hono/console/routes/clients.js +322 -0
- package/dist/hono/console/routes/clients.js.map +1 -0
- package/dist/hono/console/routes/commits.d.ts +8 -0
- package/dist/hono/console/routes/commits.d.ts.map +1 -0
- package/dist/hono/console/routes/commits.js +882 -0
- package/dist/hono/console/routes/commits.js.map +1 -0
- package/dist/hono/console/routes/context.d.ts +188 -0
- package/dist/hono/console/routes/context.d.ts.map +1 -0
- package/dist/hono/console/routes/context.js +633 -0
- package/dist/hono/console/routes/context.js.map +1 -0
- package/dist/hono/console/routes/events.d.ts +8 -0
- package/dist/hono/console/routes/events.d.ts.map +1 -0
- package/dist/hono/console/routes/events.js +501 -0
- package/dist/hono/console/routes/events.js.map +1 -0
- package/dist/hono/console/routes/maintenance.d.ts +8 -0
- package/dist/hono/console/routes/maintenance.d.ts.map +1 -0
- package/dist/hono/console/routes/maintenance.js +341 -0
- package/dist/hono/console/routes/maintenance.js.map +1 -0
- package/dist/hono/console/routes/shared.d.ts +174 -0
- package/dist/hono/console/routes/shared.d.ts.map +1 -0
- package/dist/hono/console/routes/shared.js +583 -0
- package/dist/hono/console/routes/shared.js.map +1 -0
- package/dist/hono/console/routes/stats.d.ts +8 -0
- package/dist/hono/console/routes/stats.d.ts.map +1 -0
- package/dist/hono/console/routes/stats.js +295 -0
- package/dist/hono/console/routes/stats.js.map +1 -0
- package/dist/hono/console/routes/storage.d.ts +8 -0
- package/dist/hono/console/routes/storage.d.ts.map +1 -0
- package/dist/hono/console/routes/storage.js +121 -0
- package/dist/hono/console/routes/storage.js.map +1 -0
- package/dist/hono/console/routes.d.ts +36 -0
- package/dist/hono/console/routes.d.ts.map +1 -0
- package/dist/hono/console/routes.js +112 -0
- package/dist/hono/console/routes.js.map +1 -0
- package/dist/hono/console/schema-errors.d.ts +2 -0
- package/dist/hono/console/schema-errors.d.ts.map +1 -0
- package/dist/hono/console/schema-errors.js +17 -0
- package/dist/hono/console/schema-errors.js.map +1 -0
- package/dist/hono/console/schemas.d.ts +1515 -0
- package/dist/hono/console/schemas.d.ts.map +1 -0
- package/dist/hono/console/schemas.js +661 -0
- package/dist/hono/console/schemas.js.map +1 -0
- package/dist/hono/console/types.d.ts +213 -0
- package/dist/hono/console/types.d.ts.map +1 -0
- package/dist/hono/console/types.js +2 -0
- package/dist/hono/console/types.js.map +1 -0
- package/dist/hono/console/ui.d.ts +38 -0
- package/dist/hono/console/ui.d.ts.map +1 -0
- package/dist/hono/console/ui.js +43 -0
- package/dist/hono/console/ui.js.map +1 -0
- package/dist/hono/create-server.d.ts +71 -0
- package/dist/hono/create-server.d.ts.map +1 -0
- package/dist/hono/create-server.js +121 -0
- package/dist/hono/create-server.js.map +1 -0
- package/dist/hono/errors.d.ts +13 -0
- package/dist/hono/errors.d.ts.map +1 -0
- package/dist/hono/errors.js +21 -0
- package/dist/hono/errors.js.map +1 -0
- package/dist/hono/index.d.ts +20 -0
- package/dist/hono/index.d.ts.map +1 -0
- package/dist/hono/index.js +31 -0
- package/dist/hono/index.js.map +1 -0
- package/dist/hono/openapi.d.ts +72 -0
- package/dist/hono/openapi.d.ts.map +1 -0
- package/dist/hono/openapi.js +99 -0
- package/dist/hono/openapi.js.map +1 -0
- package/dist/hono/proxy/connection-manager.d.ts +78 -0
- package/dist/hono/proxy/connection-manager.d.ts.map +1 -0
- package/dist/hono/proxy/connection-manager.js +251 -0
- package/dist/hono/proxy/connection-manager.js.map +1 -0
- package/dist/hono/proxy/index.d.ts +8 -0
- package/dist/hono/proxy/index.d.ts.map +1 -0
- package/dist/hono/proxy/index.js +8 -0
- package/dist/hono/proxy/index.js.map +1 -0
- package/dist/hono/proxy/routes.d.ts +86 -0
- package/dist/hono/proxy/routes.d.ts.map +1 -0
- package/dist/hono/proxy/routes.js +183 -0
- package/dist/hono/proxy/routes.js.map +1 -0
- package/dist/hono/rate-limit.d.ts +101 -0
- package/dist/hono/rate-limit.d.ts.map +1 -0
- package/dist/hono/rate-limit.js +184 -0
- package/dist/hono/rate-limit.js.map +1 -0
- package/dist/hono/realtime-sync-packs.d.ts +43 -0
- package/dist/hono/realtime-sync-packs.d.ts.map +1 -0
- package/dist/hono/realtime-sync-packs.js +219 -0
- package/dist/hono/realtime-sync-packs.js.map +1 -0
- package/dist/hono/routes/audit.d.ts +12 -0
- package/dist/hono/routes/audit.d.ts.map +1 -0
- package/dist/hono/routes/audit.js +385 -0
- package/dist/hono/routes/audit.js.map +1 -0
- package/dist/hono/routes/auth-leases.d.ts +8 -0
- package/dist/hono/routes/auth-leases.d.ts.map +1 -0
- package/dist/hono/routes/auth-leases.js +88 -0
- package/dist/hono/routes/auth-leases.js.map +1 -0
- package/dist/hono/routes/combined.d.ts +8 -0
- package/dist/hono/routes/combined.d.ts.map +1 -0
- package/dist/hono/routes/combined.js +392 -0
- package/dist/hono/routes/combined.js.map +1 -0
- package/dist/hono/routes/context.d.ts +314 -0
- package/dist/hono/routes/context.d.ts.map +1 -0
- package/dist/hono/routes/context.js +1147 -0
- package/dist/hono/routes/context.js.map +1 -0
- package/dist/hono/routes/health.d.ts +8 -0
- package/dist/hono/routes/health.d.ts.map +1 -0
- package/dist/hono/routes/health.js +16 -0
- package/dist/hono/routes/health.js.map +1 -0
- package/dist/hono/routes/realtime.d.ts +9 -0
- package/dist/hono/routes/realtime.d.ts.map +1 -0
- package/dist/hono/routes/realtime.js +626 -0
- package/dist/hono/routes/realtime.js.map +1 -0
- package/dist/hono/routes/shared.d.ts +689 -0
- package/dist/hono/routes/shared.d.ts.map +1 -0
- package/dist/hono/routes/shared.js +972 -0
- package/dist/hono/routes/shared.js.map +1 -0
- package/dist/hono/routes/snapshots.d.ts +10 -0
- package/dist/hono/routes/snapshots.d.ts.map +1 -0
- package/dist/hono/routes/snapshots.js +281 -0
- package/dist/hono/routes/snapshots.js.map +1 -0
- package/dist/hono/routes.d.ts +19 -0
- package/dist/hono/routes.d.ts.map +1 -0
- package/dist/hono/routes.js +37 -0
- package/dist/hono/routes.js.map +1 -0
- package/dist/hono/validation.d.ts +5 -0
- package/dist/hono/validation.d.ts.map +1 -0
- package/dist/hono/validation.js +47 -0
- package/dist/hono/validation.js.map +1 -0
- package/dist/hono/websocket-origin.d.ts +9 -0
- package/dist/hono/websocket-origin.d.ts.map +1 -0
- package/dist/hono/websocket-origin.js +96 -0
- package/dist/hono/websocket-origin.js.map +1 -0
- package/dist/hono/ws.d.ts +341 -0
- package/dist/hono/ws.d.ts.map +1 -0
- package/dist/hono/ws.js +711 -0
- package/dist/hono/ws.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/libsql.d.ts +29 -0
- package/dist/libsql.d.ts.map +1 -0
- package/dist/libsql.js +25 -0
- package/dist/libsql.js.map +1 -0
- package/dist/migrate.js.map +1 -1
- package/dist/neon.d.ts +21 -0
- package/dist/neon.d.ts.map +1 -0
- package/dist/neon.js +22 -0
- package/dist/neon.js.map +1 -0
- package/dist/notify.d.ts +30 -0
- package/dist/notify.d.ts.map +1 -1
- package/dist/notify.js +160 -41
- package/dist/notify.js.map +1 -1
- package/dist/pglite.d.ts +37 -0
- package/dist/pglite.d.ts.map +1 -0
- package/dist/pglite.js +37 -0
- package/dist/pglite.js.map +1 -0
- package/dist/plugins/index.d.ts +2 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +2 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/types.d.ts +73 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/types.js +30 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/postgres/index.d.ts +68 -0
- package/dist/postgres/index.d.ts.map +1 -0
- package/dist/postgres/index.js +924 -0
- package/dist/postgres/index.js.map +1 -0
- package/dist/proxy/collection.d.ts +0 -2
- package/dist/proxy/collection.d.ts.map +1 -1
- package/dist/proxy/collection.js +2 -17
- package/dist/proxy/collection.js.map +1 -1
- package/dist/proxy/handler.d.ts +1 -1
- package/dist/proxy/handler.d.ts.map +1 -1
- package/dist/proxy/handler.js +1 -2
- package/dist/proxy/handler.js.map +1 -1
- package/dist/proxy/index.d.ts +1 -1
- package/dist/proxy/index.d.ts.map +1 -1
- package/dist/proxy/index.js +1 -1
- package/dist/proxy/index.js.map +1 -1
- package/dist/proxy/mutation-detector.js.map +1 -1
- package/dist/proxy/oplog.d.ts.map +1 -1
- package/dist/proxy/oplog.js +32 -8
- package/dist/proxy/oplog.js.map +1 -1
- package/dist/prune.d.ts +8 -1
- package/dist/prune.d.ts.map +1 -1
- package/dist/prune.js +68 -28
- package/dist/prune.js.map +1 -1
- package/dist/pull.d.ts +31 -0
- package/dist/pull.d.ts.map +1 -1
- package/dist/pull.js +1011 -471
- package/dist/pull.js.map +1 -1
- package/dist/push.d.ts +36 -2
- package/dist/push.d.ts.map +1 -1
- package/dist/push.js +603 -358
- package/dist/push.js.map +1 -1
- package/dist/realtime/in-memory.js.map +1 -1
- package/dist/realtime/index.d.ts +2 -1
- package/dist/realtime/index.d.ts.map +1 -1
- package/dist/realtime/index.js +1 -0
- package/dist/realtime/index.js.map +1 -1
- package/dist/realtime/types.d.ts +12 -0
- package/dist/realtime/types.d.ts.map +1 -1
- package/dist/realtime/types.js +13 -1
- package/dist/realtime/types.js.map +1 -1
- package/dist/relay/client-role/forward-engine.d.ts +63 -0
- package/dist/relay/client-role/forward-engine.d.ts.map +1 -0
- package/dist/relay/client-role/forward-engine.js +267 -0
- package/dist/relay/client-role/forward-engine.js.map +1 -0
- package/dist/relay/client-role/index.d.ts +9 -0
- package/dist/relay/client-role/index.d.ts.map +1 -0
- package/dist/relay/client-role/index.js +9 -0
- package/dist/relay/client-role/index.js.map +1 -0
- package/dist/relay/client-role/pull-engine.d.ts +72 -0
- package/dist/relay/client-role/pull-engine.d.ts.map +1 -0
- package/dist/relay/client-role/pull-engine.js +249 -0
- package/dist/relay/client-role/pull-engine.js.map +1 -0
- package/dist/relay/client-role/sequence-mapper.d.ts +65 -0
- package/dist/relay/client-role/sequence-mapper.d.ts.map +1 -0
- package/dist/relay/client-role/sequence-mapper.js +161 -0
- package/dist/relay/client-role/sequence-mapper.js.map +1 -0
- package/dist/relay/evaluation/relay-paths.d.ts +41 -0
- package/dist/relay/evaluation/relay-paths.d.ts.map +1 -0
- package/dist/relay/evaluation/relay-paths.js +504 -0
- package/dist/relay/evaluation/relay-paths.js.map +1 -0
- package/dist/relay/evaluation/rust-boundary.d.ts +47 -0
- package/dist/relay/evaluation/rust-boundary.d.ts.map +1 -0
- package/dist/relay/evaluation/rust-boundary.js +220 -0
- package/dist/relay/evaluation/rust-boundary.js.map +1 -0
- package/dist/relay/index.d.ts +37 -0
- package/dist/relay/index.d.ts.map +1 -0
- package/dist/relay/index.js +44 -0
- package/dist/relay/index.js.map +1 -0
- package/dist/relay/migrate.d.ts +18 -0
- package/dist/relay/migrate.d.ts.map +1 -0
- package/dist/relay/migrate.js +99 -0
- package/dist/relay/migrate.js.map +1 -0
- package/dist/relay/mode-manager.d.ts +60 -0
- package/dist/relay/mode-manager.d.ts.map +1 -0
- package/dist/relay/mode-manager.js +114 -0
- package/dist/relay/mode-manager.js.map +1 -0
- package/dist/relay/realtime.d.ts +90 -0
- package/dist/relay/realtime.d.ts.map +1 -0
- package/dist/relay/realtime.js +147 -0
- package/dist/relay/realtime.js.map +1 -0
- package/dist/relay/relay.d.ts +190 -0
- package/dist/relay/relay.d.ts.map +1 -0
- package/dist/relay/relay.js +320 -0
- package/dist/relay/relay.js.map +1 -0
- package/dist/relay/schema.d.ts +158 -0
- package/dist/relay/schema.d.ts.map +1 -0
- package/dist/relay/schema.js +7 -0
- package/dist/relay/schema.js.map +1 -0
- package/dist/relay/server-role/index.d.ts +56 -0
- package/dist/relay/server-role/index.d.ts.map +1 -0
- package/dist/relay/server-role/index.js +193 -0
- package/dist/relay/server-role/index.js.map +1 -0
- package/dist/relay/server-role/pull.d.ts +27 -0
- package/dist/relay/server-role/pull.d.ts.map +1 -0
- package/dist/relay/server-role/pull.js +24 -0
- package/dist/relay/server-role/pull.js.map +1 -0
- package/dist/relay/server-role/push.d.ts +29 -0
- package/dist/relay/server-role/push.d.ts.map +1 -0
- package/dist/relay/server-role/push.js +122 -0
- package/dist/relay/server-role/push.js.map +1 -0
- package/dist/s3/index.d.ts +83 -0
- package/dist/s3/index.d.ts.map +1 -0
- package/dist/s3/index.js +223 -0
- package/dist/s3/index.js.map +1 -0
- package/dist/schema.d.ts +137 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +1 -0
- package/dist/schema.js.map +1 -1
- package/dist/service-worker/index.d.ts +114 -0
- package/dist/service-worker/index.d.ts.map +1 -0
- package/dist/service-worker/index.js +487 -0
- package/dist/service-worker/index.js.map +1 -0
- package/dist/snapshot-artifacts/sqlite-bun.d.ts +15 -0
- package/dist/snapshot-artifacts/sqlite-bun.d.ts.map +1 -0
- package/dist/snapshot-artifacts/sqlite-bun.js +128 -0
- package/dist/snapshot-artifacts/sqlite-bun.js.map +1 -0
- package/dist/snapshot-artifacts.d.ts +206 -0
- package/dist/snapshot-artifacts.d.ts.map +1 -0
- package/dist/snapshot-artifacts.js +545 -0
- package/dist/snapshot-artifacts.js.map +1 -0
- package/dist/snapshot-chunks/db-metadata.d.ts +18 -0
- package/dist/snapshot-chunks/db-metadata.d.ts.map +1 -1
- package/dist/snapshot-chunks/db-metadata.js +91 -63
- package/dist/snapshot-chunks/db-metadata.js.map +1 -1
- package/dist/snapshot-chunks/types.d.ts +2 -0
- package/dist/snapshot-chunks/types.d.ts.map +1 -1
- package/dist/snapshot-chunks.d.ts +33 -3
- package/dist/snapshot-chunks.d.ts.map +1 -1
- package/dist/snapshot-chunks.js +136 -55
- package/dist/snapshot-chunks.js.map +1 -1
- package/dist/sqlite/index.d.ts +53 -0
- package/dist/sqlite/index.d.ts.map +1 -0
- package/dist/sqlite/index.js +795 -0
- package/dist/sqlite/index.js.map +1 -0
- package/dist/sqlite3.d.ts +22 -0
- package/dist/sqlite3.d.ts.map +1 -0
- package/dist/sqlite3.js +99 -0
- package/dist/sqlite3.js.map +1 -0
- package/dist/stats.d.ts +8 -0
- package/dist/stats.d.ts.map +1 -1
- package/dist/stats.js +45 -13
- package/dist/stats.js.map +1 -1
- package/dist/subscriptions/cache.d.ts +3 -0
- package/dist/subscriptions/cache.d.ts.map +1 -1
- package/dist/subscriptions/cache.js +44 -0
- package/dist/subscriptions/cache.js.map +1 -1
- package/dist/subscriptions/resolve.d.ts +3 -1
- package/dist/subscriptions/resolve.d.ts.map +1 -1
- package/dist/subscriptions/resolve.js +90 -51
- package/dist/subscriptions/resolve.js.map +1 -1
- package/dist/sync.d.ts +3 -0
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +8 -4
- package/dist/sync.js.map +1 -1
- package/package.json +296 -7
- package/src/auth-leases.ts +649 -0
- package/src/better-sqlite3.ts +35 -0
- package/src/blobs/access.ts +244 -0
- package/src/blobs/adapters/database.ts +125 -43
- package/src/blobs/index.ts +1 -0
- package/src/blobs/manager.ts +366 -65
- package/src/blobs/migrate.ts +16 -8
- package/src/blobs/types.ts +4 -0
- package/src/bun-sqlite-ambient.d.ts +19 -0
- package/src/bun-sqlite.ts +27 -0
- package/src/clients.ts +1 -0
- package/src/cloudflare/durable-object.ts +289 -0
- package/src/cloudflare/index.ts +22 -0
- package/src/cloudflare/r2.ts +526 -0
- package/src/cloudflare/scope-cache.ts +341 -0
- package/src/cloudflare/sentry.ts +230 -0
- package/src/cloudflare/worker.ts +77 -0
- package/src/commit-integrity.ts +371 -0
- package/src/crdt-yjs/index.ts +931 -0
- package/src/d1.ts +16 -0
- package/src/dialect/base.ts +71 -5
- package/src/dialect/helpers.ts +31 -0
- package/src/dialect/types.ts +47 -0
- package/src/encrypted-crdt.ts +786 -0
- package/src/errors.ts +22 -0
- package/src/filesystem/index.ts +262 -0
- package/src/handlers/collection.ts +78 -78
- package/src/handlers/create-handler.ts +540 -147
- package/src/handlers/types.ts +116 -0
- package/src/helpers/index.ts +2 -0
- package/src/helpers/scope-authorization.ts +27 -0
- package/src/helpers/scope-commit-index.ts +52 -0
- package/src/hono/api-key-auth.ts +177 -0
- package/src/hono/audit-redaction.ts +135 -0
- package/src/hono/blobs.ts +851 -0
- package/src/hono/console/gateway.ts +3046 -0
- package/src/hono/console/live-auth.ts +46 -0
- package/src/hono/console/route-descriptor.ts +22 -0
- package/src/hono/console/routes/api-keys.ts +721 -0
- package/src/hono/console/routes/clients.ts +447 -0
- package/src/hono/console/routes/commits.ts +1137 -0
- package/src/hono/console/routes/context.ts +956 -0
- package/src/hono/console/routes/events.ts +669 -0
- package/src/hono/console/routes/maintenance.ts +461 -0
- package/src/hono/console/routes/shared.ts +816 -0
- package/src/hono/console/routes/stats.ts +392 -0
- package/src/hono/console/routes/storage.ts +159 -0
- package/src/hono/console/routes.ts +146 -0
- package/src/hono/console/schema-errors.ts +23 -0
- package/src/hono/console/schemas.ts +914 -0
- package/src/hono/console/types.ts +223 -0
- package/src/hono/console/ui.ts +100 -0
- package/src/hono/create-server.ts +230 -0
- package/src/hono/errors.ts +50 -0
- package/src/hono/index.ts +54 -0
- package/src/hono/openapi.ts +139 -0
- package/src/hono/proxy/connection-manager.ts +340 -0
- package/src/hono/proxy/index.ts +8 -0
- package/src/hono/proxy/routes.ts +272 -0
- package/src/hono/rate-limit.ts +319 -0
- package/src/hono/realtime-sync-packs.ts +354 -0
- package/src/hono/routes/audit.ts +499 -0
- package/src/hono/routes/auth-leases.ts +119 -0
- package/src/hono/routes/combined.ts +583 -0
- package/src/hono/routes/context.ts +1629 -0
- package/src/hono/routes/health.ts +26 -0
- package/src/hono/routes/realtime.ts +808 -0
- package/src/hono/routes/shared.ts +1626 -0
- package/src/hono/routes/snapshots.ts +345 -0
- package/src/hono/routes.ts +68 -0
- package/src/hono/validation.ts +81 -0
- package/src/hono/websocket-origin.ts +131 -0
- package/src/hono/ws.ts +1134 -0
- package/src/index.ts +6 -0
- package/src/libsql.ts +51 -0
- package/src/neon.ts +28 -0
- package/src/notify.ts +224 -44
- package/src/pglite.ts +68 -0
- package/src/plugins/index.ts +1 -0
- package/src/plugins/types.ts +144 -0
- package/src/postgres/index.ts +1291 -0
- package/src/proxy/collection.ts +5 -27
- package/src/proxy/handler.ts +2 -2
- package/src/proxy/index.ts +0 -2
- package/src/proxy/oplog.ts +41 -10
- package/src/prune.ts +137 -36
- package/src/pull.ts +1504 -591
- package/src/push.ts +881 -443
- package/src/realtime/index.ts +2 -0
- package/src/realtime/types.ts +35 -0
- package/src/relay/bun-types.d.ts +50 -0
- package/src/relay/client-role/forward-engine.ts +355 -0
- package/src/relay/client-role/index.ts +9 -0
- package/src/relay/client-role/pull-engine.ts +329 -0
- package/src/relay/client-role/sequence-mapper.ts +201 -0
- package/src/relay/evaluation/relay-paths.ts +699 -0
- package/src/relay/evaluation/rust-boundary.ts +464 -0
- package/src/relay/index.ts +50 -0
- package/src/relay/migrate.ts +113 -0
- package/src/relay/mode-manager.ts +142 -0
- package/src/relay/realtime.ts +207 -0
- package/src/relay/relay.ts +431 -0
- package/src/relay/schema.ts +171 -0
- package/src/relay/server-role/index.ts +338 -0
- package/src/relay/server-role/pull.ts +43 -0
- package/src/relay/server-role/push.ts +164 -0
- package/src/s3/index.ts +346 -0
- package/src/schema.ts +141 -1
- package/src/service-worker/index.ts +773 -0
- package/src/snapshot-artifacts/sqlite-bun.ts +168 -0
- package/src/snapshot-artifacts.ts +896 -0
- package/src/snapshot-chunks/db-metadata.ts +131 -72
- package/src/snapshot-chunks/types.ts +2 -0
- package/src/snapshot-chunks.ts +194 -70
- package/src/sqlite/index.ts +1064 -0
- package/src/sqlite3.ts +137 -0
- package/src/stats.ts +76 -13
- package/src/subscriptions/cache.ts +58 -0
- package/src/subscriptions/resolve.ts +99 -58
- package/src/sync.ts +16 -6
- package/src/blobs/adapters/database.test.ts +0 -67
- package/src/notify.test.ts +0 -520
- package/src/proxy/handler.test.ts +0 -126
- package/src/proxy/mutation-detector.test.ts +0 -71
- package/src/snapshot-chunks/db-metadata.test.ts +0 -172
- package/src/subscriptions/resolve.test.ts +0 -180
package/src/handlers/types.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
BinarySnapshotColumn,
|
|
3
|
+
BinarySnapshotRowsEncoder,
|
|
2
4
|
ScopePattern,
|
|
3
5
|
ScopeValues,
|
|
4
6
|
ScopeValuesForKeys,
|
|
5
7
|
StoredScopes,
|
|
8
|
+
SyncAuthLeaseProvenance,
|
|
9
|
+
SyncChange,
|
|
6
10
|
SyncOp,
|
|
7
11
|
SyncOperation,
|
|
8
12
|
SyncOperationResult,
|
|
@@ -43,6 +47,11 @@ export interface ApplyOperationResult {
|
|
|
43
47
|
emittedChanges: EmittedChange[];
|
|
44
48
|
}
|
|
45
49
|
|
|
50
|
+
export interface BatchApplyOperationInput {
|
|
51
|
+
op: SyncOperation;
|
|
52
|
+
opIndex: number;
|
|
53
|
+
}
|
|
54
|
+
|
|
46
55
|
/**
|
|
47
56
|
* Context for server operations.
|
|
48
57
|
*/
|
|
@@ -74,6 +83,11 @@ export interface ServerSnapshotContext<
|
|
|
74
83
|
cursor: string | null;
|
|
75
84
|
/** Max rows to return */
|
|
76
85
|
limit: number;
|
|
86
|
+
/**
|
|
87
|
+
* Client schema version targeted by this snapshot.
|
|
88
|
+
* Use this to emit the correct generated client row shape for older clients.
|
|
89
|
+
*/
|
|
90
|
+
schemaVersion: number;
|
|
77
91
|
}
|
|
78
92
|
|
|
79
93
|
/**
|
|
@@ -94,6 +108,11 @@ export interface ServerApplyOperationContext<
|
|
|
94
108
|
* Use this to transform payloads from older client versions.
|
|
95
109
|
*/
|
|
96
110
|
schemaVersion: number;
|
|
111
|
+
/**
|
|
112
|
+
* Auth lease provenance captured when the client queued the commit.
|
|
113
|
+
* This is audit/replay context only; handlers must still use current auth.
|
|
114
|
+
*/
|
|
115
|
+
authLease?: SyncAuthLeaseProvenance;
|
|
97
116
|
}
|
|
98
117
|
|
|
99
118
|
/**
|
|
@@ -200,6 +219,35 @@ export interface ServerHandlerOptions<
|
|
|
200
219
|
*/
|
|
201
220
|
snapshotChunkTtlMs?: number;
|
|
202
221
|
|
|
222
|
+
/**
|
|
223
|
+
* Stable binary snapshot column metadata. Generators should provide this for
|
|
224
|
+
* Rust/native clients so the server does not need to infer column order and
|
|
225
|
+
* value types from every snapshot chunk at runtime.
|
|
226
|
+
*/
|
|
227
|
+
snapshotBinaryColumns?: readonly BinarySnapshotColumn[];
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Version-aware binary snapshot column metadata. Returning null intentionally
|
|
231
|
+
* disables fallback to current metadata.
|
|
232
|
+
*/
|
|
233
|
+
snapshotBinaryColumnsForVersion?: (
|
|
234
|
+
schemaVersion: number
|
|
235
|
+
) => readonly BinarySnapshotColumn[] | null | undefined;
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Optional generated binary snapshot encoder. When present, binary bootstrap
|
|
239
|
+
* chunks use this instead of the generic object-row encoder.
|
|
240
|
+
*/
|
|
241
|
+
snapshotBinaryEncoder?: BinarySnapshotRowsEncoder;
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Version-aware generated binary snapshot encoder. Returning null
|
|
245
|
+
* intentionally disables fallback to the current encoder.
|
|
246
|
+
*/
|
|
247
|
+
snapshotBinaryEncoderForVersion?: (
|
|
248
|
+
schemaVersion: number
|
|
249
|
+
) => BinarySnapshotRowsEncoder | null | undefined;
|
|
250
|
+
|
|
203
251
|
/**
|
|
204
252
|
* Transform client payload → server row on writes.
|
|
205
253
|
*/
|
|
@@ -245,6 +293,9 @@ export interface ServerTableHandler<
|
|
|
245
293
|
/** Table name */
|
|
246
294
|
table: string;
|
|
247
295
|
|
|
296
|
+
/** Primary key column for row ids and artifact/import metadata. */
|
|
297
|
+
primaryKeyColumn?: string;
|
|
298
|
+
|
|
248
299
|
/** Scope patterns used by this handler */
|
|
249
300
|
scopePatterns: ScopePattern[];
|
|
250
301
|
|
|
@@ -258,6 +309,58 @@ export interface ServerTableHandler<
|
|
|
258
309
|
*/
|
|
259
310
|
snapshotChunkTtlMs?: number;
|
|
260
311
|
|
|
312
|
+
/**
|
|
313
|
+
* Stable binary snapshot column metadata used by binary bootstrap chunks.
|
|
314
|
+
*/
|
|
315
|
+
snapshotBinaryColumns?: readonly BinarySnapshotColumn[];
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Version-aware binary snapshot column metadata. Generated handlers should
|
|
319
|
+
* use this when old client schema versions can have different row shapes.
|
|
320
|
+
* Returning null intentionally disables fallback to current metadata.
|
|
321
|
+
*/
|
|
322
|
+
snapshotBinaryColumnsForVersion?: (
|
|
323
|
+
schemaVersion: number
|
|
324
|
+
) => readonly BinarySnapshotColumn[] | null | undefined;
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Optional generated binary snapshot encoder used by binary bootstrap chunks.
|
|
328
|
+
*/
|
|
329
|
+
snapshotBinaryEncoder?: BinarySnapshotRowsEncoder;
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Version-aware binary snapshot encoder. Returning null intentionally
|
|
333
|
+
* disables fallback to the current generated encoder.
|
|
334
|
+
*/
|
|
335
|
+
snapshotBinaryEncoderForVersion?: (
|
|
336
|
+
schemaVersion: number
|
|
337
|
+
) => BinarySnapshotRowsEncoder | null | undefined;
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Project a persisted incremental change row to the requested client schema
|
|
341
|
+
* before pull plugins, wire integrity, and response encoding run.
|
|
342
|
+
*
|
|
343
|
+
* Generated divergent-schema handlers use this to keep the commit log in the
|
|
344
|
+
* current client row shape while serving older clients their targeted row
|
|
345
|
+
* shape.
|
|
346
|
+
*/
|
|
347
|
+
projectChangeForVersion?: (
|
|
348
|
+
change: SyncChange,
|
|
349
|
+
schemaVersion: number
|
|
350
|
+
) => SyncChange;
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Hint for push engine savepoint optimization on single-op commits.
|
|
354
|
+
*
|
|
355
|
+
* When true, the handler guarantees that a rejected single operation
|
|
356
|
+
* does not leave durable writes behind before returning the rejection.
|
|
357
|
+
* This allows pushCommit() to skip SAVEPOINT overhead for single-op
|
|
358
|
+
* commits on savepoint-capable dialects.
|
|
359
|
+
*
|
|
360
|
+
* Omit or set false for custom handlers unless this guarantee holds.
|
|
361
|
+
*/
|
|
362
|
+
canRejectSingleOperationWithoutSavepoint?: boolean;
|
|
363
|
+
|
|
261
364
|
/**
|
|
262
365
|
* Resolve allowed scope values for the current actor.
|
|
263
366
|
*/
|
|
@@ -284,4 +387,17 @@ export interface ServerTableHandler<
|
|
|
284
387
|
op: SyncOperation,
|
|
285
388
|
opIndex: number
|
|
286
389
|
): Promise<ApplyOperationResult>;
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Apply multiple operations in order.
|
|
393
|
+
*
|
|
394
|
+
* Implementations may internally batch writes but must preserve the same
|
|
395
|
+
* observable semantics as sequential applyOperation calls:
|
|
396
|
+
* - results are returned in operation order
|
|
397
|
+
* - processing stops at the first non-applied result
|
|
398
|
+
*/
|
|
399
|
+
applyOperationBatch?(
|
|
400
|
+
ctx: ServerApplyOperationContext<DB, Auth>,
|
|
401
|
+
operations: BatchApplyOperationInput[]
|
|
402
|
+
): Promise<ApplyOperationResult[]>;
|
|
287
403
|
}
|
package/src/helpers/index.ts
CHANGED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ScopeValues, StoredScopes } from '@syncular/core';
|
|
2
|
+
|
|
3
|
+
function scopeValueAllows(
|
|
4
|
+
allowed: ScopeValues[string] | undefined,
|
|
5
|
+
rowValue: string
|
|
6
|
+
): boolean {
|
|
7
|
+
if (allowed === undefined) return false;
|
|
8
|
+
const allowedValues = Array.isArray(allowed) ? allowed : [allowed];
|
|
9
|
+
return allowedValues.includes('*') || allowedValues.includes(rowValue);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function rowScopesAllowed(args: {
|
|
13
|
+
rowScopes: StoredScopes;
|
|
14
|
+
allowedScopes: ScopeValues;
|
|
15
|
+
requiredScopeKeys: readonly string[];
|
|
16
|
+
}): boolean {
|
|
17
|
+
for (const key of args.requiredScopeKeys) {
|
|
18
|
+
const rowValue = args.rowScopes[key];
|
|
19
|
+
if (typeof rowValue !== 'string' || rowValue.length === 0) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
if (!scopeValueAllows(args.allowedScopes[key], rowValue)) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { ScopeValues, StoredScopes } from '@syncular/core';
|
|
2
|
+
|
|
3
|
+
export interface ScopeCommitIndexChange {
|
|
4
|
+
table: string;
|
|
5
|
+
scopes: ScopeValues | StoredScopes;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface ScopeCommitIndexEntry {
|
|
9
|
+
table: string;
|
|
10
|
+
scopeKey: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function scopeKeysFromScopeValues(
|
|
14
|
+
scopes: ScopeValues | StoredScopes | null | undefined
|
|
15
|
+
): string[] {
|
|
16
|
+
if (!scopes || typeof scopes !== 'object') return [];
|
|
17
|
+
const keys = new Set<string>();
|
|
18
|
+
|
|
19
|
+
for (const [key, rawValue] of Object.entries(scopes)) {
|
|
20
|
+
const prefix = key.replace(/_id$/, '');
|
|
21
|
+
const values = Array.isArray(rawValue) ? rawValue : [rawValue];
|
|
22
|
+
for (const value of values) {
|
|
23
|
+
if (typeof value === 'string') {
|
|
24
|
+
if (value.length > 0) keys.add(`${prefix}:${value}`);
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (typeof value === 'number' || typeof value === 'bigint') {
|
|
28
|
+
keys.add(`${prefix}:${String(value)}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return Array.from(keys);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function createScopeCommitIndexEntries(
|
|
37
|
+
changes: readonly ScopeCommitIndexChange[]
|
|
38
|
+
): ScopeCommitIndexEntry[] {
|
|
39
|
+
const entries = new Map<string, ScopeCommitIndexEntry>();
|
|
40
|
+
|
|
41
|
+
for (const change of changes) {
|
|
42
|
+
if (!change.table) continue;
|
|
43
|
+
for (const scopeKey of scopeKeysFromScopeValues(change.scopes)) {
|
|
44
|
+
const key = `${change.table}\u0000${scopeKey}`;
|
|
45
|
+
if (!entries.has(key)) {
|
|
46
|
+
entries.set(key, { table: change.table, scopeKey });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return Array.from(entries.values());
|
|
52
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/server/hono - API Key Authentication Helper
|
|
3
|
+
*
|
|
4
|
+
* Provides utilities for validating API keys in relay/proxy routes.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { sha256Hex } from '@syncular/core';
|
|
8
|
+
import type { ServerSyncDialect } from '@syncular/server';
|
|
9
|
+
import type { Context } from 'hono';
|
|
10
|
+
import { type Kysely, sql } from 'kysely';
|
|
11
|
+
import { type ApiKeyType, ApiKeyTypeSchema } from './console/schemas';
|
|
12
|
+
import { syncError } from './errors';
|
|
13
|
+
|
|
14
|
+
interface SyncApiKeysTable {
|
|
15
|
+
key_id: string;
|
|
16
|
+
key_hash: string;
|
|
17
|
+
key_prefix: string;
|
|
18
|
+
name: string;
|
|
19
|
+
key_type: string;
|
|
20
|
+
scope_keys: unknown | null;
|
|
21
|
+
actor_id: string | null;
|
|
22
|
+
created_at: string;
|
|
23
|
+
expires_at: string | null;
|
|
24
|
+
last_used_at: string | null;
|
|
25
|
+
revoked_at: string | null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
type ApiKeyDb = {
|
|
29
|
+
sync_api_keys: SyncApiKeysTable;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
interface ValidateApiKeyResult {
|
|
33
|
+
keyId: string;
|
|
34
|
+
keyType: ApiKeyType;
|
|
35
|
+
actorId: string | null;
|
|
36
|
+
scopeKeys: string[];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Validates an API key from Authorization header.
|
|
41
|
+
* Updates last_used_at on successful validation.
|
|
42
|
+
*/
|
|
43
|
+
export async function validateApiKey<DB extends ApiKeyDb>(
|
|
44
|
+
db: Kysely<DB>,
|
|
45
|
+
dialect: ServerSyncDialect,
|
|
46
|
+
authHeader: string | undefined
|
|
47
|
+
): Promise<ValidateApiKeyResult | null> {
|
|
48
|
+
if (!authHeader?.startsWith('Bearer ')) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const secretKey = authHeader.slice(7);
|
|
53
|
+
if (!secretKey?.startsWith('sk_')) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Hash the provided key
|
|
58
|
+
const keyHash = await hashApiKey(secretKey);
|
|
59
|
+
|
|
60
|
+
// Look up key by hash
|
|
61
|
+
const rowResult = await sql<{
|
|
62
|
+
key_id: string;
|
|
63
|
+
key_type: string;
|
|
64
|
+
actor_id: string | null;
|
|
65
|
+
scope_keys: unknown | null;
|
|
66
|
+
expires_at: string | null;
|
|
67
|
+
revoked_at: string | null;
|
|
68
|
+
}>`
|
|
69
|
+
select key_id, key_type, actor_id, scope_keys, expires_at, revoked_at
|
|
70
|
+
from ${sql.table('sync_api_keys')}
|
|
71
|
+
where key_hash = ${keyHash}
|
|
72
|
+
limit 1
|
|
73
|
+
`.execute(db);
|
|
74
|
+
const row = rowResult.rows[0];
|
|
75
|
+
|
|
76
|
+
if (!row) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const parsedKeyType = ApiKeyTypeSchema.safeParse(row.key_type);
|
|
81
|
+
if (!parsedKeyType.success) return null;
|
|
82
|
+
|
|
83
|
+
// Check if revoked
|
|
84
|
+
if (row.revoked_at) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Check if expired
|
|
89
|
+
if (row.expires_at) {
|
|
90
|
+
const expiresAt = new Date(row.expires_at);
|
|
91
|
+
if (expiresAt < new Date()) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Update last_used_at
|
|
97
|
+
const now = new Date().toISOString();
|
|
98
|
+
await sql`
|
|
99
|
+
update ${sql.table('sync_api_keys')}
|
|
100
|
+
set last_used_at = ${now}
|
|
101
|
+
where key_id = ${row.key_id}
|
|
102
|
+
`.execute(db);
|
|
103
|
+
|
|
104
|
+
// Parse scopes
|
|
105
|
+
const scopeKeys = dialect.dbToArray(row.scope_keys);
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
keyId: row.key_id,
|
|
109
|
+
keyType: parsedKeyType.data,
|
|
110
|
+
actorId: row.actor_id,
|
|
111
|
+
scopeKeys,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Creates an authenticator for relay/proxy routes.
|
|
117
|
+
* Returns actorId from the API key if valid and allowed.
|
|
118
|
+
*/
|
|
119
|
+
export function createApiKeyAuthenticator<DB extends ApiKeyDb>(
|
|
120
|
+
db: Kysely<DB>,
|
|
121
|
+
dialect: ServerSyncDialect,
|
|
122
|
+
allowedTypes: ApiKeyType[]
|
|
123
|
+
): (c: Context) => Promise<{ actorId: string } | null> {
|
|
124
|
+
return async (c: Context) => {
|
|
125
|
+
const authHeader = c.req.header('Authorization');
|
|
126
|
+
const result = await validateApiKey(db, dialect, authHeader);
|
|
127
|
+
|
|
128
|
+
if (!result) {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Check if key type is allowed
|
|
133
|
+
if (!allowedTypes.includes(result.keyType)) {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Return actorId (use key's actorId if set, otherwise use a default)
|
|
138
|
+
return {
|
|
139
|
+
actorId: result.actorId ?? `api-key:${result.keyId}`,
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Middleware that validates API key and attaches result to context.
|
|
146
|
+
*/
|
|
147
|
+
export function apiKeyAuthMiddleware<DB extends ApiKeyDb>(
|
|
148
|
+
db: Kysely<DB>,
|
|
149
|
+
dialect: ServerSyncDialect,
|
|
150
|
+
allowedTypes: ApiKeyType[]
|
|
151
|
+
) {
|
|
152
|
+
return async (
|
|
153
|
+
c: Context,
|
|
154
|
+
next: () => Promise<void>
|
|
155
|
+
): Promise<Response | undefined> => {
|
|
156
|
+
const authHeader = c.req.header('Authorization');
|
|
157
|
+
const result = await validateApiKey(db, dialect, authHeader);
|
|
158
|
+
|
|
159
|
+
if (!result) {
|
|
160
|
+
return syncError(c, 401, 'sync.auth_required');
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (!allowedTypes.includes(result.keyType)) {
|
|
164
|
+
return syncError(c, 403, 'sync.forbidden', 'Invalid key type');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Attach to context for downstream handlers
|
|
168
|
+
c.set('apiKey', result);
|
|
169
|
+
|
|
170
|
+
await next();
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Hash function (same as in routes.ts)
|
|
175
|
+
async function hashApiKey(secretKey: string): Promise<string> {
|
|
176
|
+
return sha256Hex(secretKey);
|
|
177
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import {
|
|
2
|
+
parseJsonValue,
|
|
3
|
+
SYNC_CRDT_CHECKPOINTS_TABLE,
|
|
4
|
+
SYNC_CRDT_UPDATES_TABLE,
|
|
5
|
+
} from '@syncular/server';
|
|
6
|
+
|
|
7
|
+
type AuditChangeKind =
|
|
8
|
+
| 'app_row'
|
|
9
|
+
| 'delete'
|
|
10
|
+
| 'blob_reference'
|
|
11
|
+
| 'encrypted_field_envelope'
|
|
12
|
+
| 'encrypted_crdt_update'
|
|
13
|
+
| 'encrypted_crdt_checkpoint';
|
|
14
|
+
|
|
15
|
+
interface AuditChangeRedaction {
|
|
16
|
+
payload: 'omitted';
|
|
17
|
+
reason: 'audit_redacted_by_default';
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface AuditChangeSummary {
|
|
21
|
+
changeKind: AuditChangeKind;
|
|
22
|
+
fields: string[];
|
|
23
|
+
scopeFields: string[];
|
|
24
|
+
sensitiveFields: string[];
|
|
25
|
+
redaction: AuditChangeRedaction;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function summarizeAuditChange(args: {
|
|
29
|
+
table: string;
|
|
30
|
+
op: 'upsert' | 'delete';
|
|
31
|
+
rowJson: unknown | null;
|
|
32
|
+
scopes: unknown;
|
|
33
|
+
}): AuditChangeSummary {
|
|
34
|
+
const row = parseJsonRecord(args.rowJson);
|
|
35
|
+
const fields = Object.keys(row).sort();
|
|
36
|
+
const sensitiveFields = detectSensitiveFields(row);
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
changeKind: classifyAuditChange({
|
|
40
|
+
table: args.table,
|
|
41
|
+
op: args.op,
|
|
42
|
+
row,
|
|
43
|
+
sensitiveFields,
|
|
44
|
+
}),
|
|
45
|
+
fields,
|
|
46
|
+
scopeFields: Object.keys(parseJsonRecord(args.scopes)).sort(),
|
|
47
|
+
sensitiveFields,
|
|
48
|
+
redaction: {
|
|
49
|
+
payload: 'omitted',
|
|
50
|
+
reason: 'audit_redacted_by_default',
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function classifyAuditChange(args: {
|
|
56
|
+
table: string;
|
|
57
|
+
op: 'upsert' | 'delete';
|
|
58
|
+
row: Record<string, unknown>;
|
|
59
|
+
sensitiveFields: string[];
|
|
60
|
+
}): AuditChangeKind {
|
|
61
|
+
if (args.table === SYNC_CRDT_UPDATES_TABLE) {
|
|
62
|
+
return 'encrypted_crdt_update';
|
|
63
|
+
}
|
|
64
|
+
if (args.table === SYNC_CRDT_CHECKPOINTS_TABLE) {
|
|
65
|
+
return 'encrypted_crdt_checkpoint';
|
|
66
|
+
}
|
|
67
|
+
if (args.op === 'delete') {
|
|
68
|
+
return 'delete';
|
|
69
|
+
}
|
|
70
|
+
if (args.sensitiveFields.some((field) => isEncryptedFieldName(field))) {
|
|
71
|
+
return 'encrypted_field_envelope';
|
|
72
|
+
}
|
|
73
|
+
if (args.sensitiveFields.length > 0) {
|
|
74
|
+
return 'blob_reference';
|
|
75
|
+
}
|
|
76
|
+
return 'app_row';
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function detectSensitiveFields(row: Record<string, unknown>): string[] {
|
|
80
|
+
const sensitive = new Set<string>();
|
|
81
|
+
|
|
82
|
+
for (const [field, value] of Object.entries(row)) {
|
|
83
|
+
const parsed = parseJsonValue(value);
|
|
84
|
+
if (isEncryptedFieldName(field) || isEncryptedEnvelope(parsed)) {
|
|
85
|
+
sensitive.add(field);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (isBlobRef(parsed)) {
|
|
89
|
+
sensitive.add(field);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return Array.from(sensitive).sort();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function parseJsonRecord(value: unknown): Record<string, unknown> {
|
|
97
|
+
const parsed = parseJsonValue(value);
|
|
98
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
99
|
+
return {};
|
|
100
|
+
}
|
|
101
|
+
return parsed as Record<string, unknown>;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function isBlobRef(value: unknown): boolean {
|
|
105
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
const record = value as Record<string, unknown>;
|
|
109
|
+
return (
|
|
110
|
+
typeof record.hash === 'string' &&
|
|
111
|
+
record.hash.length > 0 &&
|
|
112
|
+
(typeof record.size === 'number' || typeof record.size === 'bigint')
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function isEncryptedEnvelope(value: unknown): boolean {
|
|
117
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
const record = value as Record<string, unknown>;
|
|
121
|
+
return (
|
|
122
|
+
typeof record.ciphertext === 'string' &&
|
|
123
|
+
(typeof record.key_id === 'string' || typeof record.keyId === 'string')
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function isEncryptedFieldName(field: string): boolean {
|
|
128
|
+
return (
|
|
129
|
+
field === 'ciphertext' ||
|
|
130
|
+
field === 'key_id' ||
|
|
131
|
+
field === 'keyId' ||
|
|
132
|
+
field.endsWith('_encrypted') ||
|
|
133
|
+
field.endsWith('_ciphertext')
|
|
134
|
+
);
|
|
135
|
+
}
|