edgebase-worker 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,166 @@
1
+ # EdgeBase Worker - Example Deployment
2
+
3
+ This is an **example deployment** of EdgeBase using **published NPM packages**.
4
+
5
+ > **For External Users:** This demonstrates how to use `@edgebasejs/worker` and the EdgeBase CLI to deploy a complete backend to Cloudflare Workers, independently from the monorepo.
6
+
7
+ This package is the Cloudflare Workers backend only.
8
+ The admin UI is deployed separately via `@edgebasejs/admin-console` and connects to this worker URL.
9
+
10
+ ## Features
11
+
12
+ - **Auth**: Login/Register with email and password
13
+ - **Todos CRUD**: Create, read, update, delete todos
14
+ - **User Isolation**: Each user only sees their own todos
15
+ - **Session Management**: Token-based authentication
16
+
17
+ ## Schema & Migrations
18
+
19
+ - Schema source: `apps/worker/edgebase.schema.ts`
20
+ - Migrations: `apps/worker/migrations/*.sql`
21
+ - Worker entrypoint: `apps/worker/src/index.ts` (EdgeBase worker factory)
22
+
23
+ Generate SDK + migrations after schema changes:
24
+
25
+ ```bash
26
+ cd apps/worker
27
+ npx edgebase generate
28
+ ```
29
+
30
+ Apply migrations to local D1:
31
+
32
+ ```bash
33
+ cd apps/worker
34
+ npx edgebase migrate
35
+ ```
36
+
37
+ Note: In development, the worker can auto-initialize tables from the schema.
38
+ In production, run migrations explicitly.
39
+
40
+ ## Quick Start
41
+
42
+ ```bash
43
+ # Install dependencies
44
+ npm install
45
+
46
+ # Start worker development server
47
+ npm run dev
48
+ # Opens: http://localhost:8787 (Worker API)
49
+ ```
50
+
51
+ Start admin console separately (in another terminal):
52
+
53
+ ```bash
54
+ cd ../admin-console
55
+ npm run dev
56
+ # Opens: http://localhost:3001
57
+ # First open asks for Worker URL (e.g. http://localhost:8787)
58
+ ```
59
+
60
+ Build/publish commands are available via the EdgeBase CLI:
61
+
62
+ ```bash
63
+ # Start development
64
+ npm run dev
65
+
66
+ # Build for deployment
67
+ npm run build
68
+
69
+ # Deploy to Cloudflare Workers
70
+ npm run deploy
71
+
72
+ # Publish to npm
73
+ npm run publish
74
+ ```
75
+
76
+ ## API Endpoints
77
+
78
+ ### Auth
79
+
80
+ ```bash
81
+ # Login
82
+ curl -X POST http://localhost:8787/auth/login \
83
+ -H "Content-Type: application/json" \
84
+ -d '{"email":"user@example.com","password":"password123"}'
85
+
86
+ # Register
87
+ curl -X POST http://localhost:8787/auth/register \
88
+ -H "Content-Type: application/json" \
89
+ -d '{"email":"user@example.com","password":"password123"}'
90
+ ```
91
+
92
+ ### Todos
93
+
94
+ ```bash
95
+ TOKEN="..." # From login response
96
+
97
+ # Create todo
98
+ curl -X POST http://localhost:8787/todos \
99
+ -H "Authorization: Bearer $TOKEN" \
100
+ -H "Content-Type: application/json" \
101
+ -d '{"title":"Buy milk","completed":false}'
102
+
103
+ # Get all todos
104
+ curl http://localhost:8787/todos \
105
+ -H "Authorization: Bearer $TOKEN"
106
+
107
+ # Get single todo
108
+ curl http://localhost:8787/todos/TODOID \
109
+ -H "Authorization: Bearer $TOKEN"
110
+
111
+ # Update todo
112
+ curl -X PATCH http://localhost:8787/todos/TODOID \
113
+ -H "Authorization: Bearer $TOKEN" \
114
+ -H "Content-Type: application/json" \
115
+ -d '{"completed":true}'
116
+
117
+ # Delete todo
118
+ curl -X DELETE http://localhost:8787/todos/TODOID \
119
+ -H "Authorization: Bearer $TOKEN"
120
+ ```
121
+
122
+ ## Storage
123
+
124
+ Uses **Cloudflare D1** (SQLite). System tables and entity tables are managed via EdgeBase migrations.
125
+
126
+ ## Deployment
127
+
128
+ ```bash
129
+ # Build for production
130
+ npm run build
131
+
132
+ # Deploy to Cloudflare Workers
133
+ npm run deploy
134
+
135
+ # Or publish worker package
136
+ npm run publish
137
+ ```
138
+
139
+ Set environment variables in `wrangler.toml` for production.
140
+
141
+ ### About the Admin Console
142
+
143
+ The admin console is a separate deployment:
144
+ - Uses this worker via its URL
145
+ - On first start it asks for the Worker URL
146
+ - Supports login with an existing admin account
147
+ - Supports first-admin setup when no admin exists yet
148
+
149
+ ## Architecture
150
+
151
+ ```
152
+ Client (React Native + Expo)
153
+
154
+ EdgeBase SDK
155
+
156
+ This Worker (REST API)
157
+
158
+ In-Memory Storage (or D1 in production)
159
+ ```
160
+
161
+ The app communicates with this worker via HTTP. The SDK handles:
162
+
163
+ - Authentication (token management)
164
+ - Offline-first caching
165
+ - Sync logic
166
+ - Query caching
@@ -0,0 +1,48 @@
1
+ // EdgeBase schema definition for worker
2
+ import type { DatabaseSchema } from '@edgebasejs/types';
3
+
4
+ const schema: DatabaseSchema = {
5
+ entities: {
6
+ todos: {
7
+ fields: {
8
+ id: {
9
+ type: 'string',
10
+ required: true,
11
+ primary: true,
12
+ },
13
+ userId: {
14
+ type: 'reference',
15
+ reference: 'users',
16
+ required: true,
17
+ },
18
+ title: {
19
+ type: 'string',
20
+ required: true,
21
+ },
22
+ completed: {
23
+ type: 'boolean',
24
+ required: true,
25
+ default: false,
26
+ },
27
+ createdAt: {
28
+ type: 'timestamp',
29
+ required: true,
30
+ },
31
+ updatedAt: {
32
+ type: 'timestamp',
33
+ required: true,
34
+ },
35
+ },
36
+ accessRules: {
37
+ create: (user: any, data: any) => data.userId === user.id,
38
+ read: (user: any, data: any) => data.userId === user.id,
39
+ update: (user: any, existing: any, updates: any) =>
40
+ existing.userId === user.id && (!updates.userId || updates.userId === existing.userId),
41
+ delete: (user: any, existing: any) => existing.userId === user.id,
42
+ },
43
+ indexes: [{ fields: ['userId'] }],
44
+ },
45
+ },
46
+ };
47
+
48
+ export default schema;
@@ -0,0 +1,29 @@
1
+ CREATE TABLE IF NOT EXISTS users (
2
+ id TEXT PRIMARY KEY,
3
+ email TEXT NOT NULL UNIQUE,
4
+ password_hash TEXT NOT NULL,
5
+ created_at INTEGER NOT NULL,
6
+ updated_at INTEGER NOT NULL
7
+ );
8
+
9
+ CREATE TABLE IF NOT EXISTS refresh_tokens (
10
+ id TEXT PRIMARY KEY,
11
+ user_id TEXT NOT NULL,
12
+ token TEXT NOT NULL UNIQUE,
13
+ expires_at INTEGER NOT NULL,
14
+ created_at INTEGER NOT NULL,
15
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
16
+ );
17
+
18
+ CREATE TABLE IF NOT EXISTS sync_metadata (
19
+ entity TEXT NOT NULL,
20
+ record_id TEXT NOT NULL,
21
+ version INTEGER NOT NULL,
22
+ updated_at INTEGER NOT NULL,
23
+ deleted_at INTEGER,
24
+ PRIMARY KEY (entity, record_id)
25
+ );
26
+
27
+ CREATE INDEX IF NOT EXISTS idx_sync_metadata_updated ON sync_metadata(entity, updated_at);
28
+ CREATE INDEX IF NOT EXISTS idx_refresh_tokens_user ON refresh_tokens(user_id);
29
+ CREATE INDEX IF NOT EXISTS idx_refresh_tokens_token ON refresh_tokens(token);
@@ -0,0 +1,7 @@
1
+ CREATE TABLE todos (
2
+ id TEXT PRIMARY KEY,
3
+ title TEXT NOT NULL,
4
+ completed INTEGER NOT NULL DEFAULT 0,
5
+ createdAt INTEGER NOT NULL,
6
+ updatedAt INTEGER NOT NULL
7
+ );
@@ -0,0 +1,2 @@
1
+ ALTER TABLE todos ADD COLUMN userId TEXT;
2
+ CREATE INDEX IF NOT EXISTS idx_todos_userId ON todos(userId);
@@ -0,0 +1,21 @@
1
+ CREATE TABLE IF NOT EXISTS admins (
2
+ id TEXT PRIMARY KEY,
3
+ email TEXT NOT NULL UNIQUE,
4
+ password_hash TEXT NOT NULL,
5
+ role TEXT NOT NULL,
6
+ is_active INTEGER NOT NULL DEFAULT 1,
7
+ created_at INTEGER NOT NULL,
8
+ updated_at INTEGER NOT NULL
9
+ );
10
+
11
+ CREATE TABLE IF NOT EXISTS admin_refresh_tokens (
12
+ id TEXT PRIMARY KEY,
13
+ admin_id TEXT NOT NULL,
14
+ token TEXT NOT NULL UNIQUE,
15
+ expires_at INTEGER NOT NULL,
16
+ created_at INTEGER NOT NULL,
17
+ FOREIGN KEY (admin_id) REFERENCES admins(id) ON DELETE CASCADE
18
+ );
19
+
20
+ CREATE INDEX IF NOT EXISTS idx_admin_refresh_tokens_admin ON admin_refresh_tokens(admin_id);
21
+ CREATE INDEX IF NOT EXISTS idx_admin_refresh_tokens_token ON admin_refresh_tokens(token);
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "edgebase-worker",
3
+ "version": "0.1.0",
4
+ "description": "EdgeBase Worker - Cloudflare Workers deployment (uses published npm packages)",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "dependencies": {
8
+ "@edgebasejs/worker": "0.1.12"
9
+ },
10
+ "devDependencies": {
11
+ "@cloudflare/workers-types": "^4.20240605.0",
12
+ "@edgebasejs/cli": "^0.9.1",
13
+ "@edgebasejs/types": "^0.1.12",
14
+ "@types/node": "^25.2.2",
15
+ "typescript": "^5.4.5",
16
+ "wrangler": "^3.28.0"
17
+ },
18
+ "scripts": {
19
+ "dev": "npm run dev:worker",
20
+ "dev:worker": "wrangler dev --ip 0.0.0.0",
21
+ "build": "edgebase build",
22
+ "type-check": "../../node_modules/.bin/tsc --noEmit",
23
+ "deploy": "npm run build && wrangler deploy"
24
+ }
25
+ }
package/src/index.ts ADDED
@@ -0,0 +1,18 @@
1
+ import { createEdgeBaseWorker } from '@edgebasejs/worker';
2
+ import schema from '../edgebase.schema';
3
+
4
+ const app = createEdgeBaseWorker({
5
+ schema,
6
+ getDb: (c) => c.env.DB,
7
+ getJwtSecret: (c) => c.env.JWT_SECRET,
8
+ getEnvironment: (c) => c.env.ENVIRONMENT,
9
+ getR2Bucket: (c) => c.env.FILES,
10
+ apiVersion: '0.1.0',
11
+ // Auto-initialize database on first request (safe with CREATE TABLE IF NOT EXISTS)
12
+ autoInitialize: true,
13
+ // Admin Console disabled - RSC rendering not supported on Edge Runtime
14
+ // For admin features, deploy a separate instance or use external admin service
15
+ adminConsole: false,
16
+ });
17
+
18
+ export default app;
package/tsconfig.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "compilerOptions": {
3
+ "lib": ["ES2020"],
4
+ "target": "ES2020",
5
+ "outDir": "./dist",
6
+ "types": ["@cloudflare/workers-types", "node"],
7
+ "jsx": "react-jsx",
8
+ "skipLibCheck": true,
9
+ "skipDefaultLibCheck": true,
10
+ "noEmit": false,
11
+ "moduleResolution": "node",
12
+ "module": "ES2020",
13
+ "declaration": false,
14
+ "baseUrl": ".",
15
+ "paths": {
16
+ "@edgebasejs/types": ["../../packages/shared-types/src"]
17
+ }
18
+ },
19
+ "include": ["src"],
20
+ "exclude": ["node_modules", "dist", "edgebase.schema.ts"]
21
+ }
package/wrangler.toml ADDED
@@ -0,0 +1,38 @@
1
+ name = "edgebase-worker"
2
+ main = "src/index.ts"
3
+ compatibility_date = "2024-09-23"
4
+ compatibility_flags = ["nodejs_compat"]
5
+
6
+ # Default environment (development/local)
7
+ [[d1_databases]]
8
+ binding = "DB"
9
+ database_name = "edgebase"
10
+ database_id = "2ddd0305-d96d-48ad-84bd-5d7697c33728"
11
+
12
+ [[r2_buckets]]
13
+ binding = "FILES"
14
+ bucket_name = "edgebase-files"
15
+ preview_bucket_name = "edgebase-files-preview"
16
+
17
+ [vars]
18
+ JWT_SECRET = "dev-secret-change-in-production"
19
+ ENVIRONMENT = "development"
20
+
21
+ # Production environment
22
+ [env.production]
23
+ [[env.production.d1_databases]]
24
+ binding = "DB"
25
+ database_name = "edgebase"
26
+ database_id = "2ddd0305-d96d-48ad-84bd-5d7697c33728"
27
+
28
+ [[env.production.r2_buckets]]
29
+ binding = "FILES"
30
+ bucket_name = "edgebase-files"
31
+
32
+ [env.production.vars]
33
+ JWT_SECRET = "2db53d655ad743e29574e8d1912440afbaacf0651fb002e0676dfc490f23a968"
34
+ ENVIRONMENT = "production"
35
+
36
+ [[env.production.routes]]
37
+ pattern = "backend.edgebase.tandamo.com"
38
+ custom_domain = true