Skip to content

Conversation

@teetangh
Copy link

Summary

This PR introduces comprehensive improvements to the n8n-nodes-couchbase package including test infrastructure, bug fixes, and code quality enhancements.

Test Infrastructure

  • Add Vitest test framework with coverage support
  • Create test mocks for Couchbase SDK and n8n-workflow
  • Add test fixtures for credentials and documents

Bug Fixes

  • EPUB temp file cleanup: Fix memory leak where temporary files were never cleaned up
  • Connection idle timeout: Add 30-second auto-close for unused connections to prevent connection leaks
  • Vector store update cleanup: Fix undefined vectorStore in finally block
  • Type checking: Replace fragile constructor.name checks with proper type guards

Error Handling

  • Add comprehensive error handling with specific Couchbase error types (DocumentExistsError, DocumentNotFoundError, ParsingFailureError, IndexNotFoundError)
  • Provide user-friendly error messages with actionable descriptions

Input Validation

  • Add document ID validation (empty check, 250-byte limit)
  • Add SQL++ query validation
  • Add search results limit validation (1-10000 range)
  • Add JSON document parsing with proper type safety

Code Quality

  • Improve credential security with required fields, placeholders, and descriptions
  • Standardize empty search results response format
  • Add shared constants file for configuration
  • Add retry utility for transient failures
  • Add JSDoc documentation to key functions

Test Plan

  • TypeScript compiles without errors (npx tsc --noEmit)
  • Lint passes (pnpm lint)
  • Build succeeds (pnpm build)
  • Tests pass (pnpm test - 2/2 tests passing)

- Add Vitest test framework with coverage support
- Fix EPUB temp file cleanup memory leak
- Add connection idle timeout (30s) to prevent connection leaks
- Add comprehensive error handling with specific Couchbase error types
- Add input validation for document IDs, queries, and result limits
- Fix type safety issues in document parsing
- Improve credential security with required fields and descriptions
- Fix fragile constructor.name type checking in processDocuments
- Fix vector store update operation cleanup
- Standardize empty search results response format
- Add retry utility for transient failures
- Add shared constants file for configuration
- Add JSDoc documentation to key functions
@gemini-code-assist
Copy link

Summary of Changes

Hello @teetangh, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request delivers a substantial upgrade to the n8n-nodes-couchbase package, focusing on enhancing its stability, usability, and maintainability. It integrates a new testing framework, addresses several critical bugs, significantly improves error handling and input validation, and refines overall code quality through better documentation and utility functions.

Highlights

  • Test Infrastructure: Introduced Vitest test framework with coverage support, including test mocks for Couchbase SDK and n8n-workflow, and test fixtures for credentials and documents.
  • Bug Fixes: Resolved issues such as EPUB temporary file cleanup to prevent memory leaks, implemented a 30-second auto-close for unused connections to prevent connection leaks, fixed an undefined vectorStore in a finally block, and replaced fragile constructor.name checks with proper type guards for improved reliability.
  • Error Handling: Added comprehensive error handling for specific Couchbase error types (e.g., DocumentExistsError, DocumentNotFoundError, ParsingFailureError, IndexNotFoundError) and provided user-friendly, actionable error messages.
  • Input Validation: Implemented robust input validation for document IDs (empty check, 250-byte limit), SQL++ queries, search results limits (1-10000 range), and JSON document parsing with type safety.
  • Code Quality & Maintainability: Improved credential security with required fields and descriptions, standardized empty search results response format, introduced a shared constants file, added a retry utility for transient failures, and enhanced JSDoc documentation for key functions.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This is an excellent and comprehensive pull request that significantly improves the n8n-nodes-couchbase package. The addition of a test suite with Vitest, robust error handling, input validation, and fixes for memory and connection leaks are all major enhancements. The code quality is much improved with the introduction of shared constants and a retry utility. My review includes a few suggestions to further improve maintainability by reducing code duplication and to fix a minor issue in value parsing.

Comment on lines +44 to +47
// Validation constants
const MAX_DOCUMENT_ID_LENGTH = 250; // Couchbase max key length in bytes
const MIN_RESULTS_LIMIT = 1;
const MAX_RESULTS_LIMIT = 10000;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

These constants are also defined in the new utils/constants.ts file. To avoid code duplication and improve maintainability, please remove these local definitions and import them from @utils/constants instead.

Comment on lines +140 to +182
function parseDocumentValue(
context: IExecuteFunctions,
value: unknown,
): IDataObject | IDataObject[] | string | number | boolean {
// If it's already an object (not null, not array), return it
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
return value as IDataObject;
}

// If it's an array, return it
if (Array.isArray(value)) {
return value as IDataObject[];
}

// If it's a string, try to parse as JSON
if (typeof value === 'string') {
const trimmed = value.trim();
// Check if it looks like JSON (starts with { or [)
if (trimmed.startsWith('{') || trimmed.startsWith('[')) {
try {
return JSON.parse(trimmed) as IDataObject | IDataObject[];
} catch {
throw new NodeOperationError(
context.getNode(),
'Invalid JSON in document value',
{
description: 'The document value appears to be JSON but could not be parsed. Please check the syntax.',
},
);
}
}
// Return string as-is if it's not JSON-like (Couchbase supports non-JSON values)
return value;
}

// Return primitives as-is (numbers, booleans, etc.)
if (typeof value === 'number' || typeof value === 'boolean') {
return value;
}

// Default fallback - return empty object
return {} as IDataObject;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current implementation of parseDocumentValue converts a null input into an empty object {}. Since Couchbase can store null values, it would be more accurate to handle null explicitly and return it, allowing users to store null values in their documents. This requires updating the function's return type to include null.

function parseDocumentValue(
	context: IExecuteFunctions,
	value: unknown,
): IDataObject | IDataObject[] | string | number | boolean | null {
	// Handle null explicitly, as Couchbase supports it.
	if (value === null) {
		return null;
	}

	// If it's already an object (not null, not array), return it
	if (typeof value === 'object' && !Array.isArray(value)) {
		return value as IDataObject;
	}

	// If it's an array, return it
	if (Array.isArray(value)) {
		return value as IDataObject[];
	}

	// If it's a string, try to parse as JSON
	if (typeof value === 'string') {
		const trimmed = value.trim();
		// Check if it looks like JSON (starts with { or [)
		if (trimmed.startsWith('{') || trimmed.startsWith('[')) {
			try {
				return JSON.parse(trimmed) as IDataObject | IDataObject[];
			} catch {
				throw new NodeOperationError(
					context.getNode(),
					'Invalid JSON in document value',
					{
						description: 'The document value appears to be JSON but could not be parsed. Please check the syntax.',
					},
				);
			}
		}
		// Return string as-is if it's not JSON-like (Couchbase supports non-JSON values)
		return value;
	}

	// Return primitives as-is (numbers, booleans, etc.)
	if (typeof value === 'number' || typeof value === 'boolean') {
		return value;
	}

	// Default fallback - return empty object for undefined or other unhandled types
	return {} as IDataObject;
}

Comment on lines +15 to +17
// Connection configuration constants
const CONNECTION_TIMEOUT_MS = 10000; // 10 seconds
const CONNECTION_IDLE_TIMEOUT_MS = 30000; // 30 seconds - auto-close after inactivity

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

These constants are also defined in utils/constants.ts. The version in utils/constants.ts is preferable as it allows overriding via environment variables. Please remove these local definitions and import them from ../constants at the top of the file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant