@e-techsolutions/e-baas-sdk 1.0.6 → 1.0.8

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 CHANGED
@@ -1,23 +1,103 @@
1
1
  # E-BaaS SDK
2
2
 
3
- The official TypeScript SDK for E-BaaS (Enterprise Backend as a Service) - A comprehensive backend-as-a-service platform similar to Supabase.
3
+ The official TypeScript SDK for E-BaaS (Enterprise Backend as a Service) - A comprehensive backend-as-a-service platform.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- npm install @e-techsolutions/e-baas-sdk
8
+ npm install @e-techsolutions/e-baas-sdk@latest
9
9
  # or
10
- yarn add @e-techsolutions/e-baas-sdk
10
+ yarn add @e-techsolutions/e-baas-sdk@latest
11
11
  ```
12
12
 
13
13
  ## Quick Start
14
14
 
15
15
  ```typescript
16
- import { createClient } from '@e-techsolutions/e-baas-sdk';
16
+ import { createClient } from "@e-techsolutions/e-baas-sdk";
17
17
 
18
- const ebaas = createClient('https://your-project.e-baas.apiservices.app.br', 'your-anon-key');
18
+ // Basic configuration (required)
19
+ const EBAAS_URL = process.env.EBAAS_API_URL; // required - https://your-api-e-baas-service
20
+ const EBAAS_KEY = process.env.EBAAS_API_KEY; // required - your API key
21
+ const WORKSPACE_ID = process.env.EBAAS_WORKSPACE_ID; // required - your workspace ID
22
+
23
+ export const ebaas = createClient(EBAAS_URL, EBAAS_KEY, {
24
+ // Database configuration (required)
25
+ database: {
26
+ workspaceId: WORKSPACE_ID, // required
27
+ autoDetectCustomDatabase: true, // optional (default: false)
28
+ },
29
+ // Other configurations are optional
30
+ });
31
+ ```
32
+
33
+ ### Complete Authentication Flow
34
+
35
+ ```typescript
36
+ // 1. User login
37
+ const { user, session, error } = await ebaas.auth.signIn({
38
+ email: "user@example.com",
39
+ password: "secure-password",
40
+ });
41
+
42
+ if (error) {
43
+ console.error("Login failed:", error);
44
+ return;
45
+ }
46
+
47
+ // 2. Configure session in SDK (REQUIRED!)
48
+ ebaas.auth.setSession(session);
49
+
50
+ // 3. Persist session (optional)
51
+ localStorage.setItem("ebaas_session", JSON.stringify(session));
52
+ localStorage.setItem("ebaas_user", JSON.stringify(user));
53
+
54
+ // 4. Now you can use database operations normally
55
+ const { data: users, error } = await ebaas.from("users").select("*");
56
+
57
+ if (error) {
58
+ console.error("Error fetching users:", error);
59
+ } else {
60
+ console.log("Users found:", users.length);
61
+ }
19
62
  ```
20
63
 
64
+ ### Session Restoration
65
+
66
+ ```typescript
67
+ // Restore session on app initialization
68
+ const restoreSession = () => {
69
+ const savedSession = localStorage.getItem("ebaas_session");
70
+ const savedUser = localStorage.getItem("ebaas_user");
71
+
72
+ if (savedSession && savedUser) {
73
+ const sessionData = JSON.parse(savedSession);
74
+
75
+ // Check if not expired
76
+ if (sessionData.expires_at > Date.now()) {
77
+ // Restore session in SDK
78
+ ebaas.auth.setSession(sessionData);
79
+ console.log("✅ Session restored automatically");
80
+ } else {
81
+ // Clear expired session
82
+ localStorage.removeItem("ebaas_session");
83
+ localStorage.removeItem("ebaas_user");
84
+ }
85
+ }
86
+ };
87
+ ```
88
+
89
+ ### Environment Variables
90
+
91
+ Create a `.env` file in your project root:
92
+
93
+ ```env
94
+ EBAAS_API_URL=https://your-api-e-baas-service
95
+ EBAAS_API_KEY=your-api-key-here
96
+ EBAAS_WORKSPACE_ID=your-workspace-id-here
97
+ ```
98
+
99
+ **Note**: This works with any bundler (Webpack, Vite, Next.js, etc.) that supports `process.env`.
100
+
21
101
  ## Features
22
102
 
23
103
  - **Authentication** - Email/password and OAuth providers (Google, GitHub, Facebook)
@@ -35,15 +115,15 @@ const ebaas = createClient('https://your-project.e-baas.apiservices.app.br', 'yo
35
115
  ```typescript
