mcp-quickbase 2.0.5 → 2.2.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/.crewchief/runs/state.json +3 -0
- package/.mcp.json +6 -32
- package/.sdd/tickets/RELS_relationship-management/README.md +98 -0
- package/.sdd/tickets/RELS_relationship-management/planning/analysis.md +190 -0
- package/.sdd/tickets/RELS_relationship-management/planning/architecture.md +413 -0
- package/.sdd/tickets/RELS_relationship-management/planning/plan.md +177 -0
- package/.sdd/tickets/RELS_relationship-management/planning/quality-strategy.md +335 -0
- package/.sdd/tickets/RELS_relationship-management/planning/review-updates.md +95 -0
- package/.sdd/tickets/RELS_relationship-management/planning/security-review.md +213 -0
- package/.sdd/tickets/RELS_relationship-management/planning/ticket-review.md +885 -0
- package/.sdd/tickets/RELS_relationship-management/tasks/RELS.1001_domain-setup.md +96 -0
- package/.sdd/tickets/RELS_relationship-management/tasks/RELS.1002_get-relationships-tool.md +142 -0
- package/.sdd/tickets/RELS_relationship-management/tasks/RELS.1003_register-phase1-tools.md +105 -0
- package/.sdd/tickets/RELS_relationship-management/tasks/RELS.2001_create-relationship-tool.md +151 -0
- package/.sdd/tickets/RELS_relationship-management/tasks/RELS.2002_update-relationship-tool.md +145 -0
- package/.sdd/tickets/RELS_relationship-management/tasks/RELS.3001_delete-relationship-tool.md +154 -0
- package/.sdd/tickets/RELS_relationship-management/tasks/RELS.4001_integration-testing.md +159 -0
- package/.sdd/tickets/RELS_relationship-management/tasks/RELS.4002_final-verification.md +182 -0
- package/.sdd/tickets/RELS_relationship-management/tasks/RELS_TASK_INDEX.md +179 -0
- package/crewchief.config.js +31 -0
- package/dist/client/quickbase.d.ts +7 -2
- package/dist/client/quickbase.js +64 -51
- package/dist/client/quickbase.js.map +1 -1
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/server.d.ts +3 -3
- package/dist/mcp/server.js +21 -17
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp-stdio-server.js +64 -49
- package/dist/mcp-stdio-server.js.map +1 -1
- package/dist/server.js +84 -83
- package/dist/server.js.map +1 -1
- package/dist/tools/apps/create_app.d.ts +2 -2
- package/dist/tools/apps/create_app.js +23 -23
- package/dist/tools/apps/create_app.js.map +1 -1
- package/dist/tools/apps/index.d.ts +4 -4
- package/dist/tools/apps/index.js +3 -3
- package/dist/tools/apps/list_tables.d.ts +7 -7
- package/dist/tools/apps/list_tables.js +28 -27
- package/dist/tools/apps/list_tables.js.map +1 -1
- package/dist/tools/apps/update_app.d.ts +2 -2
- package/dist/tools/apps/update_app.js +28 -26
- package/dist/tools/apps/update_app.js.map +1 -1
- package/dist/tools/base.d.ts +3 -3
- package/dist/tools/base.js +7 -7
- package/dist/tools/base.js.map +1 -1
- package/dist/tools/configure_cache.d.ts +3 -3
- package/dist/tools/configure_cache.js +16 -16
- package/dist/tools/configure_cache.js.map +1 -1
- package/dist/tools/fields/create_field.d.ts +8 -7
- package/dist/tools/fields/create_field.js +39 -29
- package/dist/tools/fields/create_field.js.map +1 -1
- package/dist/tools/fields/delete_field.d.ts +79 -0
- package/dist/tools/fields/delete_field.js +105 -0
- package/dist/tools/fields/delete_field.js.map +1 -0
- package/dist/tools/fields/get_field.d.ts +91 -0
- package/dist/tools/fields/get_field.js +82 -0
- package/dist/tools/fields/get_field.js.map +1 -0
- package/dist/tools/fields/index.d.ts +5 -3
- package/dist/tools/fields/index.js +11 -5
- package/dist/tools/fields/index.js.map +1 -1
- package/dist/tools/fields/update_field.d.ts +7 -15
- package/dist/tools/fields/update_field.js +39 -38
- package/dist/tools/fields/update_field.js.map +1 -1
- package/dist/tools/files/download_file.d.ts +2 -2
- package/dist/tools/files/download_file.js +35 -35
- package/dist/tools/files/download_file.js.map +1 -1
- package/dist/tools/files/index.d.ts +3 -3
- package/dist/tools/files/index.js +3 -3
- package/dist/tools/files/upload_file.d.ts +2 -2
- package/dist/tools/files/upload_file.js +52 -44
- package/dist/tools/files/upload_file.js.map +1 -1
- package/dist/tools/index.d.ts +13 -12
- package/dist/tools/index.js +6 -3
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/records/bulk_create_records.d.ts +2 -2
- package/dist/tools/records/bulk_create_records.js +28 -28
- package/dist/tools/records/bulk_create_records.js.map +1 -1
- package/dist/tools/records/bulk_update_records.d.ts +2 -2
- package/dist/tools/records/bulk_update_records.js +27 -27
- package/dist/tools/records/bulk_update_records.js.map +1 -1
- package/dist/tools/records/create_record.d.ts +2 -2
- package/dist/tools/records/create_record.js +40 -40
- package/dist/tools/records/create_record.js.map +1 -1
- package/dist/tools/records/index.d.ts +6 -6
- package/dist/tools/records/index.js +3 -3
- package/dist/tools/records/query_records.d.ts +3 -3
- package/dist/tools/records/query_records.js +82 -78
- package/dist/tools/records/query_records.js.map +1 -1
- package/dist/tools/records/update_record.d.ts +2 -2
- package/dist/tools/records/update_record.js +31 -29
- package/dist/tools/records/update_record.js.map +1 -1
- package/dist/tools/registry.d.ts +1 -1
- package/dist/tools/registry.js +1 -1
- package/dist/tools/relationships/create_relationship.d.ts +150 -0
- package/dist/tools/relationships/create_relationship.js +181 -0
- package/dist/tools/relationships/create_relationship.js.map +1 -0
- package/dist/tools/relationships/delete_relationship.d.ts +66 -0
- package/dist/tools/relationships/delete_relationship.js +85 -0
- package/dist/tools/relationships/delete_relationship.js.map +1 -0
- package/dist/tools/relationships/get_relationships.d.ts +126 -0
- package/dist/tools/relationships/get_relationships.js +126 -0
- package/dist/tools/relationships/get_relationships.js.map +1 -0
- package/dist/tools/relationships/index.d.ts +14 -0
- package/dist/tools/relationships/index.js +37 -0
- package/dist/tools/relationships/index.js.map +1 -0
- package/dist/tools/relationships/update_relationship.d.ts +139 -0
- package/dist/tools/relationships/update_relationship.js +168 -0
- package/dist/tools/relationships/update_relationship.js.map +1 -0
- package/dist/tools/reports/index.d.ts +2 -2
- package/dist/tools/reports/index.js +3 -3
- package/dist/tools/reports/run_report.d.ts +3 -3
- package/dist/tools/reports/run_report.js +29 -29
- package/dist/tools/reports/run_report.js.map +1 -1
- package/dist/tools/tables/create_table.d.ts +2 -49
- package/dist/tools/tables/create_table.js +26 -49
- package/dist/tools/tables/create_table.js.map +1 -1
- package/dist/tools/tables/get_table_fields.d.ts +2 -2
- package/dist/tools/tables/get_table_fields.js +25 -25
- package/dist/tools/tables/get_table_fields.js.map +1 -1
- package/dist/tools/tables/index.d.ts +4 -4
- package/dist/tools/tables/index.js +3 -3
- package/dist/tools/tables/update_table.d.ts +2 -2
- package/dist/tools/tables/update_table.js +28 -26
- package/dist/tools/tables/update_table.js.map +1 -1
- package/dist/tools/test_connection.d.ts +2 -2
- package/dist/tools/test_connection.js +28 -28
- package/dist/tools/test_connection.js.map +1 -1
- package/dist/types/api.d.ts +1 -1
- package/dist/types/mcp.d.ts +1 -1
- package/dist/utils/cache.js +16 -16
- package/dist/utils/cache.js.map +1 -1
- package/dist/utils/file.js +44 -40
- package/dist/utils/file.js.map +1 -1
- package/dist/utils/logger.js +30 -28
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/retry.js +10 -10
- package/dist/utils/retry.js.map +1 -1
- package/dist/utils/validation.d.ts +1 -1
- package/dist/utils/validation.js +39 -36
- package/dist/utils/validation.js.map +1 -1
- package/docs/README.md +6 -0
- package/docs/future-improvements.md +33 -0
- package/docs/migration-guide.md +160 -0
- package/docs/release-notes.md +89 -0
- package/package.json +5 -4
- /package/{HARDENING_SUMMARY.md → docs/hardening-summary.md} +0 -0
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.CreateRecordTool = void 0;
|
|
4
4
|
const base_1 = require("../base");
|
|
5
5
|
const logger_1 = require("../../utils/logger");
|
|
6
|
-
const logger = (0, logger_1.createLogger)(
|
|
6
|
+
const logger = (0, logger_1.createLogger)("CreateRecordTool");
|
|
7
7
|
/**
|
|
8
8
|
* Tool for creating a new record in a Quickbase table
|
|
9
9
|
*/
|
|
@@ -14,24 +14,24 @@ class CreateRecordTool extends base_1.BaseTool {
|
|
|
14
14
|
*/
|
|
15
15
|
constructor(client) {
|
|
16
16
|
super(client);
|
|
17
|
-
this.name =
|
|
18
|
-
this.description =
|
|
17
|
+
this.name = "create_record";
|
|
18
|
+
this.description = "Creates a new record in a Quickbase table";
|
|
19
19
|
/**
|
|
20
20
|
* Parameter schema for create_record
|
|
21
21
|
*/
|
|
22
22
|
this.paramSchema = {
|
|
23
|
-
type:
|
|
23
|
+
type: "object",
|
|
24
24
|
properties: {
|
|
25
25
|
table_id: {
|
|
26
|
-
type:
|
|
27
|
-
description:
|
|
26
|
+
type: "string",
|
|
27
|
+
description: "The ID of the Quickbase table",
|
|
28
28
|
},
|
|
29
29
|
data: {
|
|
30
|
-
type:
|
|
31
|
-
description:
|
|
32
|
-
}
|
|
30
|
+
type: "object",
|
|
31
|
+
description: "The data for the new record, as field ID/value pairs",
|
|
32
|
+
},
|
|
33
33
|
},
|
|
34
|
-
required: [
|
|
34
|
+
required: ["table_id", "data"],
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
@@ -41,12 +41,12 @@ class CreateRecordTool extends base_1.BaseTool {
|
|
|
41
41
|
*/
|
|
42
42
|
async run(params) {
|
|
43
43
|
const { table_id, data } = params;
|
|
44
|
-
logger.info(
|
|
45
|
-
tableId: table_id
|
|
44
|
+
logger.info("Creating new record in Quickbase table", {
|
|
45
|
+
tableId: table_id,
|
|
46
46
|
});
|
|
47
47
|
// Validate data
|
|
48
|
-
if (!data || typeof data !==
|
|
49
|
-
throw new Error(
|
|
48
|
+
if (!data || typeof data !== "object" || Object.keys(data).length === 0) {
|
|
49
|
+
throw new Error("Record data is required and must be a non-empty object");
|
|
50
50
|
}
|
|
51
51
|
// Prepare record data
|
|
52
52
|
// Convert data to { [fieldId]: { value: fieldValue } } format expected by the API
|
|
@@ -57,65 +57,65 @@ class CreateRecordTool extends base_1.BaseTool {
|
|
|
57
57
|
// Prepare request body
|
|
58
58
|
const body = {
|
|
59
59
|
to: table_id,
|
|
60
|
-
data: [recordData]
|
|
60
|
+
data: [recordData],
|
|
61
61
|
};
|
|
62
62
|
// Create the record
|
|
63
63
|
const response = await this.client.request({
|
|
64
|
-
method:
|
|
65
|
-
path:
|
|
66
|
-
body
|
|
64
|
+
method: "POST",
|
|
65
|
+
path: "/records",
|
|
66
|
+
body,
|
|
67
67
|
});
|
|
68
68
|
if (!response.success || !response.data) {
|
|
69
|
-
logger.error(
|
|
69
|
+
logger.error("Failed to create record", {
|
|
70
70
|
error: response.error,
|
|
71
|
-
tableId: table_id
|
|
71
|
+
tableId: table_id,
|
|
72
72
|
});
|
|
73
|
-
throw new Error(response.error?.message ||
|
|
73
|
+
throw new Error(response.error?.message || "Failed to create record");
|
|
74
74
|
}
|
|
75
75
|
// Safely validate response structure
|
|
76
|
-
if (typeof response.data !==
|
|
77
|
-
throw new Error(
|
|
76
|
+
if (typeof response.data !== "object" || response.data === null) {
|
|
77
|
+
throw new Error("Invalid API response: data is not an object");
|
|
78
78
|
}
|
|
79
79
|
const result = response.data;
|
|
80
80
|
// Validate metadata exists and is an object
|
|
81
|
-
if (typeof result.metadata !==
|
|
82
|
-
logger.error(
|
|
83
|
-
response: result
|
|
81
|
+
if (typeof result.metadata !== "object" || result.metadata === null) {
|
|
82
|
+
logger.error("Record creation response missing metadata", {
|
|
83
|
+
response: result,
|
|
84
84
|
});
|
|
85
|
-
throw new Error(
|
|
85
|
+
throw new Error("Record created but response metadata is missing");
|
|
86
86
|
}
|
|
87
87
|
const metadata = result.metadata;
|
|
88
88
|
// Validate createdRecordIds exists and is an array
|
|
89
89
|
if (!Array.isArray(metadata.createdRecordIds)) {
|
|
90
|
-
logger.error(
|
|
91
|
-
metadata
|
|
90
|
+
logger.error("Record creation response missing createdRecordIds array", {
|
|
91
|
+
metadata,
|
|
92
92
|
});
|
|
93
|
-
throw new Error(
|
|
93
|
+
throw new Error("Record created but no record IDs array was returned");
|
|
94
94
|
}
|
|
95
95
|
const createdRecordIds = metadata.createdRecordIds;
|
|
96
96
|
if (createdRecordIds.length === 0) {
|
|
97
|
-
logger.error(
|
|
98
|
-
metadata
|
|
97
|
+
logger.error("Record creation response has empty createdRecordIds array", {
|
|
98
|
+
metadata,
|
|
99
99
|
});
|
|
100
|
-
throw new Error(
|
|
100
|
+
throw new Error("Record created but no record ID was returned");
|
|
101
101
|
}
|
|
102
102
|
// Validate first record ID is a string
|
|
103
103
|
const recordId = createdRecordIds[0];
|
|
104
|
-
if (typeof recordId !==
|
|
105
|
-
logger.error(
|
|
104
|
+
if (typeof recordId !== "string") {
|
|
105
|
+
logger.error("Record creation response has invalid record ID type", {
|
|
106
106
|
recordId,
|
|
107
|
-
type: typeof recordId
|
|
107
|
+
type: typeof recordId,
|
|
108
108
|
});
|
|
109
|
-
throw new Error(
|
|
109
|
+
throw new Error("Record created but returned record ID is not a string");
|
|
110
110
|
}
|
|
111
|
-
logger.info(
|
|
111
|
+
logger.info("Successfully created record", {
|
|
112
112
|
recordId,
|
|
113
|
-
tableId: table_id
|
|
113
|
+
tableId: table_id,
|
|
114
114
|
});
|
|
115
115
|
return {
|
|
116
116
|
recordId,
|
|
117
117
|
tableId: table_id,
|
|
118
|
-
createdTime: new Date().toISOString()
|
|
118
|
+
createdTime: new Date().toISOString(),
|
|
119
119
|
};
|
|
120
120
|
}
|
|
121
121
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create_record.js","sourceRoot":"","sources":["../../../src/tools/records/create_record.ts"],"names":[],"mappings":";;;AAAA,kCAAmC;AAEnC,+CAAkD;AAElD,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,kBAAkB,CAAC,CAAC;AAsChD;;GAEG;AACH,MAAa,gBAAiB,SAAQ,
|
|
1
|
+
{"version":3,"file":"create_record.js","sourceRoot":"","sources":["../../../src/tools/records/create_record.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { QuickbaseClient } from
|
|
1
|
+
import { QuickbaseClient } from "../../client/quickbase";
|
|
2
2
|
/**
|
|
3
3
|
* Register all record operation tools with the registry
|
|
4
4
|
* @param client Quickbase client
|
|
5
5
|
*/
|
|
6
6
|
export declare function registerRecordTools(client: QuickbaseClient): void;
|
|
7
|
-
export * from
|
|
8
|
-
export * from
|
|
9
|
-
export * from
|
|
10
|
-
export * from
|
|
11
|
-
export * from
|
|
7
|
+
export * from "./query_records";
|
|
8
|
+
export * from "./create_record";
|
|
9
|
+
export * from "./update_record";
|
|
10
|
+
export * from "./bulk_create_records";
|
|
11
|
+
export * from "./bulk_update_records";
|
|
@@ -22,20 +22,20 @@ const update_record_1 = require("./update_record");
|
|
|
22
22
|
const bulk_create_records_1 = require("./bulk_create_records");
|
|
23
23
|
const bulk_update_records_1 = require("./bulk_update_records");
|
|
24
24
|
const logger_1 = require("../../utils/logger");
|
|
25
|
-
const logger = (0, logger_1.createLogger)(
|
|
25
|
+
const logger = (0, logger_1.createLogger)("RecordTools");
|
|
26
26
|
/**
|
|
27
27
|
* Register all record operation tools with the registry
|
|
28
28
|
* @param client Quickbase client
|
|
29
29
|
*/
|
|
30
30
|
function registerRecordTools(client) {
|
|
31
|
-
logger.info(
|
|
31
|
+
logger.info("Registering record operation tools");
|
|
32
32
|
// Register individual tools
|
|
33
33
|
registry_1.toolRegistry.registerTool(new query_records_1.QueryRecordsTool(client));
|
|
34
34
|
registry_1.toolRegistry.registerTool(new create_record_1.CreateRecordTool(client));
|
|
35
35
|
registry_1.toolRegistry.registerTool(new update_record_1.UpdateRecordTool(client));
|
|
36
36
|
registry_1.toolRegistry.registerTool(new bulk_create_records_1.BulkCreateRecordsTool(client));
|
|
37
37
|
registry_1.toolRegistry.registerTool(new bulk_update_records_1.BulkUpdateRecordsTool(client));
|
|
38
|
-
logger.info(
|
|
38
|
+
logger.info("Record operation tools registered");
|
|
39
39
|
}
|
|
40
40
|
// Export all tools
|
|
41
41
|
__exportStar(require("./query_records"), exports);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { BaseTool } from
|
|
2
|
-
import { QuickbaseClient } from
|
|
1
|
+
import { BaseTool } from "../base";
|
|
2
|
+
import { QuickbaseClient } from "../../client/quickbase";
|
|
3
3
|
/**
|
|
4
4
|
* Order by configuration for query
|
|
5
5
|
*/
|
|
@@ -11,7 +11,7 @@ export interface OrderBy {
|
|
|
11
11
|
/**
|
|
12
12
|
* Ordering direction: ASC or DESC
|
|
13
13
|
*/
|
|
14
|
-
order:
|
|
14
|
+
order: "ASC" | "DESC";
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
17
|
* Parameters for query_records tool
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.QueryRecordsTool = void 0;
|
|
4
4
|
const base_1 = require("../base");
|
|
5
5
|
const logger_1 = require("../../utils/logger");
|
|
6
|
-
const logger = (0, logger_1.createLogger)(
|
|
6
|
+
const logger = (0, logger_1.createLogger)("QueryRecordsTool");
|
|
7
7
|
/**
|
|
8
8
|
* Tool for querying records from a Quickbase table
|
|
9
9
|
*/
|
|
@@ -14,63 +14,63 @@ class QueryRecordsTool extends base_1.BaseTool {
|
|
|
14
14
|
*/
|
|
15
15
|
constructor(client) {
|
|
16
16
|
super(client);
|
|
17
|
-
this.name =
|
|
18
|
-
this.description =
|
|
17
|
+
this.name = "query_records";
|
|
18
|
+
this.description = "Executes a query against a Quickbase table with optional pagination";
|
|
19
19
|
/**
|
|
20
20
|
* Parameter schema for query_records
|
|
21
21
|
*/
|
|
22
22
|
this.paramSchema = {
|
|
23
|
-
type:
|
|
23
|
+
type: "object",
|
|
24
24
|
properties: {
|
|
25
25
|
table_id: {
|
|
26
|
-
type:
|
|
27
|
-
description:
|
|
26
|
+
type: "string",
|
|
27
|
+
description: "The ID of the Quickbase table",
|
|
28
28
|
},
|
|
29
29
|
where: {
|
|
30
|
-
type:
|
|
31
|
-
description:
|
|
30
|
+
type: "string",
|
|
31
|
+
description: "Query criteria",
|
|
32
32
|
},
|
|
33
33
|
select: {
|
|
34
|
-
type:
|
|
35
|
-
description:
|
|
34
|
+
type: "array",
|
|
35
|
+
description: "Fields to select",
|
|
36
36
|
items: {
|
|
37
|
-
type:
|
|
38
|
-
}
|
|
37
|
+
type: "string",
|
|
38
|
+
},
|
|
39
39
|
},
|
|
40
40
|
orderBy: {
|
|
41
|
-
type:
|
|
42
|
-
description:
|
|
41
|
+
type: "array",
|
|
42
|
+
description: "Fields to order results by",
|
|
43
43
|
items: {
|
|
44
|
-
type:
|
|
44
|
+
type: "object",
|
|
45
45
|
properties: {
|
|
46
46
|
fieldId: {
|
|
47
|
-
type:
|
|
47
|
+
type: "string",
|
|
48
48
|
},
|
|
49
49
|
order: {
|
|
50
|
-
type:
|
|
51
|
-
enum: [
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
50
|
+
type: "string",
|
|
51
|
+
enum: ["ASC", "DESC"],
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
55
|
},
|
|
56
56
|
max_records: {
|
|
57
|
-
type:
|
|
58
|
-
description:
|
|
57
|
+
type: "number",
|
|
58
|
+
description: "Maximum number of records to return when paginating (default: 1000)",
|
|
59
59
|
},
|
|
60
60
|
skip: {
|
|
61
|
-
type:
|
|
62
|
-
description:
|
|
61
|
+
type: "number",
|
|
62
|
+
description: "Number of records to skip",
|
|
63
63
|
},
|
|
64
64
|
paginate: {
|
|
65
|
-
type:
|
|
66
|
-
description:
|
|
65
|
+
type: "boolean",
|
|
66
|
+
description: "Whether to automatically handle pagination for large result sets",
|
|
67
67
|
},
|
|
68
68
|
options: {
|
|
69
|
-
type:
|
|
70
|
-
description:
|
|
71
|
-
}
|
|
69
|
+
type: "object",
|
|
70
|
+
description: "Query options for filtering, ordering, and pagination",
|
|
71
|
+
},
|
|
72
72
|
},
|
|
73
|
-
required: [
|
|
73
|
+
required: ["table_id"],
|
|
74
74
|
};
|
|
75
75
|
}
|
|
76
76
|
/**
|
|
@@ -79,15 +79,15 @@ class QueryRecordsTool extends base_1.BaseTool {
|
|
|
79
79
|
* @returns Queried records
|
|
80
80
|
*/
|
|
81
81
|
async run(params) {
|
|
82
|
-
const { table_id, where, select, orderBy, max_records = 1000, skip = 0, paginate = false, options } = params;
|
|
83
|
-
logger.info(
|
|
82
|
+
const { table_id, where, select, orderBy, max_records = 1000, skip = 0, paginate = false, options, } = params;
|
|
83
|
+
logger.info("Querying records from Quickbase table", {
|
|
84
84
|
tableId: table_id,
|
|
85
85
|
maxRecords: max_records,
|
|
86
|
-
pagination: paginate ?
|
|
86
|
+
pagination: paginate ? "enabled" : "disabled",
|
|
87
87
|
});
|
|
88
88
|
// Prepare the query body
|
|
89
89
|
const body = {
|
|
90
|
-
from: table_id
|
|
90
|
+
from: table_id,
|
|
91
91
|
};
|
|
92
92
|
// Add where clause if provided
|
|
93
93
|
if (where) {
|
|
@@ -106,30 +106,30 @@ class QueryRecordsTool extends base_1.BaseTool {
|
|
|
106
106
|
body.options = {
|
|
107
107
|
skip,
|
|
108
108
|
top: Math.min(limit, 1000), // API has a limit of 1000 records per request
|
|
109
|
-
...(options || {})
|
|
109
|
+
...(options || {}),
|
|
110
110
|
};
|
|
111
111
|
// Execute the query
|
|
112
112
|
const response = await this.client.request({
|
|
113
|
-
method:
|
|
114
|
-
path:
|
|
115
|
-
body
|
|
113
|
+
method: "POST",
|
|
114
|
+
path: "/records/query",
|
|
115
|
+
body,
|
|
116
116
|
});
|
|
117
117
|
if (!response.success || !response.data) {
|
|
118
|
-
logger.error(
|
|
118
|
+
logger.error("Failed to query records", {
|
|
119
119
|
error: response.error,
|
|
120
|
-
tableId: table_id
|
|
120
|
+
tableId: table_id,
|
|
121
121
|
});
|
|
122
|
-
throw new Error(response.error?.message ||
|
|
122
|
+
throw new Error(response.error?.message || "Failed to query records");
|
|
123
123
|
}
|
|
124
124
|
// Safely validate response structure
|
|
125
|
-
if (typeof response.data !==
|
|
126
|
-
throw new Error(
|
|
125
|
+
if (typeof response.data !== "object" || response.data === null) {
|
|
126
|
+
throw new Error("Invalid API response: data is not an object");
|
|
127
127
|
}
|
|
128
128
|
const data = response.data;
|
|
129
129
|
// Validate records array exists
|
|
130
130
|
if (!Array.isArray(data.data)) {
|
|
131
|
-
logger.error(
|
|
132
|
-
throw new Error(
|
|
131
|
+
logger.error("Query response missing data array", { data });
|
|
132
|
+
throw new Error("Query response does not contain records array");
|
|
133
133
|
}
|
|
134
134
|
const records = data.data;
|
|
135
135
|
// Validate and type-cast fields array
|
|
@@ -140,15 +140,15 @@ class QueryRecordsTool extends base_1.BaseTool {
|
|
|
140
140
|
fields,
|
|
141
141
|
tableId: table_id,
|
|
142
142
|
numRecords: records.length,
|
|
143
|
-
skip
|
|
143
|
+
skip,
|
|
144
144
|
};
|
|
145
145
|
// Handle pagination if enabled and there may be more records
|
|
146
146
|
let allRecords = [...records];
|
|
147
147
|
let hasMore = records.length === body.options.top;
|
|
148
148
|
if (paginate && hasMore && allRecords.length < limit) {
|
|
149
|
-
logger.info(
|
|
149
|
+
logger.info("Paginating query results", {
|
|
150
150
|
recordsFetched: allRecords.length,
|
|
151
|
-
limit
|
|
151
|
+
limit,
|
|
152
152
|
});
|
|
153
153
|
let currentSkip = skip + records.length;
|
|
154
154
|
let iterationCount = 0;
|
|
@@ -160,18 +160,18 @@ class QueryRecordsTool extends base_1.BaseTool {
|
|
|
160
160
|
// Circuit breaker checks
|
|
161
161
|
iterationCount++;
|
|
162
162
|
if (iterationCount > maxIterations) {
|
|
163
|
-
logger.error(
|
|
163
|
+
logger.error("Pagination circuit breaker: too many iterations", {
|
|
164
164
|
iterationCount,
|
|
165
165
|
maxIterations,
|
|
166
|
-
totalRecords: allRecords.length
|
|
166
|
+
totalRecords: allRecords.length,
|
|
167
167
|
});
|
|
168
168
|
break;
|
|
169
169
|
}
|
|
170
170
|
if (Date.now() - startTime > maxTimeMs) {
|
|
171
|
-
logger.error(
|
|
171
|
+
logger.error("Pagination circuit breaker: timeout exceeded", {
|
|
172
172
|
timeElapsed: Date.now() - startTime,
|
|
173
173
|
maxTimeMs,
|
|
174
|
-
totalRecords: allRecords.length
|
|
174
|
+
totalRecords: allRecords.length,
|
|
175
175
|
});
|
|
176
176
|
break;
|
|
177
177
|
}
|
|
@@ -180,36 +180,48 @@ class QueryRecordsTool extends base_1.BaseTool {
|
|
|
180
180
|
body.options.top = Math.min(limit - allRecords.length, 1000);
|
|
181
181
|
// Execute next page query
|
|
182
182
|
const pageResponse = await this.client.request({
|
|
183
|
-
method:
|
|
184
|
-
path:
|
|
185
|
-
body
|
|
183
|
+
method: "POST",
|
|
184
|
+
path: "/records/query",
|
|
185
|
+
body,
|
|
186
186
|
});
|
|
187
187
|
if (!pageResponse.success || !pageResponse.data) {
|
|
188
|
-
logger.error(
|
|
188
|
+
logger.error("Failed to query additional records", {
|
|
189
189
|
error: pageResponse.error,
|
|
190
190
|
tableId: table_id,
|
|
191
|
-
skip: currentSkip
|
|
191
|
+
skip: currentSkip,
|
|
192
192
|
});
|
|
193
193
|
break;
|
|
194
194
|
}
|
|
195
195
|
// Safely validate pagination response structure
|
|
196
|
-
if (typeof pageResponse.data !==
|
|
197
|
-
|
|
196
|
+
if (typeof pageResponse.data !== "object" ||
|
|
197
|
+
pageResponse.data === null) {
|
|
198
|
+
logger.error("Invalid pagination response: data is not an object");
|
|
198
199
|
break;
|
|
199
200
|
}
|
|
200
201
|
const pageData = pageResponse.data;
|
|
201
202
|
// Validate page records array exists
|
|
202
203
|
if (!Array.isArray(pageData.data)) {
|
|
203
|
-
logger.error(
|
|
204
|
+
logger.error("Pagination response missing data array", { pageData });
|
|
204
205
|
break;
|
|
205
206
|
}
|
|
206
207
|
const pageRecords = pageData.data;
|
|
207
208
|
// Zero progress detection - prevent infinite loops from bad API responses
|
|
208
209
|
if (pageRecords.length === 0) {
|
|
209
|
-
logger.debug(
|
|
210
|
+
logger.debug("No more records returned, stopping pagination");
|
|
210
211
|
hasMore = false;
|
|
211
212
|
break;
|
|
212
213
|
}
|
|
214
|
+
// Capture length before appending to check limit correctly
|
|
215
|
+
const prevAllLen = allRecords.length;
|
|
216
|
+
// Check if adding all pageRecords would exceed limit - truncate if needed
|
|
217
|
+
if (prevAllLen + pageRecords.length > limit) {
|
|
218
|
+
logger.debug("Truncating final page to respect limit");
|
|
219
|
+
const remainingSlots = limit - prevAllLen;
|
|
220
|
+
allRecords = [...allRecords, ...pageRecords.slice(0, remainingSlots)];
|
|
221
|
+
// If we had to truncate, there are definitely more records available
|
|
222
|
+
hasMore = true;
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
213
225
|
// Add the new records to our results
|
|
214
226
|
allRecords = [...allRecords, ...pageRecords];
|
|
215
227
|
// Validate pagination progress to prevent infinite loops
|
|
@@ -217,29 +229,21 @@ class QueryRecordsTool extends base_1.BaseTool {
|
|
|
217
229
|
currentSkip += pageRecords.length;
|
|
218
230
|
// Anti-bypass check: ensure offset actually advanced
|
|
219
231
|
if (currentSkip <= previousSkip) {
|
|
220
|
-
logger.error(
|
|
232
|
+
logger.error("Pagination offset did not advance - potential infinite loop", {
|
|
221
233
|
previousSkip,
|
|
222
234
|
currentSkip,
|
|
223
|
-
recordsReceived: pageRecords.length
|
|
235
|
+
recordsReceived: pageRecords.length,
|
|
224
236
|
});
|
|
225
237
|
break;
|
|
226
238
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
logger.debug('Truncating final page to respect limit');
|
|
231
|
-
const remainingSlots = limit - allRecords.length;
|
|
232
|
-
allRecords = [...allRecords, ...pageRecords.slice(0, remainingSlots)];
|
|
233
|
-
hasMore = false;
|
|
234
|
-
break;
|
|
235
|
-
}
|
|
236
|
-
hasMore = pageRecords.length === body.options.top && allRecords.length < limit;
|
|
237
|
-
logger.debug('Fetched additional records', {
|
|
239
|
+
hasMore =
|
|
240
|
+
pageRecords.length === body.options.top && allRecords.length < limit;
|
|
241
|
+
logger.debug("Fetched additional records", {
|
|
238
242
|
newRecords: pageRecords.length,
|
|
239
243
|
totalRecords: allRecords.length,
|
|
240
244
|
limit,
|
|
241
245
|
currentSkip,
|
|
242
|
-
hasMore
|
|
246
|
+
hasMore,
|
|
243
247
|
});
|
|
244
248
|
}
|
|
245
249
|
// Update metadata for the complete result set
|
|
@@ -247,13 +251,13 @@ class QueryRecordsTool extends base_1.BaseTool {
|
|
|
247
251
|
}
|
|
248
252
|
logger.info(`Retrieved ${allRecords.length} records from table`, {
|
|
249
253
|
tableId: table_id,
|
|
250
|
-
hasMore
|
|
254
|
+
hasMore,
|
|
251
255
|
});
|
|
252
256
|
return {
|
|
253
257
|
records: allRecords,
|
|
254
258
|
totalRecords: allRecords.length,
|
|
255
259
|
hasMore,
|
|
256
|
-
metadata
|
|
260
|
+
metadata,
|
|
257
261
|
};
|
|
258
262
|
}
|
|
259
263
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query_records.js","sourceRoot":"","sources":["../../../src/tools/records/query_records.ts"],"names":[],"mappings":";;;AAAA,kCAAmC;AAEnC,+CAAkD;AAElD,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,kBAAkB,CAAC,CAAC;AA2GhD;;GAEG;AACH,MAAa,gBAAiB,SAAQ,
|
|
1
|
+
{"version":3,"file":"query_records.js","sourceRoot":"","sources":["../../../src/tools/records/query_records.ts"],"names":[],"mappings":"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"}
|