Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Fixed
- Broken CJS build outputs resulted in a "TypeError: Nylas is not a constructor" error

## [7.13.0] - 2025-09-01

### Added
Expand Down
14 changes: 14 additions & 0 deletions cjs-wrapper.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* TypeScript definitions for the CommonJS wrapper
* This provides proper typing for CommonJS imports
*/

// Re-export all types from the main module
export * from './lib/types/models/index.js';

// Import the main Nylas class type
import Nylas from './lib/types/nylas.js';

// Export as both default and named for maximum compatibility
declare const nylasExport: typeof Nylas;
export = nylasExport;
13 changes: 13 additions & 0 deletions cjs-wrapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* CommonJS wrapper for the Nylas SDK
* This file provides CommonJS compatibility by re-exporting the default export
* as the main module export while preserving named exports
*/

const nylasModule = require('./lib/cjs/nylas.js');

// Export the default export as the main module export for CJS compatibility
module.exports = nylasModule.default;

// Preserve all named exports
Object.assign(module.exports, nylasModule);
78 changes: 78 additions & 0 deletions examples/cjs-only/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# CommonJS-Only Nylas SDK Example

This example demonstrates how to use the Nylas Node.js SDK in a pure CommonJS (CJS) environment without ES module syntax.

## Purpose

- Shows CommonJS `require()` syntax with the Nylas SDK
- Demonstrates environment variable handling in CommonJS
- Provides a simple messages listing example
- Serves as a reference for projects that must use CommonJS

## Key Differences from ESM

This example showcases the CommonJS equivalent of the ESM-only example:

| ESM Syntax | CommonJS Syntax |
|------------|-----------------|
| `import Nylas from 'nylas'` | `const Nylas = require('nylas')` |
| `import dotenv from 'dotenv'` | `const dotenv = require('dotenv')` |
| `import path from 'node:path'` | `const path = require('path')` |
| `import.meta.dirname` | `__dirname` |
| `export { logger }` | `module.exports = { logger }` |

## Setup

1. **Install dependencies:**
```bash
cd examples/cjs-only
npm install
```

2. **Set up environment variables:**
- Copy `examples/.env.example` to `examples/.env`
- Fill in your `NYLAS_API_KEY` and `NYLAS_GRANT_ID`

3. **Run the example:**
```bash
npm start
# or
node index.js
```

## Requirements

- Node.js (any version - CommonJS is supported in all Node.js versions)
- Valid Nylas API credentials
- A grant with message access permissions

## What This Example Does

1. Loads environment variables using `dotenv`
2. Validates required API credentials
3. Initializes the Nylas client
4. Lists messages from the specified grant
5. Logs the results with proper error handling

## File Structure

```
cjs-only/
├── index.js # Main example file (CommonJS)
├── package.json # Package configuration (no "type": "module")
├── utils/
│ └── logger.js # Logger utility (CommonJS exports)
└── README.md # This file
```

## Troubleshooting

- **"NYLAS_API_KEY environment variable is not set"**: Make sure you've created the `.env` file in the `examples/` directory with your API key
- **"NYLAS_GRANT_ID environment variable is not set"**: Add your grant ID to the `.env` file
- **Module not found errors**: Run `npm install` to install dependencies
- **Permission errors**: Ensure your API key and grant have the necessary permissions to list messages

## Related Examples

- `../esm-only/` - ESM version of this same example
- `../messages/` - More comprehensive message handling examples
82 changes: 82 additions & 0 deletions examples/cjs-only/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* CommonJS-Only Nylas SDK Example
*
* This example demonstrates how to use the Nylas Node.js SDK in a pure CommonJS
* (CJS) environment without ES module syntax.
*
* Purpose:
* - Shows CommonJS require() syntax with the Nylas SDK
* - Demonstrates environment variable handling in CommonJS
* - Provides a simple messages listing example
*
* Usage:
* 1. Copy the parent examples/.env.example to examples/.env
* 2. Fill in your NYLAS_API_KEY and NYLAS_GRANT_ID in the .env file
* 3. Run: node index.js (or npm start)
*
* Requirements:
* - Node.js with CommonJS support (any Node.js version)
* - Valid Nylas API credentials
* - A grant with message access permissions
*/

const dotenv = require('dotenv');
const path = require('path');
const Nylas = require('nylas');
const { logger, maskSecret } = require('./utils/logger.js');

// Load from parent directory since this example lives in a subdirectory
dotenv.config({ path: path.resolve(__dirname, '../.env') });

// Fail fast if credentials are missing to provide clear error messages
const apiKey = process.env.NYLAS_API_KEY || '';
if (!apiKey) {
throw new Error('NYLAS_API_KEY environment variable is not set');
}