36
116
  // Sign up with email/password
37
117
  const { user, session, error } = await ebaas.auth.signUp({
38
- email: 'user@example.com',
39
- password: 'secure-password',
40
- name: 'John Doe'
118
+ email: "user@example.com",
119
+ password: "secure-password",
120
+ name: "John Doe",
41
121
  });
42
122
 
43
123
  // Sign in
44
124
  const { user, session, error } = await ebaas.auth.signIn({
45
- email: 'user@example.com',
46
- password: 'secure-password'
125
+ email: "user@example.com",
126
+ password: "secure-password",
47
127
  });
48
128
 
49
129
  // Get current user
@@ -53,41 +133,109 @@ const user = await ebaas.auth.getUser();
53
133
  await ebaas.auth.signOut();
54
134
  ```
55
135
 
136
+ **⚠️ IMPORTANT - Session Configuration:**
137
+
138
+ After login, you **MUST** configure the session in the SDK for all subsequent operations to work correctly:
139
+
140
+ ```typescript
141
+ // Complete authentication flow
142
+ const loginUser = async () => {
143
+ // 1. Perform login
144
+ const { user, session, error } = await ebaas.auth.signIn({
145
+ email: "user@example.com",
146
+ password: "secure-password",
147
+ });
148
+
149
+ if (error) {
150
+ console.error("Login failed:", error);
151
+ return;
152
+ }
153
+
154
+ // 2. Configure session in SDK (MANDATORY STEP!)
155
+ ebaas.auth.setSession(session);
156
+
157
+ // 3. Persist session in localStorage (optional)
158
+ localStorage.setItem("ebaas_session", JSON.stringify(session));
159
+ localStorage.setItem("ebaas_user", JSON.stringify(user));
160
+
161
+ console.log("✅ Login and session configuration completed");
162
+ };
163
+
164
+ // Restore session on application initialization
165
+ const restoreSession = () => {
166
+ const savedSession = localStorage.getItem("ebaas_session");
167
+ const savedUser = localStorage.getItem("ebaas_user");
168
+
169
+ if (savedSession && savedUser) {
170
+ const sessionData = JSON.parse(savedSession);
171
+
172
+ // Check if not expired
173
+ if (sessionData.expires_at > Date.now()) {
174
+ // Restore session in SDK
175
+ ebaas.auth.setSession(sessionData);
176
+ console.log("✅ Session restored automatically");
177
+ } else {
178
+ // Clear expired session
179
+ localStorage.removeItem("ebaas_session");
180
+ localStorage.removeItem("ebaas_user");
181
+ }
182
+ }
183
+ };
184
+ ```
185
+
56
186
  ### Database Operations
57
187
 
58
188
  ```typescript
59
189
  // Select data
190
+ const { data: users, error } = await ebaas.from("users").select("*");
191
+
192
+ if (error) {
193
+ console.error("Error fetching users:", error);
194
+ } else {
195
+ console.log("Users found:", users.length);
196
+ }
197
+
198
+ // Select specific fields for better performance
60
199
  const { data, error } = await ebaas
61
- .from('users')
62
- .select('id, name, email')
63
- .eq('status', 'active')
64
- .order('created_at', { ascending: false })
65
- .limit(10)
66
- .execute();
200
+ .from("users")
201
+ .select("id, name, email")
202
+ .eq("status", "active")
203
+ .order("created_at", { ascending: false })
204
+ .limit(10);
67
205
 
68
206
  // Insert data
