n8n-bookstack-agent-tool
Version:
Comprehensive BookStack API integration tool for n8n AI Agent with MCP framework compatibility
252 lines โข 11.5 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ResourceTester = void 0;
exports.testNextResource = testNextResource;
const index_js_1 = require("../index.js");
const error_handler_js_1 = require("../error/error-handler.js");
class ResourceTester {
constructor() {
this.testResults = {};
this.config = {
baseUrl: 'https://wiki.l7cloud.io',
authType: 'bearer',
token: 'EnRkbVwqzNSyLaVo7olU8Wx8umGznKuE',
tokenSecret: 'TyaJ0JHAenwRIgScmsffrCeSIlon4fZ2',
timeout: 30000,
retryAttempts: 3,
retryDelay: 1000
};
this.tool = new index_js_1.BookStackN8nTool(this.config);
}
async testResource(resourceName) {
console.log(`\n๐งช Testing Resource: ${resourceName.toUpperCase()}`);
console.log('='.repeat(50));
this.testResults[resourceName] = {
crud: {},
errors: {},
exports: {},
startTime: new Date(),
success: false
};
try {
await this.testCrudOperations(resourceName);
await this.testErrorHandling(resourceName);
if (resourceName === 'books') {
await this.testExportOperations(resourceName);
}
this.testResults[resourceName].success = true;
this.testResults[resourceName].endTime = new Date();
console.log(`โ
${resourceName} testing completed successfully`);
}
catch (error) {
console.error(`โ ${resourceName} testing failed:`, error);
this.testResults[resourceName].error = error.message;
this.testResults[resourceName].endTime = new Date();
}
}
async testCrudOperations(resourceName) {
console.log(`\n๐ Testing CRUD operations for ${resourceName}...`);
const operations = ['list', 'get', 'create', 'update', 'delete'];
const resourceSingular = resourceName.slice(0, -1);
for (const operation of operations) {
const commandName = operation + resourceSingular.charAt(0).toUpperCase() + resourceSingular.slice(1);
try {
console.log(` Testing ${commandName}...`);
let params = {};
if (operation === 'list') {
params = { count: 5 };
}
else if (operation === 'get' || operation === 'update' || operation === 'delete') {
params = { id: 1 };
if (operation === 'update') {
params = { ...params, name: `Test ${resourceSingular} Updated` };
}
}
else if (operation === 'create') {
params = this.getCreateParams(resourceName);
}
const result = await this.tool.execCommand(commandName, params);
console.log(` โ
${commandName}: Success`);
this.testResults[resourceName].crud[operation] = { success: true, result };
}
catch (error) {
const errorMsg = error.message || 'Unknown error';
console.log(` โ ${commandName}: ${errorMsg}`);
this.testResults[resourceName].crud[operation] = { success: false, error: errorMsg };
}
}
}
async testErrorHandling(resourceName) {
console.log(`\nโ Testing error handling for ${resourceName}...`);
const resourceSingular = resourceName.slice(0, -1);
const errorTests = [
{
name: 'Invalid ID',
command: `get${resourceSingular.charAt(0).toUpperCase() + resourceSingular.slice(1)}`,
params: { id: 999999 },
expectedError: 'NOT_FOUND'
},
{
name: 'Missing required fields',
command: `create${resourceSingular.charAt(0).toUpperCase() + resourceSingular.slice(1)}`,
params: {},
expectedError: 'VALIDATION'
}
];
for (const test of errorTests) {
try {
console.log(` Testing ${test.name}...`);
await this.tool.execCommand(test.command, test.params);
console.log(` โ ๏ธ ${test.name}: No error thrown (unexpected)`);
this.testResults[resourceName].errors[test.name] = { success: false, reason: 'No error thrown' };
}
catch (error) {
if (error instanceof error_handler_js_1.BookStackError) {
console.log(` โ
${test.name}: BookStackError handled - ${error.type}`);
this.testResults[resourceName].errors[test.name] = { success: true, errorType: error.type };
}
else {
console.log(` โ
${test.name}: Error caught - ${error.constructor?.name}`);
this.testResults[resourceName].errors[test.name] = { success: true, errorType: 'Generic' };
}
}
}
}
async testExportOperations(resourceName) {
console.log(`\n๐ Testing export operations for ${resourceName}...`);
const exportFormats = ['Html', 'Pdf', 'Markdown', 'Plaintext'];
for (const format of exportFormats) {
const commandName = `exportBook${format}`;
try {
console.log(` Testing ${commandName}...`);
const result = await this.tool.execCommand(commandName, { id: 1 });
console.log(` โ
${commandName}: Success`);
this.testResults[resourceName].exports[format] = { success: true, result };
}
catch (error) {
const errorMsg = error.message || 'Unknown error';
console.log(` โ ${commandName}: ${errorMsg}`);
this.testResults[resourceName].exports[format] = { success: false, error: errorMsg };
}
}
}
getCreateParams(resourceName) {
const timestamp = Date.now();
switch (resourceName) {
case 'books':
return { name: `Test Book ${timestamp}`, description: 'Test book created by automated testing' };
case 'chapters':
return { name: `Test Chapter ${timestamp}`, book_id: 1, description: 'Test chapter' };
case 'pages':
return { name: `Test Page ${timestamp}`, book_id: 1, html: '<p>Test page content</p>' };
case 'shelves':
return { name: `Test Shelf ${timestamp}`, description: 'Test shelf' };
case 'users':
return { name: `testuser${timestamp}`, email: `test${timestamp}@example.com`, password: 'testpassword123' };
case 'roles':
return { display_name: `Test Role ${timestamp}`, description: 'Test role' };
case 'attachments':
return { name: `test-file-${timestamp}.txt`, uploaded_to: 1 };
case 'tags':
return { name: `test-tag-${timestamp}`, value: 'test-value' };
default:
return { name: `Test ${resourceName} ${timestamp}` };
}
}
getTestResults() {
return this.testResults;
}
printSummary() {
console.log('\n๐ RESOURCE TESTING SUMMARY');
console.log('===========================');
for (const [resource, results] of Object.entries(this.testResults)) {
const duration = results.endTime ?
Math.round((results.endTime.getTime() - results.startTime.getTime()) / 1000) :
'N/A';
console.log(`\n${resource.toUpperCase()}:`);
console.log(` Status: ${results.success ? 'โ
PASSED' : 'โ FAILED'}`);
console.log(` Duration: ${duration}s`);
if (results.crud) {
const crudPassed = Object.values(results.crud).filter((r) => r.success).length;
const crudTotal = Object.keys(results.crud).length;
console.log(` CRUD: ${crudPassed}/${crudTotal} operations passed`);
}
if (results.errors) {
const errorsPassed = Object.values(results.errors).filter((r) => r.success).length;
const errorsTotal = Object.keys(results.errors).length;
console.log(` Error Handling: ${errorsPassed}/${errorsTotal} tests passed`);
}
if (results.exports) {
const exportsPassed = Object.values(results.exports).filter((r) => r.success).length;
const exportsTotal = Object.keys(results.exports).length;
console.log(` Exports: ${exportsPassed}/${exportsTotal} formats tested`);
}
}
}
}
exports.ResourceTester = ResourceTester;
async function testNextResource() {
const fs = await Promise.resolve().then(() => __importStar(require('fs')));
const todoPath = '/home/ubuntu/todo.txt';
if (!fs.existsSync(todoPath)) {
console.log('โ Todo list not found');
return null;
}
const todoContent = fs.readFileSync(todoPath, 'utf-8');
const lines = todoContent.split('\n');
for (const line of lines) {
if (line.includes('- [ ]') && (line.includes('books') || line.includes('pages') || line.includes('chapters') || line.includes('shelves') || line.includes('users') || line.includes('roles') || line.includes('attachments') || line.includes('tags'))) {
const match = line.match(/- \[ \] (\w+)/);
if (match) {
return match[1];
}
}
}
return null;
}
if (require.main === module) {
testNextResource().then(async (resource) => {
if (resource) {
const tester = new ResourceTester();
await tester.testResource(resource);
tester.printSummary();
}
else {
console.log('โ
All resources have been tested');
}
}).catch(console.error);
}
//# sourceMappingURL=resource-tester.js.map