@baasix/baasix 0.1.68 → 0.1.70
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/dist/routes/openapi.route.d.ts.map +1 -1
- package/dist/routes/openapi.route.js +4 -0
- package/dist/routes/openapi.route.js.map +1 -1
- package/dist/routes/schema.route.d.ts.map +1 -1
- package/dist/routes/schema.route.js +195 -49
- package/dist/routes/schema.route.js.map +1 -1
- package/dist/services/HooksManager.d.ts.map +1 -1
- package/dist/services/HooksManager.js +16 -0
- package/dist/services/HooksManager.js.map +1 -1
- package/dist/services/MCPService.d.ts.map +1 -1
- package/dist/services/MCPService.js +258 -39
- package/dist/services/MCPService.js.map +1 -1
- package/dist/services/MailService.d.ts.map +1 -1
- package/dist/services/MailService.js +5 -3
- package/dist/services/MailService.js.map +1 -1
- package/package.json +1 -1
|
@@ -186,6 +186,22 @@ if (!globalThis.__baasix_hooksManagerInitialized) {
|
|
|
186
186
|
hooksManager.registerHook('baasix_UserRole', 'items.create.after', invalidateUserRoleCacheFromHook);
|
|
187
187
|
hooksManager.registerHook('baasix_UserRole', 'items.update.after', invalidateUserRoleCacheFromHook);
|
|
188
188
|
hooksManager.registerHook('baasix_UserRole', 'items.delete.after', invalidateUserRoleCacheFromHook);
|
|
189
|
+
// Evict session cache when a session record is deleted via ItemsService
|
|
190
|
+
// This ensures auth/me returns 401 immediately instead of waiting for 30s TTL
|
|
191
|
+
hooksManager.registerHook('baasix_Sessions', 'items.delete.after', async (context) => {
|
|
192
|
+
try {
|
|
193
|
+
const token = context.document?.token;
|
|
194
|
+
if (!token)
|
|
195
|
+
return context;
|
|
196
|
+
const { getCache } = await import('../utils/cache.js');
|
|
197
|
+
const cache = getCache();
|
|
198
|
+
await cache.delete(`auth:session:${token}`);
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
console.error('[HooksManager] Failed to invalidate session cache:', error.message);
|
|
202
|
+
}
|
|
203
|
+
return context;
|
|
204
|
+
});
|
|
189
205
|
}
|
|
190
206
|
export default hooksManager;
|
|
191
207
|
//# sourceMappingURL=HooksManager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HooksManager.js","sourceRoot":"","sources":["../../baasix/services/HooksManager.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"HooksManager.js","sourceRoot":"","sources":["../../baasix/services/HooksManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MCPService.d.ts","sourceRoot":"","sources":["../../baasix/services/MCPService.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMpE;;;;;GAKG;AACH,UAAU,iBAAiB;IACzB,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,OAAO,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACpB,GAAG,IAAI,CAAC;IACT,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,GAAG,IAAI,CAAC;IACT,WAAW,EAAE,GAAG,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;
|
|
1
|
+
{"version":3,"file":"MCPService.d.ts","sourceRoot":"","sources":["../../baasix/services/MCPService.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMpE;;;;;GAKG;AACH,UAAU,iBAAiB;IACzB,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,OAAO,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACpB,GAAG,IAAI,CAAC;IACT,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,GAAG,IAAI,CAAC;IACT,WAAW,EAAE,GAAG,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAkUD;;GAEG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,iBAAiB,GAAG,IAAI,CAExF;AA0BD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAExD;AAwID;;GAEG;AACH,wBAAgB,eAAe,IAAI,SAAS,CA0lE3C;;;;;;AAED,wBAAoE"}
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
17
17
|
import { z } from "zod";
|
|
18
18
|
import env from "../utils/env.js";
|
|
19
|
+
const SUPPORTED_SCHEMA_FIELD_TYPES_DESCRIPTION = "Supported field types: String, Text, TEXT, CiText, HTML, Integer, BigInt, Decimal, Float, Real, Double, DOUBLE, Boolean, Date, DateTime, DateTime_NO_TZ, Time, Time_NO_TZ, UUID, SUID, TOKEN, JSON, JSONB, Enum, ENUM, VIRTUAL, Array_Integer, Array_String, Array_Double, Array_Decimal, Array_DateTime, Array_DateTime_NO_TZ, Array_Date, Array_Time, Array_Time_NO_TZ, Array_UUID, Array_Boolean, Range_Integer, Range_Double, Range_Decimal, Range_Date, Range_DateTime, Range_DateTime_NO_TZ, Range_Time, Range_Time_NO_TZ, Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, GeometryCollection, Geography.";
|
|
19
20
|
// ==================== Helper Functions ====================
|
|
20
21
|
// Session storage for authenticated MCP clients
|
|
21
22
|
const mcpSessions = new Map();
|
|
@@ -94,6 +95,9 @@ const TOOL_ACTION_MAP = {
|
|
|
94
95
|
baasix_add_index: "create",
|
|
95
96
|
baasix_create_relationship: "create",
|
|
96
97
|
baasix_update_schema: "update",
|
|
98
|
+
baasix_add_schema_field: "create",
|
|
99
|
+
baasix_update_schema_field: "update",
|
|
100
|
+
baasix_delete_schema_field: "delete",
|
|
97
101
|
baasix_update_relationship: "update",
|
|
98
102
|
baasix_delete_schema: "delete",
|
|
99
103
|
baasix_remove_index: "delete",
|
|
@@ -139,6 +143,7 @@ const TOOL_ACTION_MAP = {
|
|
|
139
143
|
baasix_list_permissions: "read",
|
|
140
144
|
baasix_get_permission: "read",
|
|
141
145
|
baasix_get_permissions: "read",
|
|
146
|
+
baasix_get_role_collection_permissions: "read",
|
|
142
147
|
baasix_create_permission: "create",
|
|
143
148
|
baasix_update_permission: "update",
|
|
144
149
|
baasix_delete_permission: "delete",
|
|
@@ -190,8 +195,10 @@ KEY CONCEPTS:
|
|
|
190
195
|
|
|
191
196
|
COMMON TASK MAPPING:
|
|
192
197
|
- "Create a table" or "create a collection" → use baasix_create_schema (this creates both the schema definition AND the database table)
|
|
193
|
-
- "Add a column/field" → use
|
|
194
|
-
- "
|
|
198
|
+
- "Add a single column/field" → use baasix_add_schema_field
|
|
199
|
+
- "Update a single column/field" → use baasix_update_schema_field
|
|
200
|
+
- "Remove a single column/field" → use baasix_delete_schema_field
|
|
201
|
+
- "Bulk schema edits across many fields" → use baasix_update_schema (⚠️ full replacement)
|
|
195
202
|
- "Insert/add data" or "create a record" → use baasix_create_item
|
|
196
203
|
- "Query/list/fetch data" or "get rows" → use baasix_list_items
|
|
197
204
|
- "Sum", "count", "average", "total", "report", "stats", "analytics", "dashboard", "min/max" → use baasix_generate_report (NOT baasix_list_items)
|
|
@@ -214,7 +221,15 @@ WORKFLOW FOR CREATING A NEW TABLE:
|
|
|
214
221
|
3. baasix_add_index — (optional) add indexes for performance
|
|
215
222
|
4. baasix_create_permission — (optional) set role-based access
|
|
216
223
|
|
|
217
|
-
SCHEMA FIELD TYPES:
|
|
224
|
+
SCHEMA FIELD TYPES:
|
|
225
|
+
- String/Text: String, Text, TEXT, CiText, HTML
|
|
226
|
+
- Numbers: Integer, BigInt, Decimal, Float, Real, Double, DOUBLE
|
|
227
|
+
- Date/time: Date, DateTime, DateTime_NO_TZ, Time, Time_NO_TZ
|
|
228
|
+
- IDs/tokens: UUID, SUID, TOKEN
|
|
229
|
+
- JSON/enums/virtual: JSON, JSONB, Enum, ENUM, VIRTUAL
|
|
230
|
+
- Arrays: Array_Integer, Array_String, Array_Double, Array_Decimal, Array_DateTime, Array_DateTime_NO_TZ, Array_Date, Array_Time, Array_Time_NO_TZ, Array_UUID, Array_Boolean
|
|
231
|
+
- Ranges: Range_Integer, Range_Double, Range_Decimal, Range_Date, Range_DateTime, Range_DateTime_NO_TZ, Range_Time, Range_Time_NO_TZ
|
|
232
|
+
- PostGIS: Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, GeometryCollection, Geography
|
|
218
233
|
|
|
219
234
|
DEFAULT VALUE TYPES: { type: "UUIDV4" }, { type: "SUID" }, { type: "NOW" }, { type: "AUTOINCREMENT" }, { type: "SQL", value: "..." }
|
|
220
235
|
|
|
@@ -318,18 +333,20 @@ The update_schema tool performs a full replacement, so you need the complete cur
|
|
|
318
333
|
This creates both the schema definition AND the actual PostgreSQL table with all specified columns.
|
|
319
334
|
|
|
320
335
|
FIELD TYPES:
|
|
321
|
-
- String:
|
|
322
|
-
-
|
|
323
|
-
-
|
|
324
|
-
-
|
|
325
|
-
-
|
|
326
|
-
-
|
|
327
|
-
-
|
|
328
|
-
-
|
|
329
|
-
|
|
330
|
-
-
|
|
331
|
-
-
|
|
332
|
-
-
|
|
336
|
+
- String/Text: String, Text, TEXT, CiText, HTML
|
|
337
|
+
- Numbers: Integer, BigInt, Decimal, Float, Real, Double, DOUBLE
|
|
338
|
+
- Date/time: Date, DateTime, DateTime_NO_TZ, Time, Time_NO_TZ
|
|
339
|
+
- IDs/tokens: UUID, SUID, TOKEN
|
|
340
|
+
- JSON/enums/virtual: JSON, JSONB, Enum, ENUM, VIRTUAL
|
|
341
|
+
- Arrays: Array_Integer, Array_String, Array_Double, Array_Decimal, Array_DateTime, Array_DateTime_NO_TZ, Array_Date, Array_Time, Array_Time_NO_TZ, Array_UUID, Array_Boolean
|
|
342
|
+
- Ranges: Range_Integer, Range_Double, Range_Decimal, Range_Date, Range_DateTime, Range_DateTime_NO_TZ, Range_Time, Range_Time_NO_TZ
|
|
343
|
+
- PostGIS: Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, GeometryCollection, Geography
|
|
344
|
+
|
|
345
|
+
COMMON TYPE-SPECIFIC RULES:
|
|
346
|
+
- String: requires values.length (e.g., { "type": "String", "values": { "length": 255 } })
|
|
347
|
+
- Decimal: requires values.precision and values.scale
|
|
348
|
+
- Enum/ENUM: requires values.values array
|
|
349
|
+
- Array_* / Range_* / PostGIS types use explicit type names (recommended over generic aliases)
|
|
333
350
|
|
|
334
351
|
FIELD OPTIONS: allowNull (boolean), unique (boolean), primaryKey (boolean), defaultValue (value or { type: "UUIDV4"|"SUID"|"NOW"|"AUTOINCREMENT" })
|
|
335
352
|
|
|
@@ -338,13 +355,31 @@ ALWAYS include an "id" field as primary key. Add "timestamps": true in the schem
|
|
|
338
355
|
EXAMPLE — Create a "products" table:
|
|
339
356
|
collection: "products"
|
|
340
357
|
schema: { "timestamps": true, "fields": { "id": { "type": "UUID", "primaryKey": true, "defaultValue": { "type": "UUIDV4" } }, "name": { "type": "String", "allowNull": false, "values": { "length": 255 } }, "price": { "type": "Decimal", "values": { "precision": 10, "scale": 2 }, "defaultValue": 0 }, "inStock": { "type": "Boolean", "defaultValue": true } } }`, {
|
|
341
|
-
collection: z.string().describe("
|
|
358
|
+
collection: z.string().describe("Name of the new collection/table. Must be a valid PostgreSQL identifier (letters, numbers, underscores; cannot start with a number). Max 63 chars."),
|
|
342
359
|
schema: z
|
|
343
360
|
.object({
|
|
344
|
-
|
|
361
|
+
timestamps: z.boolean().optional().describe("Set true to auto-add createdAt and updatedAt DateTime columns managed by Baasix. Recommended for most tables."),
|
|
362
|
+
paranoid: z.boolean().optional().describe("Set true to enable soft deletes: adds a deletedAt column. Deleted records are hidden from queries but not physically removed."),
|
|
363
|
+
sortEnabled: z.boolean().optional().describe("Set true to add a 'sort' Integer column for manual ordering of records."),
|
|
364
|
+
usertrack: z.boolean().optional().describe("Set true to track which user created/updated each record. Adds userCreated and userUpdated M2O fields to baasix_User."),
|
|
365
|
+
fields: z.record(z.object({
|
|
366
|
+
type: z.string().describe(`${SUPPORTED_SCHEMA_FIELD_TYPES_DESCRIPTION} Type-specific requirements: String needs values.length, Decimal needs values.precision+scale, enum-like types need values.values.`),
|
|
367
|
+
allowNull: z.boolean().optional().describe("Allow NULL values. Default: true. Set false to add a NOT NULL constraint."),
|
|
368
|
+
unique: z.boolean().optional().describe("Enforce a UNIQUE constraint on this column."),
|
|
369
|
+
primaryKey: z.boolean().optional().describe("Mark as the primary key column."),
|
|
370
|
+
defaultValue: z.union([z.string(), z.number(), z.boolean(), z.null(), z.object({ type: z.string(), value: z.string().optional() })]).optional().describe("Default value: a literal (e.g. 0, 'active', true) or { type: 'UUIDV4' | 'SUID' | 'NOW' | 'AUTOINCREMENT' | 'SQL', value?: 'expr' }."),
|
|
371
|
+
values: z.object({
|
|
372
|
+
length: z.number().optional().describe("Max character length — required for String/VARCHAR (e.g. 255)"),
|
|
373
|
+
precision: z.number().optional().describe("Total digits — required for Decimal (e.g. 10)"),
|
|
374
|
+
scale: z.number().optional().describe("Decimal places — required for Decimal (e.g. 2)"),
|
|
375
|
+
type: z.string().optional().describe("Element type — required for Array (e.g. 'String', 'Integer')"),
|
|
376
|
+
values: z.array(z.string()).optional().describe("Allowed values — required for Enum (e.g. ['active','inactive'])"),
|
|
377
|
+
}).optional().describe("Type-specific config. String→{length}, Decimal→{precision,scale}, Array→{type}, Enum→{values:[...]}"),
|
|
378
|
+
description: z.string().optional().describe("Human-readable description stored in schema metadata only."),
|
|
379
|
+
}).passthrough()).describe("Field definitions keyed by column name. ALWAYS include an 'id' primary key field (type UUID with defaultValue {type:'UUIDV4'})."),
|
|
345
380
|
})
|
|
346
381
|
.passthrough()
|
|
347
|
-
.describe("Schema definition"),
|
|
382
|
+
.describe("Schema definition for the new table"),
|
|
348
383
|
}, async (args, extra) => {
|
|
349
384
|
const { collection, schema } = args;
|
|
350
385
|
const res = await callRoute('POST', '/schemas', extra, { collectionName: collection, schema });
|
|
@@ -359,12 +394,17 @@ schema: { "timestamps": true, "fields": { "id": { "type": "UUID", "primaryKey":
|
|
|
359
394
|
registerTool("baasix_update_schema", `Modify an existing database table — add new columns, change column types, or remove columns.
|
|
360
395
|
Use this when asked to 'add a field', 'add a column', or 'alter a table'.
|
|
361
396
|
|
|
397
|
+
✅ PREFERRED for single-column changes:
|
|
398
|
+
- Add one column: use baasix_add_schema_field
|
|
399
|
+
- Update one column: use baasix_update_schema_field
|
|
400
|
+
- Delete one column: use baasix_delete_schema_field
|
|
401
|
+
|
|
362
402
|
⚠️ CRITICAL: This performs a FULL REPLACEMENT of the schema definition, NOT a merge.
|
|
363
403
|
You MUST first call baasix_get_schema to retrieve the current schema, then include ALL existing fields
|
|
364
404
|
and add/modify/remove only the fields you need. If you send only new fields, ALL existing fields will
|
|
365
405
|
be LOST from the schema definition.
|
|
366
406
|
|
|
367
|
-
CORRECT WORKFLOW to add a column:
|
|
407
|
+
CORRECT WORKFLOW to add a column using full-replacement (baasix_update_schema):
|
|
368
408
|
1. Call baasix_get_schema for the collection
|
|
369
409
|
2. Copy the entire existing schema (including name, timestamps, paranoid, and ALL fields)
|
|
370
410
|
3. Add/modify/remove the desired fields while keeping all other fields intact
|
|
@@ -397,10 +437,28 @@ EXAMPLE — Adding a "description" field to an existing "products" table that ha
|
|
|
397
437
|
collection: z.string().describe("Collection name"),
|
|
398
438
|
schema: z
|
|
399
439
|
.object({
|
|
400
|
-
|
|
440
|
+
timestamps: z.boolean().optional().describe("true=keep/add createdAt+updatedAt columns. false=remove them. Omit to leave unchanged."),
|
|
441
|
+
paranoid: z.boolean().optional().describe("true=keep/add deletedAt soft-delete column. false=remove it. Omit to leave unchanged."),
|
|
442
|
+
sortEnabled: z.boolean().optional().describe("true=keep/add 'sort' Integer column. Omit to leave unchanged."),
|
|
443
|
+
usertrack: z.boolean().optional().describe("true=keep/add userCreated+userUpdated tracking fields. Omit to leave unchanged."),
|
|
444
|
+
fields: z.record(z.object({
|
|
445
|
+
type: z.string().describe(SUPPORTED_SCHEMA_FIELD_TYPES_DESCRIPTION),
|
|
446
|
+
allowNull: z.boolean().optional().describe("Allow NULL. Default true. false=NOT NULL constraint."),
|
|
447
|
+
unique: z.boolean().optional().describe("Enforce UNIQUE constraint."),
|
|
448
|
+
primaryKey: z.boolean().optional().describe("Primary key column."),
|
|
449
|
+
defaultValue: z.union([z.string(), z.number(), z.boolean(), z.null(), z.object({ type: z.string(), value: z.string().optional() })]).optional().describe("Literal default or { type: 'UUIDV4'|'SUID'|'NOW'|'AUTOINCREMENT'|'SQL', value?: 'expr' }."),
|
|
450
|
+
values: z.object({
|
|
451
|
+
length: z.number().optional().describe("Required for String/VARCHAR"),
|
|
452
|
+
precision: z.number().optional().describe("Required for Decimal"),
|
|
453
|
+
scale: z.number().optional().describe("Required for Decimal"),
|
|
454
|
+
type: z.string().optional().describe("Required for Array element type"),
|
|
455
|
+
values: z.array(z.string()).optional().describe("Required for Enum allowed values"),
|
|
456
|
+
}).optional(),
|
|
457
|
+
description: z.string().optional().describe("Field description (metadata only)"),
|
|
458
|
+
}).passthrough()).optional().describe("The COMPLETE field definitions — ALL existing fields plus your changes. This REPLACES the entire fields object. Missing fields will be removed from schema definition."),
|
|
401
459
|
})
|
|
402
460
|
.passthrough()
|
|
403
|
-
.describe("The COMPLETE schema definition.
|
|
461
|
+
.describe("The COMPLETE schema definition. Replaces the entire schema. Fetch current schema with baasix_get_schema first, then include ALL fields plus your additions/modifications."),
|
|
404
462
|
}, async (args, extra) => {
|
|
405
463
|
const { collection, schema } = args;
|
|
406
464
|
const res = await callRoute('PATCH', `/schemas/${encodeURIComponent(collection)}`, extra, { schema });
|
|
@@ -408,6 +466,113 @@ EXAMPLE — Adding a "description" field to an existing "products" table that ha
|
|
|
408
466
|
return errorResult(res.error || `Failed to update collection '${collection}'`);
|
|
409
467
|
return successResult({ success: true, message: `Collection '${collection}' updated successfully` });
|
|
410
468
|
});
|
|
469
|
+
registerTool("baasix_add_schema_field", `Add a single field/column to an existing collection without sending the full schema.
|
|
470
|
+
Use this instead of baasix_update_schema when you only need to add one column.
|
|
471
|
+
Do NOT use for relation fields — use baasix_create_relationship for foreign keys.
|
|
472
|
+
|
|
473
|
+
FIELD TYPES:
|
|
474
|
+
- String/Text: String, Text, TEXT, CiText, HTML
|
|
475
|
+
- Numbers: Integer, BigInt, Decimal, Float, Real, Double, DOUBLE
|
|
476
|
+
- Date/time: Date, DateTime, DateTime_NO_TZ, Time, Time_NO_TZ
|
|
477
|
+
- IDs/tokens: UUID, SUID, TOKEN
|
|
478
|
+
- JSON/enums/virtual: JSON, JSONB, Enum, ENUM, VIRTUAL
|
|
479
|
+
- Arrays: Array_Integer, Array_String, Array_Double, Array_Decimal, Array_DateTime, Array_DateTime_NO_TZ, Array_Date, Array_Time, Array_Time_NO_TZ, Array_UUID, Array_Boolean
|
|
480
|
+
- Ranges: Range_Integer, Range_Double, Range_Decimal, Range_Date, Range_DateTime, Range_DateTime_NO_TZ, Range_Time, Range_Time_NO_TZ
|
|
481
|
+
- PostGIS: Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, GeometryCollection, Geography
|
|
482
|
+
|
|
483
|
+
COMMON TYPE-SPECIFIC RULES:
|
|
484
|
+
- String: requires values.length (e.g. 255)
|
|
485
|
+
- Decimal: requires values.precision and values.scale
|
|
486
|
+
- Enum/ENUM: requires values.values array
|
|
487
|
+
- Array_* / Range_* / PostGIS types use explicit type names (recommended over generic aliases)
|
|
488
|
+
|
|
489
|
+
EXAMPLE — Add a nullable "bio" text column:
|
|
490
|
+
{ collection: "users", fieldName: "bio", field: { type: "Text", allowNull: true } }
|
|
491
|
+
|
|
492
|
+
EXAMPLE — Add a "status" enum with default:
|
|
493
|
+
{ collection: "orders", fieldName: "status", field: { type: "Enum", allowNull: false, defaultValue: "pending", values: { values: ["pending","processing","shipped","delivered"] } } }`, {
|
|
494
|
+
collection: z.string().describe("Name of the collection/table to add the field to"),
|
|
495
|
+
fieldName: z.string().describe("Column name to create. Must be a valid PostgreSQL identifier (letters, numbers, underscores; cannot start with a number). Max 63 chars."),
|
|
496
|
+
field: z
|
|
497
|
+
.object({
|
|
498
|
+
type: z.string().describe(`${SUPPORTED_SCHEMA_FIELD_TYPES_DESCRIPTION} Prefer explicit array/range/postgis types (for example Array_UUID, Range_DateTime, Point) over generic aliases.`),
|
|
499
|
+
allowNull: z.boolean().optional().describe("Whether the column can be NULL. Default: true. Set false to enforce NOT NULL."),
|
|
500
|
+
unique: z.boolean().optional().describe("Set true to add a UNIQUE constraint — no two rows can have the same value."),
|
|
501
|
+
primaryKey: z.boolean().optional().describe("Mark this column as the primary key. Rarely needed for new fields; typically only 'id' is the PK."),
|
|
502
|
+
defaultValue: z.union([
|
|
503
|
+
z.string(), z.number(), z.boolean(), z.null(),
|
|
504
|
+
z.object({ type: z.enum(["UUIDV4", "SUID", "NOW", "AUTOINCREMENT", "SQL"]), value: z.string().optional() })
|
|
505
|
+
]).optional().describe("Default value for the column. Use a literal (e.g. 0, 'active', true) or a special object: { type: 'UUIDV4' } for auto UUID, { type: 'SUID' } for short ID, { type: 'NOW' } for current timestamp, { type: 'AUTOINCREMENT' } for auto-increment integer, { type: 'SQL', value: 'expr' } for raw SQL expression."),
|
|
506
|
+
values: z.object({
|
|
507
|
+
length: z.number().optional().describe("Max character length — required for String/VARCHAR (e.g. 255)"),
|
|
508
|
+
precision: z.number().optional().describe("Total number of digits — required for Decimal (e.g. 10)"),
|
|
509
|
+
scale: z.number().optional().describe("Number of decimal places — required for Decimal (e.g. 2)"),
|
|
510
|
+
type: z.string().optional().describe("Element data type — required for Array (e.g. 'String', 'Integer', 'UUID')"),
|
|
511
|
+
values: z.array(z.string()).optional().describe("Allowed enum values — required for Enum (e.g. ['active','inactive','pending'])"),
|
|
512
|
+
}).optional().describe("Type-specific configuration: String→{length}, Decimal→{precision,scale}, Array→{type}, Enum→{values:[...]}"),
|
|
513
|
+
description: z.string().optional().describe("Human-readable description stored in schema metadata only, not in the DB column."),
|
|
514
|
+
})
|
|
515
|
+
.passthrough()
|
|
516
|
+
.describe("Field/column definition object"),
|
|
517
|
+
}, async (args, extra) => {
|
|
518
|
+
const { collection, fieldName, field } = args;
|
|
519
|
+
const res = await callRoute('POST', `/schemas/${encodeURIComponent(collection)}/fields`, extra, { fieldName, field });
|
|
520
|
+
if (!res.ok)
|
|
521
|
+
return errorResult(res.error || `Failed to add field '${fieldName}' to '${collection}'`);
|
|
522
|
+
return successResult({ success: true, message: `Field '${fieldName}' added to '${collection}' successfully` });
|
|
523
|
+
});
|
|
524
|
+
registerTool("baasix_update_schema_field", `Update properties of a single existing field/column in a collection.
|
|
525
|
+
This is a PARTIAL update — only the properties you send are merged into the existing field definition.
|
|
526
|
+
Do NOT use for relation fields — use baasix_update_relationship instead.
|
|
527
|
+
|
|
528
|
+
EXAMPLE — Make a field non-nullable:
|
|
529
|
+
{ collection: "products", fieldName: "name", field: { allowNull: false } }
|
|
530
|
+
|
|
531
|
+
EXAMPLE — Change a String field's max length:
|
|
532
|
+
{ collection: "users", fieldName: "username", field: { type: "String", values: { length: 100 } } }
|
|
533
|
+
|
|
534
|
+
EXAMPLE — Add a default value to an existing field:
|
|
535
|
+
{ collection: "orders", fieldName: "status", field: { defaultValue: "pending" } }`, {
|
|
536
|
+
collection: z.string().describe("Name of the collection/table that contains the field"),
|
|
537
|
+
fieldName: z.string().describe("Name of the existing field/column to update. Use baasix_get_schema to see all fields."),
|
|
538
|
+
field: z
|
|
539
|
+
.object({
|
|
540
|
+
type: z.string().optional().describe(`${SUPPORTED_SCHEMA_FIELD_TYPES_DESCRIPTION} Changing type on a populated column may require data migration.`),
|
|
541
|
+
allowNull: z.boolean().optional().describe("Set false to add a NOT NULL constraint, true to allow NULLs."),
|
|
542
|
+
unique: z.boolean().optional().describe("Set true to add a UNIQUE constraint, false to remove it."),
|
|
543
|
+
defaultValue: z.union([
|
|
544
|
+
z.string(), z.number(), z.boolean(), z.null(),
|
|
545
|
+
z.object({ type: z.enum(["UUIDV4", "SUID", "NOW", "AUTOINCREMENT", "SQL"]), value: z.string().optional() })
|
|
546
|
+
]).optional().describe("New default value. Literal or special object: { type: 'UUIDV4'|'SUID'|'NOW'|'AUTOINCREMENT'|'SQL', value?: 'expr' }."),
|
|
547
|
+
values: z.object({
|
|
548
|
+
length: z.number().optional().describe("Max character length for String/VARCHAR"),
|
|
549
|
+
precision: z.number().optional().describe("Total digits for Decimal"),
|
|
550
|
+
scale: z.number().optional().describe("Decimal places for Decimal"),
|
|
551
|
+
type: z.string().optional().describe("Element type for Array"),
|
|
552
|
+
values: z.array(z.string()).optional().describe("Allowed values for Enum"),
|
|
553
|
+
}).optional().describe("Type-specific settings to update"),
|
|
554
|
+
description: z.string().optional().describe("Human-readable description stored in schema metadata"),
|
|
555
|
+
})
|
|
556
|
+
.passthrough()
|
|
557
|
+
.describe("Partial field definition — only the properties you include are merged into the existing field"),
|
|
558
|
+
}, async (args, extra) => {
|
|
559
|
+
const { collection, fieldName, field } = args;
|
|
560
|
+
const res = await callRoute('PATCH', `/schemas/${encodeURIComponent(collection)}/fields/${encodeURIComponent(fieldName)}`, extra, { field });
|
|
561
|
+
if (!res.ok)
|
|
562
|
+
return errorResult(res.error || `Failed to update field '${fieldName}' in '${collection}'`);
|
|
563
|
+
return successResult({ success: true, message: `Field '${fieldName}' updated in '${collection}' successfully` });
|
|
564
|
+
});
|
|
565
|
+
registerTool("baasix_delete_schema_field", `Delete a single field/column from a collection.
|
|
566
|
+
This updates schema definition only via schema manager logic and does not directly execute DROP COLUMN SQL.`, {
|
|
567
|
+
collection: z.string().describe("Collection name"),
|
|
568
|
+
fieldName: z.string().describe("Field/column name to delete"),
|
|
569
|
+
}, async (args, extra) => {
|
|
570
|
+
const { collection, fieldName } = args;
|
|
571
|
+
const res = await callRoute('DELETE', `/schemas/${encodeURIComponent(collection)}/fields/${encodeURIComponent(fieldName)}`, extra);
|
|
572
|
+
if (!res.ok)
|
|
573
|
+
return errorResult(res.error || `Failed to delete field '${fieldName}' from '${collection}'`);
|
|
574
|
+
return successResult({ success: true, message: `Field '${fieldName}' deleted from '${collection}' successfully` });
|
|
575
|
+
});
|
|
411
576
|
registerTool("baasix_delete_schema", `DROP/DELETE an entire database table and all its data permanently.
|
|
412
577
|
Use this when asked to 'drop a table', 'delete a collection', or 'remove a table'.
|
|
413
578
|
|
|
@@ -481,21 +646,22 @@ PARAMETERS:
|
|
|
481
646
|
- target: the related table (e.g., "categories")
|
|
482
647
|
- alias: reverse-access name on the target table (e.g., "products" so categories.products works)
|
|
483
648
|
- onDelete: CASCADE | RESTRICT | SET NULL
|
|
649
|
+
- through: optional custom junction table for M2M/M2A. Recommendation: include "_junction" suffix (for example "products_tags_junction") for naming consistency.
|
|
484
650
|
|
|
485
651
|
EXAMPLE — products belongsTo categories:
|
|
486
652
|
sourceCollection: "products"
|
|
487
653
|
relationshipData: { "name": "category", "type": "M2O", "target": "categories", "alias": "products", "onDelete": "CASCADE" }`, {
|
|
488
|
-
sourceCollection: z.string().describe("
|
|
654
|
+
sourceCollection: z.string().describe("Name of the collection/table that will own the relationship (the table that gets the FK column for M2O/O2O)."),
|
|
489
655
|
relationshipData: z
|
|
490
656
|
.object({
|
|
491
|
-
name: z.string().describe("
|
|
492
|
-
type: z.enum(["M2O", "O2M", "O2O", "M2M", "M2A"]).describe("Relationship type"),
|
|
493
|
-
target: z.string().optional().describe("
|
|
494
|
-
alias: z.string().optional().describe("
|
|
495
|
-
onDelete: z.enum(["CASCADE", "RESTRICT", "SET NULL"]).optional().describe("
|
|
496
|
-
onUpdate: z.enum(["CASCADE", "RESTRICT", "SET NULL"]).optional().describe("
|
|
497
|
-
tables: z.array(z.string()).optional().describe("
|
|
498
|
-
through: z.string().optional().describe("Custom junction table
|
|
657
|
+
name: z.string().describe("Field name for the relationship in the source collection (e.g. 'category'). For M2O/O2O this creates a '{name}_Id' FK column. Used to access the relation (e.g. product.category). Keep it lowercase camelCase."),
|
|
658
|
+
type: z.enum(["M2O", "O2M", "O2O", "M2M", "M2A"]).describe("Relationship type: M2O=BelongsTo (adds FK column to source), O2M=HasMany (virtual reverse, no column), O2O=HasOne (unique FK), M2M=Many-to-Many (auto-creates junction table), M2A=Polymorphic (one source to many different target types)."),
|
|
659
|
+
target: z.string().optional().describe("Name of the target collection/table being referenced. Required for M2O, O2M, O2O, M2M. For M2A use 'tables' instead."),
|
|
660
|
+
alias: z.string().optional().describe("Reverse-access name added to the target collection (e.g. if products M2O categories with alias='products', then categories.products returns all related products). Defaults to the source collection name."),
|
|
661
|
+
onDelete: z.enum(["CASCADE", "RESTRICT", "SET NULL"]).optional().describe("What happens to the source record when the referenced target record is deleted. CASCADE=delete source too, RESTRICT=prevent target deletion if source exists, SET NULL=set FK to NULL."),
|
|
662
|
+
onUpdate: z.enum(["CASCADE", "RESTRICT", "SET NULL"]).optional().describe("What happens to the FK when the target PK changes. CASCADE=update FK automatically, RESTRICT=block update, SET NULL=set FK to NULL."),
|
|
663
|
+
tables: z.array(z.string()).optional().describe("Required for M2A only. Array of target collection names this collection can relate to polymorphically (e.g. ['images','documents','videos'])."),
|
|
664
|
+
through: z.string().optional().describe("Custom name for the auto-created junction table in M2M/M2A. Recommended naming: include '_junction' suffix (example: 'products_tags_junction'). If omitted, Baasix auto-generates '{source}_{target}_junction'."),
|
|
499
665
|
})
|
|
500
666
|
.describe("Relationship configuration"),
|
|
501
667
|
}, async (args, extra) => {
|
|
@@ -849,7 +1015,8 @@ Each permission defines: role_Id (which role), collection (which table), action
|
|
|
849
1015
|
Filter examples:
|
|
850
1016
|
All permissions for a role: {"role_Id": {"eq": "<role-uuid>"}}
|
|
851
1017
|
All read permissions: {"action": {"eq": "read"}}
|
|
852
|
-
Permissions for a table: {"collection": {"eq": "products"}}
|
|
1018
|
+
Permissions for a table: {"collection": {"eq": "products"}}
|
|
1019
|
+
Single targeted permission (role + collection + optional action): {"AND": [{"role_Id": {"eq": "<role-uuid>"}}, {"collection": {"eq": "products"}}, {"action": {"eq": "read"}}]}`, {
|
|
853
1020
|
filter: z.record(z.any()).optional().describe("Filter: {\"role_Id\": {\"eq\": \"<uuid>\"}}, {\"collection\": {\"eq\": \"products\"}}, {\"action\": {\"eq\": \"read\"}}"),
|
|
854
1021
|
sort: z.string().optional().describe("Sort as 'field:asc' or 'field:desc'"),
|
|
855
1022
|
page: z.number().optional().default(1).describe("Page number"),
|
|
@@ -1417,6 +1584,56 @@ Accepts either the role name (e.g., "editor", "public") or the role UUID.`, {
|
|
|
1417
1584
|
return errorResult(error);
|
|
1418
1585
|
}
|
|
1419
1586
|
});
|
|
1587
|
+
registerTool("baasix_get_role_collection_permissions", `Get permissions for one specific role and collection, with optional action filter.
|
|
1588
|
+
Use this when you want a targeted RBAC check instead of listing all permissions.
|
|
1589
|
+
|
|
1590
|
+
Accepts role name (e.g., "editor", "public") or role UUID.
|
|
1591
|
+
Returns matching permission rows for that role+collection (and action if provided).`, {
|
|
1592
|
+
role: z.string().describe("Role name (e.g., 'editor', 'public') or role UUID"),
|
|
1593
|
+
collection: z.string().describe("Collection/table name to filter permissions for"),
|
|
1594
|
+
action: z.enum(["create", "read", "update", "delete"]).optional().describe("Optional action filter. If omitted, returns all actions for the role+collection."),
|
|
1595
|
+
}, async (args, extra) => {
|
|
1596
|
+
const { role, collection, action } = args;
|
|
1597
|
+
try {
|
|
1598
|
+
// Find role by name or id
|
|
1599
|
+
const roleParams = new URLSearchParams();
|
|
1600
|
+
roleParams.append('filter', JSON.stringify({ OR: [{ name: { eq: role } }, { id: { eq: role } }] }));
|
|
1601
|
+
roleParams.append('limit', '1');
|
|
1602
|
+
const rolesRes = await callRoute('GET', `/items/baasix_Role?${roleParams}`, extra);
|
|
1603
|
+
if (!rolesRes.ok)
|
|
1604
|
+
return errorResult(rolesRes.error || `Failed to look up role '${role}'`);
|
|
1605
|
+
const rolesData = rolesRes.data?.data || rolesRes.data;
|
|
1606
|
+
if (!Array.isArray(rolesData) || !rolesData.length) {
|
|
1607
|
+
return errorResult(`Role '${role}' not found`);
|
|
1608
|
+
}
|
|
1609
|
+
const roleId = rolesData[0].id;
|
|
1610
|
+
const filter = {
|
|
1611
|
+
role_Id: { eq: roleId },
|
|
1612
|
+
collection: { eq: collection },
|
|
1613
|
+
};
|
|
1614
|
+
if (action) {
|
|
1615
|
+
filter.action = { eq: action };
|
|
1616
|
+
}
|
|
1617
|
+
const permParams = new URLSearchParams();
|
|
1618
|
+
permParams.append('filter', JSON.stringify(filter));
|
|
1619
|
+
permParams.append('limit', '-1');
|
|
1620
|
+
const permRes = await callRoute('GET', `/permissions?${permParams}`, extra);
|
|
1621
|
+
if (!permRes.ok)
|
|
1622
|
+
return errorResult(permRes.error || 'Failed to get targeted permissions');
|
|
1623
|
+
const data = permRes.data?.data || permRes.data;
|
|
1624
|
+
const permissions = Array.isArray(data) ? data : [];
|
|
1625
|
+
return successResult({
|
|
1626
|
+
role: rolesData[0],
|
|
1627
|
+
collection,
|
|
1628
|
+
action: action || null,
|
|
1629
|
+
permissions,
|
|
1630
|
+
totalCount: permissions.length,
|
|
1631
|
+
});
|
|
1632
|
+
}
|
|
1633
|
+
catch (error) {
|
|
1634
|
+
return errorResult(error);
|
|
1635
|
+
}
|
|
1636
|
+
});
|
|
1420
1637
|
// ==================== Update Permissions for Role Tool ====================
|
|
1421
1638
|
registerTool("baasix_update_permissions", `Bulk set/update access control permissions for a role — define which tables a role can create, read, update, or delete. Creates new permissions or updates existing ones. Automatically reloads the permission cache.
|
|
1422
1639
|
|
|
@@ -1759,17 +1976,19 @@ Returns authenticated: false if no user is logged in (public/anonymous access).`
|
|
|
1759
1976
|
}
|
|
1760
1977
|
});
|
|
1761
1978
|
// ==================== Update Relationship Tool ====================
|
|
1762
|
-
registerTool("baasix_update_relationship",
|
|
1763
|
-
|
|
1764
|
-
|
|
1979
|
+
registerTool("baasix_update_relationship", `Modify configuration of an existing foreign key / relationship (e.g. change delete behavior or alias).
|
|
1980
|
+
This does NOT change the relationship type or target — to do that, delete and recreate the relationship.
|
|
1981
|
+
Use baasix_get_schema first to see the current relationship configuration.`, {
|
|
1982
|
+
sourceCollection: z.string().describe("Name of the collection that owns the relationship (the table with the FK column)."),
|
|
1983
|
+
relationshipName: z.string().describe("Name of the relationship field to update. Use baasix_get_schema to see existing relationships and their exact names."),
|
|
1765
1984
|
relationshipData: z
|
|
1766
1985
|
.object({
|
|
1767
|
-
alias: z.string().optional().describe("
|
|
1768
|
-
onDelete: z.enum(["CASCADE", "RESTRICT", "SET NULL"]).optional().describe("
|
|
1769
|
-
onUpdate: z.enum(["CASCADE", "RESTRICT", "SET NULL"]).optional().describe("
|
|
1770
|
-
description: z.string().optional().describe("
|
|
1986
|
+
alias: z.string().optional().describe("New reverse-access name on the target collection (e.g. 'orders' on baasix_User so user.orders returns all related orders)."),
|
|
1987
|
+
onDelete: z.enum(["CASCADE", "RESTRICT", "SET NULL"]).optional().describe("What happens to the source record when the referenced target is deleted. CASCADE=delete source too, RESTRICT=block deletion, SET NULL=set FK to NULL."),
|
|
1988
|
+
onUpdate: z.enum(["CASCADE", "RESTRICT", "SET NULL"]).optional().describe("What happens to the FK when the target PK changes. CASCADE=update FK, RESTRICT=block update, SET NULL=set FK to NULL."),
|
|
1989
|
+
description: z.string().optional().describe("Human-readable description stored in schema metadata only."),
|
|
1771
1990
|
})
|
|
1772
|
-
.describe("Updated relationship configuration"),
|
|
1991
|
+
.describe("Updated relationship configuration — only include the properties you want to change"),
|
|
1773
1992
|
}, async (args, extra) => {
|
|
1774
1993
|
const { sourceCollection, relationshipName, relationshipData } = args;
|
|
1775
1994
|
const res = await callRoute('PATCH', `/schemas/${encodeURIComponent(sourceCollection)}/relationships/${encodeURIComponent(relationshipName)}`, extra, relationshipData);
|