69
- const { data, error } = await ebaas
70
- .from('users')
71
- .insert([
72
- { name: 'John Doe', email: 'john@example.com' },
73
- { name: 'Jane Smith', email: 'jane@example.com' }
74
- ]);
207
+ const { data: newUser, error: insertError } = await ebaas.from("users").insert({
208
+ name: "John Doe",
209
+ email: "john@example.com",
210
+ });
211
+
212
+ if (insertError) {
213
+ console.error("Error creating user:", insertError);
214
+ } else {
215
+ console.log("User created successfully:", newUser);
216
+ }
75
217
 
76
218
  // Update data
77
- const { data, error } = await ebaas
78
- .from('users')
79
- .update({ status: 'inactive' })
80
- .eq('id', 123);
219
+ const { data: updated, error: updateError } = await ebaas.from("users").update({ name: "John Smith" }).eq("id", 123);
220
+
221
+ if (updateError) {
222
+ console.error("Error updating user:", updateError);
223
+ } else {
224
+ console.log("User updated successfully:", updated);
225
+ }
81
226
 
82
227
  // Delete data
83
- const { data, error } = await ebaas
84
- .from('users')
85
- .delete()
86
- .eq('status', 'inactive');
228
+ const { data, error } = await ebaas.from("users").delete().eq("id", 123);
229
+
230
+ if (error) {
231
+ console.error("Error deleting user:", error);
232
+ } else {
233
+ console.log("User deleted successfully");
234
+ }
87
235
 
88
236
  // RPC (stored procedures)
