mcp-quickbase 2.0.1
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/CHANGELOG.md +82 -0
- package/LICENSE +21 -0
- package/README.md +301 -0
- package/dist/client/quickbase.d.ts +28 -0
- package/dist/client/quickbase.js +235 -0
- package/dist/client/quickbase.js.map +1 -0
- package/dist/mcp/index.d.ts +4 -0
- package/dist/mcp/index.js +21 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +19 -0
- package/dist/mcp/server.js +102 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp-stdio-server.d.ts +2 -0
- package/dist/mcp-stdio-server.js +168 -0
- package/dist/mcp-stdio-server.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +318 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/apps/create_app.d.ts +87 -0
- package/dist/tools/apps/create_app.js +87 -0
- package/dist/tools/apps/create_app.js.map +1 -0
- package/dist/tools/apps/index.d.ts +9 -0
- package/dist/tools/apps/index.js +40 -0
- package/dist/tools/apps/index.js.map +1 -0
- package/dist/tools/apps/list_tables.d.ts +108 -0
- package/dist/tools/apps/list_tables.js +100 -0
- package/dist/tools/apps/list_tables.js.map +1 -0
- package/dist/tools/apps/update_app.d.ts +91 -0
- package/dist/tools/apps/update_app.js +99 -0
- package/dist/tools/apps/update_app.js.map +1 -0
- package/dist/tools/base.d.ts +47 -0
- package/dist/tools/base.js +63 -0
- package/dist/tools/base.js.map +1 -0
- package/dist/tools/configure_cache.d.ts +81 -0
- package/dist/tools/configure_cache.js +77 -0
- package/dist/tools/configure_cache.js.map +1 -0
- package/dist/tools/fields/create_field.d.ts +121 -0
- package/dist/tools/fields/create_field.js +102 -0
- package/dist/tools/fields/create_field.js.map +1 -0
- package/dist/tools/fields/index.d.ts +8 -0
- package/dist/tools/fields/index.js +37 -0
- package/dist/tools/fields/index.js.map +1 -0
- package/dist/tools/fields/update_field.d.ts +112 -0
- package/dist/tools/fields/update_field.js +114 -0
- package/dist/tools/fields/update_field.js.map +1 -0
- package/dist/tools/files/download_file.d.ts +111 -0
- package/dist/tools/files/download_file.js +173 -0
- package/dist/tools/files/download_file.js.map +1 -0
- package/dist/tools/files/index.d.ts +8 -0
- package/dist/tools/files/index.js +37 -0
- package/dist/tools/files/index.js.map +1 -0
- package/dist/tools/files/upload_file.d.ts +107 -0
- package/dist/tools/files/upload_file.js +211 -0
- package/dist/tools/files/upload_file.js.map +1 -0
- package/dist/tools/index.d.ts +18 -0
- package/dist/tools/index.js +65 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/records/bulk_create_records.d.ts +75 -0
- package/dist/tools/records/bulk_create_records.js +104 -0
- package/dist/tools/records/bulk_create_records.js.map +1 -0
- package/dist/tools/records/bulk_update_records.d.ts +77 -0
- package/dist/tools/records/bulk_update_records.js +102 -0
- package/dist/tools/records/bulk_update_records.js.map +1 -0
- package/dist/tools/records/create_record.d.ts +68 -0
- package/dist/tools/records/create_record.js +123 -0
- package/dist/tools/records/create_record.js.map +1 -0
- package/dist/tools/records/index.d.ts +11 -0
- package/dist/tools/records/index.js +46 -0
- package/dist/tools/records/index.js.map +1 -0
- package/dist/tools/records/query_records.d.ts +164 -0
- package/dist/tools/records/query_records.js +261 -0
- package/dist/tools/records/query_records.js.map +1 -0
- package/dist/tools/records/update_record.d.ts +81 -0
- package/dist/tools/records/update_record.js +99 -0
- package/dist/tools/records/update_record.js.map +1 -0
- package/dist/tools/registry.d.ts +41 -0
- package/dist/tools/registry.js +66 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/reports/index.d.ts +6 -0
- package/dist/tools/reports/index.js +31 -0
- package/dist/tools/reports/index.js.map +1 -0
- package/dist/tools/reports/run_report.d.ts +70 -0
- package/dist/tools/reports/run_report.js +72 -0
- package/dist/tools/reports/run_report.js.map +1 -0
- package/dist/tools/tables/create_table.d.ts +142 -0
- package/dist/tools/tables/create_table.js +119 -0
- package/dist/tools/tables/create_table.js.map +1 -0
- package/dist/tools/tables/get_table_fields.d.ts +108 -0
- package/dist/tools/tables/get_table_fields.js +96 -0
- package/dist/tools/tables/get_table_fields.js.map +1 -0
- package/dist/tools/tables/index.d.ts +9 -0
- package/dist/tools/tables/index.js +40 -0
- package/dist/tools/tables/index.js.map +1 -0
- package/dist/tools/tables/update_table.d.ts +91 -0
- package/dist/tools/tables/update_table.js +99 -0
- package/dist/tools/tables/update_table.js.map +1 -0
- package/dist/tools/test_connection.d.ts +51 -0
- package/dist/tools/test_connection.js +101 -0
- package/dist/tools/test_connection.js.map +1 -0
- package/dist/types/api.d.ts +70 -0
- package/dist/types/api.js +6 -0
- package/dist/types/api.js.map +1 -0
- package/dist/types/config.d.ts +49 -0
- package/dist/types/config.js +3 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/mcp.d.ts +55 -0
- package/dist/types/mcp.js +3 -0
- package/dist/types/mcp.js.map +1 -0
- package/dist/utils/cache.d.ts +87 -0
- package/dist/utils/cache.js +211 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/file.d.ts +40 -0
- package/dist/utils/file.js +167 -0
- package/dist/utils/file.js.map +1 -0
- package/dist/utils/logger.d.ts +37 -0
- package/dist/utils/logger.js +144 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/retry.d.ts +39 -0
- package/dist/utils/retry.js +88 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/validation.d.ts +32 -0
- package/dist/utils/validation.js +227 -0
- package/dist/utils/validation.js.map +1 -0
- package/docs/README.md +41 -0
- package/docs/architecture.md +94 -0
- package/docs/claude-prompts.md +218 -0
- package/docs/deployment.md +244 -0
- package/docs/developer-guide.md +537 -0
- package/docs/final-qa-report.md +243 -0
- package/docs/performance-benchmarks.md +306 -0
- package/docs/quick-reference.md +109 -0
- package/docs/quickstart.md +183 -0
- package/docs/security-review.md +263 -0
- package/docs/tools.md +269 -0
- package/package.json +68 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.UploadFileTool = void 0;
|
|
37
|
+
const base_1 = require("../base");
|
|
38
|
+
const logger_1 = require("../../utils/logger");
|
|
39
|
+
const file_1 = require("../../utils/file");
|
|
40
|
+
const logger = (0, logger_1.createLogger)('UploadFileTool');
|
|
41
|
+
/**
|
|
42
|
+
* Tool for uploading a file to a field in a Quickbase record
|
|
43
|
+
*/
|
|
44
|
+
class UploadFileTool extends base_1.BaseTool {
|
|
45
|
+
/**
|
|
46
|
+
* Constructor
|
|
47
|
+
* @param client Quickbase client
|
|
48
|
+
*/
|
|
49
|
+
constructor(client) {
|
|
50
|
+
super(client);
|
|
51
|
+
this.name = 'upload_file';
|
|
52
|
+
this.description = 'Uploads a file to a field in a Quickbase record';
|
|
53
|
+
/**
|
|
54
|
+
* Parameter schema for upload_file
|
|
55
|
+
*/
|
|
56
|
+
this.paramSchema = {
|
|
57
|
+
type: 'object',
|
|
58
|
+
properties: {
|
|
59
|
+
table_id: {
|
|
60
|
+
type: 'string',
|
|
61
|
+
description: 'The ID of the table (must be a file attachment field)'
|
|
62
|
+
},
|
|
63
|
+
record_id: {
|
|
64
|
+
type: 'string',
|
|
65
|
+
description: 'The ID of the record'
|
|
66
|
+
},
|
|
67
|
+
field_id: {
|
|
68
|
+
type: 'string',
|
|
69
|
+
description: 'The ID of the field (must be a file attachment field)'
|
|
70
|
+
},
|
|
71
|
+
file_path: {
|
|
72
|
+
type: 'string',
|
|
73
|
+
description: 'Path to the file to upload'
|
|
74
|
+
},
|
|
75
|
+
file_name: {
|
|
76
|
+
type: 'string',
|
|
77
|
+
description: 'Custom file name (optional, defaults to the original filename)'
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
required: ['table_id', 'record_id', 'field_id', 'file_path']
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Run the upload_file tool
|
|
85
|
+
* @param params Tool parameters
|
|
86
|
+
* @returns Upload result
|
|
87
|
+
*/
|
|
88
|
+
async run(params) {
|
|
89
|
+
const { table_id, record_id, field_id, file_path, file_name } = params;
|
|
90
|
+
logger.info('Uploading file to Quickbase record', {
|
|
91
|
+
tableId: table_id,
|
|
92
|
+
recordId: record_id,
|
|
93
|
+
fieldId: field_id,
|
|
94
|
+
filePath: file_path
|
|
95
|
+
});
|
|
96
|
+
// Check if the file exists
|
|
97
|
+
if (!(0, file_1.fileExists)(file_path)) {
|
|
98
|
+
throw new Error(`File not found: ${file_path}`);
|
|
99
|
+
}
|
|
100
|
+
// Get file information
|
|
101
|
+
const fileInfo = (0, file_1.getFileInfo)(file_path);
|
|
102
|
+
if (!fileInfo) {
|
|
103
|
+
throw new Error(`Unable to get file information: ${file_path}`);
|
|
104
|
+
}
|
|
105
|
+
// Validate file size (max 100MB)
|
|
106
|
+
const MAX_FILE_SIZE = 100 * 1024 * 1024; // 100MB
|
|
107
|
+
if (fileInfo.size > MAX_FILE_SIZE) {
|
|
108
|
+
throw new Error(`File size ${fileInfo.size} bytes exceeds maximum allowed size of ${MAX_FILE_SIZE} bytes`);
|
|
109
|
+
}
|
|
110
|
+
// Secure file path validation - prevent directory traversal attacks
|
|
111
|
+
const path = await Promise.resolve().then(() => __importStar(require('path')));
|
|
112
|
+
const fs = await Promise.resolve().then(() => __importStar(require('fs')));
|
|
113
|
+
// First, validate the input path before any resolution
|
|
114
|
+
if (!file_path || typeof file_path !== 'string') {
|
|
115
|
+
throw new Error('Invalid file path: must be a non-empty string');
|
|
116
|
+
}
|
|
117
|
+
// Reject obvious traversal attempts immediately
|
|
118
|
+
if (file_path.includes('..') || file_path.startsWith('/') || file_path.includes('\\')) {
|
|
119
|
+
throw new Error('Invalid file path: directory traversal detected');
|
|
120
|
+
}
|
|
121
|
+
// Define allowed working directory (current directory only)
|
|
122
|
+
const workingDir = process.cwd();
|
|
123
|
+
let resolvedPath;
|
|
124
|
+
try {
|
|
125
|
+
// Resolve the path relative to working directory
|
|
126
|
+
resolvedPath = path.resolve(workingDir, file_path);
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
throw new Error('Invalid file path format');
|
|
130
|
+
}
|
|
131
|
+
// Critical security check: ensure resolved path is within working directory
|
|
132
|
+
if (!resolvedPath.startsWith(workingDir + path.sep) && resolvedPath !== workingDir) {
|
|
133
|
+
throw new Error('Invalid file path: access outside working directory denied');
|
|
134
|
+
}
|
|
135
|
+
// Verify file exists and is readable
|
|
136
|
+
try {
|
|
137
|
+
await fs.promises.access(resolvedPath, fs.constants.R_OK);
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
throw new Error(`File access denied or file does not exist: ${file_path}`);
|
|
141
|
+
}
|
|
142
|
+
// Memory-efficient file reading with size validation
|
|
143
|
+
const CHUNK_SIZE = 1024 * 1024; // 1MB chunks
|
|
144
|
+
let fileBase64;
|
|
145
|
+
try {
|
|
146
|
+
if (fileInfo.size > 10 * 1024 * 1024) { // > 10MB, use streaming
|
|
147
|
+
logger.debug('Using streaming read for large file', { size: fileInfo.size });
|
|
148
|
+
// Stream the file in chunks to prevent memory overflow
|
|
149
|
+
const chunks = [];
|
|
150
|
+
const readStream = fs.createReadStream(resolvedPath, { highWaterMark: CHUNK_SIZE });
|
|
151
|
+
for await (const chunk of readStream) {
|
|
152
|
+
chunks.push(chunk.toString('base64'));
|
|
153
|
+
}
|
|
154
|
+
fileBase64 = chunks.join('');
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
// Small files can be read directly
|
|
158
|
+
const fileBuffer = (0, file_1.readFileAsBuffer)(file_path);
|
|
159
|
+
if (!fileBuffer) {
|
|
160
|
+
throw new Error(`Unable to read file: ${file_path}`);
|
|
161
|
+
}
|
|
162
|
+
fileBase64 = fileBuffer.toString('base64');
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
throw new Error(`Failed to read file: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
167
|
+
}
|
|
168
|
+
// Prepare the file upload request
|
|
169
|
+
const body = {
|
|
170
|
+
tableId: table_id,
|
|
171
|
+
recordId: record_id,
|
|
172
|
+
fieldId: field_id,
|
|
173
|
+
fileName: file_name || fileInfo.name,
|
|
174
|
+
contentType: fileInfo.mimeType,
|
|
175
|
+
fileData: fileBase64
|
|
176
|
+
};
|
|
177
|
+
// Upload the file
|
|
178
|
+
const response = await this.client.request({
|
|
179
|
+
method: 'POST',
|
|
180
|
+
path: '/files',
|
|
181
|
+
body
|
|
182
|
+
});
|
|
183
|
+
if (!response.success || !response.data) {
|
|
184
|
+
logger.error('Failed to upload file', {
|
|
185
|
+
error: response.error,
|
|
186
|
+
tableId: table_id,
|
|
187
|
+
recordId: record_id,
|
|
188
|
+
fieldId: field_id
|
|
189
|
+
});
|
|
190
|
+
throw new Error(response.error?.message || 'Failed to upload file');
|
|
191
|
+
}
|
|
192
|
+
const fileData = response.data;
|
|
193
|
+
logger.info('Successfully uploaded file', {
|
|
194
|
+
tableId: table_id,
|
|
195
|
+
recordId: record_id,
|
|
196
|
+
fieldId: field_id,
|
|
197
|
+
fileName: file_name || fileInfo.name
|
|
198
|
+
});
|
|
199
|
+
return {
|
|
200
|
+
recordId: record_id,
|
|
201
|
+
fieldId: field_id,
|
|
202
|
+
tableId: table_id,
|
|
203
|
+
fileName: file_name || fileInfo.name,
|
|
204
|
+
fileSize: fileInfo.size,
|
|
205
|
+
version: fileData.version || 1,
|
|
206
|
+
uploadTime: new Date().toISOString()
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
exports.UploadFileTool = UploadFileTool;
|
|
211
|
+
//# sourceMappingURL=upload_file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload_file.js","sourceRoot":"","sources":["../../../src/tools/files/upload_file.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { QuickbaseClient } from '../client/quickbase';
|
|
2
|
+
import { CacheService } from '../utils/cache';
|
|
3
|
+
/**
|
|
4
|
+
* Initialize all MCP tools and register them with the registry
|
|
5
|
+
* @param client Quickbase client
|
|
6
|
+
* @param cacheService Cache service
|
|
7
|
+
*/
|
|
8
|
+
export declare function initializeTools(client: QuickbaseClient, cacheService: CacheService): void;
|
|
9
|
+
export * from './registry';
|
|
10
|
+
export * from './base';
|
|
11
|
+
export * from './test_connection';
|
|
12
|
+
export * from './configure_cache';
|
|
13
|
+
export * from './apps';
|
|
14
|
+
export * from './tables';
|
|
15
|
+
export * from './fields';
|
|
16
|
+
export * from './records';
|
|
17
|
+
export * from './files';
|
|
18
|
+
export * from './reports';
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.initializeTools = initializeTools;
|
|
18
|
+
const registry_1 = require("./registry");
|
|
19
|
+
const test_connection_1 = require("./test_connection");
|
|
20
|
+
const configure_cache_1 = require("./configure_cache");
|
|
21
|
+
const apps_1 = require("./apps");
|
|
22
|
+
const tables_1 = require("./tables");
|
|
23
|
+
const fields_1 = require("./fields");
|
|
24
|
+
const records_1 = require("./records");
|
|
25
|
+
const files_1 = require("./files");
|
|
26
|
+
const reports_1 = require("./reports");
|
|
27
|
+
const logger_1 = require("../utils/logger");
|
|
28
|
+
const logger = (0, logger_1.createLogger)('ToolsInit');
|
|
29
|
+
/**
|
|
30
|
+
* Initialize all MCP tools and register them with the registry
|
|
31
|
+
* @param client Quickbase client
|
|
32
|
+
* @param cacheService Cache service
|
|
33
|
+
*/
|
|
34
|
+
function initializeTools(client, cacheService) {
|
|
35
|
+
logger.info('Initializing MCP tools');
|
|
36
|
+
// Register connection tools
|
|
37
|
+
registry_1.toolRegistry.registerTool(new test_connection_1.TestConnectionTool(client));
|
|
38
|
+
registry_1.toolRegistry.registerTool(new configure_cache_1.ConfigureCacheTool(client, cacheService));
|
|
39
|
+
// Register app management tools
|
|
40
|
+
(0, apps_1.registerAppTools)(client);
|
|
41
|
+
// Register table operation tools
|
|
42
|
+
(0, tables_1.registerTableTools)(client);
|
|
43
|
+
// Register field management tools
|
|
44
|
+
(0, fields_1.registerFieldTools)(client);
|
|
45
|
+
// Register record operation tools
|
|
46
|
+
(0, records_1.registerRecordTools)(client);
|
|
47
|
+
// Register file operation tools
|
|
48
|
+
(0, files_1.registerFileTools)(client);
|
|
49
|
+
// Register report operation tools
|
|
50
|
+
(0, reports_1.registerReportTools)(client);
|
|
51
|
+
// Additional tools will be registered here
|
|
52
|
+
logger.info(`Registered ${registry_1.toolRegistry.getToolCount()} tools`);
|
|
53
|
+
}
|
|
54
|
+
// Export all tools and related types
|
|
55
|
+
__exportStar(require("./registry"), exports);
|
|
56
|
+
__exportStar(require("./base"), exports);
|
|
57
|
+
__exportStar(require("./test_connection"), exports);
|
|
58
|
+
__exportStar(require("./configure_cache"), exports);
|
|
59
|
+
__exportStar(require("./apps"), exports);
|
|
60
|
+
__exportStar(require("./tables"), exports);
|
|
61
|
+
__exportStar(require("./fields"), exports);
|
|
62
|
+
__exportStar(require("./records"), exports);
|
|
63
|
+
__exportStar(require("./files"), exports);
|
|
64
|
+
__exportStar(require("./reports"), exports);
|
|
65
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAoBA,0CA+BC;AAjDD,yCAA0C;AAC1C,uDAAuD;AACvD,uDAAuD;AACvD,iCAA0C;AAC1C,qCAA8C;AAC9C,qCAA8C;AAC9C,uCAAgD;AAChD,mCAA4C;AAC5C,uCAAgD;AAChD,4CAA+C;AAE/C,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,WAAW,CAAC,CAAC;AAEzC;;;;GAIG;AACH,SAAgB,eAAe,CAC7B,MAAuB,EACvB,YAA0B;IAE1B,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IAEtC,4BAA4B;IAC5B,uBAAY,CAAC,YAAY,CAAC,IAAI,oCAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1D,uBAAY,CAAC,YAAY,CAAC,IAAI,oCAAkB,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;IAExE,gCAAgC;IAChC,IAAA,uBAAgB,EAAC,MAAM,CAAC,CAAC;IAEzB,iCAAiC;IACjC,IAAA,2BAAkB,EAAC,MAAM,CAAC,CAAC;IAE3B,kCAAkC;IAClC,IAAA,2BAAkB,EAAC,MAAM,CAAC,CAAC;IAE3B,kCAAkC;IAClC,IAAA,6BAAmB,EAAC,MAAM,CAAC,CAAC;IAE5B,gCAAgC;IAChC,IAAA,yBAAiB,EAAC,MAAM,CAAC,CAAC;IAE1B,kCAAkC;IAClC,IAAA,6BAAmB,EAAC,MAAM,CAAC,CAAC;IAE5B,2CAA2C;IAE3C,MAAM,CAAC,IAAI,CAAC,cAAc,uBAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;AACjE,CAAC;AAED,qCAAqC;AACrC,6CAA2B;AAC3B,yCAAuB;AACvB,oDAAkC;AAClC,oDAAkC;AAClC,yCAAuB;AACvB,2CAAyB;AACzB,2CAAyB;AACzB,4CAA0B;AAC1B,0CAAwB;AACxB,4CAA0B"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { BaseTool } from '../base';
|
|
2
|
+
import { QuickbaseClient } from '../../client/quickbase';
|
|
3
|
+
/**
|
|
4
|
+
* Parameters for bulk_create_records tool
|
|
5
|
+
*/
|
|
6
|
+
export interface BulkCreateRecordsParams {
|
|
7
|
+
/**
|
|
8
|
+
* The ID of the table to create records in
|
|
9
|
+
*/
|
|
10
|
+
table_id: string;
|
|
11
|
+
/**
|
|
12
|
+
* Array of record data to insert
|
|
13
|
+
*/
|
|
14
|
+
records: Record<string, any>[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Response from bulk creating records
|
|
18
|
+
*/
|
|
19
|
+
export interface BulkCreateRecordsResult {
|
|
20
|
+
/**
|
|
21
|
+
* Array of created record IDs
|
|
22
|
+
*/
|
|
23
|
+
recordIds: string[];
|
|
24
|
+
/**
|
|
25
|
+
* The ID of the table the records were created in
|
|
26
|
+
*/
|
|
27
|
+
tableId: string;
|
|
28
|
+
/**
|
|
29
|
+
* Number of records created
|
|
30
|
+
*/
|
|
31
|
+
createdCount: number;
|
|
32
|
+
/**
|
|
33
|
+
* Creation timestamp
|
|
34
|
+
*/
|
|
35
|
+
createdTime?: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Tool for creating multiple records in a Quickbase table
|
|
39
|
+
*/
|
|
40
|
+
export declare class BulkCreateRecordsTool extends BaseTool<BulkCreateRecordsParams, BulkCreateRecordsResult> {
|
|
41
|
+
name: string;
|
|
42
|
+
description: string;
|
|
43
|
+
/**
|
|
44
|
+
* Parameter schema for bulk_create_records
|
|
45
|
+
*/
|
|
46
|
+
paramSchema: {
|
|
47
|
+
type: string;
|
|
48
|
+
properties: {
|
|
49
|
+
table_id: {
|
|
50
|
+
type: string;
|
|
51
|
+
description: string;
|
|
52
|
+
};
|
|
53
|
+
records: {
|
|
54
|
+
type: string;
|
|
55
|
+
description: string;
|
|
56
|
+
items: {
|
|
57
|
+
type: string;
|
|
58
|
+
additionalProperties: boolean;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
required: string[];
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Constructor
|
|
66
|
+
* @param client Quickbase client
|
|
67
|
+
*/
|
|
68
|
+
constructor(client: QuickbaseClient);
|
|
69
|
+
/**
|
|
70
|
+
* Run the bulk_create_records tool
|
|
71
|
+
* @param params Tool parameters
|
|
72
|
+
* @returns Bulk create result
|
|
73
|
+
*/
|
|
74
|
+
protected run(params: BulkCreateRecordsParams): Promise<BulkCreateRecordsResult>;
|
|
75
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BulkCreateRecordsTool = void 0;
|
|
4
|
+
const base_1 = require("../base");
|
|
5
|
+
const logger_1 = require("../../utils/logger");
|
|
6
|
+
const logger = (0, logger_1.createLogger)('BulkCreateRecordsTool');
|
|
7
|
+
/**
|
|
8
|
+
* Tool for creating multiple records in a Quickbase table
|
|
9
|
+
*/
|
|
10
|
+
class BulkCreateRecordsTool extends base_1.BaseTool {
|
|
11
|
+
/**
|
|
12
|
+
* Constructor
|
|
13
|
+
* @param client Quickbase client
|
|
14
|
+
*/
|
|
15
|
+
constructor(client) {
|
|
16
|
+
super(client);
|
|
17
|
+
this.name = 'bulk_create_records';
|
|
18
|
+
this.description = 'Creates multiple records in a Quickbase table';
|
|
19
|
+
/**
|
|
20
|
+
* Parameter schema for bulk_create_records
|
|
21
|
+
*/
|
|
22
|
+
this.paramSchema = {
|
|
23
|
+
type: 'object',
|
|
24
|
+
properties: {
|
|
25
|
+
table_id: {
|
|
26
|
+
type: 'string',
|
|
27
|
+
description: 'The ID of the Quickbase table'
|
|
28
|
+
},
|
|
29
|
+
records: {
|
|
30
|
+
type: 'array',
|
|
31
|
+
description: 'Array of record data to insert',
|
|
32
|
+
items: {
|
|
33
|
+
type: 'object',
|
|
34
|
+
additionalProperties: true
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
required: ['table_id', 'records']
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Run the bulk_create_records tool
|
|
43
|
+
* @param params Tool parameters
|
|
44
|
+
* @returns Bulk create result
|
|
45
|
+
*/
|
|
46
|
+
async run(params) {
|
|
47
|
+
const { table_id, records } = params;
|
|
48
|
+
logger.info(`Bulk creating ${records.length} records in Quickbase table`, {
|
|
49
|
+
tableId: table_id,
|
|
50
|
+
recordCount: records.length
|
|
51
|
+
});
|
|
52
|
+
// Validate records
|
|
53
|
+
if (!records || !Array.isArray(records) || records.length === 0) {
|
|
54
|
+
throw new Error('Records array is required and must not be empty');
|
|
55
|
+
}
|
|
56
|
+
// Prepare record data
|
|
57
|
+
const formattedRecords = records.map(record => {
|
|
58
|
+
const recordData = {};
|
|
59
|
+
for (const [field, value] of Object.entries(record)) {
|
|
60
|
+
recordData[field] = { value };
|
|
61
|
+
}
|
|
62
|
+
return recordData;
|
|
63
|
+
});
|
|
64
|
+
// Prepare request body
|
|
65
|
+
const body = {
|
|
66
|
+
to: table_id,
|
|
67
|
+
data: formattedRecords
|
|
68
|
+
};
|
|
69
|
+
// Create the records
|
|
70
|
+
const response = await this.client.request({
|
|
71
|
+
method: 'POST',
|
|
72
|
+
path: '/records',
|
|
73
|
+
body
|
|
74
|
+
});
|
|
75
|
+
if (!response.success || !response.data) {
|
|
76
|
+
logger.error('Failed to bulk create records', {
|
|
77
|
+
error: response.error,
|
|
78
|
+
tableId: table_id
|
|
79
|
+
});
|
|
80
|
+
throw new Error(response.error?.message || 'Failed to bulk create records');
|
|
81
|
+
}
|
|
82
|
+
const result = response.data;
|
|
83
|
+
const metadata = result.metadata || {};
|
|
84
|
+
if (!metadata.createdRecordIds || metadata.createdRecordIds.length === 0) {
|
|
85
|
+
logger.error('Bulk record creation response missing record IDs', {
|
|
86
|
+
response: result
|
|
87
|
+
});
|
|
88
|
+
throw new Error('Records created but no record IDs were returned');
|
|
89
|
+
}
|
|
90
|
+
const recordIds = metadata.createdRecordIds;
|
|
91
|
+
logger.info(`Successfully created ${recordIds.length} records`, {
|
|
92
|
+
recordCount: recordIds.length,
|
|
93
|
+
tableId: table_id
|
|
94
|
+
});
|
|
95
|
+
return {
|
|
96
|
+
recordIds,
|
|
97
|
+
tableId: table_id,
|
|
98
|
+
createdCount: recordIds.length,
|
|
99
|
+
createdTime: new Date().toISOString()
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
exports.BulkCreateRecordsTool = BulkCreateRecordsTool;
|
|
104
|
+
//# sourceMappingURL=bulk_create_records.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bulk_create_records.js","sourceRoot":"","sources":["../../../src/tools/records/bulk_create_records.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { BaseTool } from '../base';
|
|
2
|
+
import { QuickbaseClient } from '../../client/quickbase';
|
|
3
|
+
/**
|
|
4
|
+
* Parameters for bulk_update_records tool
|
|
5
|
+
*/
|
|
6
|
+
export interface BulkUpdateRecordsParams {
|
|
7
|
+
/**
|
|
8
|
+
* The ID of the table containing the records
|
|
9
|
+
*/
|
|
10
|
+
table_id: string;
|
|
11
|
+
/**
|
|
12
|
+
* Array of record data to update (must include record IDs)
|
|
13
|
+
*/
|
|
14
|
+
records: Array<Record<string, any> & {
|
|
15
|
+
id: string;
|
|
16
|
+
}>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Response from bulk updating records
|
|
20
|
+
*/
|
|
21
|
+
export interface BulkUpdateRecordsResult {
|
|
22
|
+
/**
|
|
23
|
+
* Array of updated record IDs
|
|
24
|
+
*/
|
|
25
|
+
recordIds: string[];
|
|
26
|
+
/**
|
|
27
|
+
* The ID of the table containing the records
|
|
28
|
+
*/
|
|
29
|
+
tableId: string;
|
|
30
|
+
/**
|
|
31
|
+
* Number of records updated
|
|
32
|
+
*/
|
|
33
|
+
updatedCount: number;
|
|
34
|
+
/**
|
|
35
|
+
* Update timestamp
|
|
36
|
+
*/
|
|
37
|
+
updatedTime?: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Tool for updating multiple records in a Quickbase table
|
|
41
|
+
*/
|
|
42
|
+
export declare class BulkUpdateRecordsTool extends BaseTool<BulkUpdateRecordsParams, BulkUpdateRecordsResult> {
|
|
43
|
+
name: string;
|
|
44
|
+
description: string;
|
|
45
|
+
/**
|
|
46
|
+
* Parameter schema for bulk_update_records
|
|
47
|
+
*/
|
|
48
|
+
paramSchema: {
|
|
49
|
+
type: string;
|
|
50
|
+
properties: {
|
|
51
|
+
table_id: {
|
|
52
|
+
type: string;
|
|
53
|
+
description: string;
|
|
54
|
+
};
|
|
55
|
+
records: {
|
|
56
|
+
type: string;
|
|
57
|
+
description: string;
|
|
58
|
+
items: {
|
|
59
|
+
type: string;
|
|
60
|
+
additionalProperties: boolean;
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
required: string[];
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Constructor
|
|
68
|
+
* @param client Quickbase client
|
|
69
|
+
*/
|
|
70
|
+
constructor(client: QuickbaseClient);
|
|
71
|
+
/**
|
|
72
|
+
* Run the bulk_update_records tool
|
|
73
|
+
* @param params Tool parameters
|
|
74
|
+
* @returns Bulk update result
|
|
75
|
+
*/
|
|
76
|
+
protected run(params: BulkUpdateRecordsParams): Promise<BulkUpdateRecordsResult>;
|
|
77
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BulkUpdateRecordsTool = void 0;
|
|
4
|
+
const base_1 = require("../base");
|
|
5
|
+
const logger_1 = require("../../utils/logger");
|
|
6
|
+
const logger = (0, logger_1.createLogger)('BulkUpdateRecordsTool');
|
|
7
|
+
/**
|
|
8
|
+
* Tool for updating multiple records in a Quickbase table
|
|
9
|
+
*/
|
|
10
|
+
class BulkUpdateRecordsTool extends base_1.BaseTool {
|
|
11
|
+
/**
|
|
12
|
+
* Constructor
|
|
13
|
+
* @param client Quickbase client
|
|
14
|
+
*/
|
|
15
|
+
constructor(client) {
|
|
16
|
+
super(client);
|
|
17
|
+
this.name = 'bulk_update_records';
|
|
18
|
+
this.description = 'Updates multiple records in a Quickbase table';
|
|
19
|
+
/**
|
|
20
|
+
* Parameter schema for bulk_update_records
|
|
21
|
+
*/
|
|
22
|
+
this.paramSchema = {
|
|
23
|
+
type: 'object',
|
|
24
|
+
properties: {
|
|
25
|
+
table_id: {
|
|
26
|
+
type: 'string',
|
|
27
|
+
description: 'The ID of the Quickbase table'
|
|
28
|
+
},
|
|
29
|
+
records: {
|
|
30
|
+
type: 'array',
|
|
31
|
+
description: 'Array of record data to update (must include record IDs)',
|
|
32
|
+
items: {
|
|
33
|
+
type: 'object',
|
|
34
|
+
additionalProperties: true
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
required: ['table_id', 'records']
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Run the bulk_update_records tool
|
|
43
|
+
* @param params Tool parameters
|
|
44
|
+
* @returns Bulk update result
|
|
45
|
+
*/
|
|
46
|
+
async run(params) {
|
|
47
|
+
const { table_id, records } = params;
|
|
48
|
+
logger.info(`Bulk updating ${records.length} records in Quickbase table`, {
|
|
49
|
+
tableId: table_id,
|
|
50
|
+
recordCount: records.length
|
|
51
|
+
});
|
|
52
|
+
// Validate records
|
|
53
|
+
if (!records || !Array.isArray(records) || records.length === 0) {
|
|
54
|
+
throw new Error('Records array is required and must not be empty');
|
|
55
|
+
}
|
|
56
|
+
// Check if all records have IDs
|
|
57
|
+
const missingIds = records.some(record => !record.id);
|
|
58
|
+
if (missingIds) {
|
|
59
|
+
throw new Error('All records must include an "id" field for bulk updates');
|
|
60
|
+
}
|
|
61
|
+
// Prepare record data
|
|
62
|
+
const formattedRecords = records.map(record => {
|
|
63
|
+
const { id, ...fields } = record;
|
|
64
|
+
const recordData = { id };
|
|
65
|
+
for (const [field, value] of Object.entries(fields)) {
|
|
66
|
+
recordData[field] = { value };
|
|
67
|
+
}
|
|
68
|
+
return recordData;
|
|
69
|
+
});
|
|
70
|
+
// Prepare request body
|
|
71
|
+
const body = {
|
|
72
|
+
to: table_id,
|
|
73
|
+
data: formattedRecords
|
|
74
|
+
};
|
|
75
|
+
// Update the records
|
|
76
|
+
const response = await this.client.request({
|
|
77
|
+
method: 'POST',
|
|
78
|
+
path: '/records',
|
|
79
|
+
body
|
|
80
|
+
});
|
|
81
|
+
if (!response.success || !response.data) {
|
|
82
|
+
logger.error('Failed to bulk update records', {
|
|
83
|
+
error: response.error,
|
|
84
|
+
tableId: table_id
|
|
85
|
+
});
|
|
86
|
+
throw new Error(response.error?.message || 'Failed to bulk update records');
|
|
87
|
+
}
|
|
88
|
+
const recordIds = records.map(record => record.id);
|
|
89
|
+
logger.info(`Successfully updated ${recordIds.length} records`, {
|
|
90
|
+
recordCount: recordIds.length,
|
|
91
|
+
tableId: table_id
|
|
92
|
+
});
|
|
93
|
+
return {
|
|
94
|
+
recordIds,
|
|
95
|
+
tableId: table_id,
|
|
96
|
+
updatedCount: recordIds.length,
|
|
97
|
+
updatedTime: new Date().toISOString()
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
exports.BulkUpdateRecordsTool = BulkUpdateRecordsTool;
|
|
102
|
+
//# sourceMappingURL=bulk_update_records.js.map
|