@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,586 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "tables/*.xs"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Xanoscript Table Examples
|
|
6
|
+
|
|
7
|
+
Below are some examples of tables defined in Xanoscript.
|
|
8
|
+
|
|
9
|
+
## inventory_management_table
|
|
10
|
+
|
|
11
|
+
```xs
|
|
12
|
+
table "inventory_item" {
|
|
13
|
+
auth = false
|
|
14
|
+
schema {
|
|
15
|
+
uuid id {
|
|
16
|
+
description = "Unique identifier for the inventory item"
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
text name filters=trim {
|
|
20
|
+
description = "Name of the inventory item"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
text description filters=trim {
|
|
24
|
+
description = "Detailed description of the inventory item"
|
|
25
|
+
sensitive = true
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
decimal price? filters=min:0 {
|
|
29
|
+
description = "Price of the inventory item in decimal format"
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
int stock_quantity? filters=min:0 {
|
|
33
|
+
description = "Current quantity of the item in stock"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
int[] category_ids {
|
|
37
|
+
table = "category"
|
|
38
|
+
description = "Foreign key reference to the product categories"
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
timestamp last_updated?=now {
|
|
42
|
+
description = "Timestamp when the inventory record was last updated"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
timestamp created_at?=now {
|
|
46
|
+
description = "Timestamp when the inventory item was created"
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
json item_properties? {
|
|
50
|
+
description = "Additional properties stored as JSON (color, size, weight, etc.)"
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
text sku filters=trim {
|
|
54
|
+
description = "Stock Keeping Unit - unique product identifier"
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
decimal cost? filters=min:0 {
|
|
58
|
+
description = "Cost price of the item for internal calculations"
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
int reorder_level? filters=min:0 {
|
|
62
|
+
description = "Minimum stock level that triggers reorder alerts"
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
bool is_active?=1 {
|
|
66
|
+
description = "Indicates whether the item is currently active in inventory"
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
text supplier_name? filters=trim {
|
|
70
|
+
description = "Name of the primary supplier for this item"
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
text location? filters=trim {
|
|
74
|
+
description = "Physical location/warehouse section where item is stored"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
index = [
|
|
79
|
+
{type: "primary", field: [{name: "id"}]}
|
|
80
|
+
{type: "btree|unique", field: [{name: "name", op: "asc"}]}
|
|
81
|
+
{type: "btree|unique", field: [{name: "sku", op: "asc"}]}
|
|
82
|
+
{type: "btree", field: [{name: "stock_quantity", op: "asc"}]}
|
|
83
|
+
{type: "btree", field: [{name: "last_updated", op: "desc"}]}
|
|
84
|
+
{type: "btree", field: [{name: "is_active", op: "asc"}]}
|
|
85
|
+
{type: "gin", field: [{name: "item_properties"}]}
|
|
86
|
+
{type: "btree", field: [{name: "reorder_level", op: "asc"}]}
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## shopping_cart_items_table
|
|
92
|
+
|
|
93
|
+
```xs
|
|
94
|
+
table "shopping_cart_items" {
|
|
95
|
+
auth = false
|
|
96
|
+
schema {
|
|
97
|
+
int id {
|
|
98
|
+
description = "Unique identifier for the cart item"
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
int user_id {
|
|
102
|
+
table = "user"
|
|
103
|
+
description = "ID of the user who owns the cart"
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
int product_id {
|
|
107
|
+
table = "product"
|
|
108
|
+
description = "ID of the product added to the cart"
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
int quantity filters=min:0 {
|
|
112
|
+
description = "Quantity of the product in the cart (non-negative)"
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
decimal unit_price filters=min:0 {
|
|
116
|
+
description = "Unit price of the product (non-negative)"
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
timestamp last_updated?=now {
|
|
120
|
+
description = "Timestamp of the last update to the cart item"
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
index = [
|
|
125
|
+
{type: "primary", field: [{name: "id"}]}
|
|
126
|
+
{
|
|
127
|
+
type : "btree"
|
|
128
|
+
field: [{name: "user_id"}, {name: "product_id"}]
|
|
129
|
+
}
|
|
130
|
+
]
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## weekly_slack_pets_prompt
|
|
135
|
+
|
|
136
|
+
```xs
|
|
137
|
+
table "slack_prompts" {
|
|
138
|
+
auth = false
|
|
139
|
+
schema {
|
|
140
|
+
int id {
|
|
141
|
+
description = "Identifier for the Slack prompt"
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
text prompt filters=trim {
|
|
145
|
+
description = "The Slack prompt message to be sent"
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
bool is_used? {
|
|
149
|
+
description = "Boolean flag indicating whether this prompt has been used"
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
text gif_url filters=trim {
|
|
153
|
+
description = "URL of the GIF file to be sent with the prompt"
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
timestamp created_at?=now {
|
|
157
|
+
description = "Timestamp when the prompt was created"
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
timestamp used_at? {
|
|
161
|
+
description = "Timestamp when the prompt was last used"
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
enum type? {
|
|
165
|
+
values = ["pets"]
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
index = [
|
|
170
|
+
{type: "primary", field: [{name: "id"}]}
|
|
171
|
+
{type: "btree", field: [{name: "is_used", op: "asc"}]}
|
|
172
|
+
{type: "btree", field: [{name: "created_at", op: "desc"}]}
|
|
173
|
+
]
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## orders_table
|
|
178
|
+
|
|
179
|
+
```xs
|
|
180
|
+
table "orders" {
|
|
181
|
+
auth = false
|
|
182
|
+
schema {
|
|
183
|
+
uuid id {
|
|
184
|
+
description = "Unique identifier for the order"
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
decimal order_total filters=min:0 {
|
|
188
|
+
description = "Total amount for the order"
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
timestamp order_date?=now {
|
|
192
|
+
description = "Date and time when the order was placed"
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
bool is_fulfilled? {
|
|
196
|
+
description = "Indicates whether the order has been fulfilled"
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
int customer_id? {
|
|
200
|
+
table = "customer"
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
enum order_status? {
|
|
204
|
+
values = [
|
|
205
|
+
"draft"
|
|
206
|
+
"confirmed"
|
|
207
|
+
"fulfilling"
|
|
208
|
+
"shipping"
|
|
209
|
+
"delivered"
|
|
210
|
+
"returned"
|
|
211
|
+
]
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
index = [{type: "primary", field: [{name: "id"}]}]
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## payment_transaction
|
|
220
|
+
|
|
221
|
+
```xs
|
|
222
|
+
table "payment_transactions" {
|
|
223
|
+
description = "Table to store payment transaction details"
|
|
224
|
+
auth = false
|
|
225
|
+
schema {
|
|
226
|
+
int id {
|
|
227
|
+
description = "Unique identifier for the transaction"
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
uuid ?order_id? {
|
|
231
|
+
table = "orders"
|
|
232
|
+
description = "Associated order ID"
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
text[] logs {
|
|
236
|
+
description = "Array of logs or comments related to the transaction"
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
int customer_id {
|
|
240
|
+
table = "user"
|
|
241
|
+
description = "Customer ID related to the transaction"
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
decimal amount filters=min:0 {
|
|
245
|
+
description = "Transaction amount"
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
text payment_method filters=trim {
|
|
249
|
+
description = "Payment method used (e.g., credit card, PayPal)"
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
enum transaction_status {
|
|
253
|
+
values = ["completed", "pending", "failed"]
|
|
254
|
+
description = "Current status of the transaction (e.g., completed, pending)"
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
timestamp transaction_date?=now {
|
|
258
|
+
description = "Date and time of the transaction"
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
json payment_gateway_metadata {
|
|
262
|
+
description = "Metadata from the payment gateway"
|
|
263
|
+
sensitive = true
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
index = [
|
|
268
|
+
{type: "primary", field: [{name: "id"}]}
|
|
269
|
+
{type: "btree", field: [{name: "order_id", op: "asc"}]}
|
|
270
|
+
]
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## blog_post_table
|
|
275
|
+
|
|
276
|
+
```xs
|
|
277
|
+
table "blog_post" {
|
|
278
|
+
auth = false
|
|
279
|
+
schema {
|
|
280
|
+
uuid id {
|
|
281
|
+
description = "Unique identifier for the blog post"
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
text title filters=trim {
|
|
285
|
+
description = "Title of the blog post"
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
text content filters=trim {
|
|
289
|
+
description = "Main content/body of the blog post"
|
|
290
|
+
sensitive = true
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
text[] tags {
|
|
294
|
+
description = "Array of tags associated with the blog post"
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
int author_id {
|
|
298
|
+
table = "user"
|
|
299
|
+
description = "ID of the author who created the blog post"
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
timestamp ?publication_date?=now {
|
|
303
|
+
description = "Date and time when the blog post was published"
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
json tags? {
|
|
307
|
+
description = "Array of tags associated with the blog post for categorization"
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
bool is_draft?=1 {
|
|
311
|
+
description = "Indicates whether the blog post is in draft status (not published)"
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
timestamp created_at?=now {
|
|
315
|
+
description = "Timestamp when the blog post was created"
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
timestamp updated_at? {
|
|
319
|
+
description = "Timestamp when the blog post was last updated"
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
text slug filters=trim {
|
|
323
|
+
description = "URL-friendly version of the title for SEO purposes"
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
int view_count? {
|
|
327
|
+
description = "Number of times the blog post has been viewed"
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
index = [
|
|
332
|
+
{type: "primary", field: [{name: "id"}]}
|
|
333
|
+
{type: "btree", field: [{name: "author_id", op: "asc"}]}
|
|
334
|
+
{
|
|
335
|
+
type : "btree"
|
|
336
|
+
field: [{name: "publication_date", op: "desc"}]
|
|
337
|
+
}
|
|
338
|
+
{type: "btree|unique", field: [{name: "slug", op: "asc"}]}
|
|
339
|
+
{type: "btree", field: [{name: "is_draft", op: "asc"}]}
|
|
340
|
+
]
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
## table_for_user_profile
|
|
345
|
+
|
|
346
|
+
```xs
|
|
347
|
+
table "user_profile" {
|
|
348
|
+
description = "Table to store user profiles for a social networking platform"
|
|
349
|
+
auth = false
|
|
350
|
+
schema {
|
|
351
|
+
int id {
|
|
352
|
+
description = "Unique user ID"
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
text full_name filters=trim {
|
|
356
|
+
description = "User's full name"
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
email email filters=trim|lower {
|
|
360
|
+
description = "User's email address"
|
|
361
|
+
sensitive = true
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
text profile_picture_url filters=trim {
|
|
365
|
+
description = "URL of the user's profile picture"
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
timestamp registration_date?=now {
|
|
369
|
+
description = "Date and time the user registered"
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
bool is_active?=1 {
|
|
373
|
+
description = "Indicates if the user is active"
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
int user? {
|
|
377
|
+
table = "user"
|
|
378
|
+
description = "A reference to the associated user account."
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
index = [
|
|
383
|
+
{type: "primary", field: [{name: "id"}]}
|
|
384
|
+
{type: "btree|unique", field: [{name: "email", op: "asc"}]}
|
|
385
|
+
{
|
|
386
|
+
type : "btree"
|
|
387
|
+
field: [{name: "registration_date", op: "desc"}]
|
|
388
|
+
}
|
|
389
|
+
{type: "btree|unique", field: [{name: "user", op: "asc"}]}
|
|
390
|
+
]
|
|
391
|
+
}
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
## product_reviews
|
|
395
|
+
|
|
396
|
+
```xs
|
|
397
|
+
table "product_reviews" {
|
|
398
|
+
auth = false
|
|
399
|
+
schema {
|
|
400
|
+
int id {
|
|
401
|
+
description = "Unique identifier for the review"
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
int rating filters=min:1|max:5 {
|
|
405
|
+
description = "Rating given by the customer (1 to 5)"
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
text review_text filters=trim {
|
|
409
|
+
description = "Text of the review provided by the customer"
|
|
410
|
+
sensitive = true
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
timestamp review_date?=now {
|
|
414
|
+
description = "Date and time when the review was submitted"
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
bool is_verified? {
|
|
418
|
+
description = "Indicates whether the review is verified"
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
json metadata {
|
|
422
|
+
description = "Additional metadata for the review (e.g., tags)"
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
int product_id {
|
|
426
|
+
table = "product"
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
int customer_id {
|
|
430
|
+
table = "customer"
|
|
431
|
+
description = "Author of the review"
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
index = [
|
|
436
|
+
{type: "primary", field: [{name: "id"}]}
|
|
437
|
+
{type: "btree", field: [{name: "product_id", op: "asc"}]}
|
|
438
|
+
{type: "btree", field: [{name: "customer_id", op: "asc"}]}
|
|
439
|
+
]
|
|
440
|
+
}
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
## user_analytics_endpoint
|
|
444
|
+
|
|
445
|
+
```xs
|
|
446
|
+
table "user_activity" {
|
|
447
|
+
auth = false
|
|
448
|
+
schema {
|
|
449
|
+
int id
|
|
450
|
+
int user_id
|
|
451
|
+
text action_type
|
|
452
|
+
text action_details?
|
|
453
|
+
text session_id
|
|
454
|
+
timestamp session_start_time?
|
|
455
|
+
timestamp session_end_time?
|
|
456
|
+
int session_duration?
|
|
457
|
+
text page_url?
|
|
458
|
+
text referrer_url?
|
|
459
|
+
text user_agent?
|
|
460
|
+
text ip_address?
|
|
461
|
+
text device_type?
|
|
462
|
+
text browser?
|
|
463
|
+
text country?
|
|
464
|
+
text region?
|
|
465
|
+
text city?
|
|
466
|
+
timestamp created_at?=now
|
|
467
|
+
timestamp updated_at?=now
|
|
468
|
+
int page_load_time?
|
|
469
|
+
json metadata?
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
index = [
|
|
473
|
+
{type: "primary", field: [{name: "id"}]}
|
|
474
|
+
{type: "btree", field: [{name: "user_id", op: "asc"}]}
|
|
475
|
+
{type: "btree", field: [{name: "session_id", op: "asc"}]}
|
|
476
|
+
{type: "btree", field: [{name: "action_type", op: "asc"}]}
|
|
477
|
+
{type: "btree", field: [{name: "created_at", op: "desc"}]}
|
|
478
|
+
{
|
|
479
|
+
type : "btree"
|
|
480
|
+
field: [
|
|
481
|
+
{name: "user_id", op: "asc"}
|
|
482
|
+
{name: "created_at", op: "desc"}
|
|
483
|
+
]
|
|
484
|
+
}
|
|
485
|
+
]
|
|
486
|
+
}
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
## survey_form_builder_system
|
|
490
|
+
|
|
491
|
+
```xs
|
|
492
|
+
table "surveys" {
|
|
493
|
+
auth = false
|
|
494
|
+
schema {
|
|
495
|
+
int id {
|
|
496
|
+
description = "Unique identifier for the survey"
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
text title filters=trim {
|
|
500
|
+
description = "Survey title displayed to respondents"
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
text description? {
|
|
504
|
+
description = "Optional survey description or instructions"
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
enum status? {
|
|
508
|
+
values = ["draft", "active", "closed", "archived"]
|
|
509
|
+
description = "Survey status - draft, active, closed, or archived"
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
json settings? {
|
|
513
|
+
description = "Survey settings like anonymous responses, deadline, etc."
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
timestamp created_at?=now {
|
|
517
|
+
description = "When the survey was created"
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
timestamp updated_at?=now {
|
|
521
|
+
description = "When the survey was last updated"
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
int created_by? {
|
|
525
|
+
description = "ID of user who created the survey"
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
index = [
|
|
530
|
+
{type: "primary", field: [{name: "id"}]}
|
|
531
|
+
{type: "btree", field: [{name: "status", op: "asc"}]}
|
|
532
|
+
{type: "btree", field: [{name: "created_by", op: "asc"}]}
|
|
533
|
+
{type: "btree", field: [{name: "created_at", op: "desc"}]}
|
|
534
|
+
]
|
|
535
|
+
}
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
## product_table
|
|
539
|
+
|
|
540
|
+
```xs
|
|
541
|
+
table "product" {
|
|
542
|
+
auth = false
|
|
543
|
+
schema {
|
|
544
|
+
int id {
|
|
545
|
+
description = "Unique product ID"
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
text name filters=trim {
|
|
549
|
+
description = "Product name"
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
text description filters=trim {
|
|
553
|
+
description = "Detailed product description"
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
decimal price? filters=min:0 {
|
|
557
|
+
description = "Product price (non-negative)"
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
int stock_quantity? filters=min:0 {
|
|
561
|
+
description = "Available stock quantity (non-negative)"
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
int category_id filters=min:0 {
|
|
565
|
+
description = "Category ID for product classification"
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
text sku filters=trim {
|
|
569
|
+
description = "Stock-keeping unit (unique identifier)"
|
|
570
|
+
sensitive = true
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
timestamp created_at?=now {
|
|
574
|
+
description = "Timestamp of product creation"
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
int in_cart?
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
index = [
|
|
581
|
+
{type: "primary", field: [{name: "id"}]}
|
|
582
|
+
{type: "btree", field: [{name: "category_id", op: "asc"}]}
|
|
583
|
+
{type: "btree|unique", field: [{name: "sku", op: "asc"}]}
|
|
584
|
+
]
|
|
585
|
+
}
|
|
586
|
+
```
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "tables/*.xs"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# How to Define Tables in XanoScript
|
|
6
|
+
|
|
7
|
+
A **table** in XanoScript defines the structure of a database table, including its fields, types, relationships, and indexes. Tables are created in the `tables` folder and are essential for organizing and storing data in your application.
|
|
8
|
+
|
|
9
|
+
## Built-in tables
|
|
10
|
+
|
|
11
|
+
Most of the time, a `user` table with user name, email, and password (hashed) will already be present in the Xano workspace (`tables/<table_id>_user.xs`), and is already used by the authentication system. You can customize it by adding fields to it, indexes, and relationships as needed.
|
|
12
|
+
|
|
13
|
+
## Table Structure
|
|
14
|
+
|
|
15
|
+
A table file consists of:
|
|
16
|
+
|
|
17
|
+
- The table name (e.g., `order`, `product`)
|
|
18
|
+
- A `schema` block listing all fields and their properties
|
|
19
|
+
- An `index` block for efficient querying
|
|
20
|
+
- Optional `auth`, indicating that this table can be used for authentication by an API endpoint, meaning the `id` contained in the auth token can be matched against the `id` field in this table (usually this is only set for a `user` table)
|
|
21
|
+
|
|
22
|
+
## Example Table
|
|
23
|
+
|
|
24
|
+
!!! IMPORTANT !!!
|
|
25
|
+
EACH TABLE SHOULD HAVE AN `id` FIELD, THIS IS THE PRIMARY KEY, IT CAN EITHER BE AN INT OR A UUID, IT SHOULD BE NAMED `id` AND IT SHOULD BE THE PRIMARY KEY.
|
|
26
|
+
!!! IMPORTANT !!!
|
|
27
|
+
|
|
28
|
+
The following xanoscript would be stored in `tables/user.xs`
|
|
29
|
+
|
|
30
|
+
```xs
|
|
31
|
+
table "shopping_cart_items" {
|
|
32
|
+
auth = false
|
|
33
|
+
schema {
|
|
34
|
+
int id {
|
|
35
|
+
description = "Unique identifier for the cart item"
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
int user_id {
|
|
39
|
+
table = "user"
|
|
40
|
+
description = "ID of the user who owns the cart"
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
int product_id {
|
|
44
|
+
table = "product"
|
|
45
|
+
description = "ID of the product added to the cart"
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
int quantity filters=min:0 {
|
|
49
|
+
description = "Quantity of the product in the cart (non-negative)"
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
decimal unit_price filters=min:0 {
|
|
53
|
+
description = "Unit price of the product (non-negative)"
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
timestamp last_updated?=now {
|
|
57
|
+
description = "Timestamp of the last update to the cart item"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
index = [
|
|
62
|
+
{type: "primary", field: [{name: "id"}]}
|
|
63
|
+
{
|
|
64
|
+
type : "btree"
|
|
65
|
+
field: [{name: "user_id"}, {name: "product_id"}]
|
|
66
|
+
}
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Field Types
|
|
72
|
+
|
|
73
|
+
Supported types for table columns include:
|
|
74
|
+
|
|
75
|
+
- `int` (integer)
|
|
76
|
+
- `text`
|
|
77
|
+
- `email`
|
|
78
|
+
- `password`
|
|
79
|
+
- `decimal`
|
|
80
|
+
- `bool`
|
|
81
|
+
- `timestamp`
|
|
82
|
+
- `date`
|
|
83
|
+
- `uuid`
|
|
84
|
+
- `vector`
|
|
85
|
+
- `json`
|
|
86
|
+
- `image`
|
|
87
|
+
- `video`
|
|
88
|
+
- `audio`
|
|
89
|
+
- `attachment`
|
|
90
|
+
- `enum`
|
|
91
|
+
|
|
92
|
+
## Field Options
|
|
93
|
+
|
|
94
|
+
Each field can have:
|
|
95
|
+
|
|
96
|
+
- **Optional status**: Add `?` for optional fields, e.g., `text nickname?`
|
|
97
|
+
- **Default value**: Use `?=value`, e.g., `timestamp created_at?=now`
|
|
98
|
+
- **Filters**: Process input, e.g., `filters=trim|lower`
|
|
99
|
+
- **Metadata**: Add `description` or `sensitive` for documentation and privacy
|
|
100
|
+
- **Relationships**: Reference another table with `table`, e.g., `int user_id { table = "user" }`
|
|
101
|
+
|
|
102
|
+
## Indexes
|
|
103
|
+
|
|
104
|
+
Indexes improve query performance and enforce uniqueness. Common types:
|
|
105
|
+
|
|
106
|
+
- `primary`: Main identifier (usually `id`)
|
|
107
|
+
- `btree`: Standard index, can be unique
|
|
108
|
+
- `gin`: For JSON or array fields
|
|
109
|
+
- `unique`: Ensures values are not duplicated
|
|
110
|
+
|
|
111
|
+
**Example:**
|
|
112
|
+
|
|
113
|
+
```xs
|
|
114
|
+
index = [
|
|
115
|
+
{type: "primary", field: [{name: "id"}]}
|
|
116
|
+
{type: "btree|unique", field: [{name: "email", op: "asc"}]}
|
|
117
|
+
]
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Best Practices
|
|
121
|
+
|
|
122
|
+
- Use `description` for every field to document its purpose.
|
|
123
|
+
- Mark sensitive fields with `sensitive = true`.
|
|
124
|
+
- Use filters to clean and normalize data.
|
|
125
|
+
- Define indexes for fields that are searched or must be unique.
|
|
126
|
+
- Reference related tables using `table` for foreign keys.
|
|
127
|
+
|
|
128
|
+
## Summary
|
|
129
|
+
|
|
130
|
+
- Place tables in the `tables` folder.
|
|
131
|
+
- Use the `schema` block for fields and types.
|
|
132
|
+
- Add `index` for performance and uniqueness.
|
|
133
|
+
- Use metadata and filters for clarity and data integrity.
|
|
134
|
+
- Reference other tables for relationships.
|
|
135
|
+
- Use `auth = true` for tables used in authentication, for most table use cases, this should be set to `false`.
|
|
136
|
+
|
|
137
|
+
For more examples, see the documentation or sample tables in your
|