Compare commits

..

25 Commits

Author SHA1 Message Date
Jiaxin Peng
a950e2e301 Update version to 2.5.0 2024-11-20 22:19:38 +00:00
Jiaxin Peng
aac7bc154a feat: consistent sync function (requestUrl) for desktop and mobile 2024-11-20 22:19:03 +00:00
Jiaxin Peng
a573ef728d chore: remove node-fetch and change the platform back to browser. 2024-11-20 22:17:49 +00:00
Jiaxin Peng
1344c14933 Update version to 2.4.3 2024-10-22 10:29:09 +01:00
Jiaxin Peng
c1f4ecd14b Update version to 2.4.3 2024-10-22 10:27:49 +01:00
Jiaxin Peng
5942876c92 fix: cannot parse title from front matter 2024-10-22 10:27:33 +01:00
Jiaxin Peng
3218eb9fba Update version to 2.4.2 2024-09-19 13:50:51 +01:00
Jiaxin Peng
48566eca20 Merge pull request #37 from jxpeng98/pluggin-does-not-appear-on-mac
fix: obsidian language not set in English, Chinese and Japanese
2024-09-19 13:49:08 +01:00
Jiaxin Peng
8bd8346423 fix: obsidian language not set in English, Chinese and Japanese 2024-09-19 13:47:57 +01:00
Jiaxin Peng
00411e9599 Merge pull request #35 from jxpeng98/mobile-fail-to-start
feat: separate mobile sync from desktop version
2024-09-03 12:19:23 +01:00
Jiaxin Peng
296125f6b4 chore: remove process from dependencies 2024-09-03 12:15:36 +01:00
Jiaxin Peng
1b385ccd0a solve: the fail to load of mobile caused by the node version 2024-09-01 23:26:22 +01:00
Jiaxin Peng
a90e4871bb Backup mobile requesturl after version 2.4.1 2024-09-01 22:57:03 +01:00
Jiaxin Peng
885ccba027 fix: test the desktop function for next and general 2024-08-31 23:43:19 +01:00
Jiaxin Peng
f282dde1b7 fix: test the desktop function of custom database
with platform function
2024-08-31 00:00:09 +01:00
Jiaxin Peng
bc166d8db1 Update version to 2.4.1 2024-08-28 20:31:28 +01:00
Jiaxin Peng
7612637951 Merge pull request #34 from jxpeng98/code-highlight-issue
fix code highlight issue
2024-08-28 20:30:49 +01:00
Jiaxin Peng
e8b1617916 fix item type error for iteration 2024-08-28 20:30:05 +01:00
Jiaxin Peng
fd29ed820e fix code highlight issue 2024-08-28 20:26:06 +01:00
Jiaxin Peng
1f58670906 Update version to 2.4.0 2024-08-19 11:24:23 +01:00
Jiaxin Peng
fc47d36e8d Merge pull request #32 from jxpeng98/long-notes-support
Long notes support
2024-08-18 22:39:00 +01:00
Jiaxin Peng
cd4e610c46 modify type of pageProperties 2024-08-18 18:42:59 +01:00
Jiaxin Peng
b05c248c44 feat: support long notes syncing 2024-08-18 17:16:08 +01:00
Jiaxin Peng
800e218dee Update version to 2.3.5 2024-08-18 13:08:04 +01:00
Jiaxin Peng
3b774552af update martian 2024-08-18 13:07:52 +01:00
20 changed files with 722 additions and 388 deletions

3
.gitignore vendored
View File

@@ -21,3 +21,6 @@ data.json
# Exclude macOS Finder (System Explorer) View States # Exclude macOS Finder (System Explorer) View States
.DS_Store .DS_Store
.history .history
# local data
local-data

View File

@@ -1,11 +1,15 @@
## Improvements ## Fix
- Change the way to sync the notes to notion for better debugging and error handling. - Fix the bug that the plugin does not work in the mobile app.
- 修复了在移动端应用中插件无法工作的问题。
For now, if you have any error, you will see a notice in the top-right corner of the app. You can check the error message in the developer console (F12) for more details. ## Feature
You can enter the developer console by pressing `option+cmd+I`(Mac) or `ctrl+shift+I`(Windows/Linux) in the app. - Both desktop and mobile apps support syncing long markdown files.
- 桌面端和移动端应用都支持长篇 markdown 文件同步。
You can also toggle the developer console from the menu `View -> Toggle Developer Tools`. ## Issue
- Bullet list over 3 levels is not supported.
- 无法同步超过三个分支的列表。

View File

