### Install Couchbase Node.js Client Source: https://github.com/couchbase/couchnode/blob/master/README.md Install the latest release using npm. For the development version, install directly from GitHub. ```bash npm install couchbase ``` ```bash npm install "git+https://github.com/couchbase/couchnode.git#master" ``` -------------------------------- ### Example Output for SDK Pruning Script Source: https://github.com/couchbase/couchnode/blob/master/README.md This is an example output from the `help-prune` script, illustrating potential size savings by removing mismatched platform packages and Couchbase dependencies. ```bash Checking for platform packages in /tmp/couchnode-test/node_modules/@couchbase that do not match the expected platform package (couchbase-linux-x64-openssl1). Found mismatch: Path=/tmp/couchnode-test/node_modules/@couchbase/couchbase-linuxmusl-x64-openssl1 Recommendations for pruning: Removing mismatched platform=couchbase-linuxmusl-x64-openssl1 (path=/tmp/couchnode-test/node_modules/@couchbase/couchbase-linuxmusl-x64-openssl1) saves ~13.31 MB on disk. Removing Couchbase deps/ (path=/tmp/couchnode-test/node_modules/couchbase/deps) saves ~45.51 MB on disk. Removing Couchbase src/ (path=/tmp/couchnode-test/node_modules/couchbase/src) saves ~0.61 MB on disk. ``` -------------------------------- ### Basic Winston Integration Source: https://github.com/couchbase/couchnode/blob/master/LOGGING.md Integrate Couchbase with Winston for logging. Install Winston (`npm install winston`). ```typescript import winston from 'winston' import { connect } from 'couchbase' const logger = winston.createLogger({ level: 'info', format: winston.format.combine( winston.format.timestamp(), winston.format.json() ), transports: [ new winston.transports.Console() ] }) const cluster = await connect('couchbase://localhost', { username: 'Administrator', password: 'password', logger: logger }) ``` -------------------------------- ### Basic Pino Integration Source: https://github.com/couchbase/couchnode/blob/master/LOGGING.md Integrate Couchbase with Pino for basic logging. Ensure Pino is installed (`npm install pino`). ```typescript import pino from 'pino' import { connect } from 'couchbase' const logger = pino({ level: 'info' }) const cluster = await connect('couchbase://localhost', { username: 'Administrator', password: 'password', logger: logger }) ``` -------------------------------- ### Setup Python Virtual Environment Source: https://github.com/couchbase/couchnode/blob/master/BUILDING.md Sets up a Python virtual environment for managing dependencies required for autogen scripts. Replace `` with your desired path. ```bash python3 -m venv ``` ```bash source /bin/activate ``` -------------------------------- ### Install clang for Python Source: https://github.com/couchbase/couchnode/blob/master/BUILDING.md Installs the `clang` Python package, which is a dependency for the `gen-bindings-json.py` script. This command should be run within the activated virtual environment. ```bash python3 -m pip install clang ``` -------------------------------- ### Pino with Custom Configuration Source: https://github.com/couchbase/couchnode/blob/master/LOGGING.md Configure Pino with custom log levels, formatters, and transports for enhanced logging. Install `pino-pretty` for colored output (`npm install pino-pretty`). ```typescript import pino from 'pino' import { connect } from 'couchbase' const logger = pino({ level: 'debug', formatters: { level: (label) => { return { level: label } } }, transport: { target: 'pino-pretty', // need the pino-pretty package options: { colorize: true, translateTime: 'SYS:standard' } } }) const cluster = await connect('couchbase://localhost', { username: 'Administrator', password: 'password', logger: logger }) ``` -------------------------------- ### Setting Log Level via Environment Variable Source: https://github.com/couchbase/couchnode/blob/master/LOGGING.md The simplest way to enable logging is by setting the CNLOGLEVEL environment variable before starting your application. This configures the SDK's log output to the console. ```APIDOC ## Setting Log Level via Environment Variable ### Description Configure the SDK's log output by setting the `CNLOGLEVEL` environment variable. This variable controls the verbosity of logs sent to the console. ### Usage Set the environment variable before running your Node.js application: ```bash CNLOGLEVEL=info node your-app.js ``` ### Log Levels Accepted values (case-insensitive): - `trace`: Most verbose, logs everything. - `debug`: Detailed debugging information. - `info`: General informational messages. - `warn`: Warning messages and above. - `error`: Error messages only (least verbose). Invalid values will be ignored, and logging will be disabled. ``` -------------------------------- ### Set Logging Level via Environment Variable Source: https://github.com/couchbase/couchnode/blob/master/LOGGING.md Set the CNLOGLEVEL environment variable to control SDK log output. This example sets the level to INFO, outputting messages at INFO level and above to the console. ```console CNLOGLEVEL=info node your-app.js ``` -------------------------------- ### Simple Custom Logger Implementation - JavaScript Source: https://github.com/couchbase/couchnode/blob/master/LOGGING.md Implement a custom logger object that conforms to the SDK's Logger interface. This example logs messages to the console with custom prefixes for each level. ```javascript const customLogger = { trace: (msg, ...args) => console.log('[TRACE]', msg, ...args), debug: (msg, ...args) => console.log('[DEBUG]', msg, ...args), info: (msg, ...args) => console.log('[INFO]', msg, ...args), warn: (msg, ...args) => console.warn('[WARN]', msg, ...args), error: (msg, ...args) => console.error('[ERROR]', msg, ...args) } const cluster = await connect('couchbase://localhost', { username: 'Administrator', password: 'password', logger: customLogger }) ``` -------------------------------- ### Full-Text Search (FTS) with Match Query Source: https://context7.com/couchbase/couchnode/llms.txt Perform full-text searches using `cluster.searchQuery`. This example searches the 'travel-index' for 'Air France', retrieves specific fields, and applies HTML highlighting. It also shows how to access total hits from metadata. ```typescript import { connect, SearchQuery, SearchRequest, VectorQuery, VectorSearch } from 'couchbase' const cluster = await connect('couchbase://127.0.0.1', { username: 'Administrator', password: 'password', }) // Full-text match query const ftsResult = await cluster.searchQuery( 'travel-index', SearchQuery.match('Air France'), { limit: 5, fields: ['name', 'country'], highlight: { style: 'html', fields: ['name'] }, } ) ftsResult.rows.forEach(row => { console.log('Score:', row.score, 'ID:', row.id, 'Fields:', row.fields) }) console.log('Total hits:', ftsResult.meta.metrics?.totalRows) // Vector search with a prefilter const embedding = Array.from({ length: 1536 }, () => Math.random()) const vectorResult = await cluster.search( 'vector-index', SearchRequest.create( VectorSearch.fromVectorQuery( new VectorQuery('description_embedding', embedding).numCandidates(5) ) ), { limit: 3 } ) vectorResult.rows.forEach(row => console.log('Vector hit:', row.id, 'Score:', row.score)) await cluster.close() ``` -------------------------------- ### N1QL / SQL++ Queries with Named Parameters Source: https://context7.com/couchbase/couchnode/llms.txt Execute N1QL queries using named parameters for clarity and security. Supports scan consistency options and metric collection. Ensure the `travel-sample` bucket and `inventory.airline` collection exist for this example. ```typescript import { connect, QueryScanConsistency } from 'couchbase' const cluster = await connect('couchbase://127.0.0.1', { username: 'Administrator', password: 'password', }) // Named parameters const result = await cluster.query( 'SELECT name, country FROM `travel-sample`.inventory.airline WHERE country = $country ORDER BY name LIMIT $limit', { parameters: { country: 'France', limit: 5 }, scanConsistency: QueryScanConsistency.RequestPlus, metrics: true, } ) result.rows.forEach(row => console.log(row.name, '-', row.country)) console.log('Elapsed:', result.meta.metrics?.elapsedTime) // Positional parameters const result2 = await cluster.query( 'SELECT * FROM `default` WHERE type = $1 AND active = $2', { parameters: ['airline', true] } ) await cluster.close() ``` -------------------------------- ### Configure Gerrit Remote and Hooks Source: https://github.com/couchbase/couchnode/blob/master/CONTRIBUTING.md Add the Gerrit remote repository and install the commit-msg hook for Gerrit integration. Ensure your Gerrit username is correctly substituted. ```bash $ git remote add gerrit ssh://${USERNAME}@review.couchbase.org:29418/couchnode $ scp -P 29418 ${USERNAME}@review.couchbase.org:hooks/commit-msg .git/hooks $ chmod a+x .git/hooks/commit-msg ``` -------------------------------- ### Debug Package Integration Source: https://github.com/couchbase/couchnode/blob/master/LOGGING.md Adapt the Debug package to implement the Couchbase Logger interface for logging. Install debug (`npm install debug`). ```typescript import createDebug from 'debug' import { connect, Logger } from 'couchbase' const debugLogger = createDebug('couchbase') // Create an adapter that implements the Logger interface class CustomLogger implements Logger { trace(msg: string, ...args: any[]): void { debugLogger('[TRACE]', msg, ...args) } debug(msg: string, ...args: any[]): void { debugLogger('[DEBUG]', msg, ...args) } info(msg: string, ...args: any[]): void { debugLogger('[INFO]', msg, ...args) } warn(msg: string, ...args: any[]): void { debugLogger('[WARN]', msg, ...args) } error(msg: string, ...args: any[]): void { debugLogger('[ERROR]', msg, ...args) } } const logger = new CustomLogger() const cluster = await connect('couchbase://localhost', { username: 'Administrator', password: 'password', logger: logger }) ``` -------------------------------- ### Get Cluster Diagnostics and Ping Services with Couchbase Node.js SDK Source: https://context7.com/couchbase/couchnode/llms.txt Use `cluster.diagnostics()` for a snapshot of connection states and `cluster.ping()` to actively check service responsiveness and latency. Specify `ServiceType` for targeted pings. ```typescript import { connect, ServiceType } from 'couchbase' const cluster = await connect('couchbase://127.0.0.1', { username: 'Administrator', password: 'password', }) // Passive diagnostics: connection state snapshot const diagResult = await cluster.diagnostics({ reportId: 'my-diag-001' }) console.log('Diagnostics state:', diagResult.state) Object.entries(diagResult.services).forEach(([service, endpoints]) => { endpoints.forEach(ep => console.log(` [${service}] ${ep.remote} - ${ep.state}`)) }) // Active ping: check which services are responsive const pingResult = await cluster.ping({ serviceTypes: [ServiceType.KeyValue, ServiceType.Query], reportId: 'health-check', }) Object.entries(pingResult.services).forEach(([service, endpoints]) => { endpoints.forEach(ep => { console.log(` [${service}] ${ep.remote} latency=${ep.latency}ms ok=${ep.error === undefined}`) }) }) await cluster.close() ``` -------------------------------- ### Simple Custom Logger Implementation - TypeScript Source: https://github.com/couchbase/couchnode/blob/master/LOGGING.md Implement a custom logger class that conforms to the SDK's Logger interface. This example logs messages to the console with custom prefixes for each level. ```typescript class CustomLogger implements Logger { trace(msg: string, ...args: any[]): void { console.log('[TRACE]', msg, ...args) } debug(msg: string, ...args: any[]): void { console.log('[DEBUG]', msg, ...args) } info(msg: string, ...args: any[]): void { console.log('[INFO]', msg, ...args) } warn(msg: string, ...args: any[]): void { console.warn('[WARN]', msg, ...args) } error(msg: string, ...args: any[]): void { console.error('[ERROR]', msg, ...args) } } customLogger = new CustomLogger() const cluster = await connect('couchbase://localhost', { username: 'Administrator', password: 'password', logger: customLogger }) ``` -------------------------------- ### Get Couchbase Node.js Version Source: https://github.com/couchbase/couchnode/blob/master/CMakeLists.txt Retrieves the version of the Couchbase Node.js package by executing a Node.js script to read the package.json file. ```cmake function(get_couchnode_version) execute_process(COMMAND node -e "console.log(JSON.parse(fs.readFileSync('${PROJECT_SOURCE_DIR}/package.json')).version)" OUTPUT_VARIABLE sdk_version) string(STRIP "${sdk_version}" SDK_VERSION) set(COUCHNODE_VERSION "${SDK_VERSION}" PARENT_SCOPE) endfunction() ``` -------------------------------- ### Scoped SQL++ Queries Source: https://context7.com/couchbase/couchnode/llms.txt Execute N1QL queries within a specific scope, simplifying queries by not requiring fully qualified collection names. This example queries the `airline` and `route` collections within the `inventory` scope of the `travel-sample` bucket. ```typescript import { connect } from 'couchbase' const cluster = await connect('couchbase://127.0.0.1', { username: 'Administrator', password: 'password', }) const scope = cluster.bucket('travel-sample').scope('inventory') // Query using unqualified collection names within the scope const result = await scope.query( 'SELECT a.name, r.destinationairport FROM airline a JOIN route r ON a.iata = r.airlineid WHERE a.country = $1 LIMIT 5', { parameters: ['France'] } ) result.rows.forEach(row => console.log(row)) await cluster.close() ``` -------------------------------- ### Analytics Queries Source: https://context7.com/couchbase/couchnode/llms.txt Run analytics queries against the Couchbase Analytics Service for large-scale ad hoc analysis without impacting transactional performance. This example counts airlines in the 'United States' using a placeholder parameter. ```typescript import { connect } from 'couchbase' const cluster = await connect('couchbase://127.0.0.1', { username: 'Administrator', password: 'password', }) const result = await cluster.analyticsQuery( 'SELECT VALUE COUNT(*) FROM `travel-sample`.inventory.airline WHERE country = ?', { parameters: ['United States'] } ) console.log('US Airlines count:', result.rows[0]) console.log('Analytics status:', result.meta.status) await cluster.close() ``` -------------------------------- ### Build Client Binary via npm Source: https://github.com/couchbase/couchnode/blob/master/BUILDING.md Builds the client binary using the `prebuild` npm script with the `--use-boringssl` flag. This is a streamlined way to compile the SDK. ```bash npm run prebuild -- --use-boringssl ``` -------------------------------- ### Compile Client Binary with cmake-js Source: https://github.com/couchbase/couchnode/blob/master/BUILDING.md Compiles the client binary using `cmake-js`, similar to the configure step but executes the build process. This command will automatically clean and re-build upon failure. ```bash npx cmake-js compile \ --runtime node \ --runtime-version $(node --version) \ --CDUSE_STATIC_OPENSSL=OFF \ --CDCPM_DOWNLOAD_ALL=OFF \ --CDCPM_USE_NAMED_CACHE_DIRECTORIES=ON \ --CDCPM_USE_LOCAL_PACKAGES=OFF \ --CDCPM_SOURCE_CACHE=$CXXCBC_CACHE_DIR ``` -------------------------------- ### Connect and Perform Basic Operations (JavaScript) Source: https://github.com/couchbase/couchnode/blob/master/README.md Instantiate a connection to a Couchbase cluster, add a document, and retrieve its contents. Ensure you have a Couchbase cluster running and accessible with the provided credentials. ```javascript const couchbase = require('couchbase') async function main() { const cluster = await couchbase.connect( 'couchbase://127.0.0.1', { username: 'username', password: 'password', } ) const bucket = cluster.bucket('default') const coll = bucket.defaultCollection() await coll.upsert('testdoc', { foo: 'bar' }) const res = await coll.get('testdoc') console.log(res.content) } // Run the main function main() .then((_) => { console.log ('Success!') }) .catch((err) => { console.log('ERR:', err) }) ``` -------------------------------- ### Using Couchbase List, Map, Queue, and Set Data Structures Source: https://context7.com/couchbase/couchnode/llms.txt Demonstrates the usage of Couchbase's high-level data structure wrappers for lists, maps, queues, and sets. Ensure the Couchbase cluster is running and accessible with the provided credentials. ```typescript import { connect } from 'couchbase' const cluster = await connect('couchbase://127.0.0.1', { username: 'Administrator', password: 'password', }) const collection = cluster.bucket('default').defaultCollection() // CouchbaseList const list = collection.list('mylist') await list.push('first') await list.push('second') console.log('List size:', await list.size()) console.log('List[0]:', await list.getAt(0)) await list.removeAt(0) // CouchbaseMap const map = collection.map('mymap') await map.set('key1', 'value1') await map.set('key2', { nested: true }) console.log('Has key1:', await map.exists('key1')) console.log('key2 value:', await map.get('key2')) console.log('Map keys:', await map.keys()) // CouchbaseQueue (FIFO) const queue = collection.queue('myqueue') await queue.push({ task: 'process_order', orderId: 42 }) const next = await queue.pop() console.log('Dequeued:', next) // CouchbaseSet const set = collection.set('myset') await set.add('member1') await set.add('member2') await set.add('member1') // duplicates are ignored console.log('Set size:', await set.size()) console.log('Contains member1:', await set.contains('member1')) await cluster.close() ``` -------------------------------- ### Connect and Perform Basic Operations (TypeScript) Source: https://github.com/couchbase/couchnode/blob/master/README.md Instantiate a connection to a Couchbase cluster, add a document, and retrieve its contents using TypeScript. Ensure you have a Couchbase cluster running and accessible with the provided credentials. ```typescript import { Bucket, Cluster, Collection, connect, GetResult, } from 'couchbase' async function main() { const cluster: Cluster = await connect( 'couchbase://127.0.0.1', { username: 'username', password: 'password', } ) const bucket: Bucket = cluster.bucket('default') const coll: Collection = bucket.defaultCollection() await coll.upsert('testdoc', { foo: 'bar' }) const res: GetResult = await coll.get('testdoc') console.log(res.content) } // Run the main function main() .then((_) => { console.log ('Success!') }) .catch((err) => { console.log('ERR:', err) }) ``` -------------------------------- ### Download Node.js Windows Library Source: https://github.com/couchbase/couchnode/blob/master/CMakeLists.txt Downloads the appropriate Node.js library (`node.lib`) for Windows, supporting both standard Node.js and Electron runtimes, and different architectures (x64, x86). ```cmake function(download_nodejs_win_lib) if(NODE_RUNTIME STREQUAL "electron") set(NODE_LIB_URL "https://artifacts.electronjs.org/headers/dist/v${NODE_RUNTIMEVERSION}") if(NODE_ARCH STREQUAL "x64") set(NODE_LIB_URL "${NODE_LIB_URL}/x64") endif() else() set(NODE_LIB_URL "https://nodejs.org/dist/v${NODE_RUNTIMEVERSION}") if(NODE_ARCH STREQUAL "x64") set(NODE_LIB_URL "${NODE_LIB_URL}/win-x64") else() set(NODE_LIB_URL "${NODE_LIB_URL}/win-x86") endif() endif() set(NODE_LIB_URL "${NODE_LIB_URL}/node.lib") FetchContent_Declare( nodejs_win_lib URL ${NODE_LIB_URL} DOWNLOAD_NO_EXTRACT TRUE ) message("Downloading ${NODE_RUNTIME} v${NODE_RUNTIMEVERSION} win lib...") FetchContent_MakeAvailable(nodejs_win_lib) message("Downloaded ${NODE_RUNTIME} v${NODE_RUNTIMEVERSION} win lib to ${nodejs_win_lib_SOURCE_DIR}") set(NODEJS_LIB "${nodejs_win_lib_SOURCE_DIR}/node.lib" PARENT_SCOPE) endfunction() ``` -------------------------------- ### Clone Repository Source: https://github.com/couchbase/couchnode/blob/master/CONTRIBUTING.md Clone the Couchbase Node.js SDK repository from GitHub to begin development. ```bash $ git clone https://github.com/couchbase/couchnode.git ``` -------------------------------- ### connect Source: https://context7.com/couchbase/couchnode/llms.txt Establishes a connection to a Couchbase cluster and returns a Cluster instance. Supports various connection options including credentials and timeouts. ```APIDOC ## connect — Connect to a Couchbase Cluster The top-level `connect` function establishes a connection to a Couchbase cluster and returns a fully initialized `Cluster` instance. Accepts a connection string and options including credentials, TLS config, custom timeouts, tracers, meters, and a config profile. ### Method `connect(connectionString: string, options?: ConnectOptions): Promise` ### Parameters #### Connection String - **connectionString** (string) - Required - The connection string for the Couchbase cluster (e.g., `couchbase://127.0.0.1`). #### Options - **username** (string) - Optional - The username for authentication. - **password** (string) - Optional - The password for authentication. - **timeouts** (object) - Optional - Configuration for various timeouts. - **kvTimeout** (number) - Optional - Timeout for Key-Value operations in milliseconds. - **queryTimeout** (number) - Optional - Timeout for query operations in milliseconds. - **managementTimeout** (number) - Optional - Timeout for management operations in milliseconds. ### Request Example ```typescript import { connect } from 'couchbase' async function main() { const cluster = await connect('couchbase://127.0.0.1', { username: 'Administrator', password: 'password', timeouts: { kvTimeout: 5000, queryTimeout: 30000, managementTimeout: 30000, }, }) console.log('Connected to cluster') await cluster.close() } main().catch(console.error) ``` ### Response #### Success Response (Cluster Instance) - **Cluster** - An instance of the `Cluster` object representing the connection. ``` -------------------------------- ### Configure Node.js Windows Library Download Source: https://github.com/couchbase/couchnode/blob/master/CMakeLists.txt Handles the download of the Node.js Windows library for older versions of cmake-js. This is necessary when the full Node.js Windows lib is not automatically downloaded. ```cmake SET(NODEJS_LIB "") download_nodejs_win_lib() ``` -------------------------------- ### Pessimistic Locking with Get and Lock/Unlock Source: https://context7.com/couchbase/couchnode/llms.txt Retrieves a document and locks it for a specified duration using `collection.getAndLock`. The lock must be released with `collection.unlock` using the obtained CAS. If the lock is held, subsequent operations will implicitly unlock upon successful completion. ```typescript import { connect } from 'couchbase' const cluster = await connect('couchbase://127.0.0.1', { username: 'Administrator', password: 'password', }) const collection = cluster.bucket('default').defaultCollection() // Lock the document for 15 seconds const locked = await collection.getAndLock('counter::orders', 15) console.log('Locked with CAS:', locked.cas) try { // Perform some work, then replace while holding the lock await collection.replace('counter::orders', { value: locked.content.value + 1 }, { cas: locked.cas, }) console.log('Updated and implicitly unlocked') } catch (err) { // Release lock explicitly on error await collection.unlock('counter::orders', locked.cas) throw err } await cluster.close() ``` -------------------------------- ### Perform Sub-Document Reads with lookupIn Source: https://context7.com/couchbase/couchnode/llms.txt Use `lookupIn` to retrieve specific fields or metadata from within a document without fetching the entire document. Define the desired fields using `LookupInSpec` which supports `get`, `exists`, and `count` operations, as well as macros like `LookupInMacro.Expiry`. ```typescript import { connect, LookupInSpec, LookupInMacro } from 'couchbase' const cluster = await connect('couchbase://127.0.0.1', { username: 'Administrator', password: 'password', }) const collection = cluster.bucket('travel-sample').scope('inventory').collection('airline') const result = await collection.lookupIn('airline_10', [ LookupInSpec.get('name'), LookupInSpec.get('country'), LookupInSpec.exists('iata'), LookupInSpec.get(LookupInMacro.Expiry), // fetch document expiry ]) console.log('Name:', result.content[0].value) // 'Air France' console.log('Country:', result.content[1].value) // 'France' console.log('Has IATA?', result.content[2].value) // true console.log('Expiry:', result.content[3].value) await cluster.close() ``` -------------------------------- ### Programmatic Console Logger - JavaScript Source: https://github.com/couchbase/couchnode/blob/master/LOGGING.md Create a console logger programmatically using `couchbase.createConsoleLogger` and `couchbase.LogLevel.INFO`. This logger is passed to the connect function. ```javascript const couchbase = require('couchbase') const cluster = await couchbase.connect('couchbase://localhost', { username: 'Administrator', password: 'password', logger: couchbase.createConsoleLogger(couchbase.LogLevel.INFO) }) ``` -------------------------------- ### Configure Build with cmake-js Source: https://github.com/couchbase/couchnode/blob/master/BUILDING.md Configures the build process using `cmake-js`, specifying Node.js runtime, version, and various CMake build options. It directs `cmake-js` to use a local source cache for dependencies. ```bash npx cmake-js configure \ --runtime node \ --runtime-version $(node --version) \ --CDUSE_STATIC_OPENSSL=OFF \ --CDCPM_DOWNLOAD_ALL=OFF \ --CDCPM_USE_NAMED_CACHE_DIRECTORIES=ON \ --CDCPM_USE_LOCAL_PACKAGES=OFF \ --CDCPM_SOURCE_CACHE=$CXXCBC_CACHE_DIR ``` -------------------------------- ### Handle Electron Runtime and BoringSSL Source: https://github.com/couchbase/couchnode/blob/master/CMakeLists.txt If the runtime is Electron, BoringSSL is used, and static OpenSSL linking is disabled. ```cmake if(USE_STATIC_OPENSSL AND "${NODE_RUNTIME}" STREQUAL "electron") message(STATUS "Found electron runtime, using BoringSSL.") set(USE_STATIC_OPENSSL FALSE) endif() message(STATUS "USE_STATIC_OPENSSL=${USE_STATIC_OPENSSL}") ``` -------------------------------- ### Display Node.js Configuration Variables Source: https://github.com/couchbase/couchnode/blob/master/CMakeLists.txt Outputs the final configured values for NODEJS_INC_DIR and NODEJS_LIB to the console for debugging purposes. ```cmake message(STATUS "NODEJS_INC_DIR=${NODEJS_INC_DIR}") message(STATUS "NODEJS_LIB=${NODEJS_LIB}") ``` -------------------------------- ### Navigate Data Hierarchy: Bucket, Scope, Collection Source: https://context7.com/couchbase/couchnode/llms.txt Opens references to a bucket, scope, and collection. `bucket()` triggers an asynchronous open, while `scope()` and `collection()` are synchronous reference accessors. The default collection can also be accessed directly. ```typescript import { connect } from 'couchbase' const cluster = await connect('couchbase://127.0.0.1', { username: 'Administrator', password: 'password', }) const bucket = cluster.bucket('travel-sample') const scope = bucket.scope('inventory') const collection = scope.collection('airline') // Access the default collection directly const defaultCollection = bucket.defaultCollection() await cluster.close() ``` -------------------------------- ### Perform Scans with RangeScan, SamplingScan, and PrefixScan Source: https://context7.com/couchbase/couchnode/llms.txt Execute key-value scans using `RangeScan`, `SamplingScan`, or `PrefixScan` for bulk data access. `RangeScan` targets keys within a specified range, `SamplingScan` retrieves random documents, and `PrefixScan` targets keys with a given prefix. For indexed queries, SQL++ is recommended. ```typescript import { connect, RangeScan, SamplingScan, PrefixScan, ScanTerm } from 'couchbase' const cluster = await connect('couchbase://127.0.0.1', { username: 'Administrator', password: 'password', }) const collection = cluster.bucket('default').defaultCollection() // Range scan between two keys (inclusive) const rangeResults = await collection.scan( new RangeScan(new ScanTerm('user::1000'), new ScanTerm('user::2000')), { idsOnly: false } ) console.log('Range scan results:', rangeResults.length) // Sampling scan: random sample of up to 10 documents const sampleResults = await collection.scan( new SamplingScan(10, /* seed */ 42) ) sampleResults.forEach(r => console.log(r.id, r.content)) // Prefix scan: all keys starting with 'airline_' const prefixResults = await collection.scan(new PrefixScan('airline_')) prefixResults.forEach(r => console.log('Key:', r.id)) await cluster.close() ``` -------------------------------- ### Manage Buckets with Couchbase Node.js SDK Source: https://context7.com/couchbase/couchnode/llms.txt Utilize `cluster.buckets()` to manage buckets. This includes creating new buckets with specified configurations (name, RAM, type, replicas, storage backend), listing all existing buckets, and dropping buckets. ```typescript import { connect, BucketType, StorageBackend } from 'couchbase' const cluster = await connect('couchbase://127.0.0.1', { username: 'Administrator', password: 'password', }) const buckets = cluster.buckets() // Create a new bucket await buckets.createBucket({ name: 'my-new-bucket', ramQuotaMB: 128, bucketType: BucketType.Couchbase, storageBackend: StorageBackend.Couchstore, numReplicas: 1, flushEnabled: false, }) console.log('Bucket created') // List all buckets const allBuckets = await buckets.getAllBuckets() allBuckets.forEach(b => console.log(b.name, b.ramQuotaMB + 'MB')) // Drop the bucket await buckets.dropBucket('my-new-bucket') console.log('Bucket dropped') await cluster.close() ``` -------------------------------- ### Programmatic Console Logger Source: https://github.com/couchbase/couchnode/blob/master/LOGGING.md You can programmatically create and configure a console logger using the `createConsoleLogger` function, specifying the desired log level and an optional prefix. ```APIDOC ## Programmatic Console Logger ### Description Create a console logger instance programmatically using `createConsoleLogger`. This allows for finer control over logging behavior, including setting a specific log level and adding a custom prefix to all log messages. ### Basic Usage (TypeScript) ```typescript import { connect, createConsoleLogger, LogLevel } from 'couchbase' const cluster = await connect('couchbase://localhost', { username: 'Administrator', password: 'password', logger: createConsoleLogger(LogLevel.INFO) }) ``` ### Basic Usage (JavaScript) ```javascript const couchbase = require('couchbase') const cluster = await couchbase.connect('couchbase://localhost', { username: 'Administrator', password: 'password', logger: couchbase.createConsoleLogger(couchbase.LogLevel.INFO) }) ``` ### Logging Prefix Add a prefix to all log messages for easier identification: ```typescript import { connect, createConsoleLogger, LogLevel } from 'couchbase' const logger = createConsoleLogger(LogLevel.DEBUG, '[Couchbase]') const cluster = await connect('couchbase://localhost', { username: 'Administrator', password: 'password', logger: logger }) logger.info('Connection established!') ``` #### Output Example ```console [Couchbase] Connection established! ``` ``` -------------------------------- ### Connect to a Couchbase Cluster Source: https://context7.com/couchbase/couchnode/llms.txt Establishes a connection to a Couchbase cluster using a connection string and optional credentials and timeouts. Always close the connection when done. ```typescript import { connect, DurabilityLevel } from 'couchbase' async function main() { const cluster = await connect('couchbase://127.0.0.1', { username: 'Administrator', password: 'password', timeouts: { kvTimeout: 5000, // 5s KV timeout queryTimeout: 30000, // 30s query timeout managementTimeout: 30000, }, }) console.log('Connected to cluster') // Always close the connection when done await cluster.close() } main().catch(console.error) ``` -------------------------------- ### Generate bindings.json Source: https://github.com/couchbase/couchnode/blob/master/BUILDING.md Generates the `bindings.json` file, which is used by the autogen tooling. This command can be run without arguments, or with specific paths for LLVM and system headers. ```bash python3 gen-bindings-json.py ``` ```bash python gen-bindings-json.py -v $(llvm-config --version) -i $(llvm-config --includedir) -l $(llvm-config --libdir) -s $(xcrun --show-sdk-path) ``` -------------------------------- ### Set Minimum CMake Version and Policies Source: https://github.com/couchbase/couchnode/blob/master/CMakeLists.txt Specifies the minimum required CMake version and sets policies for compatibility. ```cmake cmake_minimum_required(VERSION 3.19) cmake_policy(SET CMP0042 NEW) cmake_policy(SET CMP0048 NEW) ``` -------------------------------- ### cluster.bucket / bucket.scope / scope.collection Source: https://context7.com/couchbase/couchnode/llms.txt Navigates the data hierarchy by opening references to a bucket, scope, and collection. `bucket()` is asynchronous, while `scope()` and `collection()` are synchronous. ```APIDOC ## cluster.bucket / bucket.scope / scope.collection — Navigate the Data Hierarchy Opens a reference to a bucket, scope, and collection in sequence. `bucket()` triggers an asynchronous open on the underlying connection. `scope()` and `collection()` are synchronous reference accessors. ### Method Signatures - **`cluster.bucket(name: string): Bucket`** - **`bucket.scope(name: string): Scope`** - **`scope.collection(name: string): Collection`** - **`bucket.defaultCollection(): Collection`** ### Parameters - **name** (string) - Required - The name of the bucket, scope, or collection to reference. ### Usage Example ```typescript import { connect } from 'couchbase' const cluster = await connect('couchbase://127.0.0.1', { username: 'Administrator', password: 'password', }) const bucket = cluster.bucket('travel-sample') const scope = bucket.scope('inventory') const collection = scope.collection('airline') // Access the default collection directly const defaultCollection = bucket.defaultCollection() await cluster.close() ``` ``` -------------------------------- ### cluster.buckets Source: https://context7.com/couchbase/couchnode/llms.txt Returns a `BucketManager` for creating, updating, listing, and dropping buckets on the cluster. ```APIDOC ## `cluster.buckets` — Bucket Management Returns a `BucketManager` for creating, updating, listing, and dropping buckets on the cluster. ```typescript import { connect, BucketType, StorageBackend } from 'couchbase' const cluster = await connect('couchbase://127.0.0.1', { username: 'Administrator', password: 'password', }) const buckets = cluster.buckets() // Create a new bucket await buckets.createBucket({ name: 'my-new-bucket', ramQuotaMB: 128, bucketType: BucketType.Couchbase, storageBackend: StorageBackend.Couchstore, numReplicas: 1, flushEnabled: false, }) console.log('Bucket created') // List all buckets const allBuckets = await buckets.getAllBuckets() allBuckets.forEach(b => console.log(b.name, b.ramQuotaMB + 'MB')) // Drop the bucket await buckets.dropBucket('my-new-bucket') console.log('Bucket dropped') await cluster.close() ``` ``` -------------------------------- ### Read Document from Replicas with getAnyReplica and getAllReplicas Source: https://context7.com/couchbase/couchnode/llms.txt Read documents from replica nodes for high availability. `getAnyReplica` returns the first available replica's data, while `getAllReplicas` fetches all available copies. This is useful when the primary node might be unavailable. ```typescript import { connect } from 'couchbase' const cluster = await connect('couchbase://127.0.0.1', { username: 'Administrator', password: 'password', }) const collection = cluster.bucket('travel-sample').scope('inventory').collection('airline') // Get from any available replica (fastest response) const anyReplica = await collection.getAnyReplica('airline_10') console.log('From replica?', anyReplica.isReplica) console.log('Content:', anyReplica.content) // Get from all replicas const allReplicas = await collection.getAllReplicas('airline_10') allReplicas.forEach((replica, i) => { console.log(`Replica ${i} (isReplica=${replica.isReplica}):`, replica.content.name) }) await cluster.close() ``` -------------------------------- ### Set CPM Cache via npm Source: https://github.com/couchbase/couchnode/blob/master/BUILDING.md Configures the build environment by setting the CPM cache and using BoringSSL. This command is used to prepare dependencies for the build. ```bash npm run prebuild -- --configure --set-cpm-cache --use-boringssl ``` -------------------------------- ### Project Definition and C++ Standard Source: https://github.com/couchbase/couchnode/blob/master/CMakeLists.txt Defines the project name and sets the C++ standard to C++17. ```cmake set(CMAKE_CXX_STANDARD 17) project (couchbase_impl) ``` -------------------------------- ### Configure Build for Non-Static OpenSSL on Windows Source: https://github.com/couchbase/couchnode/blob/master/CMakeLists.txt Sets specific CMake variables and compiler flags for building with non-static OpenSSL on Windows, including the C runtime library and secure warnings. ```cmake if(NOT USE_STATIC_OPENSSL) set(COUCHBASE_CXX_CLIENT_POST_LINKED_OPENSSL OFF CACHE BOOL "" FORCE) set(COUCHBASE_CXX_CLIENT_STATIC_BORINGSSL ON CACHE BOOL "" FORCE) if(WIN32) # Using /MD compile flag as that is what BoringSSL uses and since we cannot override their CMake config # (see link below), we need to use the DLL-specific version of the run-time library. # REF: https://github.com/google/boringssl/blob/f86dd185939a0a81dbbaea4f26d95f299d26811b/CMakeLists.txt#L203-L216 set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") add_definitions(-D_CRT_SECURE_NO_WARNINGS) SET(NODEJS_LIB "${CMAKE_JS_LIB}") endif() else() set(COUCHBASE_CXX_CLIENT_POST_LINKED_OPENSSL ON CACHE BOOL "" FORCE) # cmake-js >= v7.0 no longer downloads the full Node.js headers and utilizes the https://github.com/nodejs/node-api-headers # project. Since we rely on Node's OpenSSL we need to pull in more than just the node-api headers, so lets download # the headers ourselves. if(CMAKE_JS_VERSION VERSION_GREATER_EQUAL "7.0.0") set(NODEJS_INC_DIR "") download_nodejs_headers() set(NODEJS_INC_DIR "${NODEJS_INC_DIR};${CMAKE_JS_INC}") if(WIN32) ``` -------------------------------- ### Prune Couchbase SDK for AWS Lambda Source: https://github.com/couchbase/couchnode/blob/master/README.md Explore the Couchbase SDK to run a script that helps in pruning unnecessary platform packages for smaller AWS Lambda deployment packages. This script provides recommendations for size reduction. ```bash npm explore couchbase -- npm run help-prune ``` -------------------------------- ### Winston with Multiple Transports Source: https://github.com/couchbase/couchnode/blob/master/LOGGING.md Configure Winston with multiple transports to log to different destinations like the console and files, with different log levels for each. ```typescript import winston from 'winston' import { connect } from 'couchbase' const logger = winston.createLogger({ level: 'debug', format: winston.format.combine( winston.format.timestamp(), winston.format.errors({ stack: true }), winston.format.json() ), transports: [ // Write all logs to console new winston.transports.Console({ format: winston.format.combine( winston.format.colorize(), winston.format.simple() ) }), // Write all logs to a file new winston.transports.File({ filename: 'couchbase.log', level: 'info' }), // Write error logs to a separate file new winston.transports.File({ filename: 'couchbase-error.log', level: 'error' }) ] }) const cluster = await connect('couchbase://localhost', { username: 'Administrator', password: 'password', logger: logger }) ``` -------------------------------- ### `collection.binary` Source: https://context7.com/couchbase/couchnode/llms.txt Provides access to binary operations on a collection, including atomic counter increments/decrements and appending/prepending binary data to documents. ```APIDOC ## `collection.binary` — Binary Counter and Append/Prepend Operations Returns a `BinaryCollection` providing atomic numeric counter operations (`increment`, `decrement`) and binary string operations (`append`, `prepend`). ```typescript import { connect } from 'couchbase' const cluster = await connect('couchbase://127.0.0.1', { username: 'Administrator', password: 'password' }) const binary = cluster.bucket('default').defaultCollection().binary() // Increment a counter, creating with initial value 0 if it doesn't exist const incrResult = await binary.increment('page_views::home', 1, { initial: 0 }) console.log('Counter value:', incrResult.value) // Decrement const decrResult = await binary.decrement('page_views::home', 1) console.log('After decrement:', decrResult.value) // Append bytes to an existing raw document await binary.append('log::2024', Buffer.from('\nNew log line')) await cluster.close() ``` ``` -------------------------------- ### Enable Debug Output Source: https://github.com/couchbase/couchnode/blob/master/LOGGING.md Enable debug output for the Debug package by setting the DEBUG environment variable before running your application. ```console DEBUG=couchbase node your-app.js ``` -------------------------------- ### Pino with Child Logger Source: https://github.com/couchbase/couchnode/blob/master/LOGGING.md Create a child logger with Pino to add context, such as a component name, to log messages. ```typescript import pino from 'pino' import { connect } from 'couchbase' const baseLogger = pino({ level: 'info' }) const couchbaseLogger = baseLogger.child({ component: 'couchbase' }) const cluster = await connect('couchbase://localhost', { username: 'Administrator', password: 'password', logger: couchbaseLogger }) ``` -------------------------------- ### Populate Node.js Autogen Code Source: https://github.com/couchbase/couchnode/blob/master/BUILDING.md Populates SDK autogen code sections by running the Node.js binding generator script. This script uses the generated `bindings.json` to create or update binding code. ```javascript node gen-bindings.js.js ``` -------------------------------- ### `cluster.query` Source: https://context7.com/couchbase/couchnode/llms.txt Executes SQL++ (N1QL) queries against the entire cluster. It supports parameterized queries, scan consistency options, read-only mode, and streaming results. ```APIDOC ## `cluster.query` — N1QL / SQL++ Queries Executes a SQL++ (N1QL) query against the cluster. Supports parameterized queries, scan consistency options, read-only mode, and streaming row-by-row. ```typescript import { connect, QueryScanConsistency } from 'couchbase' const cluster = await connect('couchbase://127.0.0.1', { username: 'Administrator', password: 'password' }) // Named parameters const result = await cluster.query( 'SELECT name, country FROM `travel-sample`.inventory.airline WHERE country = $country ORDER BY name LIMIT $limit', { parameters: { country: 'France', limit: 5 }, scanConsistency: QueryScanConsistency.RequestPlus, metrics: true, } ) result.rows.forEach(row => console.log(row.name, '-', row.country)) console.log('Elapsed:', result.meta.metrics?.elapsedTime) // Positional parameters const result2 = await cluster.query( 'SELECT * FROM `default` WHERE type = $1 AND active = $2', { parameters: ['airline', true] } ) await cluster.close() ``` ``` -------------------------------- ### Format Node.js Source Files Source: https://github.com/couchbase/couchnode/blob/master/BUILDING.md Formats Node.js source files using `prettier`. This command ensures consistent code style for the TypeScript binding file. Assumes the CWD is `tools`. ```bash npx prettier --write ../lib/binding.ts ``` -------------------------------- ### Custom Logger Interface Source: https://github.com/couchbase/couchnode/blob/master/LOGGING.md The SDK supports custom logger integration by adhering to a defined Logger interface, allowing you to use your preferred logging libraries. ```APIDOC ## Custom Logger Integration ### Logger Interface The SDK expects a logger object that conforms to the following interface. All methods are optional, and the SDK will safely handle loggers that implement only a subset of these methods. ```typescript interface Logger { trace?(message: string, ...args: any[]): void debug?(message: string, ...args: any[]): void info?(message: string, ...args: any[]): void warn?(message: string, ...args: any[]): void error?(message: string, ...args: any[]): void } ``` ### Simple Custom Logger (TypeScript) ```typescript class CustomLogger implements Logger { trace(msg: string, ...args: any[]): void { console.log('[TRACE]', msg, ...args) } debug(msg: string, ...args: any[]): void { console.log('[DEBUG]', msg, ...args) } info(msg: string, ...args: any[]): void { console.log('[INFO]', msg, ...args) } warn(msg: string, ...args: any[]): void { console.warn('[WARN]', msg, ...args) } error(msg: string, ...args: any[]): void { console.error('[ERROR]', msg, ...args) } } const customLogger = new CustomLogger() const cluster = await connect('couchbase://localhost', { username: 'Administrator', password: 'password', logger: customLogger }) ``` ### Simple Custom Logger (JavaScript) ```javascript const customLogger = { trace: (msg, ...args) => console.log('[TRACE]', msg, ...args), debug: (msg, ...args) => console.log('[DEBUG]', msg, ...args), info: (msg, ...args) => console.log('[INFO]', msg, ...args), warn: (msg, ...args) => console.warn('[WARN]', msg, ...args), error: (msg, ...args) => console.error('[ERROR]', msg, ...args) } const cluster = await connect('couchbase://localhost', { username: 'Administrator', password: 'password', logger: customLogger }) ``` ### Integration with Pino Pino is a fast, low-overhead logging library (`npm install pino`). Its API naturally matches the Couchbase Logger interface, making integration straightforward. ```