mirror of
https://github.com/jxpeng98/obsidian-to-NotionNext
synced 2026-07-29 08:08:34 +08:00
Compare commits
18 Commits
v2.8.0-bet
...
2.8.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b08c46c233 | ||
|
|
8dfb82b4ce | ||
|
|
8502650033 | ||
|
|
30e34e3f8c | ||
|
|
ec3d3e85a2 | ||
|
|
fe04e8df7f | ||
|
|
d36deb7b30 | ||
|
|
e8295746e1 | ||
|
|
83df1111c4 | ||
|
|
6e8be42e3c | ||
|
|
6b02cb219e | ||
|
|
cd7eb78378 | ||
|
|
3e00f127e9 | ||
|
|
4fb3b99996 | ||
|
|
269d354734 | ||
|
|
a37bda1575 | ||
|
|
19d66917d2 | ||
|
|
a9acfbe956 |
2
.github/workflows/prerelease.yml
vendored
2
.github/workflows/prerelease.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "18"
|
||||
node-version: "22"
|
||||
|
||||
- name: Build
|
||||
id: build
|
||||
|
||||
73
.github/workflows/release.yml
vendored
73
.github/workflows/release.yml
vendored
@@ -5,14 +5,14 @@ on:
|
||||
branches:
|
||||
- main
|
||||
tags:
|
||||
# Only trigger for release tags (e.g., v1.0.0, v2.3.4)
|
||||
# Excludes prerelease tags (e.g., v2.8.0-beta.3, v1.0.0-rc.1)
|
||||
- "v[0-9]+.[0-9]+.[0-9]"
|
||||
- "v[0-9]+.[0-9]+.[0-9][0-9]"
|
||||
- "v[0-9]+.[0-9]+.[0-9][0-9][0-9]"
|
||||
- "v[0-9]+.[0-9][0-9].[0-9]"
|
||||
- "v[0-9]+.[0-9][0-9].[0-9][0-9]"
|
||||
- "v[0-9]+.[0-9][0-9].[0-9][0-9][0-9]"
|
||||
# Only trigger for release tags (e.g., 1.0.0, 2.3.4)
|
||||
# Excludes prerelease tags (e.g., 2.8.0-beta.3, 1.0.0-rc.1)
|
||||
- "[0-9]+.[0-9]+.[0-9]"
|
||||
- "[0-9]+.[0-9]+.[0-9][0-9]"
|
||||
- "[0-9]+.[0-9]+.[0-9][0-9][0-9]"
|
||||
- "[0-9]+.[0-9][0-9].[0-9]"
|
||||
- "[0-9]+.[0-9][0-9].[0-9][0-9]"
|
||||
- "[0-9]+.[0-9][0-9].[0-9][0-9][0-9]"
|
||||
|
||||
env:
|
||||
PLUGIN_NAME: share-to-notionnext # Change this to match the id of your plugin.
|
||||
@@ -27,7 +27,7 @@ jobs:
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "18"
|
||||
node-version: "22"
|
||||
|
||||
# - name: Generate changelog
|
||||
# id: changelog
|
||||
@@ -48,21 +48,67 @@ jobs:
|
||||
ls
|
||||
echo "tag_name=$(git tag --sort version:refname | tail -n 1)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Generate release notes
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
run: |
|
||||
node - <<'NODE'
|
||||
const fs = require('fs');
|
||||
|
||||
const tag = process.env.GITHUB_REF_NAME;
|
||||
if (!tag) {
|
||||
throw new Error('GITHUB_REF_NAME is not set');
|
||||
}
|
||||
|
||||
const changelog = fs.readFileSync('CHANGELOG.md', 'utf8');
|
||||
const lines = changelog.split(/\r?\n/);
|
||||
|
||||
const escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
const headerRe = new RegExp(`^##\\s+${escapeRegex(tag)}\\b`);
|
||||
|
||||
const start = lines.findIndex((line) => headerRe.test(line));
|
||||
if (start === -1) {
|
||||
throw new Error(`Could not find changelog section for tag "${tag}"`);
|
||||
}
|
||||
|
||||
let end = lines.length;
|
||||
for (let i = start + 1; i < lines.length; i++) {
|
||||
if (/^##\s+/.test(lines[i])) {
|
||||
end = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let section = lines.slice(start, end);
|
||||
while (section.length > 0 && section[section.length - 1].trim() === '') {
|
||||
section.pop();
|
||||
}
|
||||
if (section.length > 0 && section[section.length - 1].trim() === '---') {
|
||||
section.pop();
|
||||
while (section.length > 0 && section[section.length - 1].trim() === '') {
|
||||
section.pop();
|
||||
}
|
||||
}
|
||||
|
||||
fs.writeFileSync('release-notes.md', `${section.join('\n')}\n`);
|
||||
NODE
|
||||
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
|
||||
VERSION: ${{ github.ref }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: ${{ github.ref }}
|
||||
body_path: ${{ env.CHANGELOG_FILENAME }}
|
||||
tag_name: ${{ github.ref_name }}
|
||||
release_name: ${{ github.ref_name }}
|
||||
body_path: release-notes.md
|
||||
draft: false
|
||||
prerelease: false
|
||||
|
||||
- name: Upload zip file
|
||||
id: upload-zip
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
|
||||
@@ -74,6 +120,7 @@ jobs:
|
||||
|
||||
- name: Upload main.js
|
||||
id: upload-main
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
|
||||
@@ -85,6 +132,7 @@ jobs:
|
||||
|
||||
- name: Upload manifest.json
|
||||
id: upload-manifest
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
|
||||
@@ -96,6 +144,7 @@ jobs:
|
||||
|
||||
- name: Upload markdown template
|
||||
id: upload-md
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
|
||||
|
||||
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "18"
|
||||
node-version: "22"
|
||||
|
||||
- name: Build
|
||||
id: build
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -28,3 +28,6 @@ local-data
|
||||
# vitepress
|
||||
docs/.vitepress/dist
|
||||
docs/.vitepress/cache
|
||||
|
||||
# claude code
|
||||
.claude
|
||||
88
CHANGELOG.md
88
CHANGELOG.md
@@ -1,5 +1,93 @@
|
||||
# Changelog
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Added
|
||||
|
||||
### Changed
|
||||
|
||||
### Fixed
|
||||
## v2.8.3 (2026-03-04)
|
||||
|
||||
### Added
|
||||
|
||||
### Changed
|
||||
|
||||
### Fixed
|
||||
|
||||
## 2.8.2 (2026-03-04)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed version bump with `tag-version-prefix="v"` in `.npmrc` causing incorrect version format in `package.json` (e.g. `v2.8.1` instead of `2.8.1`)
|
||||
|
||||
## 2.8.1 (2026-03-04)
|
||||
|
||||
### Added
|
||||
|
||||
- **Auto-sync success notice setting**: Toggle whether to show success notifications for auto-sync (defaults to off)
|
||||
|
||||
### Changed
|
||||
|
||||
- Auto-sync is quieter by default: success and "start upload" notices are suppressed unless explicitly enabled
|
||||
|
||||
### Fixed
|
||||
|
||||
- Auto-sync no longer shows "All blocks has been uploaded" (`BlockUploaded`) notice when success notices are disabled
|
||||
|
||||
## 2.8.0 (2026-01-29)
|
||||
|
||||
### Added
|
||||
|
||||
- **Auto Sync**: Automatically sync notes on content or frontmatter changes, with configurable delay and multi-database support
|
||||
- **Attachment Upload**: Upload local images and PDFs to Notion via the File Upload API and insert them as `image`/`file` blocks
|
||||
- **Auto-copy Notion Link**: Option to copy the Notion page link to clipboard after syncing
|
||||
- **Auto-sync frontmatter key**: Customize the frontmatter key for auto-sync database lists (default: `autosync-database`)
|
||||
- Comprehensive i18n support for UI and notifications
|
||||
- Prerelease workflow for beta testing via GitHub Actions and BRAT
|
||||
|
||||
### Changed
|
||||
|
||||
- Improved auto-sync behavior and notices for files without `autosync-database` or missing NotionID
|
||||
- Limited attachment link parsing to **Wikilinks** and **standard Markdown links** (Obsidian/App URL formats are now TODO/disabled)
|
||||
- Standardized Notion API request header `Notion-Version` to `2025-09-03`
|
||||
- Reduced per-file upload limit to **5MB** to maximize compatibility across Notion plans
|
||||
- Enhanced settings tab and documentation for auto-sync usage
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed mobile compatibility issues by using `window.setTimeout` instead of `NodeJS.Timeout`
|
||||
- Prevented sync loops and improved change detection for frontmatter/body updates
|
||||
- File placeholder tokens no longer break due to Markdown underscore parsing
|
||||
- Better block ordering when attachments are on standalone lines in Markdown
|
||||
- Preserve image captions when converting `external` images to `file_upload`
|
||||
- Avoid duplicate filename display on uploaded `file` blocks
|
||||
- Fixed `undefined` appearing in sync success notification by adding missing `sync-preffix` i18n key
|
||||
|
||||
---
|
||||
|
||||
## v2.8.0-beta.4 (2026-01-04)
|
||||
|
||||
### Added
|
||||
|
||||
- **Attachment Upload**: Upload local images and PDFs to Notion via the File Upload API and insert them as `image`/`file` blocks
|
||||
- **Auto-sync safeguard**: Auto-sync is skipped for notes containing internal attachments (manual sync required)
|
||||
|
||||
### Changed
|
||||
|
||||
- Limited attachment link parsing to **Wikilinks** and **standard Markdown links** (Obsidian/App URL formats are now TODO/disabled)
|
||||
- Standardized Notion API request header `Notion-Version` to `2025-09-03`
|
||||
- Reduced per-file upload limit to **5MB** to maximize compatibility across Notion plans
|
||||
|
||||
### Fixed
|
||||
|
||||
- File placeholder tokens no longer break due to Markdown underscore parsing
|
||||
- Better block ordering when attachments are on standalone lines in Markdown
|
||||
- Preserve image captions when converting `external` images to `file_upload`
|
||||
- Avoid duplicate filename display on uploaded `file` blocks
|
||||
|
||||
---
|
||||
|
||||
## v2.8.0-beta.3 (2025-12-10)
|
||||
|
||||
### Added
|
||||
|
||||
@@ -7,6 +7,35 @@ description: Release notes and updates for Obsidian to NotionNext
|
||||
|
||||
Welcome to the Changelog for Obsidian to NotionNext! Here you'll find a detailed list of all the updates, improvements, and bug fixes made to the plugin over time from the version `2.7.0` onwards.
|
||||
|
||||
## v2.8.0 (2026-01-29)
|
||||
|
||||
### Added
|
||||
|
||||
- **Auto Sync**: Automatically sync notes on content or frontmatter changes, with configurable delay and multi-database support
|
||||
- **Attachment Upload**: Upload local images and PDFs to Notion via the File Upload API and insert them as `image`/`file` blocks
|
||||
- **Auto-copy Notion Link**: Option to copy the Notion page link to clipboard after syncing
|
||||
- **Auto-sync frontmatter key**: Customize the frontmatter key for auto-sync database lists (default: `autosync-database`)
|
||||
- Comprehensive i18n support for UI and notifications
|
||||
- Prerelease workflow for beta testing via GitHub Actions and BRAT
|
||||
|
||||
### Changed
|
||||
|
||||
- Improved auto-sync behavior and notices for files without `autosync-database` or missing NotionID
|
||||
- Limited attachment link parsing to **Wikilinks** and **standard Markdown links** (Obsidian/App URL formats are now TODO/disabled)
|
||||
- Standardized Notion API request header `Notion-Version` to `2025-09-03`
|
||||
- Reduced per-file upload limit to **5MB** to maximize compatibility across Notion plans
|
||||
- Enhanced settings tab and documentation for auto-sync usage
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed mobile compatibility issues by using `window.setTimeout` instead of `NodeJS.Timeout`
|
||||
- Prevented sync loops and improved change detection for frontmatter/body updates
|
||||
- File placeholder tokens no longer break due to Markdown underscore parsing
|
||||
- Better block ordering when attachments are on standalone lines in Markdown
|
||||
- Preserve image captions when converting `external` images to `file_upload`
|
||||
- Avoid duplicate filename display on uploaded `file` blocks
|
||||
- Fixed `undefined` appearing in sync success notification by adding missing `sync-preffix` i18n key
|
||||
|
||||
## v2.8.0-beta.2 (2025-11-05)
|
||||
|
||||
### Featured
|
||||
|
||||
@@ -5,6 +5,6 @@ description: Planned features and improvements for Obsidian to NotionNext
|
||||
|
||||
# Roadmap
|
||||
|
||||
- [ ] Automatic Syncing: Implement automatic syncing of notes at regular intervals or upon changes.
|
||||
- [ ] File Attachments: Support for syncing file attachments from Obsidian to Notion.
|
||||
- [x] Automatic Syncing: Implement automatic syncing of notes at regular intervals or upon changes.
|
||||
- [x] File Attachments: Support for syncing file attachments from Obsidian to Notion.
|
||||
- [ ] Relation Property: Enable mapping of Obsidian links to Notion relation properties.
|
||||
|
||||
@@ -4,3 +4,32 @@ description: Obsidian to NotionNext 的版本更新与变更记录
|
||||
---
|
||||
|
||||
欢迎来到 Obsidian to NotionNext 的更新日志!这里会记录自 `2.7.0` 版本起的所有更新、改进以及问题修复,方便你快速了解插件的演进情况。
|
||||
|
||||
## v2.8.0 (2026-01-29)
|
||||
|
||||
### 新增
|
||||
|
||||
- **自动同步**:当内容或 frontmatter 变化时自动同步,支持可配置延迟与多数据库
|
||||
- **附件上传**:通过 File Upload API 上传本地图片与 PDF,并插入为 `image`/`file` 块
|
||||
- **自动复制 Notion 链接**:同步后自动复制页面链接到剪贴板
|
||||
- **自动同步 frontmatter key**:可自定义自动同步数据库列表的 frontmatter key(默认 `autosync-database`)
|
||||
- 完整的 UI 与通知 i18n 支持
|
||||
- 通过 GitHub Actions + BRAT 的预发布测试流程
|
||||
|
||||
### 变更
|
||||
|
||||
- 优化自动同步行为与提示:无 `autosync-database` 或缺少 NotionID 的文件处理更智能
|
||||
- 限制附件链接解析为 **Wikilinks** 与 **标准 Markdown 链接**(Obsidian/App URL 暂停/待办)
|
||||
- 统一 Notion API 请求头 `Notion-Version` 为 `2025-09-03`
|
||||
- 单文件上传限制降为 **5MB**,提升兼容性
|
||||
- 强化设置面板与自动同步相关文档
|
||||
|
||||
### 修复
|
||||
|
||||
- 移动端兼容性修复:使用 `window.setTimeout` 替代 `NodeJS.Timeout`
|
||||
- 防止同步循环,改进 frontmatter/正文变更检测
|
||||
- 修复 Markdown 下划线导致的占位符解析问题
|
||||
- 修复附件独占行时的块顺序
|
||||
- 保留 `external` 图片转为 `file_upload` 时的图片标题
|
||||
- 避免上传 `file` 块时重复显示文件名
|
||||
- 修复同步成功通知出现 `undefined`(补充 `sync-preffix` i18n key)
|
||||
|
||||
@@ -3,6 +3,6 @@ title: 路线图
|
||||
description: Obsidian to NotionNext 的规划功能与未来改进
|
||||
---
|
||||
|
||||
- [ ] 自动同步:支持按时间间隔或内容变更自动同步笔记。
|
||||
- [ ] 附件支持:允许将 Obsidian 笔记中的附件一同上传到 Notion。
|
||||
- [x] 自动同步:支持按时间间隔或内容变更自动同步笔记。
|
||||
- [x] 附件支持:允许将 Obsidian 笔记中的附件一同上传到 Notion。
|
||||
- [ ] 关联属性:实现将 Obsidian 链接映射到 Notion 的 relation 属性。
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"id": "share-to-notionnext",
|
||||
"name": "Share to NotionNext",
|
||||
"version": "2.7.0",
|
||||
"minAppVersion": "0.0.1",
|
||||
"description": "Shares obsidian md file to notion with notion api for NotionNext web deploy, originally created by EasyChris/obsidian-to-notion.",
|
||||
"author": "EasyChris, jxpeng98",
|
||||
"authorUrl": "https://github.com/jxpeng98",
|
||||
"isDesktopOnly": false
|
||||
"id": "share-to-notionnext",
|
||||
"name": "Share to NotionNext",
|
||||
"version": "2.8.3",
|
||||
"minAppVersion": "0.0.1",
|
||||
"description": "Shares obsidian md file to notion with notion api for NotionNext web deploy, originally created by EasyChris/obsidian-to-notion.",
|
||||
"author": "EasyChris, jxpeng98",
|
||||
"authorUrl": "https://github.com/jxpeng98",
|
||||
"isDesktopOnly": false
|
||||
}
|
||||
@@ -1,19 +1,19 @@
|
||||
{
|
||||
"name": "share-to-notionnext",
|
||||
"version": "2.7.0",
|
||||
"version": "2.8.3",
|
||||
"type": "module",
|
||||
"description": "Share files to any Notion database using the Notion API, originally created by EasyChris/obsidian-to-notion.",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"dev": "node esbuild.config.mjs",
|
||||
"build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production",
|
||||
"version": "node version-bump.mjs && git add manifest.json versions.json"
|
||||
"version": "node version-bump.mjs && git add manifest.json versions.json CHANGELOG.md"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Jiaxin PENG",
|
||||
"license": "GNU GPLv3",
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.5.7",
|
||||
"@types/node": "^22.11.3",
|
||||
"@types/yaml-front-matter": "^4.1.3",
|
||||
"@typescript-eslint/eslint-plugin": "^6.16.0",
|
||||
"@typescript-eslint/parser": "^6.16.0",
|
||||
|
||||
@@ -44,6 +44,8 @@ export const en = {
|
||||
AutoSyncDelay: "Auto Sync Delay (seconds)",
|
||||
AutoSyncDelayDesc: "Delay in seconds to wait before syncing after a change. Prevents excessive syncs (default: 5s, min: 2s).",
|
||||
AutoSyncDelayText: "Enter delay in seconds",
|
||||
AutoSyncSuccessNotice: "Auto Sync Success Notice",
|
||||
AutoSyncSuccessNoticeDesc: "Show a notification when auto-sync succeeds (default: off; failures are still notified).",
|
||||
NotionGeneralSettingHeader: "General Notion Database Settings",
|
||||
NotionGeneralButton: "General Database Sync",
|
||||
NotionGeneralButtonDesc: "Enables the 'Sync to General Database' command in the command palette (default: on).",
|
||||
|
||||
@@ -42,6 +42,8 @@ export const ja = {
|
||||
AutoSyncDelay: "自動同期の遅延(秒)",
|
||||
AutoSyncDelayDesc: "変更が検知されてから同期を開始するまでの遅延時間(秒)。同期の頻発を防ぎます(デフォルト:5秒、最小:2秒)。",
|
||||
AutoSyncDelayText: "遅延秒数を入力",
|
||||
AutoSyncSuccessNotice: "自動同期成功通知",
|
||||
AutoSyncSuccessNoticeDesc: "自動同期が成功したときに通知を表示します(デフォルト:オフ。失敗時は通知されます)。",
|
||||
NotionGeneralSettingHeader: "一般Notionデータベース設定",
|
||||
NotionGeneralButton: "一般データベース同期",
|
||||
NotionGeneralButtonDesc: "有効にすると、コマンドパレットに「一般データベースへ同期」が表示されます(デフォルト:オン)。",
|
||||
|
||||
@@ -44,6 +44,8 @@ export const zh = {
|
||||
AutoSyncDelay: "自动同步延迟(秒)",
|
||||
AutoSyncDelayDesc: "文档修改后,等待指定秒数再触发自动同步,以避免频繁操作(默认 5 秒,最少 2 秒)",
|
||||
AutoSyncDelayText: "输入延迟秒数",
|
||||
AutoSyncSuccessNotice: "自动同步成功通知",
|
||||
AutoSyncSuccessNoticeDesc: "是否在自动同步成功后弹出通知(默认关闭,仅在失败时通知)",
|
||||
NotionGeneralSettingHeader: "通用 Notion 数据库设置",
|
||||
NotionGeneralButton: "通用数据库同步",
|
||||
NotionGeneralButtonDesc: "启用后,命令面板中将显示“同步到通用数据库”命令(默认开启)",
|
||||
|
||||
16
src/main.ts
16
src/main.ts
@@ -92,6 +92,9 @@ export default class ObsidianSyncNotionPlugin extends Plugin {
|
||||
if (typeof this.settings.autoSyncDelay !== 'number' || this.settings.autoSyncDelay < 2) {
|
||||
this.settings.autoSyncDelay = DEFAULT_SETTINGS.autoSyncDelay;
|
||||
}
|
||||
if (typeof this.settings.autoSyncSuccessNotice !== 'boolean') {
|
||||
this.settings.autoSyncSuccessNotice = DEFAULT_SETTINGS.autoSyncSuccessNotice;
|
||||
}
|
||||
if (typeof this.settings.NotionLinkDisplay !== 'boolean') {
|
||||
this.settings.NotionLinkDisplay = DEFAULT_SETTINGS.NotionLinkDisplay;
|
||||
}
|
||||
@@ -112,6 +115,7 @@ export default class ObsidianSyncNotionPlugin extends Plugin {
|
||||
const needsSave = !loadedData ||
|
||||
loadedData.autoSync === undefined ||
|
||||
loadedData.autoSyncDelay === undefined ||
|
||||
loadedData.autoSyncSuccessNotice === undefined ||
|
||||
loadedData.NotionLinkDisplay === undefined ||
|
||||
loadedData.autoCopyNotionLink === undefined ||
|
||||
loadedData.autoSyncFrontmatterKey === undefined;
|
||||
@@ -123,6 +127,7 @@ export default class ObsidianSyncNotionPlugin extends Plugin {
|
||||
} else {
|
||||
if (loadedData.autoSync === undefined) migratedFields.push('autoSync');
|
||||
if (loadedData.autoSyncDelay === undefined) migratedFields.push('autoSyncDelay');
|
||||
if (loadedData.autoSyncSuccessNotice === undefined) migratedFields.push('autoSyncSuccessNotice');
|
||||
if (loadedData.NotionLinkDisplay === undefined) migratedFields.push('NotionLinkDisplay');
|
||||
if (loadedData.autoCopyNotionLink === undefined) migratedFields.push('autoCopyNotionLink');
|
||||
|
||||
@@ -146,6 +151,7 @@ export default class ObsidianSyncNotionPlugin extends Plugin {
|
||||
console.log('[Settings] Settings saved successfully', {
|
||||
autoSync: this.settings.autoSync,
|
||||
autoSyncDelay: this.settings.autoSyncDelay,
|
||||
autoSyncSuccessNotice: this.settings.autoSyncSuccessNotice,
|
||||
NotionLinkDisplay: this.settings.NotionLinkDisplay,
|
||||
autoSyncFrontmatterKey: this.settings.autoSyncFrontmatterKey,
|
||||
databaseCount: Object.keys(this.settings.databaseDetails || {}).length
|
||||
@@ -162,6 +168,10 @@ export default class ObsidianSyncNotionPlugin extends Plugin {
|
||||
console.warn('[Settings] Invalid autoSyncDelay value, resetting to default');
|
||||
this.settings.autoSyncDelay = DEFAULT_SETTINGS.autoSyncDelay;
|
||||
}
|
||||
if (typeof this.settings.autoSyncSuccessNotice !== 'boolean') {
|
||||
console.warn('[Settings] Invalid autoSyncSuccessNotice value, resetting to default');
|
||||
this.settings.autoSyncSuccessNotice = DEFAULT_SETTINGS.autoSyncSuccessNotice;
|
||||
}
|
||||
if (typeof this.settings.NotionLinkDisplay !== 'boolean') {
|
||||
console.warn('[Settings] Invalid NotionLinkDisplay value, resetting to default');
|
||||
this.settings.NotionLinkDisplay = DEFAULT_SETTINGS.NotionLinkDisplay;
|
||||
@@ -415,11 +425,11 @@ export default class ObsidianSyncNotionPlugin extends Plugin {
|
||||
try {
|
||||
// Trigger appropriate upload command based on database format
|
||||
if (dbDetails.format === 'next') {
|
||||
await uploadCommandNext(this, this.settings, dbDetails, this.app);
|
||||
await uploadCommandNext(this, this.settings, dbDetails, this.app, { isAutoSync: true });
|
||||
} else if (dbDetails.format === 'general') {
|
||||
await uploadCommandGeneral(this, this.settings, dbDetails, this.app);
|
||||
await uploadCommandGeneral(this, this.settings, dbDetails, this.app, { isAutoSync: true });
|
||||
} else if (dbDetails.format === 'custom') {
|
||||
await uploadCommandCustom(this, this.settings, dbDetails, this.app);
|
||||
await uploadCommandCustom(this, this.settings, dbDetails, this.app, { isAutoSync: true });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`[AutoSync] Error syncing to ${dbDetails.fullName}:`, error);
|
||||
|
||||
@@ -17,6 +17,7 @@ export interface PluginSettings {
|
||||
autoCopyNotionLink: boolean;
|
||||
autoSync: boolean;
|
||||
autoSyncDelay: number;
|
||||
autoSyncSuccessNotice: boolean;
|
||||
autoSyncFrontmatterKey: string;
|
||||
proxy: string;
|
||||
GeneralButton: boolean;
|
||||
@@ -57,6 +58,7 @@ export const DEFAULT_SETTINGS: PluginSettings = {
|
||||
autoCopyNotionLink: true,
|
||||
autoSync: false,
|
||||
autoSyncDelay: 5,
|
||||
autoSyncSuccessNotice: false,
|
||||
autoSyncFrontmatterKey: DEFAULT_AUTO_SYNC_DATABASE_KEY,
|
||||
proxy: "",
|
||||
GeneralButton: true,
|
||||
@@ -100,6 +102,15 @@ export class ObsidianSettingTab extends PluginSettingTab {
|
||||
this.createSettingEl(containerEl, i18nConfig.AutoCopyNotionLink, i18nConfig.AutoCopyNotionLinkDesc, 'toggle', i18nConfig.AutoCopyNotionLink, this.plugin.settings.autoCopyNotionLink, 'autoCopyNotionLink')
|
||||
|
||||
this.createSettingEl(containerEl, i18nConfig.AutoSync, i18nConfig.AutoSyncDesc, 'toggle', i18nConfig.AutoSync, this.plugin.settings.autoSync, 'autoSync')
|
||||
this.createSettingEl(
|
||||
containerEl,
|
||||
i18nConfig.AutoSyncSuccessNotice,
|
||||
i18nConfig.AutoSyncSuccessNoticeDesc,
|
||||
'toggle',
|
||||
i18nConfig.AutoSyncSuccessNotice,
|
||||
this.plugin.settings.autoSyncSuccessNotice,
|
||||
'autoSyncSuccessNotice'
|
||||
)
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName(i18nConfig.AutoSyncFrontmatterKey)
|
||||
@@ -369,4 +380,3 @@ export class ObsidianSettingTab extends PluginSettingTab {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ interface BaseSyncRequest {
|
||||
markdown: string;
|
||||
nowFile: TFile;
|
||||
app: App;
|
||||
isAutoSync?: boolean;
|
||||
}
|
||||
|
||||
interface GeneralSyncRequest extends BaseSyncRequest {
|
||||
@@ -91,6 +92,7 @@ export class Upload2Notion extends UploadBase {
|
||||
|
||||
async sync(request: SyncRequest): Promise<NotionPageResponse> {
|
||||
const startedAt = Date.now();
|
||||
this.isAutoSync = !!request.isAutoSync;
|
||||
|
||||
let response: NotionPageResponse;
|
||||
|
||||
|
||||
@@ -18,12 +18,20 @@ interface PreparedBlocks {
|
||||
export abstract class UploadBase {
|
||||
protected plugin: MyPlugin;
|
||||
protected dbDetails: DatabaseDetails;
|
||||
protected isAutoSync = false;
|
||||
|
||||
protected constructor(plugin: MyPlugin, dbDetails: DatabaseDetails) {
|
||||
this.plugin = plugin;
|
||||
this.dbDetails = dbDetails;
|
||||
}
|
||||
|
||||
private shouldShowSuccessNotices(): boolean {
|
||||
if (!this.isAutoSync) {
|
||||
return true;
|
||||
}
|
||||
return !!this.plugin.settings.autoSyncSuccessNotice;
|
||||
}
|
||||
|
||||
async deletePage(notionID: string) {
|
||||
const {notionAPI} = this.dbDetails;
|
||||
return requestUrl({
|
||||
@@ -190,7 +198,9 @@ export abstract class UploadBase {
|
||||
console.log(`${i18nConfig["ExtraBlockUploaded"]} to page: ${pageId}`);
|
||||
if (i === extraChunks.length - 1) {
|
||||
console.log(`${i18nConfig["BlockUploaded"]} to page: ${pageId}`);
|
||||
new Notice(`${i18nConfig["BlockUploaded"]} page: ${pageId}`, 5000);
|
||||
if (this.shouldShowSuccessNotices()) {
|
||||
new Notice(`${i18nConfig["BlockUploaded"]} page: ${pageId}`, 5000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,10 @@ import {getNowFileMarkdownContentCustom} from "./common/getMarkdownCustom";
|
||||
|
||||
const SYNC_ERROR_NOTICE_DURATION = 8000;
|
||||
|
||||
interface UploadCommandOptions {
|
||||
isAutoSync?: boolean;
|
||||
}
|
||||
|
||||
function extractErrorMessage(error: unknown): string {
|
||||
if (error instanceof Error && error.message) {
|
||||
return error.message;
|
||||
@@ -17,6 +21,16 @@ function extractErrorMessage(error: unknown): string {
|
||||
return String(error);
|
||||
}
|
||||
|
||||
function shouldShowAutoSyncSuccessNotice(
|
||||
plugin: ObsidianSyncNotionPlugin,
|
||||
options?: UploadCommandOptions,
|
||||
): boolean {
|
||||
if (!options?.isAutoSync) {
|
||||
return true;
|
||||
}
|
||||
return !!plugin.settings.autoSyncSuccessNotice;
|
||||
}
|
||||
|
||||
function notifySyncError(prefix: string, basename: string, error: unknown): void {
|
||||
const errorMessage = extractErrorMessage(error);
|
||||
console.error(`${prefix} Sync failed`, error);
|
||||
@@ -39,6 +53,7 @@ export async function uploadCommandNext(
|
||||
settings: PluginSettings,
|
||||
dbDetails: DatabaseDetails,
|
||||
app: App,
|
||||
options?: UploadCommandOptions,
|
||||
) {
|
||||
|
||||
const {notionAPI, databaseID} = dbDetails;
|
||||
@@ -91,6 +106,7 @@ export async function uploadCommandNext(
|
||||
try {
|
||||
res = await upload.sync({
|
||||
dataset: "next",
|
||||
isAutoSync: options?.isAutoSync,
|
||||
title: basename,
|
||||
emoji: emoji || "",
|
||||
cover: cover || "",
|
||||
@@ -118,7 +134,9 @@ export async function uploadCommandNext(
|
||||
|
||||
const {response} = res;
|
||||
if (response.status === 200) {
|
||||
new Notice(`${i18nConfig["sync-preffix"]} ${basename} ${i18nConfig["sync-success"]}`).noticeEl.style.color = "green";
|
||||
if (shouldShowAutoSyncSuccessNotice(plugin, options)) {
|
||||
new Notice(`${i18nConfig["sync-preffix"]} ${basename} ${i18nConfig["sync-success"]}`).noticeEl.style.color = "green";
|
||||
}
|
||||
|
||||
logCommandDebug("uploadCommandNext", "Sync succeeded", {
|
||||
filename: basename,
|
||||
@@ -146,6 +164,7 @@ export async function uploadCommandGeneral(
|
||||
settings: PluginSettings,
|
||||
dbDetails: DatabaseDetails,
|
||||
app: App,
|
||||
options?: UploadCommandOptions,
|
||||
) {
|
||||
|
||||
const {notionAPI, databaseID} = dbDetails;
|
||||
@@ -160,7 +179,9 @@ export async function uploadCommandGeneral(
|
||||
|
||||
const {markDownData, nowFile, cover, tags} = await getNowFileMarkdownContentGeneral(app, settings)
|
||||
|
||||
new Notice(i18nConfig.StartUpload.replace('{filename}', nowFile.basename));
|
||||
if (!options?.isAutoSync) {
|
||||
new Notice(i18nConfig.StartUpload.replace('{filename}', nowFile.basename));
|
||||
}
|
||||
console.log(`Start upload ${nowFile.basename}`);
|
||||
|
||||
if (markDownData) {
|
||||
@@ -177,6 +198,7 @@ export async function uploadCommandGeneral(
|
||||
try {
|
||||
res = await upload.sync({
|
||||
dataset: "general",
|
||||
isAutoSync: options?.isAutoSync,
|
||||
title: basename,
|
||||
cover: cover || "",
|
||||
tags: tags || [],
|
||||
@@ -195,7 +217,9 @@ export async function uploadCommandGeneral(
|
||||
|
||||
const {response} = res;
|
||||
if (response.status === 200) {
|
||||
new Notice(`${i18nConfig["sync-preffix"]} ${basename} ${i18nConfig["sync-success"]}`).noticeEl.style.color = "green";
|
||||
if (shouldShowAutoSyncSuccessNotice(plugin, options)) {
|
||||
new Notice(`${i18nConfig["sync-preffix"]} ${basename} ${i18nConfig["sync-success"]}`).noticeEl.style.color = "green";
|
||||
}
|
||||
|
||||
logCommandDebug("uploadCommandGeneral", "Sync succeeded", {
|
||||
filename: basename,
|
||||
@@ -223,6 +247,7 @@ export async function uploadCommandCustom(
|
||||
settings: PluginSettings,
|
||||
dbDetails: DatabaseDetails,
|
||||
app: App,
|
||||
options?: UploadCommandOptions,
|
||||
) {
|
||||
|
||||
const {notionAPI, databaseID} = dbDetails;
|
||||
@@ -237,7 +262,9 @@ export async function uploadCommandCustom(
|
||||
|
||||
const {markDownData, nowFile, cover, customValues} = await getNowFileMarkdownContentCustom(app, dbDetails)
|
||||
|
||||
new Notice(i18nConfig.StartUpload.replace('{filename}', nowFile.basename));
|
||||
if (!options?.isAutoSync) {
|
||||
new Notice(i18nConfig.StartUpload.replace('{filename}', nowFile.basename));
|
||||
}
|
||||
console.log(`Start upload ${nowFile.basename}`);
|
||||
|
||||
if (markDownData) {
|
||||
@@ -254,6 +281,7 @@ export async function uploadCommandCustom(
|
||||
try {
|
||||
res = await upload.sync({
|
||||
dataset: "custom",
|
||||
isAutoSync: options?.isAutoSync,
|
||||
cover: cover || "",
|
||||
customValues,
|
||||
markdown: markDownData,
|
||||
@@ -272,7 +300,9 @@ export async function uploadCommandCustom(
|
||||
const {response} = res;
|
||||
|
||||
if (response.status === 200) {
|
||||
new Notice(`${i18nConfig["sync-preffix"]} ${basename} ${i18nConfig["sync-success"]}`).noticeEl.style.color = "green";
|
||||
if (shouldShowAutoSyncSuccessNotice(plugin, options)) {
|
||||
new Notice(`${i18nConfig["sync-preffix"]} ${basename} ${i18nConfig["sync-success"]}`).noticeEl.style.color = "green";
|
||||
}
|
||||
|
||||
logCommandDebug("uploadCommandCustom", "Sync succeeded", {
|
||||
filename: basename,
|
||||
|
||||
@@ -12,3 +12,40 @@ writeFileSync("manifest.json", JSON.stringify(manifest, null, "\t"));
|
||||
let versions = JSON.parse(readFileSync("versions.json", "utf8"));
|
||||
versions[targetVersion] = minAppVersion;
|
||||
writeFileSync("versions.json", JSON.stringify(versions, null, "\t"));
|
||||
|
||||
// tag the changelog by converting "Unreleased" to the new version section
|
||||
function bumpChangelog(version) {
|
||||
const changelogPath = "CHANGELOG.md";
|
||||
const content = readFileSync(changelogPath, "utf8");
|
||||
|
||||
const unreleasedHeader = "## Unreleased";
|
||||
if (!content.includes(unreleasedHeader)) {
|
||||
console.warn(`[version-bump] ${unreleasedHeader} not found in ${changelogPath}, skipping changelog tagging`);
|
||||
return;
|
||||
}
|
||||
|
||||
const today = new Date().toISOString().slice(0, 10);
|
||||
const releaseHeader = `## v${version} (${today})`;
|
||||
const updated = content.replace(unreleasedHeader, releaseHeader);
|
||||
|
||||
const marker = "# Changelog\n\n";
|
||||
if (!updated.startsWith(marker)) {
|
||||
writeFileSync(changelogPath, updated);
|
||||
return;
|
||||
}
|
||||
|
||||
const newUnreleased = [
|
||||
"## Unreleased",
|
||||
"",
|
||||
"### Added",
|
||||
"",
|
||||
"### Changed",
|
||||
"",
|
||||
"### Fixed",
|
||||
"",
|
||||
].join("\n");
|
||||
|
||||
writeFileSync(changelogPath, marker + newUnreleased + updated.slice(marker.length));
|
||||
}
|
||||
|
||||
bumpChangelog(targetVersion);
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
{
|
||||
"1.0.0": "0.9.7",
|
||||
"1.0.1": "0.12.0"
|
||||
"1.0.1": "0.12.0",
|
||||
"2.8.0": "0.0.1",
|
||||
"2.8.1": "0.0.1",
|
||||
"2.8.2": "0.0.1",
|
||||
"2.8.3": "0.0.1"
|
||||
}
|
||||
Reference in New Issue
Block a user