← Files Catalyst by ZohoARCHIVED FILE
skills/catalyst-by-zoho/references/sdk-nodejs.md
24.6 KB · Oct 4, 2026 · 12:06 UTC
# Node.js SDK Reference (zcatalyst-sdk-node)
Install via `npm install zcatalyst-sdk-node`.
External docs: https://docs.catalyst.zoho.com/en/sdk/nodejs/v2/overview/
> All versions earlier than 2.5.0 are deprecated. Always use the latest version.
---
## Initialization
```js
const catalyst = require('zcatalyst-sdk-node');
// --- Advanced I/O (Express) ---
// In an Express-based Advanced I/O function, pass the Express request object:
app.post('/api/action', async (req, res) => {
const catalystApp = catalyst.initialize(req);
// ... use catalystApp
});
// --- Basic I/O ---
// In a Basic I/O function, pass the context object:
module.exports = async (context, basicIO) => {
const catalystApp = catalyst.initialize(context);
// ... use catalystApp
basicIO.write(JSON.stringify({ status: 'ok' }));
context.close();
};
// --- Event Function ---
module.exports = async (event, context) => {
const catalystApp = catalyst.initialize(context);
// event.data contains the event payload
context.close();
};
// --- Cron Function ---
module.exports = async (cronDetails, context) => {
const catalystApp = catalyst.initialize(context);
// cronDetails contains cron metadata
context.close();
};
// --- AppSail ---
// In an AppSail app (Express), same pattern as Advanced I/O:
const catalystApp = catalyst.initialize(req);
// --- Admin Scope vs User Scope ---
// Scopes apply to Data Store, File Store, and ZCQL operations.
// Admin scope bypasses row-level permissions:
const adminApp = catalyst.initialize(req, { scope: 'admin' });
// User scope restricts to the authenticated user's rows:
const userApp = catalyst.initialize(req, { scope: 'user' });
```
---
## Data Store
```js
// Get a table reference (by name or table ID)
const table = catalystApp.datastore().table('Shipments');
// Or by ID: catalystApp.datastore().table(23aborTableId);
// --- Insert a single row ---
const row = await table.insertRow({
Name: 'Alice',
Email: 'alice@example.com'
});
// row.ROWID is the auto-generated unique identifier
// --- Insert multiple rows ---
const rows = await table.insertRows([
{ Name: 'Bob', Email: 'bob@example.com' },
{ Name: 'Carol', Email: 'carol@example.com' }
]);
// --- Get a single row by ROWID ---
const singleRow = await table.getRow('123456000000012345');
// --- Get paginated rows ---
// Returns up to 200 rows per page by default.
const result = await table.getPagedRows({
nextToken: 'token_from_previous_call', // optional
maxRows: 100 // optional, default 200
});
const data = result.data;
const hasMore = result.more_records;
const nextToken = result.next_token;
// --- Update a row (ROWID is required) ---
const updated = await table.updateRow({
ROWID: '123456000000012345',
Name: 'Alice Updated'
});
// --- Delete a row ---
await table.deleteRow('123456000000012345');
```
---
## ZCQL
```js
const zcql = catalystApp.zcql();
// --- Execute a ZCQL query ---
// Supports SELECT, INSERT, UPDATE, DELETE, and JOIN queries.
const rows = await zcql.executeZCQLQuery('SELECT * FROM Shipments WHERE Status = \'Active\'');
// INSERT via ZCQL
await zcql.executeZCQLQuery(
'INSERT INTO Shipments (Name, Status) VALUES (\'Package A\', \'Pending\')'
);
// UPDATE via ZCQL
await zcql.executeZCQLQuery(
'UPDATE Shipments SET Status = \'Shipped\' WHERE ROWID = \'123456000000012345\''
);
// DELETE via ZCQL
await zcql.executeZCQLQuery(
'DELETE FROM Shipments WHERE ROWID = \'123456000000012345\''
);
// --- Execute an OLAP query ---
// OLAP queries aggregate data across large datasets.
const olapResult = await zcql.executeOLAPQuery(
'SELECT Status, COUNT(ROWID) AS cnt FROM Shipments GROUP BY Status'
);
```
---
## Cache
```js
const cache = catalystApp.cache();
// --- Get a segment instance ---
const segment = cache.segment(segmentId);
// --- Put a key-value pair ---
// Default expiry is 48 hours. Expiry is in milliseconds.
await segment.put('sessionToken', 'abc123xyz');
// With custom expiry (e.g., 1 hour = 3600000 ms)
await segment.put('tempData', 'value', 3600000);
// --- Get a cached value ---
const value = await segment.getValue('sessionToken');
// Get full cache item details (key, value, expiry info)
const item = await segment.get('sessionToken');
// --- Update a cached value ---
await segment.update('sessionToken', 'newValue456');
// --- Delete a cached key ---
await segment.delete('sessionToken');
```
---
## File Store
```js
const filestore = catalystApp.filestore();
const folder = filestore.folder(folderId);
// --- Upload a file (max 100 MB) ---
const fs = require('fs');
const fileStream = fs.createReadStream('/path/to/document.pdf');
const uploadedFile = await folder.uploadFile({
code: fileStream,
name: 'document.pdf'
});
// uploadedFile.id contains the file ID
// --- Download a file ---
const downloadStream = await folder.downloadFile(fileId);
// Pipe to response or write to disk:
downloadStream.pipe(res);
// --- Delete a file ---
await folder.deleteFile(fileId);
// --- Get file details ---
const fileDetails = await folder.getFileDetails(fileId);
```
---
## Authentication / User Management
```js
// --- userManagement() is the primary accessor in newer SDK versions ---
const userManagement = catalystApp.userManagement();
// --- Get current user (user whose scope is active) ---
const currentUser = await userManagement.getCurrentUser();
// --- Register a new user ---
const newUser = await userManagement.registerUser({
first_name: 'John',
last_name: 'Doe',
email_id: 'john@example.com',
role_id: '123456000000007003' // role ID from your project
});
// --- Get user details by user ID ---
const userDetails = await userManagement.getUserDetails(userId);
// --- Delete a user ---
await userManagement.deleteUser(userId);
// --- authentication() accessor for org-level operations ---
const auth = catalystApp.authentication();
// Get all org IDs associated with the project
const orgIds = await auth.getAllOrgIds();
// Add a user to an org
await auth.addUserToOrg(orgId, {
email_id: 'user@example.com',
role_id: roleId
});
// Get all users in an org
const orgUsers = await auth.getAllUsersInOrg(orgId);
// Enable a user
await auth.enableUser(userId);
// Disable a user
await auth.disableUser(userId);
// Reset a user's password
await auth.resetPassword(userId);
// Generate a server-side token
const token = await auth.generateServerToken();
```
---
## Email
```js
const mail = catalystApp.mail();
// --- Send an email ---
await mail.sendMail({
from_email: 'noreply@yourdomain.com',
to_email: ['recipient@example.com'],
cc: ['cc@example.com'], // optional
bcc: ['bcc@example.com'], // optional
reply_to: ['replyto@example.com'],// optional
subject: 'Order Confirmation',
content: '<h1>Thank you for your order!</h1><p>Your order #1234 is confirmed.</p>',
attachments: [ // optional
{
name: 'invoice.pdf',
content: fs.createReadStream('/path/to/invoice.pdf')
}
]
});
```
---
## Search
```js
const search = catalystApp.search();
// --- Execute a search query ---
// Searches indexed columns across specified tables.
const results = await search.executeSearchQuery({
search: 'shipping delayed',
search_table_columns: {
Shipments: ['TrackingNotes', 'Description'],
Orders: ['CustomerName', 'OrderNotes']
}
});
```
---
## Connections
```js
const connection = catalystApp.connection();
// --- Get connection credentials ---
// Retrieves OAuth tokens for a configured Catalyst Connection.
const credentials = await connection.getConnectorCredentials(connectorName);
// credentials.access_token is the OAuth access token
```
---
## Circuits
```js
const circuit = catalystApp.circuit();
// --- Execute a circuit ---
const result = await circuit.execute(circuitId, {
key1: 'value1',
key2: 'value2'
});
// result contains the circuit execution output
```
---
## NoSQL
```js
const nosql = catalystApp.nosql();
const { NoSQLItem } = require('zcatalyst-sdk-node/lib/no-sql');
// --- Get a table reference ---
const table = nosql.table('SessionStore');
// --- Insert items ---
const item = new NoSQLItem();
item.put('userId', 'string', 'user_001');
item.put('loginTime', 'number', Date.now());
item.put('active', 'boolean', true);
await table.insertItems([item]);
// --- Fetch items by partition key ---
const fetched = await table.fetchItems({
partitionKey: { name: 'userId', value: 'user_001' }
});
// --- Query table (using partition key and sort key conditions) ---
const queryResult = await table.queryTable({
partitionKey: { name: 'userId', value: 'user_001' },
sortKey: {
name: 'loginTime',
operator: 'GREATERTHAN',
value: 1700000000000
},
consistent_read: false,
limit: 50,
ascending: true
});
// Supported operators: EQUALS, BETWEEN, GREATERTHAN, LESSERTHAN,
// GREATERTHANOREQUALTO, LESSERTHANOREQUALTO
// --- Query a secondary index ---
const indexResult = await table.queryIndex('LoginTimeIndex', {
partitionKey: { name: 'active', value: true },
sortKey: {
name: 'loginTime',
operator: 'BETWEEN',
value: [1700000000000, 1710000000000]
},
limit: 100,
ascending: false
});
// --- Update items ---
const updateItem = new NoSQLItem();
updateItem.put('userId', 'string', 'user_001');
updateItem.put('loginTime', 'number', 1700000000001);
updateItem.put('active', 'boolean', false);
await table.updateItems([updateItem]);
// --- Delete items ---
await table.deleteItems([
{ partitionKey: 'user_001', sortKey: 1700000000001 }
]);
```
---
## Stratus Object Storage
### Bucket Operations
> ⚠️ **Stratus bucket names are globally unique** across ALL Catalyst projects and orgs. Generic names like `my-files` will likely already be taken. Use a project-specific suffix: `{app-name}-{project-id-prefix}` (e.g., `docvault-files-70699`). A `DUPLICATE_ENTRY` error on creation does NOT mean the bucket exists in your project — it may belong to another project entirely and will be inaccessible to you.
```js
const stratus = catalystApp.stratus();
// --- Get a bucket instance ---
const bucket = stratus.bucket('myapp-files-70699'); // Use project-specific name
// --- List all buckets ---
const buckets = await stratus.listBuckets();
// --- Get bucket details ---
const details = await bucket.getDetails();
// --- Get bucket CORS configuration ---
const cors = await bucket.getCors();
```
### Listing Objects
```js
// --- List paged objects ---
const pagedResult = await bucket.listPagedObjects({
prefix: 'uploads/', // optional: filter by prefix
maxKeys: 100, // optional: max objects per page
continuationToken: token // optional: for pagination
});
// --- List iterable objects (async iterator) ---
for await (const obj of bucket.listIterableObjects({ prefix: 'uploads/' })) {
console.log(obj.key, obj.size);
}
```
### Downloading Objects
```js
// --- Check object availability (HEAD) ---
const head = await bucket.headObject('uploads/report.pdf');
// head includes content_length, content_type, last_modified, etc.
// With options
const headVersioned = await bucket.headObject('uploads/report.pdf', {
versionId: 'v123',
throwErr: false // returns null instead of throwing if not found
});
// --- Download an object (GET) ---
const stream = await bucket.getObject('uploads/report.pdf');
stream.pipe(fs.createWriteStream('/tmp/report.pdf'));
// With range header (partial download)
const partialStream = await bucket.getObject('uploads/report.pdf', {
range: 'bytes=0-1023'
});
// --- TransferManager: range-based download ---
const transferManager = bucket.transferManager();
const iterableStream = await transferManager.getIterableObject('uploads/large-file.zip', {
partSize: 10 * 1024 * 1024 // 10 MB per part
});
const writeStream = fs.createWriteStream('/tmp/large-file.zip');
for await (const chunk of iterableStream) {
writeStream.write(chunk);
}
writeStream.end();
```
### Pre-Signed URLs
```js
// --- Generate a pre-signed URL for GET (download) ---
const getUrl = await bucket.generatePreSignedUrl('uploads/report.pdf', {
expiresIn: 3600, // seconds until expiry
activationDate: new Date(), // optional: when the URL becomes active
versionId: 'v123' // optional: specific version
});
// --- Generate a pre-signed URL for PUT (upload) ---
const putUrl = await bucket.generatePreSignedUrl('uploads/new-file.pdf', {
expiresIn: 3600,
method: 'PUT'
});
```
### Uploading Objects
```js
// --- putObject with a stream ---
const uploadStream = fs.createReadStream('/path/to/file.pdf');
await bucket.putObject('uploads/file.pdf', uploadStream);
// --- putObject with a string ---
await bucket.putObject('configs/settings.json', JSON.stringify({ theme: 'dark' }));
// --- putObject with options ---
await bucket.putObject('uploads/file.pdf', uploadStream, {
overwrite: true, // overwrite if exists (default behavior without versioning)
ttl: 86400, // time-to-live in seconds (auto-delete after 24h)
metaData: { // custom metadata
uploadedBy: 'automation',
category: 'reports'
},
extractUpload: true // extract ZIP contents and upload each file separately
});
// --- Multipart upload (recommended for files >= 100 MB) ---
const multipart = bucket.multipart();
// Step 1: Initiate
const upload = await multipart.initiateMultipartUpload('uploads/huge-video.mp4');
const uploadId = upload.uploadId;
// Step 2: Upload parts (1 to 1000 parts allowed, min 5 MB per part except last)
const part1 = await multipart.uploadPart('uploads/huge-video.mp4', uploadId, {
partNumber: 1,
body: fs.createReadStream('/path/to/part1')
});
const part2 = await multipart.uploadPart('uploads/huge-video.mp4', uploadId, {
partNumber: 2,
body: fs.createReadStream('/path/to/part2')
});
// Step 3: Complete multipart upload
await multipart.completeMultipartUpload('uploads/huge-video.mp4', uploadId, [
{ partNumber: 1, eTag: part1.eTag },
{ partNumber: 2, eTag: part2.eTag }
]);
// --- TransferManager: automatic multipart upload ---
const tm = bucket.transferManager();
await tm.putObjectAsParts('uploads/huge-video.mp4', fs.createReadStream('/path/to/video.mp4'), {
partSize: 10 * 1024 * 1024 // 10 MB per part
});
```
### Object Management
```js
// --- Unzip an object (extract in-place) ---
await bucket.unzipObject('uploads/archive.zip', {
targetPrefix: 'extracted/' // optional: extract to a specific prefix
});
// --- Rename / move an object ---
await bucket.renameObject('uploads/old-name.pdf', 'uploads/new-name.pdf');
// --- Delete a single object ---
await bucket.deleteObject('uploads/file.pdf');
// --- Delete multiple objects ---
await bucket.deleteObjects([
{ key: 'uploads/file1.pdf' },
{ key: 'uploads/file2.pdf', versionId: 'v456' }
]);
// --- Truncate a bucket (delete all objects) ---
await bucket.truncate();
// --- Delete a path (all objects under a prefix) ---
await bucket.deletePath('uploads/temp/');
```
### Object Versions
```js
// --- List iterable versions (async iterator) ---
for await (const version of bucket.listIterableVersions({ prefix: 'uploads/report.pdf' })) {
console.log(version.versionId, version.lastModified, version.isLatest);
}
```
---
## Bulk Data Store Operations
```js
const datastore = catalystApp.datastore();
const table = datastore.table('Shipments');
// --- Bulk Read ---
// Creates a bulk read job that generates a CSV file with the results.
const bulkReadJob = table.bulkJob('read');
const readResult = await bulkReadJob.createJob({
table_identifier: 'Shipments',
criteria: { // optional: filter rows
group_operator: 'AND',
group: [
{
column: 'Status',
comparator: 'equal',
value: 'Active'
}
]
}
});
// Poll readResult.job_id for status; download CSV when complete.
const jobStatus = await bulkReadJob.getJobStatus(readResult.job_id);
// --- Bulk Write ---
// Upload CSV data first to Stratus, then reference it in the write job.
const bulkWriteJob = table.bulkJob('write');
const writeResult = await bulkWriteJob.createJob({
table_identifier: 'Shipments',
file_details: {
bucketName: 'my-bucket',
objectKey: 'imports/shipments.csv',
versionID: 'v1' // optional: if versioning is enabled
}
});
// --- Bulk Delete (max 200 rows per call) ---
const rowIds = [
'123456000000012345',
'123456000000012346',
'123456000000012347'
];
await table.deleteRows(rowIds);
```
---
## Push Notifications
```js
const pushNotification = catalystApp.pushNotification();
// --- Send web push notification (up to 50 users per call) ---
const webNotif = pushNotification.web();
await webNotif.sendNotification({
message: 'Your order has been shipped!',
recipients: [userId1, userId2] // user IDs or email addresses
});
// --- Send mobile push notification ---
const mobileNotif = pushNotification.mobile(appId);
// Android notification
await mobileNotif.sendAndroidNotification({
message: 'New update available',
recipients: [userId],
additional_data: { // optional: custom payload
orderId: '12345'
}
});
// iOS notification
await mobileNotif.sendIOSNotification({
message: 'New update available',
recipients: [userId],
badge_count: 1, // optional
additional_data: {
orderId: '12345'
}
});
```
---
## Zia Services
### OCR (Optical Character Recognition)
```js
const zia = catalystApp.zia();
// --- Extract text from an image or document ---
const ocrResult = await zia.extractOpticalCharacters({
image_url: 'https://example.com/receipt.jpg'
// OR pass a file stream:
// image: fs.createReadStream('/path/to/receipt.jpg')
});
```
### AutoML
```js
// --- Execute a prediction using a trained AutoML model ---
// Supports Binary Classification, Multi-Class Classification, and Regression.
const prediction = await zia.executeAutoML(modelId, {
feature1: 'value1',
feature2: 42,
feature3: true
});
```
### Sentiment Analysis
```js
const sentiment = await zia.getSentimentAnalysis([
'The product quality is amazing!',
'Delivery was too slow and the packaging was damaged.'
]);
// Each result has: sentiment (positive/negative/neutral), confidence
```
### Named Entity Recognition (NER)
```js
const entities = await zia.getNamedEntityRecognition([
'John Doe from Acme Corp signed the contract on January 15, 2025.'
]);
// Extracts entities like person names, organizations, dates, etc.
```
### Keyword Extraction
```js
const keywords = await zia.getKeywordExtraction([
'Machine learning models improve predictive accuracy in healthcare diagnostics.'
]);
// Returns keywords and keyphrases
```
### All Text Analytics (combined)
```js
const allAnalytics = await zia.getAllTextAnalytics([
'The quarterly revenue exceeded expectations, driven by strong sales in APAC.'
]);
// Returns sentiment, NER, and keyword extraction in one call
```
### Image Moderation
```js
const moderation = await zia.moderateImage({
image_url: 'https://example.com/photo.jpg'
// OR: image: fs.createReadStream('/path/to/photo.jpg')
});
// Returns confidence scores for nudity, violence, etc.
```
### Face Detection
```js
const faces = await zia.detectFaces({
image_url: 'https://example.com/group-photo.jpg'
});
// Returns detected faces with age, gender, emotion, bounding box
```
### Object Recognition
```js
const objects = await zia.recognizeObjects({
image_url: 'https://example.com/scene.jpg'
});
// Returns identified objects with confidence scores
```
### Barcode Scanning
```js
const barcodes = await zia.scanBarcode({
image_url: 'https://example.com/barcode.jpg'
});
// Supports Codabar, EAN-13, ITF, UPC-A, QR Code, and more
```
---
## SmartBrowz
```js
const smartBrowz = catalystApp.SmartBrowz();
// --- Browser Grid ---
const grid = smartBrowz.browserGrid();
// Get all browser grids
const allGrids = await grid.getAllGrids();
// Get a specific grid by ID
const specificGrid = await grid.getGrid(gridId);
// Get a specific node in a grid
const node = await grid.getNode(gridId, nodeId);
// Stop a browser grid
await grid.stopGrid(gridId);
// --- Generate PDF ---
const pdfBuffer = await smartBrowz.generatePDF({
url: 'https://example.com/report', // Generate from URL
// OR: html: '<h1>Hello</h1>', // Generate from HTML
// OR: template_id: 'tpl_123', // Generate from template
output: {
format: 'A4',
landscape: false,
print_background: true
},
password: 'secret123' // optional: password-protect PDF
});
// --- Generate Screenshot ---
const screenshotBuffer = await smartBrowz.generateScreenshot({
url: 'https://example.com/dashboard',
output: {
format: 'png', // 'png' or 'webp'
full_page: true,
quality: 90
}
});
// --- Dataverse (web scraping/extraction) ---
const extractedData = await smartBrowz.dataverse({
url: 'https://example.com/products',
extraction_rules: {
title: { selector: 'h1.product-title', type: 'text' },
price: { selector: '.price', type: 'text' }
}
});
```
---
## Job Scheduling
### Jobs
```js
const jobScheduling = catalystApp.jobScheduling();
// --- Submit a job targeting a Function ---
const jobResult = await jobScheduling.submitJob({
job_name: 'process-orders',
jobpool_name: 'OrderPool',
target_type: 'Function',
target_name: 'ProcessOrderFunction',
job_config: { // optional: custom params passed to the target
batchSize: 50,
region: 'US'
}
});
// --- Submit a job targeting a Circuit ---
await jobScheduling.submitJob({
job_name: 'etl-pipeline',
jobpool_name: 'DataPool',
target_type: 'Circuit',
target_name: 'ETLCircuit'
});
// --- Submit a job targeting a Webhook ---
await jobScheduling.submitJob({
job_name: 'notify-webhook',
jobpool_name: 'NotifyPool',
target_type: 'Webhook',
target_name: 'SlackWebhook'
});
// --- Submit a job targeting an AppSail service ---
await jobScheduling.submitJob({
job_name: 'cleanup-task',
jobpool_name: 'MaintenancePool',
target_type: 'AppSail',
target_name: 'CleanupService'
});
// --- Delete a job ---
await jobScheduling.deleteJob(jobId);
```
### Crons
```js
const cron = jobScheduling.cron();
// --- Create a One-Time cron ---
const oneTimeCron = await cron.createCron({
cron_name: 'one-time-report',
description: 'Generate end-of-month report',
jobpool_name: 'ReportPool',
cron_type: 'OneTime',
schedule: {
time: '2025-12-31T23:59:00Z'
},
job_config: { reportType: 'monthly' }
});
// --- Create a Periodic/Every cron (recurring, < 24h interval) ---
const periodicCron = await cron.createCron({
cron_name: 'health-check',
description: 'Check system health every 15 minutes',
jobpool_name: 'MonitorPool',
cron_type: 'Periodic',
schedule: {
every: 15,
unit: 'minutes' // 'minutes' or 'hours'
}
});
// --- Create a Daily/Calendar cron ---
const dailyCron = await cron.createCron({
cron_name: 'daily-digest',
description: 'Send daily email digest at 9 AM',
jobpool_name: 'EmailPool',
cron_type: 'Calendar',
schedule: {
time: '09:00',
timezone: 'Asia/Kolkata',
days_of_week: ['MON', 'TUE', 'WED', 'THU', 'FRI']
}
});
// --- Create a Monthly cron ---
const monthlyCron = await cron.createCron({
cron_name: 'monthly-invoice',
description: 'Generate invoices on the 1st of each month',
jobpool_name: 'BillingPool',
cron_type: 'Calendar',
schedule: {
time: '00:00',
timezone: 'UTC',
days_of_month: [1]
}
});
// --- Create a Yearly cron ---
const yearlyCron = await cron.createCron({
cron_name: 'annual-cleanup',
description: 'Yearly data archival',
jobpool_name: 'ArchivePool',
cron_type: 'Calendar',
schedule: {
time: '02:00',
timezone: 'UTC',
months: ['JAN'],
days_of_month: [1]
}
});
// --- Create a cron using cron expressions ---
const exprCron = await cron.createCron({
cron_name: 'custom-schedule',
jobpool_name: 'CustomPool',
cron_type: 'CronExpression',
schedule: {
cron_expression: '0 */6 * * *' // every 6 hours
}
});
// --- Cron management ---
const cronDetails = await cron.getCron(cronId);
await cron.updateCron(cronId, { description: 'Updated description' });
await cron.pauseCron(cronId);
await cron.resumeCron(cronId);
await cron.runCron(cronId); // manually trigger a cron immediately
await cron.deleteCron(cronId);
```
---
## Pipelines
```js
const pipeline = catalystApp.pipeline();
// --- Get pipeline details ---
const details = await pipeline.getPipelineDetails(pipelineId);
// --- Execute a pipeline ---
const result = await pipeline.executePipeline(pipelineId, {
inputParam1: 'value1',
inputParam2: 'value2'
});
```
---
## Connectors
```js
const connector = catalystApp.connector();
// --- Get a connector token ---
// Retrieves OAuth credentials for a configured Catalyst Connector.
const tokenDetails = await connector.getConnectorToken(connectorName);
// tokenDetails.access_token contains the usable OAuth access token
```
SHA-256: 4f0a0449498c3d39141fc1a394c59b3b2f9401e98383e901dc0a74cc425ebaa6