evernote-upgrade-migration
SKILL.md
Evernote Upgrade & Migration
Overview
Guide for upgrading Evernote SDK versions, handling breaking changes, and migrating legacy integrations to current API patterns.
Prerequisites
- Existing Evernote integration
- Test environment for validation
- Understanding of current implementation
SDK Version History
| Version | Node.js | Key Changes |
|---|---|---|
| 2.0.x | 10+ | Promise-based API, ES6 modules |
| 1.25.x | 8+ | Legacy callback pattern |
| 1.x | 6+ | Original SDK |
Instructions
Step 1: Check Current Version
# Check installed version
npm list evernote
# Check available versions
npm view evernote versions
# Check for outdated packages
npm outdated evernote
Step 2: Review Breaking Changes
// SDK 1.x -> 2.x Breaking Changes
// 1. Client initialization changed
// OLD (1.x):
var Evernote = require('evernote').Evernote;
var client = new Evernote.Client({
consumerKey: 'key',
consumerSecret: 'secret',
sandbox: true
});
// NEW (2.x):
const Evernote = require('evernote');
const client = new Evernote.Client({
consumerKey: 'key',
consumerSecret: 'secret',
sandbox: true
});
// 2. API calls return Promises (not callbacks)
// OLD (1.x):
noteStore.listNotebooks(function(err, notebooks) {
if (err) console.error(err);
else console.log(notebooks);
});
// NEW (2.x):
noteStore.listNotebooks()
.then(notebooks => console.log(notebooks))
.catch(err => console.error(err));
// Or with async/await:
const notebooks = await noteStore.listNotebooks();
// 3. Type constructors
// OLD (1.x):
var note = new Evernote.Note();
// NEW (2.x):
const note = new Evernote.Types.Note();
Step 3: Migration Script
// scripts/migrate-to-v2.js
const fs = require('fs');
const path = require('path');
const glob = require('glob');
const migrations = [
// Client import
{
pattern: /require\(['"]evernote['"]\)\.Evernote/g,
replacement: "require('evernote')"
},
// Type constructors
{
pattern: /new Evernote\.Note\(\)/g,
replacement: 'new Evernote.Types.Note()'
},
{
pattern: /new Evernote\.Notebook\(\)/g,
replacement: 'new Evernote.Types.Notebook()'
},
{
pattern: /new Evernote\.Tag\(\)/g,
replacement: 'new Evernote.Types.Tag()'
},
{
pattern: /new Evernote\.Resource\(\)/g,
replacement: 'new Evernote.Types.Resource()'
},
// NoteFilter
{
pattern: /new Evernote\.NoteFilter\(\)/g,
replacement: 'new Evernote.NoteStore.NoteFilter()'
},
// NotesMetadataResultSpec
{
pattern: /new Evernote\.NotesMetadataResultSpec\(\)/g,
replacement: 'new Evernote.NoteStore.NotesMetadataResultSpec()'
}
];
function migrateFile(filePath) {
let content = fs.readFileSync(filePath, 'utf8');
let modified = false;
for (const { pattern, replacement } of migrations) {
if (pattern.test(content)) {
content = content.replace(pattern, replacement);
modified = true;
}
}
if (modified) {
// Create backup
fs.writeFileSync(`${filePath}.bak`, fs.readFileSync(filePath));
// Write migrated file
fs.writeFileSync(filePath, content);
console.log(`Migrated: ${filePath}`);
return true;
}
return false;
}
// Run migration
const files = glob.sync('src/**/*.js');
let migratedCount = 0;
for (const file of files) {
if (migrateFile(file)) {
migratedCount++;
}
}
console.log(`\nMigration complete. ${migratedCount} files modified.`);
console.log('Backup files created with .bak extension');
Step 4: Convert Callbacks to Promises
// utils/promisify-legacy.js
/**
* Wrapper for legacy callback-based code
*/
function promisifyNoteStore(noteStore) {
const promisified = {};
// List of methods that need promisification
const methods = [
'listNotebooks',
'getNotebook',
'createNotebook',
'updateNotebook',
'listTags',
'getTag',
'createTag',
'getNote',
'createNote',
'updateNote',
'deleteNote',
'findNotesMetadata',
'getNoteContent',
'getResource'
];
for (const method of methods) {
promisified[method] = (...args) => {
return new Promise((resolve, reject) => {
noteStore[method](...args, (err, result) => {
if (err) reject(err);
else resolve(result);
});
});
};
}
return promisified;
}
module.exports = { promisifyNoteStore };
Step 5: Upgrade Dependencies
# Update to latest version
npm install evernote@latest
# If using TypeScript, update types
npm install @types/evernote@latest --save-dev
# Update related dependencies
npm update
Step 6: Test Suite Updates
// tests/migration-tests.js
const assert = require('assert');
const Evernote = require('evernote');
describe('SDK v2 Migration Tests', () => {
let client;
let noteStore;
before(() => {
client = new Evernote.Client({
token: process.env.EVERNOTE_ACCESS_TOKEN,
sandbox: true
});
noteStore = client.getNoteStore();
});
describe('Type Constructors', () => {
it('should create Note using Types namespace', () => {
const note = new Evernote.Types.Note();
assert(note);
note.title = 'Test';
assert.equal(note.title, 'Test');
});
it('should create NoteFilter using NoteStore namespace', () => {
const filter = new Evernote.NoteStore.NoteFilter({
words: 'test'
});
assert(filter);
assert.equal(filter.words, 'test');
});
});
describe('Promise-based API', () => {
it('should return Promise from listNotebooks', async () => {
const result = noteStore.listNotebooks();
assert(result instanceof Promise);
});
it('should resolve notebooks array', async () => {
const notebooks = await noteStore.listNotebooks();
assert(Array.isArray(notebooks));
});
});
describe('Error Handling', () => {
it('should reject with EDAMUserException for invalid data', async () => {
const note = new Evernote.Types.Note();
// Missing required fields
try {
await noteStore.createNote(note);
assert.fail('Should have thrown');
} catch (error) {
assert(error.errorCode !== undefined);
}
});
});
});
Step 7: Compatibility Layer
// utils/compatibility.js
/**
* Compatibility layer for gradual migration
* Supports both callback and Promise patterns
*/
class CompatibleNoteStore {
constructor(noteStore) {
this.store = noteStore;
}
listNotebooks(callback) {
const promise = this.store.listNotebooks();
if (callback) {
// Legacy callback support
promise
.then(result => callback(null, result))
.catch(error => callback(error, null));
return;
}
return promise;
}
getNote(guid, withContent, withResources, withRecognition, withAlternate, callback) {
const promise = this.store.getNote(
guid,
withContent,
withResources,
withRecognition,
withAlternate
);
if (callback) {
promise
.then(result => callback(null, result))
.catch(error => callback(error, null));
return;
}
return promise;
}
createNote(note, callback) {
const promise = this.store.createNote(note);
if (callback) {
promise
.then(result => callback(null, result))
.catch(error => callback(error, null));
return;
}
return promise;
}
// Add more methods as needed
}
module.exports = CompatibleNoteStore;
Step 8: Deprecation Warnings
// utils/deprecation-warnings.js
const deprecations = new Set();
function warnOnce(message) {
if (!deprecations.has(message)) {
deprecations.add(message);
console.warn(`[DEPRECATION WARNING] ${message}`);
}
}
// Proxy to add deprecation warnings
function wrapWithDeprecationWarnings(noteStore) {
return new Proxy(noteStore, {
get(target, prop) {
// Warn about deprecated patterns
if (prop === 'getNote') {
return (...args) => {
if (args.length === 6 && typeof args[5] === 'function') {
warnOnce(
'Callback pattern is deprecated. ' +
'Use Promise: noteStore.getNote(...).then(note => ...)'
);
}
return target[prop](...args);
};
}
return target[prop];
}
});
}
module.exports = { wrapWithDeprecationWarnings };
Migration Checklist
## SDK v2 Migration Checklist
### Pre-Migration
- [ ] Backup current codebase
- [ ] Document current SDK version
- [ ] Review breaking changes
- [ ] Set up test environment
### Code Changes
- [ ] Update import statements
- [ ] Update type constructors (Types namespace)
- [ ] Update filter constructors (NoteStore namespace)
- [ ] Convert callbacks to Promises/async-await
- [ ] Update error handling for Promise rejections
### Testing
- [ ] Run migration script on test branch
- [ ] Execute full test suite
- [ ] Test OAuth flow end-to-end
- [ ] Test note CRUD operations
- [ ] Test search functionality
- [ ] Verify error handling
### Deployment
- [ ] Deploy to staging
- [ ] Run integration tests
- [ ] Monitor for errors
- [ ] Deploy to production
- [ ] Monitor metrics
### Cleanup
- [ ] Remove compatibility layers (after validation period)
- [ ] Remove backup files
- [ ] Update documentation
- [ ] Archive migration scripts
Output
- SDK version comparison
- Automated migration script
- Callback to Promise conversion
- Compatibility layer for gradual migration
- Migration test suite
- Deprecation warning system
Error Handling
| Issue | Cause | Solution |
|---|---|---|
Evernote.Note is not a constructor |
Old import style | Use Evernote.Types.Note |
callback is not a function |
Mixed patterns | Use Promise or callback, not both |
Cannot read property 'then' |
Using old callback-only method | Update to Promise-based method |
Resources
Next Steps
For CI/CD integration, see evernote-ci-integration.
Weekly Installs
13
Repository
jeremylongshore…s-skillsGitHub Stars
1.6K
First Seen
Feb 18, 2026
Security Audits
Installed on
codex13
mcpjam12
claude-code12
junie12
windsurf12
zencoder12