89
- const { data, error } = await ebaas.rpc('get_user_stats', {
90
- user_id: 123
237
+ const { data, error } = await ebaas.rpc("get_user_stats", {
238
+ user_id: 123,
91
239
  });
92
240
  ```
93
241
 
@@ -95,104 +243,68 @@ const { data, error } = await ebaas.rpc('get_user_stats', {
95
243
 
96
244
  ```typescript
97
245
  // Configure with automatic custom database detection
98
- const ebaas = createClient(url, key, {
246
+ const ebaas = createClient(EBAAS_URL, EBAAS_KEY, {
99
247
  database: {
100
- workspaceId: 'your-workspace-id',
101
- autoDetectCustomDatabase: true
102
- }
248
+ workspaceId: WORKSPACE_ID,
249
+ autoDetectCustomDatabase: true, // Enable custom database auto-detection
250
+ },
103
251
  });
104
-
105
- // Configure custom database credentials
106
- const credentials = {
107
- host: 'your-postgres-host.com',
108
- port: 5432,
109
- database: 'your_custom_db',
110
- username: 'db_user',
111
- password: 'db_password',
112
- schema: 'custom_schema',
113
- sslEnabled: true
114
- };
115
-
116
- // Test connection
117
- const testResult = await ebaas.database.testCustomConnection(credentials);
118
- if (testResult.success) {
119
- await ebaas.database.configureCustomDatabase(credentials);
120
- }
121
-
122
- // Check status
123
- const status = ebaas.getCustomDatabaseStatus();
124
- console.log('Using custom database:', status.hasConfig);
125
-
126
- // Use with different schema
127
- const data = await ebaas.database
128
- .schema('custom_schema')
129
- .from('users')
130
- .select('*');
131
252
  ```
132
253
 
133
- For detailed information about custom database features, see [Custom Database Guide](./CUSTOM_DATABASE_GUIDE.md).
134
-
135
254
  ### Storage
136
255
 
137
256
  ```typescript
138
257
  // Upload file
139
- const { data, error } = await ebaas.storage
140
- .from('avatars')
141
- .upload('user-123.jpg', file, {
142
- cacheControl: '3600',
143
- upsert: true
144
- });
258
+ const { data, error } = await ebaas.storage.from("avatars").upload("user-123.jpg", file, {
259
+ cacheControl: "3600",
260
+ upsert: true,
261
+ });
145
262
 
146
263
  // Download file
147
- const { data, error } = await ebaas.storage
148
- .from('avatars')
149
- .download('user-123.jpg');
264
+ const { data, error } = await ebaas.storage.from("avatars").download("user-123.jpg");
150
265
 
151
266
  // Get public URL
152
- const { data } = ebaas.storage
153
- .from('avatars')
154
- .getPublicUrl('user-123.jpg');
267
+ const { data } = ebaas.storage.from("avatars").getPublicUrl("user-123.jpg");
155
268
 
156
269
  // Get signed URL (for private files)
157
- const { data, error } = await ebaas.storage
158
- .from('private-docs')
159
- .createSignedUrl('document.pdf', 60); // 60 seconds
270
+ const { data, error } = await ebaas.storage.from("private-docs").createSignedUrl("document.pdf", 60); // 60 seconds
160
271
 
161
272
  // List files
162
- const { data, error } = await ebaas.storage
163
- .from('avatars')
164
- .list('', {
165
- limit: 100,
166
- offset: 0,
167
- sortBy: { column: 'name', order: 'asc' }
168
- });
273
+ const { data, error } = await ebaas.storage.from("avatars").list("", {
274
+ limit: 100,
275
+ offset: 0,
276
+ sortBy: { column: "name", order: "asc" },
277
+ });
169
278
  ```
170
279
 
171
280
  ### Realtime Subscriptions
172
281
 
173
282
  ```typescript
174
283
  // Subscribe to database changes
175
- const channel = ebaas.channel('realtime:users');
176
-
177
- channel.onPostgresChanges({
178
- event: '*', // INSERT, UPDATE, DELETE, or *
179
- schema: 'public',
180
- table: 'users'
181
- }, (payload) => {
182
- console.log('Change received!', payload);
183
- });
284
+ const channel = ebaas.channel("realtime:users");
285
+
286
+ channel.onPostgresChanges(
287
+ {
288
+ event: "*", // INSERT, UPDATE, DELETE, or *
289
+ schema: "public",
290
+ table: "users",
291
+ },
292
+ (payload) => {
293
+ console.log("Change received!", payload);
294
+ }
295
+ );
184
296
 
185
297
  channel.subscribe();
186
298
 
187
299
  // Broadcast messages
188
300
  channel.send({
189
- type: 'broadcast',
190
- event: 'message',
191
- payload: { text: 'Hello World!' }
301
+ type: "broadcast",
302
+ event: "message",
303
+ payload: { text: "Hello World!" },
192
304
  });
193
305
 
194
306
  // Presence tracking
195
- channel.track({ user_id: 123, status: 'online' });
307
+ channel.track({ user_id: 123, status: "online" });
196
308
 
197
309
  // Unsubscribe
198
310
  channel.unsubscribe();
@@ -203,100 +315,120 @@ channel.unsubscribe();
203
315
  #### Client-side Function Invocation
204
316
 
205
317
  ```typescript
206
- // Invoke function from client
207
- const { data, error } = await ebaas.functions.invoke('hello-world', {
208
- body: { name: 'John' },
209
- headers: { 'Content-Type': 'application/json' }
318
+ // Invoke authenticated function (requires session)
319
+ const { data, error } = await ebaas.functions.invoke("hello-world", {
320
+ body: { name: "John" },
321
+ headers: { "Content-Type": "application/json" },
322
+ });
323
+
324
+ // Invoke public function (no authentication required)
325
+ const response = await fetch("https://your-api-domain.com/functions/v1/public/hello-world", {
326
+ method: "POST",
327
+ headers: { "Content-Type": "application/json" },
328
+ body: JSON.stringify({ name: "John" }),
210
329
  });
330
+ const data = await response.json();
211
331
 
212
332
  // List functions
213
333
  const { data, error } = await ebaas.functions.list();
214
334
 
215
335
  // Get function details
216
- const { data, error } = await ebaas.functions.get('hello-world');
336
+ const { data, error } = await ebaas.functions.get("hello-world");
217
337
  ```
218
338
 
219
339
  #### Native SDK Integration in Edge Functions
220
340
 
221
- **NEW in v1.0.1+**: The SDK is now natively available within Edge Functions:
341
+ The SDK is natively available within Edge Functions with global methods:
222
342
 
223
343
  ```typescript
224
- // Edge Function example with native SDK access
225
- const { method, url } = req;
226
-
227
- if (method === 'POST') {
228
- const body = await req.json();
229
-
230
- // Native database access - no imports needed!
231
- const users = await from('users').select('*').limit(10);
232
-
233
- // Native storage access
234
- const bucket = bucket('uploads');
235
- await bucket.upload('file.jpg', body.fileData);
236
-
237
- // Native realtime notifications
238
- await channel('notifications').send('user_created', {
239
- user: body.userData
240
- });
241
-
242
- // Call other edge functions
243
- const result = await invoke('send-email', {
244
- body: { email: body.email }
245
- });
246
-
247
- return createResponse({ success: true, users, result });
248
- }
344
+ // Edge Function with native SDK access
345
+ const users = await from("users").select("*").limit(10);
346
+ const bucket = bucket("uploads");
347
+ await channel("notifications").send("user_created", { user: userData });
348
+ return createResponse({ success: true, users });
249
349
  ```
250
350
 
251
- #### Available Globals in Edge Functions
252
-
253
- - `from(table)` - Database table access
254
- - `rpc(function, args)` - RPC calls
255
- - `bucket(name)` - Storage bucket access
256
- - `channel(name)` - Realtime channel access
257
- - `invoke(functionName, options)` - Function orchestration
258
- - `ebaas.*` - Full SDK object access
259
- - `env.*` - Environment variables
260
- - `context.*` - Function execution context
351
+ **Available globals**: `from()`, `rpc()`, `bucket()`, `channel()`, `invoke()`, `ebaas.*`
261
352
 
262
353
  ## Advanced Configuration
263
354
 
264
355
  ```typescript
265
- const ebaas = createClient('https://your-project.e-baas.io', 'your-anon-key', {
266
- auth: {
267
- autoRefreshToken: true,
268
- persistSession: true,
269
- detectSessionInUrl: true
270
- },
271
- realtime: {
272
- params: {
273
- eventsPerSecond: 10
274
- }
275
- },
276
- global: {
277
- headers: {
278
- 'x-custom-header': 'custom-value'
279
- }
356
+ const ebaas = createClient(
357
+ "https://your-api-domain.com", // required - API URL
358
+ "your-api-key", // required - API Key
359
+ {
360
+ // Database configuration (required)
361
+ database: {
362
+ workspaceId: "your-workspace-id", // required - Workspace ID
363
+ autoDetectCustomDatabase: true, // optional (default: false)
364
+ },
365
+ // Authentication configuration (optional)
366
+ auth: {
367
+ autoRefreshToken: true, // optional (default: true)
368
+ persistSession: true, // optional (default: true)
369
+ detectSessionInUrl: true, // optional (default: true)
370
+ },
371
+ // Realtime configuration (optional)
372
+ realtime: {
373
+ params: {
374
+ eventsPerSecond: 10, // optional (default: 10)
375
+ },
376
+ },
377
+ // Global configuration (optional)
378
+ global: {
379
+ headers: {
380
+ "x-custom-header": "custom-value", // optional - custom headers
381
+ },
382
+ },
280
383
  }
281
- });
384
+ );
282
385
  ```
283
386
 
284
387
  ## Error Handling
285
388
 
286
389
  ```typescript
287
- import { EBaaSError } from '@e-techsolutions/e-baas-sdk';
390
+ import { EBaaSError } from "@e-techsolutions/e-baas-sdk";
288
391
 
289
392
  try {
290
- const { data } = await ebaas.from('users').select('*').execute();
393
+ const { data } = await ebaas.from("users").select("*");
291
394
  } catch (error) {
292
395
  if (error instanceof EBaaSError) {
293
- console.error('E-BaaS Error:', error.message);
294
- console.error('Status:', error.status);
295
- console.error('Details:', error.details);
396
+ console.error("E-BaaS Error:", error.message);
397
+ console.error("Status:", error.status);
398
+ console.error("Details:", error.details);
296
399
  }
297
400
  }
298
401
  ```
299
402
 
403
+ ## Secure DELETE Operations
404
+
405
+ ### Security Validation
406
+
407
+ E-BaaS implements strict validation for DELETE and UPDATE operations, requiring **at least one filter** to prevent accidental mass deletions:
408
+
409
+ ```typescript
410
+ // ✅ CORRECT: DELETE with specific filter
411
+ const { data, error } = await ebaas.from("users").delete().eq("id", 123);
412
+
413
+ // ❌ ERROR: DELETE without filters (returns "Security violation")
414
+ const { data, error } = await ebaas.from("users").delete(); // Fails with security error
415
+ ```
416
+
417
+ ### Secure DELETE Operations with Required Filters
418
+
419
+ Always use the SDK with proper filters for safe DELETE operations:
420
+
421
+ ```typescript
422
+ // DELETE using SDK with required filter
423
+ const { data, error } = await ebaas.from("users").delete().eq("id", userId);
424
+
425
+ if (error) {
426
+ console.error("Error deleting user:", error);
427
+ } else {
428
+ console.log("User deleted successfully");
429
+ }
430
+ ```
431
+
300
432
  ## TypeScript Support
301
433
 
302
434
  The SDK is built with TypeScript and provides full type safety:
@@ -309,82 +441,15 @@ interface User {
309
441
  created_at: string;
310
442
  }
311
443
 
312
- const { data, error } = await ebaas
313
- .from<User>('users')
314
- .select('*')
315
- .execute();
444
+ const { data, error } = await ebaas.from<User>("users").select("*");
316
445
 
317
446
  // data is now typed as User[] | null
318
447
  ```
319
448
 
320
449
  ## Edge Functions Runtime Support
321
450
 
322
- **NEW in v1.0.1+**: Enhanced Edge Functions with dual runtime support:
323
-
324
- ### Runtime Options
325
- - **Node.js VM** (Default) - Docker/K3s friendly, isolated-vm execution
326
- - **Deno** (Optional) - TypeScript-first runtime with Web APIs
327
-
328
- ### Features
329
- - **Native SDK Integration** - Full platform access within functions
330
- - **Auto-detected Runtime** - Automatically chooses Node.js in Docker environments
331
- - **Secure Execution** - Isolated VM with memory and timeout limits
332
- - **Function Orchestration** - Functions can call other functions
333
- - **Supabase-compatible API** - Same developer experience as Supabase Edge Functions
334
-
335
- ### Example Edge Function
336
-
337
- ```typescript
338
- // my-function.ts
339
- const { method, url } = req;
340
-
341
- // CORS handling
342
- if (method === 'OPTIONS') {
343
- return corsResponse(createResponse(null, { status: 200 }));
344
- }
345
-
346
- try {
347
- // Database operations
348
- const users = await from('users').select('name, email').limit(5);
349
-
350
- // Storage operations
351
- const files = await bucket('uploads').list('public/');
352
-
353
- // Realtime notifications
354
- await channel('notifications').send('function_executed', {
355
- timestamp: new Date().toISOString(),
356
- userCount: users.data?.length || 0
357
- });
358
-
359
- // Function orchestration
360
- const emailResult = await invoke('send-notification', {
361
- body: { message: 'Function executed successfully' }
362
- });
363
-
364
- return createResponse({
365
- success: true,
366
- users: users.data,
367
- files: files.data,
368
- emailSent: emailResult.data
369
- });
370
-
371
- } catch (error) {
372
- console.error('Function error:', error);
373
- return createResponse({ error: error.message }, { status: 500 });
374
- }
375
- ```
376
-
377
- ## Changelog
378
-
379
- ### v1.0.1 (2024-06-24)
380
- - 🚀 **NEW**: Native SDK integration in Edge Functions
381
- - 🚀 **NEW**: Dual runtime support (Node.js VM + Deno)
382
- - 🚀 **NEW**: Auto-runtime detection for Docker environments
383
- - 🚀 **NEW**: Global SDK methods in Edge Functions
384
- - 🚀 **NEW**: Function orchestration capabilities
385
- - 🔧 Enhanced security with isolated VM execution
386
- - 🔧 Improved Docker/K3s compatibility
451
+ Enhanced Edge Functions with dual runtime support (Node.js VM + Deno) and native SDK integration.
387
452
 
388
453
  ## License
389
454
 
390
- MIT
455
+ MIT