@@ -9,27 +9,28 @@
[//]: # ([中文文档](README-zh.md)) [//]: # ([中文文档](README-zh.md))
**Now, support both NotionNext and General databases with customised properties.** **Now, support All Notion databases, including NotionNext and General Notion databases, and customise the database list.**
**现在支持NotionNext和普通Notion数据库自定义数据库列表。** **现在支持所有Notion数据库包括NotionNext和一般Notion数据库以及自定义数据库列表。**
## Precautions ## Precautions
### For customised database users ### For customised database users before version 2.3.0
**⚠️⚠️⚠️: The existing customised database should be recreated if you want to update to version 2.3.0. The new version has a new database structure, and the old database structure is not compatible with the new version to build the index properly.** **⚠️⚠️⚠️: The existing customised database should be recreated if you want to update to version 2.3.0. The new version has a new database structure, and the old database structure is not compatible with the new version to build the index properly.**
### 自定义数据库用户 ### 在2.3.0版本之前的自定义数据库用户
**⚠️⚠️⚠️: 如果你想要更新到2.3.0版本,你需要重新创建自定义数据库。新版本有一个新的数据库结构,旧的数据库结构无法构建索引。** **⚠️⚠️⚠️: 如果你想要更新到2.3.0版本,你需要重新创建自定义数据库。新版本有一个新的数据库结构,旧的数据库结构无法构建索引。**
## TODO List ## TODO List
- [x] ~~Modify the Edit function for the custom properties. 改进自定义属性的编辑功能~~ - [x] Modify the Edit function for the custom properties. 改进自定义属性的编辑功能
- [x] Support sync with long notes (From `v2.4.0`). 从`v2.4.0`开始支持长笔记同步
- [x] Support custom properties for Notion General database. 支持自定义属性
- [x] Support preview for database details in plugin settings. 支持预览数据库详情
- [x] Support edit for database details in plugin settings. 支持编辑数据库详情
- [ ] Support group upload with one click 支持一键多数据库上传 - [ ] Support group upload with one click 支持一键多数据库上传
- [x] ~~Support custom properties for Notion General database. 支持自定义属性~~
- [x] ~~Support preview for database details in plugin settings. 支持预览数据库详情~~
- [x] ~~Support edit for database details in plugin settings. 支持编辑数据库详情~~
## How to use ## How to use

View File

@@ -41,7 +41,6 @@ const ctx = await esbuild.context({
"@codemirror/view", "@codemirror/view",
...builtins, ...builtins,
], ],
platform: "node",
format: "cjs", format: "cjs",
target: "es2016", target: "es2016",
logLevel: "info", logLevel: "info",

View File

@@ -1,7 +1,7 @@
{ {
"id": "share-to-notionnext", "id": "share-to-notionnext",
"name": "Share to NotionNext", "name": "Share to NotionNext",
"version": "2.3.4", "version": "2.5.0",
"minAppVersion": "0.0.1", "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.", "description": "Shares obsidian md file to notion with notion api for NotionNext web deploy, originally created by EasyChris/obsidian-to-notion.",
"author": "EasyChris, jxpeng98", "author": "EasyChris, jxpeng98",

View File

@@ -1,8 +1,8 @@
{ {
"name": "share-to-notionnext", "name": "share-to-notionnext",
"version": "2.3.4", "version": "2.5.0",
"type": "module", "type": "module",
"description": "Shares obsidian md file to notion with notion api for NotionNext web deploy, originally created by EasyChris/obsidian-to-notion.", "description": "Share files to any Notion database using the Notion API, originally created by EasyChris/obsidian-to-notion.",
"main": "main.js", "main": "main.js",
"scripts": { "scripts": {
"dev": "node esbuild.config.mjs", "dev": "node esbuild.config.mjs",
@@ -24,10 +24,8 @@
"typescript": "5.2.2" "typescript": "5.2.2"
}, },
"dependencies": { "dependencies": {
"@tryfabric/martian": "^1.2.4", "@jxpeng98/martian": "^1.2.7",
"https-proxy-agent": "^7.0.2", "https-proxy-agent": "^7.0.2",
"node-fetch": "^3.3.2",
"process": "^0.11.10",
"remark-math": "^6.0.0", "remark-math": "^6.0.0",
"yaml": "^2.3.4", "yaml": "^2.3.4",
"yaml-front-matter": "^4.1.1" "yaml-front-matter": "^4.1.1"

View File

@@ -8,10 +8,42 @@ export const I18n: {[key: string]:any} = {
ja, ja,
}; };
export const I18nConfig = (lang: string): any => { class I18nManager {
return I18n[lang]; private currentLanguage: string;
};
constructor() {
this.currentLanguage = this.detectLanguage();
}
// return the language to use
private detectLanguage(): string {
const storedLanguage = window.localStorage.getItem("language"); const storedLanguage = window.localStorage.getItem("language");
if (storedLanguage && this.isLanguageSupported(storedLanguage)) {
console.log(`Using stored language: ${storedLanguage}`);
return storedLanguage;
}
export const i18nConfig = I18n[storedLanguage || window.navigator.language.split('-')[0] || "en"]; const browserLanguage = window.navigator.language.split("-")[0];
if (this.isLanguageSupported(browserLanguage)) {
console.log(`Using browser language: ${browserLanguage}`);
return browserLanguage;
}
// Default to English if no match is found
console.log("Using default language: en");
return "en";
}
private isLanguageSupported(lang: string): boolean {
return Object.prototype.hasOwnProperty.call(I18n, lang);
}
// Get the i18n configuration for the current language
public getConfig(): any {
return I18n[this.currentLanguage];
}
}
export const i18nManager = new I18nManager();
export const i18nConfig = i18nManager.getConfig();

View File

@@ -76,4 +76,8 @@ export const en = {
AddNewProperty: "Add New Property", AddNewProperty: "Add New Property",
AddNewPropertyDesc: "Add new property match with your notion database", AddNewPropertyDesc: "Add new property match with your notion database",
CopyErrorMessage: "Auto copy failed, please copy it manually", CopyErrorMessage: "Auto copy failed, please copy it manually",
BlockUploaded: "All blocks uploaded",
ExtraBlockUploaded: "Extra blocks uploaded",
CheckConsole: "Check the console for more information \n opt+cmd+i/ctrl+shift+i",
"reach-mobile-limit": "The number of blocks exceeds the limit of 100, please use the desktop plugin",
} }

View File

@@ -68,4 +68,7 @@ export const ja = {
AddNewProperty: "新しいプロパティを追加", AddNewProperty: "新しいプロパティを追加",
AddNewPropertyDesc: "新しいプロパティを追加してください", AddNewPropertyDesc: "新しいプロパティを追加してください",
CopyErrorMessage: "自動コピーに失敗しました", CopyErrorMessage: "自動コピーに失敗しました",
BlockUploaded: "ブロックがアップロードされました",
ExtraBlockUploaded: "追加ブロックがアップロードされました",
CheckConsole: "詳細情報を確認するには、コンソールを開いてください \n opt+cmd+i/ctrl+shift+i",
}; };

View File

@@ -71,4 +71,7 @@ export const zh = {
AddNewProperty: "添加新属性", AddNewProperty: "添加新属性",
AddNewPropertyDesc: "添加一个和Notion数据库匹配的新属性", AddNewPropertyDesc: "添加一个和Notion数据库匹配的新属性",
CopyErrorMessage: "复制链接失败,请手动复制", CopyErrorMessage: "复制链接失败,请手动复制",
BlockUploaded: "所有内容已成功上传",
ExtraBlockUploaded: "额外内容已成功上传",
CheckConsole: "opt+cmd+i/ctrl+shift+i\n打开控制台查看更多信息",
} }

View File

@@ -20,7 +20,7 @@ export default class ObsidianSyncNotionPlugin extends Plugin {
addIcons(); addIcons();
// This creates an icon in the left ribbon. // This creates an icon in the left ribbon.
const ribbonIconEl = this.addRibbonIcon( this.addRibbonIcon(
"notion-logo", "notion-logo",
i18nConfig.ribbonIcon, i18nConfig.ribbonIcon,
async (evt: MouseEvent) => { async (evt: MouseEvent) => {

View File

@@ -50,8 +50,10 @@ export async function uploadCommandNext(
const {response} = res; const {response} = res;
if (response.status === 200) { if (response.status === 200) {
new Notice(`${i18nConfig["sync-preffix"]} ${basename} ${i18nConfig["sync-success"]}`).noticeEl.style.color = "green"; new Notice(`${i18nConfig["sync-preffix"]} ${basename} ${i18nConfig["sync-success"]}`).noticeEl.style.color = "green";
console.log(`${i18nConfig["sync-preffix"]} ${basename} ${i18nConfig["sync-success"]}`);
} else { } else {
new Notice(`${i18nConfig["sync-fail"]} ${basename}`, 5000); new Notice(`${i18nConfig["sync-fail"]} ${basename}`, 5000);
console.log(`${i18nConfig["sync-fail"]} ${basename}`);
} }
} }
@@ -76,6 +78,9 @@ export async function uploadCommandGeneral(
const {markDownData, nowFile, cover, tags} = await getNowFileMarkdownContentGeneral(app, settings) const {markDownData, nowFile, cover, tags} = await getNowFileMarkdownContentGeneral(app, settings)
new Notice(`Start upload ${nowFile.basename}`);
console.log(`Start upload ${nowFile.basename}`);
if (markDownData) { if (markDownData) {
const {basename} = nowFile; const {basename} = nowFile;
@@ -85,8 +90,10 @@ export async function uploadCommandGeneral(
const {response} = res; const {response} = res;
if (response.status === 200) { if (response.status === 200) {
new Notice(`${i18nConfig["sync-preffix"]} ${basename} ${i18nConfig["sync-success"]}`).noticeEl.style.color = "green"; new Notice(`${i18nConfig["sync-preffix"]} ${basename} ${i18nConfig["sync-success"]}`).noticeEl.style.color = "green";
console.log(`${i18nConfig["sync-preffix"]} ${basename} ${i18nConfig["sync-success"]}`);
} else { } else {
new Notice(`${i18nConfig["sync-fail"]} ${basename}`, 5000); new Notice(`${i18nConfig["sync-fail"]} ${basename}`, 5000);
console.log(`${i18nConfig["sync-fail"]} ${basename}`);
} }
} }
@@ -111,6 +118,9 @@ export async function uploadCommandCustom(
const {markDownData, nowFile, cover, customValues} = await getNowFileMarkdownContentCustom(app, dbDetails) const {markDownData, nowFile, cover, customValues} = await getNowFileMarkdownContentCustom(app, dbDetails)
new Notice(`Start upload ${nowFile.basename}`);
console.log(`Start upload ${nowFile.basename}`);
if (markDownData) { if (markDownData) {
const {basename} = nowFile; const {basename} = nowFile;
@@ -118,10 +128,13 @@ export async function uploadCommandCustom(
const res = await upload.syncMarkdownToNotionCustom(cover, customValues, markDownData, nowFile, this.app); const res = await upload.syncMarkdownToNotionCustom(cover, customValues, markDownData, nowFile, this.app);
const {response} = res; const {response} = res;
if (response.status === 200) { if (response.status === 200) {
new Notice(`${i18nConfig["sync-preffix"]} ${basename} ${i18nConfig["sync-success"]}`).noticeEl.style.color = "green"; new Notice(`${i18nConfig["sync-preffix"]} ${basename} ${i18nConfig["sync-success"]}`).noticeEl.style.color = "green";
console.log(`${i18nConfig["sync-preffix"]} ${basename} ${i18nConfig["sync-success"]}`);
} else { } else {
new Notice(`${i18nConfig["sync-fail"]} ${basename}`, 5000); new Notice(`${i18nConfig["sync-fail"]} ${basename}`, 5000);
console.log(`${i18nConfig["sync-fail"]} ${basename}`);
} }
} }

View File

@@ -1,6 +1,6 @@
import { App, Notice, requestUrl, TFile } from "obsidian"; import { App, Notice, requestUrl, TFile } from "obsidian";
import { Client } from '@notionhq/client'; import { Client } from '@notionhq/client';
import { markdownToBlocks, } from "@tryfabric/martian"; import { markdownToBlocks, } from "@jxpeng98/martian";
import * as yamlFrontMatter from "yaml-front-matter"; import * as yamlFrontMatter from "yaml-front-matter";
// import * as yaml from "yaml" // import * as yaml from "yaml"
import MyPlugin from "src/main"; import MyPlugin from "src/main";

View File

@@ -1,13 +1,16 @@
import { App, Notice, TFile } from "obsidian"; import {App, Notice, TFile, requestUrl} from "obsidian";
import { Client } from "@notionhq/client"; import {markdownToBlocks} from "@jxpeng98/martian";
import { markdownToBlocks } from "@tryfabric/martian";
import * as yamlFrontMatter from "yaml-front-matter"; import * as yamlFrontMatter from "yaml-front-matter";
// import * as yaml from "yaml"
import MyPlugin from "src/main"; import MyPlugin from "src/main";
import {DatabaseDetails, PluginSettings} from "../../ui/settingTabs"; import {DatabaseDetails, PluginSettings} from "../../ui/settingTabs";
import {UploadBaseGeneral} from "./BaseUpload2NotionGeneral"; import {UploadBaseGeneral} from "./BaseUpload2NotionGeneral";
import {updateYamlInfo} from "../updateYaml"; import {updateYamlInfo} from "../updateYaml";
import fetch from 'node-fetch'; import {i18nConfig} from "../../lang/I18n";
interface CreatePageResponse {
response: any;
data: any;
}
export class Upload2NotionGeneral extends UploadBaseGeneral { export class Upload2NotionGeneral extends UploadBaseGeneral {
settings: PluginSettings; settings: PluginSettings;
@@ -47,7 +50,7 @@ export class Upload2NotionGeneral extends UploadBaseGeneral {
cover: string, cover: string,
tags: string[], tags: string[],
childArr: any, childArr: any,
) { ): Promise<CreatePageResponse> {
const { const {
databaseID, databaseID,
@@ -57,6 +60,41 @@ export class Upload2NotionGeneral extends UploadBaseGeneral {
notionAPI notionAPI
} = this.dbDetails; } = this.dbDetails;
// remove the annotations from the childArr if type is code block
childArr.forEach((block: any) => {
if (block.type === "code") {
block.code.rich_text.forEach((item: any) => {
if (item.type === "text" && item.annotations) {
delete item.annotations;
}
}
);
}
}
);
// check the length of the childArr and split it into chunks of 100
const childArrLength = childArr.length;
let extraArr: any[] = [];
let firstArr: any;
let pushCount = 0;
console.log(`Page includes ${childArrLength} blocks`)
if (childArrLength > 100) {
for (let i = 0; i < childArr.length; i += 100) {
if (i == 0) {
firstArr = childArr.slice(0, 100);
} else {
const chunk = childArr.slice(i, i + 100);
extraArr.push(chunk);
pushCount++;
}
}
} else {
firstArr = childArr;
}
const bodyString: any = { const bodyString: any = {
parent: { parent: {
database_id: databaseID, database_id: databaseID,
@@ -81,7 +119,7 @@ export class Upload2NotionGeneral extends UploadBaseGeneral {
} }
: {}), : {}),
}, },
children: childArr, children: firstArr,
}; };
if (cover) { if (cover) {
@@ -104,28 +142,74 @@ export class Upload2NotionGeneral extends UploadBaseGeneral {
console.log(bodyString) console.log(bodyString)
const response = await fetch("https://api.notion.com/v1/pages", { let response: any;
let data: any;
response = await requestUrl({
url: `https://api.notion.com/v1/pages`,
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Authorization": "Bearer " + notionAPI, // 'User-Agent': 'obsidian.md',
Authorization:
"Bearer " + notionAPI,
"Notion-Version": "2022-06-28", "Notion-Version": "2022-06-28",
}, },
body: JSON.stringify(bodyString), body: JSON.stringify(bodyString),
throw: false
}); });
const data: any = await response.json(); data = await response.json;
if (!response.ok) {
new Notice(`Error ${data.status}: ${data.code} \n Check the console for more information \n opt+cmd+i/ctrl+shift+i`, 5000); // console.log(data)
// console.log(response.status)
if (response.status !== 200) {
new Notice(`Error ${data.status}: ${data.code} \n ${i18nConfig["CheckConsole"]}`, 5000);
console.log(`Error message: \n ${data.message}`); console.log(`Error message: \n ${data.message}`);
} else { } else {
console.log(`Page created: ${data.url}`); console.log(`Page created: ${data.url}`);
console.log(`Page ID: ${data.id}`); console.log(`Page ID: ${data.id}`);
} }
//
// upload the rest of the blocks
if (pushCount > 0) {
for (let i = 0; i < pushCount; i++) {
const extraBlocks = {
children: extraArr[i],
};
console.log(extraBlocks)
const extraResponse = await requestUrl({
url: `https://api.notion.com/v1/blocks/${data.id}/children`,
method: "PATCH",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + notionAPI,
"Notion-Version": "2022-06-28",
},
body: JSON.stringify(extraBlocks),
});
const extraData: any = await extraResponse.json;
if (extraResponse.status !== 200) {
new Notice(`Error ${extraData.status}: ${extraData.code} \n ${i18nConfig["CheckConsole"]}`, 5000);
console.log(`Error message: \n ${extraData.message}`);
} else {
console.log(`${i18nConfig["ExtraBlockUploaded"]} to page: ${data.id}`);
if (i === pushCount - 1) {
console.log(`${i18nConfig["BlockUploaded"]} to page: ${data.id}`);
new Notice(`${i18nConfig["BlockUploaded"]} page: ${data.id}`, 5000);
}
}
}
}
return { return {
response, // for status code response,
data // for id and url data
} }
} }
@@ -146,11 +230,11 @@ export class Upload2NotionGeneral extends UploadBaseGeneral {
const yamlContent: any = yamlFrontMatter.loadFront(markdown); const yamlContent: any = yamlFrontMatter.loadFront(markdown);
const __content = yamlContent.__content; const __content = yamlContent.__content;
const file2Block = markdownToBlocks(__content, options); const file2Block = markdownToBlocks(__content, options);
const frontmasster = const frontMatter =
app.metadataCache.getFileCache(nowFile)?.frontmatter; app.metadataCache.getFileCache(nowFile)?.frontmatter;
const {abName} = this.dbDetails const {abName} = this.dbDetails
const notionIDKey = `NotionID-${abName}`; const notionIDKey = `NotionID-${abName}`;
const notionID = frontmasster ? frontmasster[notionIDKey] : null; const notionID = frontMatter ? frontMatter[notionIDKey] : null;
if (notionID) { if (notionID) {
@@ -170,7 +254,14 @@ export class Upload2NotionGeneral extends UploadBaseGeneral {
// console.log(response) // console.log(response)
if (response && response.status === 200) { if (response && response.status === 200) {
await updateYamlInfo(markdown, nowFile, data, app, this.plugin, this.dbDetails); await updateYamlInfo(
markdown,
nowFile,
data,
app,
this.plugin,
this.dbDetails,
);
} }
return res; return res;

View File

@@ -1,6 +1,6 @@
import { App, Notice, requestUrl, TFile } from "obsidian"; import { App, Notice, requestUrl, TFile } from "obsidian";
import { Client } from '@notionhq/client'; import { Client } from '@notionhq/client';
import { markdownToBlocks, } from "@tryfabric/martian"; import { markdownToBlocks, } from "@jxpeng98/martian";
import * as yamlFrontMatter from "yaml-front-matter"; import * as yamlFrontMatter from "yaml-front-matter";
// import * as yaml from "yaml" // import * as yaml from "yaml"
import MyPlugin from "src/main"; import MyPlugin from "src/main";

View File

@@ -1,22 +1,25 @@
import {UploadBaseNext} from "./BaseUpload2NotionNext"; import {UploadBaseNext} from "./BaseUpload2NotionNext";
import { App, Notice, TFile } from "obsidian"; import {App, Notice, TFile, requestUrl} from "obsidian";
import { Client } from '@notionhq/client'; import {markdownToBlocks} from "@jxpeng98/martian";
import { markdownToBlocks, } from "@tryfabric/martian";
import * as yamlFrontMatter from "yaml-front-matter"; import * as yamlFrontMatter from "yaml-front-matter";
// import * as yaml from "yaml"
import MyPlugin from "src/main"; import MyPlugin from "src/main";
import {DatabaseDetails, PluginSettings} from "../../ui/settingTabs"; import {DatabaseDetails, PluginSettings} from "../../ui/settingTabs";
import {updateYamlInfo} from "../updateYaml"; import {updateYamlInfo} from "../updateYaml";
import { LIMITS, paragraph } from "@tryfabric/martian/src/notion"; import {LIMITS, paragraph} from "@jxpeng98/martian/src/notion";
import fetch from 'node-fetch'; import {i18nConfig} from "../../lang/I18n";
interface CreatePageResponse {
response: any;
data: any;
}
export class Upload2NotionNext extends UploadBaseNext { export class Upload2NotionNext extends UploadBaseNext {
settings: PluginSettings; settings: PluginSettings;
dbDetails: DatabaseDetails dbDetails: DatabaseDetails;
constructor(plugin: MyPlugin, dbDetails: DatabaseDetails) { constructor(plugin: MyPlugin, dbDetails: DatabaseDetails) {
super(plugin, dbDetails); super(plugin, dbDetails);
this.dbDetails = dbDetails this.dbDetails = dbDetails;
} }
// 因为需要解析notion的block进行对比非常的麻烦 // 因为需要解析notion的block进行对比非常的麻烦
@@ -35,16 +38,16 @@ export class Upload2NotionNext extends UploadBaseNext {
paword: string, paword: string,
favicon: string, favicon: string,
datetime: string, datetime: string,
childArr: any childArr: any,
) { ) {
await this.deletePage(notionID) await this.deletePage(notionID);
const { databaseID } = this.dbDetails const {databaseID} = this.dbDetails;
const databaseCover = await this.getDataBase(databaseID) const databaseCover = await this.getDataBase(databaseID);
if (cover == null) { if (cover == null) {
cover = databaseCover cover = databaseCover;
} }
return await this.createPage( return await this.createPage(
@@ -60,7 +63,8 @@ export class Upload2NotionNext extends UploadBaseNext {
paword, paword,
favicon, favicon,
datetime, datetime,
childArr) childArr,
);
} }
async createPage( async createPage(
@@ -76,16 +80,47 @@ export class Upload2NotionNext extends UploadBaseNext {
pawrod: string, pawrod: string,
favicon: string, favicon: string,
datetime: string, datetime: string,
childArr: any childArr: any,
) { ): Promise<CreatePageResponse> {
const {databaseID, notionAPI} = this.dbDetails;
const { // remove the annotations from the childArr if type is code block
databaseID, childArr.forEach((block: any) => {
notionAPI if (block.type === "code") {
} = this.dbDetails block.code.rich_text.forEach((item: any) => {
if (item.type === "text" && item.annotations) {
delete item.annotations;
}
}
);
}
}
);
// check the length of the childArr
// if it is too long, split it into multiple pages
const childArrLength = childArr.length;
let extraArr: any[] = [];
let firstArr: any;
let pushCount = 0;
const bodyString: any = { console.log(`Page includes ${childArrLength} blocks`)
if (childArrLength > 100) {
for (let i = 0; i < childArr.length; i += 100) {
if (i == 0) {
firstArr = childArr.slice(0, 100);
} else {
const chunk = childArr.slice(i, i + 100);
extraArr.push(chunk);
pushCount++;
}
}
} else {
firstArr = childArr;
}
const pageProperties: any = {
parent: { parent: {
database_id: databaseID, database_id: databaseID,
}, },
@@ -94,144 +129,189 @@ export class Upload2NotionNext extends UploadBaseNext {
title: [ title: [
{ {
text: { text: {
content: title content: title,
}, },
}, },
], ],
}, },
type: { type: {
select: { select: {
name: type || 'Post' name: type || "Post",
} },
}, },
status: { status: {
select: { select: {
name: stats || 'Draft' name: stats || "Draft",
} },
}, },
category: { category: {
select: { select: {
name: category || 'Obsidian' name: category || "Obsidian",
} },
}, },
password: { password: {
rich_text: [ rich_text: [
{ {
text: { text: {
content: pawrod || '' content: pawrod || "",
} },
} },
] ],
}, },
icon: { icon: {
rich_text: [ rich_text: [
{ {
text: { text: {
content: favicon || '' content: favicon || "",
} },
} },
] ],
}, },
date: { date: {
date: { date: {
start: datetime || new Date().toISOString() start: datetime || new Date().toISOString(),
}
}
}, },
children: childArr, },
} },
};
// add tags // add tags
if (tags) { if (tags) {
bodyString.properties.tags = { pageProperties.properties.tags = {
multi_select: tags.map(tag => { multi_select: tags.map((tag) => {
return { "name": tag } return {name: tag};
}) }),
} };
} }
// add title icon // add title icon
if (emoji) { if (emoji) {
bodyString.icon = { pageProperties.icon = {
emoji: emoji emoji: emoji,
} };
} }
// add slug // add slug
if (slug) { if (slug) {
bodyString.properties.slug = { pageProperties.properties.slug = {
rich_text: [ rich_text: [
{ {
text: { text: {
content: slug content: slug,
} },
} },
] ],
} };
} }
// check if summary is available // check if summary is available
if (summary) { if (summary) {
bodyString.properties.summary = { pageProperties.properties.summary = {
rich_text: [ rich_text: [
{ {
text: { text: {
content: summary content: summary,
},
},
],
};
} }
}
]
}
}
if (cover) { if (cover) {
bodyString.cover = { pageProperties.cover = {
type: "external", type: "external",
external: { external: {
url: cover url: cover,
} },
} };
} }
if (!bodyString.cover && this.plugin.settings.bannerUrl) { if (!pageProperties.cover && this.plugin.settings.bannerUrl) {
bodyString.cover = { pageProperties.cover = {
type: "external", type: "external",
external: { external: {
url: this.plugin.settings.bannerUrl url: this.plugin.settings.bannerUrl,
} },
} };
} }
console.log(bodyString) const bodyString: any = {
...pageProperties,
children: firstArr,
};
const response = await fetch("https://api.notion.com/v1/pages", { console.log(bodyString);
let response: any;
let data: any;
response = await requestUrl({
url: `https://api.notion.com/v1/pages`,
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Authorization": "Bearer " + notionAPI, // 'User-Agent': 'obsidian.md',
Authorization:
"Bearer " + notionAPI,
"Notion-Version": "2022-06-28", "Notion-Version": "2022-06-28",
}, },
body: JSON.stringify(bodyString), body: JSON.stringify(bodyString),
throw: false
}); });
const data: any = await response.json(); data = await response.json;
// can use response.ok or response.status === 200 // console.log(data)
if (!response.ok) { // console.log(response.status)
new Notice(`Error ${data.status}: ${data.code} \n Check the console for more information \n opt+cmd+i/ctrl+shift+i`, 5000);
if (response.status !== 200) {
new Notice(`Error ${data.status}: ${data.code} \n ${i18nConfig["CheckConsole"]}`, 5000);
console.log(`Error message: \n ${data.message}`); console.log(`Error message: \n ${data.message}`);
} else { } else {
console.log(`Page created: ${data.url}`); console.log(`Page created: ${data.url}`);
console.log(`Page ID: ${data.id}`); console.log(`Page ID: ${data.id}`);
} }
//
// upload the rest of the blocks
if (pushCount > 0) {
for (let i = 0; i < pushCount; i++) {
const extraBlocks = {
children: extraArr[i],
};
console.log(extraBlocks)
const extraResponse = await requestUrl({
url: `https://api.notion.com/v1/blocks/${data.id}/children`,
method: "PATCH",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + notionAPI,
"Notion-Version": "2022-06-28",
},
body: JSON.stringify(extraBlocks),
});
const extraData: any = await extraResponse.json;
if (extraResponse.status !== 200) {
new Notice(`Error ${extraData.status}: ${extraData.code} \n ${i18nConfig["CheckConsole"]}`, 5000);
console.log(`Error message: \n ${extraData.message}`);
} else {
console.log(`${i18nConfig["ExtraBlockUploaded"]} to page: ${data.id}`);
if (i === pushCount - 1) {
console.log(`${i18nConfig["BlockUploaded"]} to page: ${data.id}`);
new Notice(`${i18nConfig["BlockUploaded"]} page: ${data.id}`, 5000);
}
}
}
}
return { return {
response, // for status code response,
data // for id and url data
} };
} }
async syncMarkdownToNotionNext( async syncMarkdownToNotionNext(
@@ -254,38 +334,36 @@ export class Upload2NotionNext extends UploadBaseNext {
const options = { const options = {
notionLimits: { notionLimits: {
truncate: false, truncate: false,
} },
} };
let res: any let res: any;
const yamlContent: any = yamlFrontMatter.loadFront(markdown); const yamlContent: any = yamlFrontMatter.loadFront(markdown);
const __content = yamlContent.__content const __content = yamlContent.__content;
const file2Block = markdownToBlocks(__content, options); const file2Block = markdownToBlocks(__content, options);
const frontmasster = app.metadataCache.getFileCache(nowFile)?.frontmatter const frontmatter =
const { abName } = this.dbDetails app.metadataCache.getFileCache(nowFile)?.frontmatter;
const {abName} = this.dbDetails;
const notionIDKey = `NotionID-${abName}`; const notionIDKey = `NotionID-${abName}`;
const notionID = frontmasster ? frontmasster[notionIDKey] : null; const notionID = frontmatter ? frontmatter[notionIDKey] : null;
// increase the limits // increase the limits
// Motivated by https://github.com/tryfabric/martian/issues/51 // Motivated by https://github.com/tryfabric/martian/issues/51
file2Block.forEach((block, index) => { file2Block.forEach((block, index) => {
if ( if (
block.type === 'paragraph' && block.type === "paragraph" &&
block.paragraph.rich_text.length > LIMITS.RICH_TEXT_ARRAYS block.paragraph.rich_text.length > LIMITS.RICH_TEXT_ARRAYS
) { ) {
const newParagraphBlocks: any[] = [];
const newParagraphBlocks: any[] = [] const chunk: any = [];
const chunk: any = [] const richTextChunks = chunk(block.paragraph.rich_text, 100);
const richTextChunks = chunk(block.paragraph.rich_text, 100)
richTextChunks.forEach((chunk: any) => { richTextChunks.forEach((chunk: any) => {
newParagraphBlocks.push(paragraph(chunk)) newParagraphBlocks.push(paragraph(chunk));
}) });
file2Block.splice(index, 1, ...newParagraphBlocks)
file2Block.splice(index, 1, ...newParagraphBlocks);
} }
}) });
if (notionID) { if (notionID) {
res = await this.updatePage( res = await this.updatePage(
@@ -302,7 +380,7 @@ export class Upload2NotionNext extends UploadBaseNext {
paword, paword,
favicon, favicon,
datetime, datetime,
file2Block file2Block,
); );
} else { } else {
res = await this.createPage( res = await this.createPage(
@@ -318,17 +396,25 @@ export class Upload2NotionNext extends UploadBaseNext {
paword, paword,
favicon, favicon,
datetime, datetime,
file2Block file2Block,
); );
} }
let {response, data} = res; let {response, data} = res;
// console.log(response)
if (response && response.status === 200) { if (response && response.status === 200) {
await updateYamlInfo(markdown, nowFile, data, app, this.plugin, this.dbDetails); await updateYamlInfo(
markdown,
nowFile,
data,
app,
this.plugin,
this.dbDetails,
);
} }
return res; return res;
} }
} }

View File

@@ -1,6 +1,6 @@
import { App, Notice, requestUrl, TFile } from "obsidian"; import { App, Notice, requestUrl, TFile } from "obsidian";
import { Client } from '@notionhq/client'; import { Client } from '@notionhq/client';
import { markdownToBlocks, } from "@tryfabric/martian"; import { markdownToBlocks, } from "@jxpeng98/martian";
import * as yamlFrontMatter from "yaml-front-matter"; import * as yamlFrontMatter from "yaml-front-matter";
// import * as yaml from "yaml" // import * as yaml from "yaml"
import MyPlugin from "src/main"; import MyPlugin from "src/main";

View File

@@ -1,14 +1,18 @@
import {App, Notice, TFile} from "obsidian"; import {App, Notice, TFile, requestUrl} from "obsidian";
import {markdownToBlocks} from "@tryfabric/martian"; import {markdownToBlocks} from "@jxpeng98/martian";
import * as yamlFrontMatter from "yaml-front-matter"; import * as yamlFrontMatter from "yaml-front-matter";
// import * as yaml from "yaml"
import MyPlugin from "src/main"; import MyPlugin from "src/main";
import {DatabaseDetails, PluginSettings} from "../../ui/settingTabs"; import {DatabaseDetails, PluginSettings} from "../../ui/settingTabs";
import {updateYamlInfo} from "../updateYaml"; import {updateYamlInfo} from "../updateYaml";
import {UploadBaseCustom} from "./BaseUpload2NotionCustom"; import {UploadBaseCustom} from "./BaseUpload2NotionCustom";
import fetch from 'node-fetch'; import {i18nConfig} from "../../lang/I18n";
interface CreatePageResponse {
response: any;
data: any;
}
export class Upload2NotionCustom extends UploadBaseCustom { export class Upload2NotionCustom extends UploadBaseCustom {
settings: PluginSettings; settings: PluginSettings;
dbDetails: DatabaseDetails; dbDetails: DatabaseDetails;
@@ -45,7 +49,7 @@ export class Upload2NotionCustom extends UploadBaseCustom {
cover: string, cover: string,
customValues: Record<string, string>, customValues: Record<string, string>,
childArr: any, childArr: any,
) { ): Promise<CreatePageResponse> {
const { const {
databaseID, databaseID,
@@ -53,7 +57,42 @@ export class Upload2NotionCustom extends UploadBaseCustom {
notionAPI notionAPI
} = this.dbDetails; } = this.dbDetails;
const bodyString: any = this.buildBodyString(customProperties, customValues, childArr); // remove the annotations from the childArr if type is code block
childArr.forEach((block: any) => {
if (block.type === "code") {
block.code.rich_text.forEach((item: any) => {
if (item.type === "text" && item.annotations) {
delete item.annotations;
}
}
);
}
}
);
// check the length of the childArr and split it into chunks of 100
const childArrLength = childArr.length;
let extraArr: any[] = [];
let firstArr: any;
let pushCount = 0;
console.log(`Page includes ${childArrLength} blocks`)
if (childArrLength > 100) {
for (let i = 0; i < childArr.length; i += 100) {
if (i == 0) {
firstArr = childArr.slice(0, 100);
} else {
const chunk = childArr.slice(i, i + 100);
extraArr.push(chunk);
pushCount++;
}
}
} else {
firstArr = childArr;
}
const bodyString: any = this.buildBodyString(customProperties, customValues, firstArr);
if (cover) { if (cover) {
bodyString.cover = { bodyString.cover = {
@@ -75,23 +114,69 @@ export class Upload2NotionCustom extends UploadBaseCustom {
console.log(bodyString) console.log(bodyString)
const response = await fetch("https://api.notion.com/v1/pages", { let response: any;
let data: any;
response = await requestUrl({
url: `https://api.notion.com/v1/pages`,
method: "POST", method: "POST",
headers: {
"Content-Type": "application/json",
// 'User-Agent': 'obsidian.md',
Authorization:
"Bearer " + notionAPI,
"Notion-Version": "2022-06-28",
},
body: JSON.stringify(bodyString),
throw: false
});
data = await response.json;
// console.log(data)
// console.log(response.status)
if (response.status !== 200) {
new Notice(`Error ${data.status}: ${data.code} \n ${i18nConfig["CheckConsole"]}`, 5000);
console.log(`Error message: \n ${data.message}`);
} else {
console.log(`Page created: ${data.url}`);
console.log(`Page ID: ${data.id}`);
}
//
// upload the rest of the blocks
if (pushCount > 0) {
for (let i = 0; i < pushCount; i++) {
const extraBlocks = {
children: extraArr[i],
};
console.log(extraBlocks)
const extraResponse = await requestUrl({
url: `https://api.notion.com/v1/blocks/${data.id}/children`,
method: "PATCH",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Authorization": "Bearer " + notionAPI, "Authorization": "Bearer " + notionAPI,
"Notion-Version": "2022-06-28", "Notion-Version": "2022-06-28",
}, },
body: JSON.stringify(bodyString), body: JSON.stringify(extraBlocks),
}); });
const data: any = await response.json(); const extraData: any = await extraResponse.json;
if (!response.ok) {
new Notice(`Error ${data.status}: ${data.code} \n Check the console for more information \n opt+cmd+i/ctrl+shift+i`, 5000); if (extraResponse.status !== 200) {
console.log(`Error message: \n ${data.message}`); new Notice(`Error ${extraData.status}: ${extraData.code} \n ${i18nConfig["CheckConsole"]}`, 5000);
console.log(`Error message: \n ${extraData.message}`);
} else { } else {
console.log(`Page created: ${data.url}`); console.log(`${i18nConfig["ExtraBlockUploaded"]} to page: ${data.id}`);
console.log(`Page ID: ${data.id}`); if (i === pushCount - 1) {
console.log(`${i18nConfig["BlockUploaded"]} to page: ${data.id}`);
new Notice(`${i18nConfig["BlockUploaded"]} page: ${data.id}`, 5000);
}
}
}
} }
return { return {
@@ -117,11 +202,11 @@ export class Upload2NotionCustom extends UploadBaseCustom {
const yamlContent: any = yamlFrontMatter.loadFront(markdown); const yamlContent: any = yamlFrontMatter.loadFront(markdown);
const __content = yamlContent.__content; const __content = yamlContent.__content;
const file2Block = markdownToBlocks(__content, options); const file2Block = markdownToBlocks(__content, options);
const frontmasster = const frontMatter =
app.metadataCache.getFileCache(nowFile)?.frontmatter; app.metadataCache.getFileCache(nowFile)?.frontmatter;
const {abName} = this.dbDetails const {abName} = this.dbDetails
const notionIDKey = `NotionID-${abName}`; const notionIDKey = `NotionID-${abName}`;
const notionID = frontmasster ? frontmasster[notionIDKey] : null; const notionID = frontMatter ? frontMatter[notionIDKey] : null;
if (notionID) { if (notionID) {
res = await this.updatePage( res = await this.updatePage(
@@ -139,7 +224,14 @@ export class Upload2NotionCustom extends UploadBaseCustom {
// console.log(response) // console.log(response)
if (response && response.status === 200) { if (response && response.status === 200) {
await updateYamlInfo(markdown, nowFile, data, app, this.plugin, this.dbDetails); await updateYamlInfo(
markdown,
nowFile,
data,
app,
this.plugin,
this.dbDetails,
);
} }
return res; return res;

View File

@@ -35,7 +35,10 @@ export async function getNowFileMarkdownContentCustom(
// If a 'title' type property exists, use the file's basename as its value // If a 'title' type property exists, use the file's basename as its value
if (titleProperty) { if (titleProperty) {
customValues[titleProperty.customName] = nowFile.basename; // Use 'basename' for the file name without extension customValues[titleProperty.customName] =
(FileCache.frontmatter && FileCache.frontmatter[titleProperty.customName]) ?
FileCache.frontmatter[titleProperty.customName] : // use the front matter value if it exists
nowFile.basename; // Use 'basename' for the file name without extension
} }
} catch (error) { } catch (error) {

View File

@@ -124,6 +124,17 @@
resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.0.tgz#b0ffd0312b4a3fd2d6f77237e7248a5ad3a680ae" resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.0.tgz#b0ffd0312b4a3fd2d6f77237e7248a5ad3a680ae"
integrity sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A== integrity sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==
"@jxpeng98/martian@^1.2.7":
version "1.2.7"
resolved "https://registry.yarnpkg.com/@jxpeng98/martian/-/martian-1.2.7.tgz#43c8e5403064eb0bae1afe44d0c369ecdd1b4888"
integrity sha512-SeGqHRUeDkCP9SEJt5sddXit+VVoGQhx/U1ePiqcww6dbK0gnv2CiDzfgtRkBFW8zoCBzkq50m/UBS0xz/VGig==
dependencies:
"@notionhq/client" "^1.0.4"
remark-gfm "^1.0.0"
remark-math "^4.0.0"
remark-parse "^9.0.0"
unified "^9.2.1"
"@nodelib/fs.scandir@2.1.5": "@nodelib/fs.scandir@2.1.5":
version "2.1.5" version "2.1.5"
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
@@ -153,17 +164,6 @@
"@types/node-fetch" "^2.5.10" "@types/node-fetch" "^2.5.10"
node-fetch "^2.6.1" node-fetch "^2.6.1"
"@tryfabric/martian@^1.2.4":
version "1.2.4"
resolved "https://registry.yarnpkg.com/@tryfabric/martian/-/martian-1.2.4.tgz#3fdfe7129f1c28bccddc34854cf353b0f37c0c02"
integrity sha512-g7SP7beaxrjxLnW//vskra07a1jsJowqp07KMouxh4gCwaF+ItHbRZN8O+1dhJivBi3VdasT71BPyk+8wzEreQ==
dependencies:
"@notionhq/client" "^1.0.4"
remark-gfm "^1.0.0"
remark-math "^4.0.0"
remark-parse "^9.0.0"
unified "^9.2.1"
"@types/codemirror@5.60.8": "@types/codemirror@5.60.8":
version "5.60.8" version "5.60.8"
resolved "https://registry.yarnpkg.com/@types/codemirror/-/codemirror-5.60.8.tgz#b647d04b470e8e1836dd84b2879988fc55c9de68" resolved "https://registry.yarnpkg.com/@types/codemirror/-/codemirror-5.60.8.tgz#b647d04b470e8e1836dd84b2879988fc55c9de68"
@@ -460,6 +460,13 @@ commander@^8.3.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66"
integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==
cross-fetch@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-4.0.0.tgz#f037aef1580bb3a1a35164ea2a848ba81b445983"
integrity sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==
dependencies:
node-fetch "^2.6.12"
data-uri-to-buffer@^4.0.0: data-uri-to-buffer@^4.0.0:
version "4.0.1" version "4.0.1"
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz#d8feb2b2881e6a4f58c2e08acfd0e2834e26222e" resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz#d8feb2b2881e6a4f58c2e08acfd0e2834e26222e"
@@ -1199,7 +1206,7 @@ node-domexception@^1.0.0:
resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5"
integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==
node-fetch@^2.6.1: node-fetch@^2.6.1, node-fetch@^2.6.12:
version "2.7.0" version "2.7.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d"
integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==
@@ -1245,11 +1252,6 @@ picomatch@^2.3.1:
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
process@^0.11.10:
version "0.11.10"
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==
queue-microtask@^1.2.2: queue-microtask@^1.2.2:
version "1.2.3" version "1.2.3"
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"