const grantId = process.env.NYLAS_GRANT_ID || '';
if (!grantId) {
throw new Error('NYLAS_GRANT_ID environment variable is not set');
}

// Initialize the Nylas client
const nylas = new Nylas({
apiKey,
apiUri: process.env.NYLAS_API_URI || 'https://api.us.nylas.com',
});

/**
* Main function to demonstrate basic Nylas SDK usage in CommonJS environment
*/
async function main() {
try {
logger.info('Listing messages...');

// Log runtime config for debugging without exposing sensitive data
logger.debug('Runtime config', {
apiKey: maskSecret(apiKey),
grantId,
apiUri: process.env.NYLAS_API_URI || 'https://api.us.nylas.com',
});

// Use basic list operation to verify SDK functionality and connectivity
const messages = await nylas.messages.list({
identifier: grantId,
});

logger.success('Messages listed successfully');

// Extract only essential fields to avoid logging sensitive message content
logger.info(
'Message subjects and ids',
messages.data.map((m) => ({ id: m.id, subject: m.subject }))
);
} catch (error) {
logger.error('Failed to list messages');
logger.debug('Error details', error);
// Exit with error code to indicate failure for automation/CI purposes
process.exit(1);
}
}

main();
70 changes: 70 additions & 0 deletions examples/cjs-only/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions examples/cjs-only/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "cjs-only",
"version": "1.0.0",
"description": "A CommonJS-only example of the Nylas NodeJS SDK usage",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node index.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"nylas": "file:../../",
"dotenv": "^17.2.2"
}
}
46 changes: 46 additions & 0 deletions examples/cjs-only/utils/logger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Pretty logger for CommonJS
const COLORS = {
reset: '\x1b[0m',
dim: '\x1b[2m',
gray: '\x1b[90m',
bold: '\x1b[1m',
info: '\x1b[36m',
success: '\x1b[32m',
warn: '\x1b[33m',
error: '\x1b[31m',
debug: '\x1b[35m',
};

function ts() {
return new Date().toISOString();
}

function maskSecret(value, visibleStart = 8, visibleEnd = 0) {
if (!value) return '';
const start = value.slice(0, visibleStart);
const end = visibleEnd ? value.slice(-visibleEnd) : '';
const hidden = Math.max(0, value.length - start.length - end.length);
return `${start}${'•'.repeat(hidden)}${end}`;
}

function print(level, symbol, message, meta) {
const color = COLORS[level] || COLORS.info;
const time = `${COLORS.dim}${ts()}${COLORS.reset}`;
const label = `${color}${symbol} ${level.toUpperCase()}${COLORS.reset}`;
const line =
typeof message === 'string' ? message : JSON.stringify(message, null, 2);
console.log(`${time} ${label} ${line}`);
if (meta !== undefined) {
console.dir(meta, { depth: null, colors: true, maxArrayLength: 100 });
}
}

const logger = {
info: (msg, meta) => print('info', 'ℹ', msg, meta),
success: (msg, meta) => print('success', '✔', msg, meta),
warn: (msg, meta) => print('warn', '⚠', msg, meta),
error: (msg, meta) => print('error', '✖', msg, meta),
debug: (msg, meta) => print('debug', '🐛', msg, meta),
};

module.exports = { logger, maskSecret };
2 changes: 1 addition & 1 deletion examples/edge-environment/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 8 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,13 @@
"url": "https://github.com/nylas/nylas-nodejs.git"
},
"exports": {
"import": "./lib/esm/nylas.js",
"require": "./lib/cjs/nylas.js",
"types": "./lib/types/nylas.d.ts"
"import": {
"types": "./lib/types/nylas.d.ts",
"default": "./lib/esm/nylas.js"
},
"require": {
"types": "./cjs-wrapper.d.ts",
"default": "./cjs-wrapper.js"
}
}
}
4 changes: 3 additions & 1 deletion src/nylas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { Notetakers } from './resources/notetakers.js';
* A Nylas instance holds a configured http client pointing to a base URL and is intended to be reused and shared
* across threads and time.
*/
export default class Nylas {
class Nylas {
/**
* Access the Applications API
*/
Expand Down Expand Up @@ -122,3 +122,5 @@ export default class Nylas {
return this;
}
}

export default Nylas;
3 changes: 3 additions & 0 deletions tsconfig.cjs.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@
"compilerOptions": {
"module": "commonjs",
"outDir": "lib/cjs",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"moduleResolution": "node"
},
}
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"target": "es2021",
"declaration": true,
"declarationDir": "lib/types",
"esModuleInterop": false,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"moduleResolution": "node",
Expand Down