@context-action/notion-markdown
v0.2.1
Published
Complete TypeScript library for uploading/downloading markdown files to/from Notion pages and databases with bundled API
Downloads
8
Maintainers
Readme
Notion Markdown Library
A powerful TypeScript library for uploading markdown files to Notion pages and databases with frontmatter support. Built with clean architecture for reliability, extensibility, and type safety.
✨ Features
- 📝 Markdown to Notion: Upload markdown files to Notion pages and databases
- 🏷️ Frontmatter Support: Automatic YAML frontmatter property mapping for databases
- 🔒 Type-Safe: Full TypeScript support with comprehensive type definitions
- 🛡️ Robust Validation: Comprehensive validation and error handling
- 🏗️ Clean Architecture: Modular design with dependency injection
- 🧪 Well Tested: Extensive test coverage (unit, integration, contract)
- 📦 Multiple Formats: ESM, CommonJS, and CLI support
- 🚀 Easy to Use: Simple API with powerful advanced features
📦 Installation
As a Library
npm install @context-action/notion-markdownAs a CLI Tool
npm install -g @context-action/notion-markdown🚀 Quick Start
Environment Setup
export NOTION_API_KEY="secret_your_notion_api_key_here"Or create a .env file:
NOTION_API_KEY=secret_your_notion_api_key_here📦 Bundled API Usage
The library provides a complete bundled API with upload/download functionality and centralized environment configuration. See Bundled API Documentation for complete reference.
CommonJS
const {
syncMarkdownToNotion,
uploadToDatabase,
NotionClientService,
EnvironmentAdapter
} = require('@context-action/notion-markdown');ES Modules
import {
syncMarkdownToNotion,
uploadToDatabase,
NotionClientService,
EnvironmentAdapter
} from '@context-action/notion-markdown';Quick Start Example
// 1. Setup environment (recommended approach)
const { EnvironmentAdapter } = require('@context-action/notion-markdown');
const envAdapter = EnvironmentAdapter.createForTesting({
NOTION_API_KEY: process.env.NOTION_API_KEY,
NOTION_TIMEOUT: '10000'
});
// 2. Upload markdown to a page
const { syncMarkdownToNotion } = require('@context-action/notion-markdown');
const uploadResult = await syncMarkdownToNotion({
markdownPath: './document.md',
notionPageId: 'your-page-id',
overwrite: true
});
if (uploadResult.success) {
console.log(`✅ Created ${uploadResult.blocksCreated} blocks`);
}
// 3. Download page content
const { NotionClientService } = require('@context-action/notion-markdown');
const client = NotionClientService.fromEnvironment(envAdapter);
const pageData = await client.getPage('your-page-id');
const pageBlocks = await client.getPageBlocks('your-page-id');
if (pageData.success && pageBlocks.success) {
console.log(`📄 Downloaded: ${pageData.data.title}`);
console.log(`📋 Blocks: ${pageBlocks.data.length} blocks`);
}Environment Configuration
The library provides centralized environment configuration with type-safe access:
import { defaultEnvironmentAdapter, EnvironmentAdapter } from '@context-action/notion-markdown';
// Use default adapter (reads from process.env)
const apiKey = defaultEnvironmentAdapter.getRequired('NOTION_API_KEY');
const timeout = defaultEnvironmentAdapter.getNumber('NOTION_TIMEOUT', 30000);
// Create custom adapter for testing
const testAdapter = EnvironmentAdapter.createForTesting({
NOTION_API_KEY: 'test_key',
NOTION_TIMEOUT: '5000'
});
// Get configuration sections
const notionConfig = testAdapter.getNotionConfig();
const syncConfig = testAdapter.getSyncConfig();See Environment Configuration Guide for complete documentation.
CLI Usage
# Upload markdown to a page
notion-markdown sync document.md --page-id your-page-id
# Upload to database with frontmatter
notion-markdown upload-to-database document.md --database-id your-database-id
# Validate markdown
notion-markdown validate document.md
# Inspect database schema
notion-markdown inspect-database --database-id your-database-id🗃️ Database Upload with Frontmatter
Create markdown files with YAML frontmatter for automatic property mapping:
---
title: "Project Update"
status: "In Progress"
priority: "High"
due_date: "2025-12-31"
tags: ["urgent", "project"]
completed: false
score: 95
url: "https://example.com"
email: "[email protected]"
---
# Project Content
Your markdown content here will become the page content...
## Features Completed
- [x] Database integration
- [x] Frontmatter parsing
- [ ] Advanced validationProperty Type Mapping
| Frontmatter Type | Notion Property Types | Example |
|------------------|----------------------|---------|
| string | title, rich_text, url, email, phone_number | "Text value" |
| number | number | 42 |
| boolean | checkbox | true |
| Date/ISO string | date | "2025-12-31" |
| string[] | multi_select | ["tag1", "tag2"] |
| string (predefined) | select | "In Progress" |
📚 API Reference
Core Functions
uploadToDatabase(request)
Upload markdown with frontmatter to a Notion database.
const result = await uploadToDatabase({
filePath: './document.md',
databaseId: 'your-database-id',
options: {
validateProperties: true,
dryRun: false,
propertyMappings: {
'custom_field': 'Database Property Name'
}
}
});syncMarkdownToNotion(options)
Upload markdown content to a Notion page.
const result = await syncMarkdownToNotion({
markdownContent: '# Hello World\n\nThis is a test.',
notionPageId: 'page-id-here',
notionApiKey: 'your-api-key',
overwrite: true,
validateBeforeSync: true
});validateMarkdown(options)
Validate markdown content and Notion connectivity.
const validation = await validateMarkdown({
markdownPath: './document.md',
notionApiKey: process.env.NOTION_API_KEY,
strictMarkdown: true,
notionCompatibility: true
});
if (!validation.isValid) {
console.log('Issues found:');
validation.errors.forEach(error => console.log(`❌ ${error}`));
validation.warnings.forEach(warning => console.log(`⚠️ ${warning}`));
}Advanced Usage
Progress Tracking
import { SyncEngine } from '@context-action/notion-markdown';
const engine = SyncEngine.create(apiKey);
const result = await engine.sync(request, (progress) => {
console.log(`${progress.stage}: ${progress.progress}% - ${progress.message}`);
});Database Schema Inspection
import { getDatabaseSchema } from '@context-action/notion-markdown';
const schema = await getDatabaseSchema(databaseId, apiKey);
if (schema.success) {
console.log(`📊 Database: ${schema.title}`);
schema.properties.forEach(prop => {
console.log(` 📋 ${prop.name}: ${prop.type}`);
});
}🛠️ CLI Commands
Page Operations
# Upload to page
notion-markdown sync <file> --page-id <id> [options]
# Options:
# --overwrite Replace existing content
# --dry-run Test without uploading
# --validate Validate before uploadDatabase Operations
# Upload to database
notion-markdown upload-to-database <file> --database-id <id> [options]
# Inspect database schema
notion-markdown inspect-database --database-id <id>
# Validate frontmatter
notion-markdown validate-database --database-id <id> --yaml <content>
# Generate test data
notion-markdown generate-test-data --database-id <id>Validation & Testing
# Validate markdown
notion-markdown validate <file> [options]
# Test connection
notion-markdown test-connection🏗️ Architecture
Built with clean architecture principles for maintainability and extensibility:
📁 lib/notion-markdown/
├── 🧠 core/ # Domain models and types
│ ├── 📊 models/ # Data models (MarkdownFile, NotionPage, etc.)
│ ├── 🏷️ types/ # Shared TypeScript interfaces
│ └── 🔌 interfaces/ # Adapter contracts
├── ⚙️ services/ # Business logic services
│ ├── 🔄 sync/ # Sync engine and validation
│ ├── 📝 markdown/ # Markdown processing
│ └── 🗃️ database/ # Database operations
├── 🔗 adapters/ # External API adapters
│ └── 📡 notion-official/ # Notion API client
└── 💻 cli/ # Command-line interfaceKey Components
- 🚀 SyncEngine: Core synchronization with progress tracking
- 🗃️ DatabaseService: Database operations and schema management
- 📝 MarkdownParserService: Markdown parsing and validation
- 📡 NotionClientService: Notion API communication
- 🛡️ ValidationEngine: Content and schema validation
- 🏷️ FrontmatterParser: YAML frontmatter processing
⚠️ Error Handling
Comprehensive error handling with detailed context:
try {
const result = await uploadToDatabase(request);
if (!result.success) {
const { code, message, context } = result.error;
switch (code) {
case 'MISSING_FRONTMATTER':
console.log('💡 Add YAML frontmatter to your markdown file');
break;
case 'PROPERTY_VALIDATION_FAILED':
console.log('📋 Check your frontmatter properties');
console.log('Context:', context);
break;
case 'DATABASE_NOT_FOUND':
console.log('🔍 Verify your database ID and permissions');
break;
default:
console.log(`❌ ${message}`);
}
}
} catch (error) {
console.error('💥 Unexpected error:', error.message);
}Common Error Codes
| Code | Description | Solution |
|------|-------------|----------|
| MISSING_FRONTMATTER | Database upload requires frontmatter | Add YAML frontmatter to your markdown |
| PROPERTY_VALIDATION_FAILED | Invalid frontmatter properties | Check property names and types |
| FILE_NOT_FOUND | Markdown file not found | Verify file path |
| UNAUTHORIZED | Invalid Notion API key | Check your API key |
| DATABASE_NOT_FOUND | Database not accessible | Verify database ID and permissions |
🧪 Development
Setup
git clone <repository>
cd notion-markdown
npm install
cp .env.sample .env
# Edit .env with your Notion API keyAvailable Scripts
npm run build # 📦 Build the project
npm run dev # 🔄 Build in watch mode
npm run test # 🧪 Run all tests
npm run test:unit # 🔬 Run unit tests
npm run test:integration # 🔗 Run integration tests
npm run test:contract # 📋 Run contract tests
npm run lint # 🧹 Lint code
npm run lint:fix # 🔧 Fix lint issues
npm run typecheck # 🏷️ Type checking
npm run quality # ✅ Run all quality checksTesting Strategy
- 🔬 Unit Tests: Business logic and models
- 🔗 Integration Tests: Real Notion API interactions
- 📋 Contract Tests: API contract validation
- 🎯 TDD Approach: Tests before implementation
📖 Documentation
Core Documentation
- 📦 Bundled API Documentation - Complete bundled API reference with examples
- ✅ Bundled API Success Criteria - Testing results and success verification
- 🌍 Environment Configuration Guide - Centralized environment management
Additional Resources
- 🏗️ Architecture Guide - Technical architecture details
- 💻 Examples - Usage examples for different scenarios
🤝 Contributing
We welcome contributions! Please see our contributing guidelines:
- 🍴 Fork the repository
- 🌟 Create a feature branch (
git checkout -b feature/amazing-feature) - ✍️ Make your changes with tests
- ✅ Run quality checks (
npm run quality) - 📤 Submit a pull request
Development Guidelines
- 🧪 Test-Driven Development: Write tests first
- 🏗️ Clean Architecture: Follow existing patterns
- 🏷️ Type Safety: Maintain TypeScript coverage
- 📚 Documentation: Update docs for new features
- 🛡️ Backward Compatibility: Don't break existing APIs
📄 License
MIT License. See LICENSE for details.
🆘 Support & Links
🙏 Acknowledgments
- Notion API - For the powerful API
- TypeScript - For type safety
- Vitest - For fast testing
- Rollup - For efficient bundling
🚀 Built with ❤️ for seamless Notion integration
Made by developers, for developers who love organized documentation and seamless workflows.
