@xano/developer-mcp 1.0.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/LICENSE +21 -0
- package/README.md +261 -0
- package/api_docs/addon.md +193 -0
- package/api_docs/agent.md +154 -0
- package/api_docs/api_group.md +236 -0
- package/api_docs/authentication.md +68 -0
- package/api_docs/file.md +190 -0
- package/api_docs/function.md +217 -0
- package/api_docs/history.md +263 -0
- package/api_docs/index.md +104 -0
- package/api_docs/mcp_server.md +139 -0
- package/api_docs/middleware.md +205 -0
- package/api_docs/realtime.md +153 -0
- package/api_docs/table.md +151 -0
- package/api_docs/task.md +191 -0
- package/api_docs/tool.md +216 -0
- package/api_docs/triggers.md +344 -0
- package/api_docs/workspace.md +246 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +495 -0
- package/package.json +49 -0
- package/xanoscript_docs/README.md +1 -0
- package/xanoscript_docs/api_query_examples.md +1255 -0
- package/xanoscript_docs/api_query_guideline.md +129 -0
- package/xanoscript_docs/build_from_lovable.md +715 -0
- package/xanoscript_docs/db_query_guideline.md +427 -0
- package/xanoscript_docs/ephemeral_environment_guideline.md +529 -0
- package/xanoscript_docs/expression_guideline.md +1086 -0
- package/xanoscript_docs/frontend_guideline.md +67 -0
- package/xanoscript_docs/function_examples.md +1406 -0
- package/xanoscript_docs/function_guideline.md +130 -0
- package/xanoscript_docs/functions.md +2155 -0
- package/xanoscript_docs/input_guideline.md +227 -0
- package/xanoscript_docs/mcp_server_examples.md +36 -0
- package/xanoscript_docs/mcp_server_guideline.md +69 -0
- package/xanoscript_docs/query_filter.md +489 -0
- package/xanoscript_docs/table_examples.md +586 -0
- package/xanoscript_docs/table_guideline.md +137 -0
- package/xanoscript_docs/task_examples.md +511 -0
- package/xanoscript_docs/task_guideline.md +103 -0
- package/xanoscript_docs/tips_and_tricks.md +144 -0
- package/xanoscript_docs/tool_examples.md +69 -0
- package/xanoscript_docs/tool_guideline.md +139 -0
- package/xanoscript_docs/unit_testing_guideline.md +328 -0
- package/xanoscript_docs/version.json +3 -0
- package/xanoscript_docs/workspace.md +17 -0
|
@@ -0,0 +1,715 @@
|
|
|
1
|
+
## Using Xano with Lovable Projects (Agent Instructions)
|
|
2
|
+
|
|
3
|
+
Goal: Migrate a Lovable-generated project from Supabase to Xano using the SDK, while keeping the frontend behavior equivalent. Follow the steps in order. Use the listed tools where marked REQUIRED.
|
|
4
|
+
|
|
5
|
+
References:
|
|
6
|
+
|
|
7
|
+
- Tables: `table_guideline.md`, `table_examples.md`
|
|
8
|
+
- Functions: `function_guideline.md`, `function_examples.md`
|
|
9
|
+
- APIs: `api_query_guideline.md`, `api_query_examples.md`
|
|
10
|
+
- DB Queries: `db_query_guideline.md`
|
|
11
|
+
- Tips: `tips_and_tricks.md`
|
|
12
|
+
|
|
13
|
+
Tools you may need:
|
|
14
|
+
|
|
15
|
+
- REQUIRED during frontend work: `get_xano_api_specifications`
|
|
16
|
+
- REQUIRED when syncing backend: `push_all_changes_to_xano`
|
|
17
|
+
- Optional for safe experiments: `publish_ephemeral_environment`
|
|
18
|
+
|
|
19
|
+
### 1. Install the Adapter
|
|
20
|
+
|
|
21
|
+
In your Lovable project directory:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @xano/supabase-compat
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### 2. Create Xano Client
|
|
28
|
+
|
|
29
|
+
Create `src/integrations/xano/client.ts`:
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { createClient } from "@xano/supabase-compat";
|
|
33
|
+
|
|
34
|
+
export const xano = createClient(
|
|
35
|
+
import.meta.env.VITE_XANO_URL,
|
|
36
|
+
import.meta.env.VITE_XANO_AUTH_ENDPOINT, // e.g., '/api:qoUCtLER/auth'
|
|
37
|
+
{
|
|
38
|
+
auth: {
|
|
39
|
+
storage: localStorage,
|
|
40
|
+
persistSession: true,
|
|
41
|
+
autoRefreshToken: true,
|
|
42
|
+
},
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
How to find your auth endpoint:
|
|
48
|
+
|
|
49
|
+
1. In Xano, go to your Authentication API group
|
|
50
|
+
2. Look at any auth endpoint (login, signup, me)
|
|
51
|
+
3. The path will be like `/api:qoUCtLER/auth/login` or `/api:qoUCtLER/auth/signup` or `/api:qoUCtLER/auth/me`
|
|
52
|
+
4. Your auth endpoint is `/api:qoUCtLER/auth` (everything before `/login`, make sure you include the `/auth` part)
|
|
53
|
+
|
|
54
|
+
### 3. Update Environment Variables
|
|
55
|
+
|
|
56
|
+
In your `.env` file:
|
|
57
|
+
|
|
58
|
+
```env
|
|
59
|
+
# Add these
|
|
60
|
+
VITE_XANO_URL=https://your-instance.xano.io
|
|
61
|
+
VITE_XANO_AUTH_ENDPOINT=/api:qoUCtLER/auth # Replace qoUCtLER with your API group ID
|
|
62
|
+
|
|
63
|
+
# Keep Supabase vars during migration (optional)
|
|
64
|
+
# VITE_SUPABASE_URL=...
|
|
65
|
+
# VITE_SUPABASE_PUBLISHABLE_KEY=...
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 4. Update useAuth Hook
|
|
69
|
+
|
|
70
|
+
Before (`src/hooks/useAuth.ts`):
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import { supabase } from "@/integrations/supabase/client";
|
|
74
|
+
|
|
75
|
+
export function useAuth() {
|
|
76
|
+
// ... rest of the code
|
|
77
|
+
supabase.auth.onAuthStateChange(...)
|
|
78
|
+
supabase.auth.getSession()
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
After:
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
import { xano } from "@/integrations/xano/client";
|
|
86
|
+
|
|
87
|
+
export function useAuth() {
|
|
88
|
+
// ... exact same code!
|
|
89
|
+
xano.auth.onAuthStateChange(...)
|
|
90
|
+
xano.auth.getSession()
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### 5. Update Data Hooks
|
|
95
|
+
|
|
96
|
+
This is where you'll need to map Supabase table queries to Xano endpoints.
|
|
97
|
+
|
|
98
|
+
Before (`src/hooks/useChores.ts`):
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
import { supabase } from "@/integrations/supabase/client";
|
|
102
|
+
|
|
103
|
+
const loadData = async () => {
|
|
104
|
+
const { data: choresData, error } = await supabase
|
|
105
|
+
.from("chores")
|
|
106
|
+
.select("*")
|
|
107
|
+
.eq("user_id", user.id)
|
|
108
|
+
.order("created_at", { ascending: false });
|
|
109
|
+
};
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
After:
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
import { xano } from "@/integrations/xano/client";
|
|
116
|
+
|
|
117
|
+
const loadData = async () => {
|
|
118
|
+
const { data: choresData, error } = await xano
|
|
119
|
+
.endpoint("/api:your-api/chores")
|
|
120
|
+
.get({
|
|
121
|
+
user_id: user.id,
|
|
122
|
+
sort: "created_at",
|
|
123
|
+
order: "desc",
|
|
124
|
+
});
|
|
125
|
+
};
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### 6. Update Components
|
|
129
|
+
|
|
130
|
+
AuthForm.tsx — Minimal changes:
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
// Before
|
|
134
|
+
import { supabase } from "@/integrations/supabase/client";
|
|
135
|
+
|
|
136
|
+
const { error } = await supabase.auth.signUp({
|
|
137
|
+
email,
|
|
138
|
+
password,
|
|
139
|
+
options: { data: { display_name: displayName } },
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// After
|
|
143
|
+
import { xano } from "@/integrations/xano/client";
|
|
144
|
+
|
|
145
|
+
const { error } = await xano.auth.signUp({
|
|
146
|
+
email,
|
|
147
|
+
password,
|
|
148
|
+
options: { data: { display_name: displayName } },
|
|
149
|
+
});
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Backend Work in Xano (Tables + Endpoints)
|
|
153
|
+
|
|
154
|
+
Follow this section before or alongside the frontend changes.
|
|
155
|
+
|
|
156
|
+
1. Extract schema from the Lovable project (if available)
|
|
157
|
+
|
|
158
|
+
- If the project has Supabase types (e.g., `static/src/integrations/supabase/types.ts`), list tables, fields, and relationships.
|
|
159
|
+
- Use `int` for primary keys; Xano does not support string primary keys.
|
|
160
|
+
- Avoid creating cross-table references until all base tables exist; add relationships after tables are created.
|
|
161
|
+
|
|
162
|
+
2. Create or edit Xano Tables
|
|
163
|
+
|
|
164
|
+
- Create tables as per extracted schema (see table guidelines).
|
|
165
|
+
|
|
166
|
+
3. Create Xano Endpoints
|
|
167
|
+
|
|
168
|
+
- Create CRUD endpoints that match your required frontend operations (see API guidelines).
|
|
169
|
+
- Implement filtering/sorting/pagination via inputs as needed.
|
|
170
|
+
|
|
171
|
+
4. REQUIRED — Push backend changes to Xano
|
|
172
|
+
|
|
173
|
+
- Invoke `push_all_changes_to_xano` to ensure backend is in sync before frontend work.
|
|
174
|
+
|
|
175
|
+
For each Supabase table operation, create a corresponding Xano endpoint:
|
|
176
|
+
|
|
177
|
+
### Example: Chores CRUD
|
|
178
|
+
|
|
179
|
+
1. List Chores (`GET /api:xxx/chores`)
|
|
180
|
+
|
|
181
|
+
```
|
|
182
|
+
Inputs:
|
|
183
|
+
- user_id (number)
|
|
184
|
+
- sort (text, optional)
|
|
185
|
+
- order (text, optional)
|
|
186
|
+
|
|
187
|
+
Function:
|
|
188
|
+
- Query chores table
|
|
189
|
+
- Filter by user_id
|
|
190
|
+
- Order by sort field
|
|
191
|
+
- Return results
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
2. Create Chore (`POST /api:xxx/chores`)
|
|
195
|
+
|
|
196
|
+
```
|
|
197
|
+
Inputs:
|
|
198
|
+
- title (text)
|
|
199
|
+
- description (text)
|
|
200
|
+
- points (number)
|
|
201
|
+
- user_id (number)
|
|
202
|
+
|
|
203
|
+
Function:
|
|
204
|
+
- Insert into chores table
|
|
205
|
+
- Return created record
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
3. Update Chore (`PATCH /api:xxx/chores/{chore_id}`)
|
|
209
|
+
|
|
210
|
+
```
|
|
211
|
+
Inputs:
|
|
212
|
+
- chore_id (number, from path)
|
|
213
|
+
- completed (boolean)
|
|
214
|
+
- completed_at (datetime)
|
|
215
|
+
|
|
216
|
+
Function:
|
|
217
|
+
- Update chore record
|
|
218
|
+
- Return updated record
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
4. Delete Chore (`DELETE /api:xxx/chores/{chore_id}`)
|
|
222
|
+
|
|
223
|
+
```
|
|
224
|
+
Inputs:
|
|
225
|
+
- chore_id (number, from path)
|
|
226
|
+
|
|
227
|
+
Function:
|
|
228
|
+
- Delete from chores table
|
|
229
|
+
- Return success message
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Frontend Work (SDK + Mapping)
|
|
233
|
+
|
|
234
|
+
Before modifying frontend calls, perform this step:
|
|
235
|
+
|
|
236
|
+
- REQUIRED — Pull current API specs from Xano
|
|
237
|
+
- Invoke `get_xano_api_specifications` to retrieve latest endpoints, groups, and base URLs.
|
|
238
|
+
- Use the returned auth API group path for `VITE_XANO_AUTH_ENDPOINT`.
|
|
239
|
+
|
|
240
|
+
Then implement the SDK client, update `useAuth` import, and map data hooks to the Xano endpoints you created.
|
|
241
|
+
|
|
242
|
+
## Migration Checklist (Agent)
|
|
243
|
+
|
|
244
|
+
- [ ] Install `@xano/supabase-compat`
|
|
245
|
+
- [ ] Create Xano account and workspace
|
|
246
|
+
- [ ] Set up authentication in Xano (signup, login, me endpoints)
|
|
247
|
+
- [ ] Create database tables in Xano
|
|
248
|
+
- [ ] Create CRUD endpoints for each resource
|
|
249
|
+
- [ ] Create `src/integrations/xano/client.ts`
|
|
250
|
+
- [ ] Update `.env` with `VITE_XANO_URL`
|
|
251
|
+
- [ ] REQUIRED: Invoke `push_all_changes_to_xano` after backend edits
|
|
252
|
+
- [ ] REQUIRED: Invoke `get_xano_api_specifications` before frontend edits
|
|
253
|
+
- [ ] Update `useAuth` hook (change import)
|
|
254
|
+
- [ ] Update data hooks (map tables to endpoints)
|
|
255
|
+
- [ ] Update components (change imports)
|
|
256
|
+
- [ ] Test authentication flow
|
|
257
|
+
- [ ] Test all CRUD operations
|
|
258
|
+
- [ ] Remove Supabase dependencies (optional)
|
|
259
|
+
|
|
260
|
+
## Common Patterns
|
|
261
|
+
|
|
262
|
+
### Pagination
|
|
263
|
+
|
|
264
|
+
Lovable/Supabase:
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
.from('chores')
|
|
268
|
+
.select('*')
|
|
269
|
+
.range(0, 9)
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Xano:
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
.endpoint('/api:xxx/chores')
|
|
276
|
+
.get({ page: 1, per_page: 10 })
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Filtering
|
|
280
|
+
|
|
281
|
+
Lovable/Supabase:
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
.from('chores')
|
|
285
|
+
.select('*')
|
|
286
|
+
.eq('user_id', userId)
|
|
287
|
+
.eq('completed', false)
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
Xano:
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
.endpoint('/api:xxx/chores')
|
|
294
|
+
.get({
|
|
295
|
+
user_id: userId,
|
|
296
|
+
completed: false
|
|
297
|
+
})
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### Insert
|
|
301
|
+
|
|
302
|
+
Lovable/Supabase:
|
|
303
|
+
|
|
304
|
+
```typescript
|
|
305
|
+
.from('chores')
|
|
306
|
+
.insert({ title, points, user_id })
|
|
307
|
+
.select()
|
|
308
|
+
.single()
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Xano:
|
|
312
|
+
|
|
313
|
+
```typescript
|
|
314
|
+
.endpoint('/api:xxx/chores')
|
|
315
|
+
.post({ title, points, user_id })
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
## Tips (Agent)
|
|
319
|
+
|
|
320
|
+
1. Start with Auth: Get authentication working first — it's nearly identical!
|
|
321
|
+
2. One Resource at a Time: Migrate one data resource at a time
|
|
322
|
+
3. Keep Supabase During Migration: You can use both simultaneously
|
|
323
|
+
4. Test Thoroughly: Test each endpoint as you create it in Xano
|
|
324
|
+
5. Look for and convert all edge functions or custom queries into Xano queries (check the `static/supabase/functions` folder if available)
|
|
325
|
+
6. Optional: Use `run_xano_function` to test functions directly from VSCode within your Xano workspace context.
|
|
326
|
+
|
|
327
|
+
## Example: Complete Lovable Migration
|
|
328
|
+
|
|
329
|
+
You'll find a series of examples in the `supabase-compat` package, under the `examples/` (`node_modules/@xano/supabase-compat/examples/`) directory demonstrating Lovable projects migrated to Xano.
|
|
330
|
+
|
|
331
|
+
## Need Help?
|
|
332
|
+
|
|
333
|
+
- Check the main README for API reference
|
|
334
|
+
- Review the migration guide for detailed steps
|
|
335
|
+
- See comparison docs for side-by-side code examples
|
|
336
|
+
- Open an issue on GitHub
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
# Migration Guide: Supabase to Xano
|
|
341
|
+
|
|
342
|
+
This guide helps you migrate from Supabase to Xano using the Xano SDK. Follow in order. Use REQUIRED tools where indicated.
|
|
343
|
+
|
|
344
|
+
## Overview
|
|
345
|
+
|
|
346
|
+
Architectural differences:
|
|
347
|
+
|
|
348
|
+
- Supabase: Direct database access via PostgREST (table-based)
|
|
349
|
+
- Xano: API endpoints with backend logic (endpoint-based)
|
|
350
|
+
|
|
351
|
+
## Step-by-Step Migration
|
|
352
|
+
|
|
353
|
+
### 1. Install the Xano SDK
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
npm install @xano/supabase-compat
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
Optional: If you want to remove Supabase dependencies:
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
npm uninstall @supabase/supabase-js
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### 2. Update Client Initialization
|
|
366
|
+
|
|
367
|
+
Before (Supabase):
|
|
368
|
+
|
|
369
|
+
```typescript
|
|
370
|
+
// src/integrations/supabase/client.ts
|
|
371
|
+
import { createClient } from "@supabase/supabase-js";
|
|
372
|
+
|
|
373
|
+
export const supabase = createClient(
|
|
374
|
+
process.env.VITE_SUPABASE_URL,
|
|
375
|
+
process.env.VITE_SUPABASE_PUBLISHABLE_KEY,
|
|
376
|
+
{
|
|
377
|
+
auth: {
|
|
378
|
+
storage: localStorage,
|
|
379
|
+
persistSession: true,
|
|
380
|
+
autoRefreshToken: true,
|
|
381
|
+
},
|
|
382
|
+
}
|
|
383
|
+
);
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
After (Xano):
|
|
387
|
+
|
|
388
|
+
```typescript
|
|
389
|
+
// src/integrations/xano/client.ts
|
|
390
|
+
import { createClient } from "@xano/supabase-compat";
|
|
391
|
+
|
|
392
|
+
export const xano = createClient(
|
|
393
|
+
process.env.VITE_XANO_URL, // e.g., 'https://x62j-rlqn-vpsk.dev.xano.io'
|
|
394
|
+
process.env.VITE_XANO_AUTH_ENDPOINT, // e.g., '/api:qoUCtLER/auth'
|
|
395
|
+
{
|
|
396
|
+
auth: {
|
|
397
|
+
storage: localStorage,
|
|
398
|
+
persistSession: true,
|
|
399
|
+
autoRefreshToken: true,
|
|
400
|
+
},
|
|
401
|
+
}
|
|
402
|
+
);
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
### 3. Update Authentication Code
|
|
406
|
+
|
|
407
|
+
The authentication API is nearly identical, requiring minimal changes:
|
|
408
|
+
|
|
409
|
+
Before (Supabase):
|
|
410
|
+
|
|
411
|
+
```typescript
|
|
412
|
+
// Sign Up
|
|
413
|
+
const { data, error } = await supabase.auth.signUp({
|
|
414
|
+
email,
|
|
415
|
+
password,
|
|
416
|
+
options: {
|
|
417
|
+
data: { display_name: displayName },
|
|
418
|
+
},
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
// Sign In
|
|
422
|
+
const { data, error } = await supabase.auth.signInWithPassword({
|
|
423
|
+
email,
|
|
424
|
+
password,
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
// Sign Out
|
|
428
|
+
await supabase.auth.signOut();
|
|
429
|
+
|
|
430
|
+
// Auth State Listener
|
|
431
|
+
supabase.auth.onAuthStateChange((event, session) => {
|
|
432
|
+
// ...
|
|
433
|
+
});
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
After (Xano):
|
|
437
|
+
|
|
438
|
+
```typescript
|
|
439
|
+
// Sign Up (almost identical!)
|
|
440
|
+
const { data, error } = await xano.auth.signUp({
|
|
441
|
+
email,
|
|
442
|
+
password,
|
|
443
|
+
options: {
|
|
444
|
+
data: {
|
|
445
|
+
display_name: displayName,
|
|
446
|
+
// Add any additional fields required by your Xano signup endpoint
|
|
447
|
+
username: username,
|
|
448
|
+
},
|
|
449
|
+
},
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
// Sign In (identical!)
|
|
453
|
+
const { data, error } = await xano.auth.signInWithPassword({
|
|
454
|
+
email,
|
|
455
|
+
password,
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
// Sign Out (identical!)
|
|
459
|
+
await xano.auth.signOut();
|
|
460
|
+
|
|
461
|
+
// Auth State Listener (identical!)
|
|
462
|
+
xano.auth.onAuthStateChange((event, session) => {
|
|
463
|
+
// ...
|
|
464
|
+
});
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
### 4. Update Data Fetching
|
|
468
|
+
|
|
469
|
+
This is where the main changes occur. Supabase uses table-based queries, while Xano uses endpoints.
|
|
470
|
+
|
|
471
|
+
Before (Supabase):
|
|
472
|
+
|
|
473
|
+
```typescript
|
|
474
|
+
// useChores.ts
|
|
475
|
+
const { data: choresData, error } = await supabase
|
|
476
|
+
.from("chores")
|
|
477
|
+
.select("*")
|
|
478
|
+
.eq("user_id", user.id)
|
|
479
|
+
.order("created_at", { ascending: false });
|
|
480
|
+
|
|
481
|
+
// Insert
|
|
482
|
+
const { data, error } = await supabase
|
|
483
|
+
.from("chores")
|
|
484
|
+
.insert({
|
|
485
|
+
title,
|
|
486
|
+
description,
|
|
487
|
+
points,
|
|
488
|
+
user_id: user.id,
|
|
489
|
+
})
|
|
490
|
+
.select()
|
|
491
|
+
.single();
|
|
492
|
+
|
|
493
|
+
// Update
|
|
494
|
+
const { error } = await supabase
|
|
495
|
+
.from("chores")
|
|
496
|
+
.update({ completed: true })
|
|
497
|
+
.eq("id", choreId);
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
After (Xano):
|
|
501
|
+
|
|
502
|
+
```typescript
|
|
503
|
+
// useChores.ts
|
|
504
|
+
// You need to create corresponding Xano endpoints first
|
|
505
|
+
|
|
506
|
+
// Fetch chores
|
|
507
|
+
const { data: choresData, error } = await xano
|
|
508
|
+
.endpoint("/api:your-api/chores")
|
|
509
|
+
.get({
|
|
510
|
+
user_id: user.id,
|
|
511
|
+
sort: "created_at",
|
|
512
|
+
order: "desc",
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
// Insert
|
|
516
|
+
const { data, error } = await xano.endpoint("/api:your-api/chores").post({
|
|
517
|
+
title,
|
|
518
|
+
description,
|
|
519
|
+
points,
|
|
520
|
+
user_id: user.id,
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
// Update
|
|
524
|
+
const { error } = await xano
|
|
525
|
+
.endpoint(`/api:your-api/chores/${choreId}`)
|
|
526
|
+
.patch({ completed: true });
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
### 5. Create Xano Endpoints (Backend)
|
|
530
|
+
|
|
531
|
+
For each Supabase table query, you'll need to create corresponding Xano endpoints:
|
|
532
|
+
|
|
533
|
+
1. List/Query: `GET /api:xxx/chores`
|
|
534
|
+
|
|
535
|
+
- Add filters as query parameters
|
|
536
|
+
- Implement pagination (page, per_page)
|
|
537
|
+
- Add sorting options
|
|
538
|
+
|
|
539
|
+
2. Get Single: `GET /api:xxx/chores/{id}`
|
|
540
|
+
|
|
541
|
+
- Return single record
|
|
542
|
+
|
|
543
|
+
3. Create: `POST /api:xxx/chores`
|
|
544
|
+
|
|
545
|
+
- Accept data in request body
|
|
546
|
+
- Return created record
|
|
547
|
+
|
|
548
|
+
4. Update: `PATCH /api:xxx/chores/{id}`
|
|
549
|
+
|
|
550
|
+
- Accept partial data in request body
|
|
551
|
+
- Return updated record
|
|
552
|
+
|
|
553
|
+
5. Delete: `DELETE /api:xxx/chores/{id}`
|
|
554
|
+
- Return success message
|
|
555
|
+
|
|
556
|
+
REQUIRED: After creating or editing endpoints/tables, invoke `push_all_changes_to_xano`.
|
|
557
|
+
|
|
558
|
+
### 6. Update React Hooks (Frontend)
|
|
559
|
+
|
|
560
|
+
Before (useAuth with Supabase):
|
|
561
|
+
|
|
562
|
+
```typescript
|
|
563
|
+
import { supabase } from '@/integrations/supabase/client';
|
|
564
|
+
|
|
565
|
+
export function useAuth() {
|
|
566
|
+
// ... same implementation, just change the import
|
|
567
|
+
supabase.auth.onAuthStateChange(...)
|
|
568
|
+
supabase.auth.getSession()
|
|
569
|
+
}
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
After (useAuth with Xano):
|
|
573
|
+
|
|
574
|
+
```typescript
|
|
575
|
+
import { xano } from '@/integrations/xano/client';
|
|
576
|
+
|
|
577
|
+
export function useAuth() {
|
|
578
|
+
// ... same implementation!
|
|
579
|
+
xano.auth.onAuthStateChange(...)
|
|
580
|
+
xano.auth.getSession()
|
|
581
|
+
}
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
Before (useChores with Supabase):
|
|
585
|
+
|
|
586
|
+
```typescript
|
|
587
|
+
const { data, error } = await supabase
|
|
588
|
+
.from("chores")
|
|
589
|
+
.select("*")
|
|
590
|
+
.eq("user_id", user.id);
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
After (useChores with Xano):
|
|
594
|
+
|
|
595
|
+
```typescript
|
|
596
|
+
const { data, error } = await xano
|
|
597
|
+
.endpoint("/api:xxx/chores")
|
|
598
|
+
.get({ user_id: user.id });
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
### 7. Environment Variables
|
|
602
|
+
|
|
603
|
+
Update your `.env` file:
|
|
604
|
+
|
|
605
|
+
Before:
|
|
606
|
+
|
|
607
|
+
```env
|
|
608
|
+
VITE_SUPABASE_URL=https://xxx.supabase.co
|
|
609
|
+
VITE_SUPABASE_PUBLISHABLE_KEY=eyJxxx...
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
After:
|
|
613
|
+
|
|
614
|
+
```env
|
|
615
|
+
VITE_XANO_URL=https://x62j-rlqn-vpsk.dev.xano.io
|
|
616
|
+
VITE_XANO_AUTH_ENDPOINT=/api:qoUCtLER/auth # Replace with your auth API group endpoint
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
REQUIRED: Before editing frontend code, invoke `get_xano_api_specifications` and confirm the auth group path matches `VITE_XANO_AUTH_ENDPOINT`.
|
|
620
|
+
|
|
621
|
+
## Common Patterns
|
|
622
|
+
|
|
623
|
+
### Pagination
|
|
624
|
+
|
|
625
|
+
Supabase:
|
|
626
|
+
|
|
627
|
+
```typescript
|
|
628
|
+
.range(0, 9) // First 10 items
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
Xano:
|
|
632
|
+
|
|
633
|
+
```typescript
|
|
634
|
+
.get({ page: 1, per_page: 10 })
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
### Filtering
|
|
638
|
+
|
|
639
|
+
Supabase:
|
|
640
|
+
|
|
641
|
+
```typescript
|
|
642
|
+
.eq('status', 'active')
|
|
643
|
+
.gt('points', 10)
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
Xano:
|
|
647
|
+
|
|
648
|
+
```typescript
|
|
649
|
+
// Implement filtering in your Xano endpoint
|
|
650
|
+
.get({ status: 'active', min_points: 10 })
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
### Sorting
|
|
654
|
+
|
|
655
|
+
Supabase:
|
|
656
|
+
|
|
657
|
+
```typescript
|
|
658
|
+
.order('created_at', { ascending: false })
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
Xano:
|
|
662
|
+
|
|
663
|
+
```typescript
|
|
664
|
+
// Implement in Xano endpoint
|
|
665
|
+
.get({ sort_by: 'created_at', order: 'desc' })
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
## Checklist
|
|
669
|
+
|
|
670
|
+
- [ ] Install Xano SDK
|
|
671
|
+
- [ ] Update client initialization
|
|
672
|
+
- [ ] Create Xano endpoints for each table query
|
|
673
|
+
- [ ] Create Xano endpoints for each edge function
|
|
674
|
+
- [ ] Update authentication code (minimal changes)
|
|
675
|
+
- [ ] Update data fetching code (main work)
|
|
676
|
+
- [ ] Update React hooks
|
|
677
|
+
- [ ] Update environment variables
|
|
678
|
+
- [ ] REQUIRED: `push_all_changes_to_xano`
|
|
679
|
+
- [ ] REQUIRED: `get_xano_api_specifications`
|
|
680
|
+
- [ ] Test authentication flow
|
|
681
|
+
- [ ] Test all data operations
|
|
682
|
+
- [ ] Update error handling if needed
|
|
683
|
+
- [ ] Remove Supabase dependencies
|
|
684
|
+
|
|
685
|
+
## Benefits of Xano
|
|
686
|
+
|
|
687
|
+
After migration, you'll gain:
|
|
688
|
+
|
|
689
|
+
1. Backend Logic: Built-in business logic in endpoints
|
|
690
|
+
2. Visual Builder: No-code/low-code endpoint creation
|
|
691
|
+
3. Better Performance: Optimized API endpoints
|
|
692
|
+
4. Flexibility: More control over data transformations
|
|
693
|
+
5. Cost: Potentially better pricing for your use case
|
|
694
|
+
|
|
695
|
+
## Need Help?
|
|
696
|
+
|
|
697
|
+
- Review the Xano Documentation: https://docs.xano.com
|
|
698
|
+
- Check the examples directory
|
|
699
|
+
- Open an issue on GitHub
|
|
700
|
+
|
|
701
|
+
## Gradual Migration
|
|
702
|
+
|
|
703
|
+
You can use both Supabase and Xano simultaneously during migration:
|
|
704
|
+
|
|
705
|
+
```typescript
|
|
706
|
+
// Keep both clients during transition
|
|
707
|
+
import { supabase } from "@/integrations/supabase/client";
|
|
708
|
+
import { xano } from "@/integrations/xano/client";
|
|
709
|
+
|
|
710
|
+
// Migrate endpoints one at a time
|
|
711
|
+
const useSupabaseForAuth = false;
|
|
712
|
+
const authClient = useSupabaseForAuth ? supabase : xano;
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
Important: Once migration is complete, remove all Supabase dependencies from the project, including the `supabase` package in `package.json` and any Supabase-specific integrations.
|