
Security News
Axios Maintainer Confirms Social Engineering Attack Behind npm Compromise
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.
@context-action/notion-markdown
Advanced tools
Complete TypeScript library for uploading/downloading markdown files to/from Notion pages and databases with bundled API
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.
npm install @context-action/notion-markdown
npm install -g @context-action/notion-markdown
export NOTION_API_KEY="secret_your_notion_api_key_here"
Or create a .env file:
NOTION_API_KEY=secret_your_notion_api_key_here
The library provides a complete bundled API with upload/download functionality and centralized environment configuration. See Bundled API Documentation for complete reference.
const {
syncMarkdownToNotion,
uploadToDatabase,
NotionClientService,
EnvironmentAdapter
} = require('@context-action/notion-markdown');
import {
syncMarkdownToNotion,
uploadToDatabase,
NotionClientService,
EnvironmentAdapter
} from '@context-action/notion-markdown';
// 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`);
}
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.
# 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
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: "contact@example.com"
---
# Project Content
Your markdown content here will become the page content...
## Features Completed
- [x] Database integration
- [x] Frontmatter parsing
- [ ] Advanced validation
| 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" |
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}`));
}
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}`);
});
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}`);
});
}
# Upload to page
notion-markdown sync <file> --page-id <id> [options]
# Options:
# --overwrite Replace existing content
# --dry-run Test without uploading
# --validate Validate before upload
# 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>
# Validate markdown
notion-markdown validate <file> [options]
# Test connection
notion-markdown test-connection
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 interface
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);
}
| 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 |
git clone <repository>
cd notion-markdown
npm install
cp .env.sample .env
# Edit .env with your Notion API key
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 checks
We welcome contributions! Please see our contributing guidelines:
git checkout -b feature/amazing-feature)npm run quality)MIT License. See LICENSE for details.
🚀 Built with ❤️ for seamless Notion integration
Made by developers, for developers who love organized documentation and seamless workflows.
FAQs
Complete TypeScript library for uploading/downloading markdown files to/from Notion pages and databases with bundled API
We found that @context-action/notion-markdown demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.