diff --git a/README.md b/README.md index 565a9b4e..ff96c353 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,7 @@ This plugin supports almost all devices and platforms of Siyuan Note, and the sp Names not listed in order - [X] Yuque +- [ ] Web authed of Yuque - [X] Metaweblog - [X] Cnblogs - [X] Typecho @@ -75,6 +76,8 @@ Names not listed in order - [ ] Github - [ ] Hexo - [ ] Hugo +- [X] Notion +- [ ] Web authed of Notion ## Core Features diff --git a/README_zh_CN.md b/README_zh_CN.md index 74736324..be94eabc 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -66,6 +66,7 @@ 排名不分先后 - [X] 语雀 +- [ ] 语雀网页授权版 - [X] 博客园 - [X] Metaweblog - [X] Typecho @@ -73,6 +74,8 @@ - [ ] Github - [ ] Hexo - [ ] Hugo +- [X] Notion +- [ ] Notion 网页授权版 ## 核心特色 diff --git a/package.json b/package.json index 3dde6dea..a9b9cc3e 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "devDependencies": { "@terwer/esbuild-config-custom": "^1.0.12", "@terwer/eslint-config-custom": "^1.3.6", - "@types/node": "^18.17.1", + "@types/node": "^18.17.2", "@vitejs/plugin-vue": "^4.2.3", "esbuild-plugin-copy": "^2.1.1", "esbuild-style-plugin": "^1.6.2", @@ -46,11 +46,10 @@ }, "dependencies": { "@element-plus/icons-vue": "^2.1.0", - "@notionhq/client": "^2.2.10", "@vueuse/components": "^10.3.0", "@vueuse/core": "^10.3.0", "cross-fetch": "^3.1.8", - "element-plus": "^2.3.8", + "element-plus": "^2.3.9", "js-base64": "^3.7.5", "pinia": "^2.1.6", "shorthash2": "^1.0.3", @@ -61,13 +60,13 @@ "vue-i18n": "^9.2.2", "vue-router": "^4.2.4", "xmlbuilder2": "^3.1.1", - "zhi-blog-api": "^1.20.4", + "zhi-blog-api": "^1.20.8", "zhi-common": "^1.11.7", "zhi-device": "^2.3.0", "zhi-fetch-middleware": "^0.2.7", "zhi-github-middleware": "^0.1.4", "zhi-lib-base": "^0.4.3", - "zhi-siyuan-api": "^1.29.4", + "zhi-siyuan-api": "^1.29.9", "zhi-xmlrpc-middleware": "^0.4.2" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6486b197..cb35ee80 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,9 +8,6 @@ dependencies: '@element-plus/icons-vue': specifier: ^2.1.0 version: 2.1.0(vue@3.3.4) - '@notionhq/client': - specifier: ^2.2.10 - version: 2.2.10 '@vueuse/components': specifier: ^10.3.0 version: 10.3.0(vue@3.3.4) @@ -21,8 +18,8 @@ dependencies: specifier: ^3.1.8 version: 3.1.8 element-plus: - specifier: ^2.3.8 - version: 2.3.8(vue@3.3.4) + specifier: ^2.3.9 + version: 2.3.9(vue@3.3.4) js-base64: specifier: ^3.7.5 version: 3.7.5 @@ -54,8 +51,8 @@ dependencies: specifier: ^3.1.1 version: 3.1.1 zhi-blog-api: - specifier: ^1.20.4 - version: 1.20.4 + specifier: ^1.20.8 + version: 1.20.8 zhi-common: specifier: ^1.11.7 version: 1.11.7 @@ -72,8 +69,8 @@ dependencies: specifier: ^0.4.3 version: 0.4.3 zhi-siyuan-api: - specifier: ^1.29.4 - version: 1.29.4 + specifier: ^1.29.9 + version: 1.29.9 zhi-xmlrpc-middleware: specifier: ^0.4.2 version: 0.4.2 @@ -86,8 +83,8 @@ devDependencies: specifier: ^1.3.6 version: 1.3.6(@nuxt/eslint-config@0.1.1)(@typescript-eslint/eslint-plugin@5.62.0)(astro-eslint-parser@0.13.3)(eslint-config-prettier@8.10.0)(eslint-config-turbo@1.10.12)(eslint-plugin-prettier@4.2.1)(eslint-plugin-svelte@2.32.4)(eslint-plugin-vue@9.16.1)(eslint@8.46.0)(prettier-plugin-svelte@2.10.1)(prettier@2.8.8)(typescript@5.1.6) '@types/node': - specifier: ^18.17.1 - version: 18.17.1 + specifier: ^18.17.2 + version: 18.17.2 '@vitejs/plugin-vue': specifier: ^4.2.3 version: 4.2.3(vite@4.4.8)(vue@3.3.4) @@ -123,7 +120,7 @@ devDependencies: version: 31.2.2 vite: specifier: ^4.4.8 - version: 4.4.8(@types/node@18.17.1)(stylus@0.59.0) + version: 4.4.8(@types/node@18.17.2)(stylus@0.59.0) vite-plugin-html: specifier: ^3.2.0 version: 3.2.0(vite@4.4.8) @@ -160,8 +157,8 @@ packages: resolution: {integrity: sha512-dlR6LdS+0SzOAPx/TPRhnoi7hE251OVeT2Snw0RguNbBSbjUHdWr0l3vcUUDg26rEysT89kCbtw1lVorBXLLCg==} dev: true - /@astrojs/compiler@1.8.0: - resolution: {integrity: sha512-E0TI/uyO8n+IPSZ4Fvl9Lne8JKEasR6ZMGvE2G096oTWOXSsPAhRs2LomV3z+/VRepo2h+t/SdVo54wox4eJwA==} + /@astrojs/compiler@1.8.1: + resolution: {integrity: sha512-C28qplQzgIJ+JU9S+1wNx+ue2KCBUp0TTAd10EWAEkk4RsL3Tzlw0BYvLDDb4KP9jS48lXmR4/1TtZ4aavYJ8Q==} dev: true /@babel/helper-string-parser@7.22.5: @@ -879,16 +876,6 @@ packages: fastq: 1.15.0 dev: true - /@notionhq/client@2.2.10: - resolution: {integrity: sha512-MggdzjB320UI2fUFR5XmUBbRBaqNr3QCBHQyK2CqbiO2T29p8RzzQBm5c7RJqvFhi7P0MaLjuY1CI8ypGEYssg==} - engines: {node: '>=12'} - dependencies: - '@types/node-fetch': 2.6.4 - node-fetch: 2.6.12 - transitivePeerDependencies: - - encoding - dev: false - /@nuxt/eslint-config@0.1.1(eslint@8.46.0): resolution: {integrity: sha512-znm1xlbhldUubB2XGx6Ca5uarwlIieKf0o8CtxtF6eEauDbpa3T2p3JnTcdguMW2nj1YPneoGmhshANfOlghiQ==} peerDependencies: @@ -1195,23 +1182,17 @@ packages: /@types/node-fetch@2.6.3: resolution: {integrity: sha512-ETTL1mOEdq/sxUtgtOhKjyB2Irra4cjxksvcMUR5Zr4n+PxVhsCD9WS46oPbHL3et9Zde7CNRr+WUNlcHvsX+w==} dependencies: - '@types/node': 18.17.1 + '@types/node': 18.17.2 form-data: 3.0.1 dev: true - /@types/node-fetch@2.6.4: - resolution: {integrity: sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==} - dependencies: - '@types/node': 18.17.1 - form-data: 3.0.1 - dev: false - /@types/node@14.18.33: resolution: {integrity: sha512-qelS/Ra6sacc4loe/3MSjXNL1dNQ/GjxNHVzuChwMfmk7HuycRLVQN2qNY3XahK+fZc5E2szqQSKUyAF0E+2bg==} dev: true - /@types/node@18.17.1: - resolution: {integrity: sha512-xlR1jahfizdplZYRU59JlUx9uzF1ARa8jbhM11ccpCJya8kvos5jwdm2ZAgxSCwOl0fq21svP18EVwPBXMQudw==} + /@types/node@18.17.2: + resolution: {integrity: sha512-wBo3KqP/PBqje5TI9UTiuL3yWfP6sdPtjtygSOqcYZWT232dfDeDOnkDps5wqZBP9NgGgYrNejinl0faAuE+HQ==} + dev: true /@types/sass@1.45.0: resolution: {integrity: sha512-jn7qwGFmJHwUSphV8zZneO3GmtlgLsmhs/LQyVvQbIIa+fzGMUiHI4HXJZL3FT8MJmgXWbLGiVVY7ElvHq6vDA==} @@ -1227,7 +1208,7 @@ packages: /@types/stylus@0.48.38: resolution: {integrity: sha512-B5otJekvD6XM8iTrnO6e2twoTY2tKL9VkL/57/2Lo4tv3EatbCaufdi68VVtn/h4yjO+HVvYEyrNQd0Lzj6riw==} dependencies: - '@types/node': 18.17.1 + '@types/node': 18.17.2 dev: true /@types/web-bluetooth@0.0.16: @@ -1634,7 +1615,7 @@ packages: vite: ^4.0.0 vue: ^3.2.25 dependencies: - vite: 4.4.8(@types/node@18.17.1)(stylus@0.59.0) + vite: 4.4.8(@types/node@18.17.2)(stylus@0.59.0) vue: 3.3.4 dev: true @@ -2009,10 +1990,10 @@ packages: resolution: {integrity: sha512-n+fb6O40SM6sD36lGwgVIE3zeVQUMdl6ZHaHEjRI4zdaBu658XaAV1YDztF7Iga5kmeOxJYB87mcQ+lUnQs0Nw==} engines: {node: ^14.18.0 || >=16.0.0} dependencies: - '@astrojs/compiler': 1.8.0 + '@astrojs/compiler': 1.8.1 '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 - astrojs-compiler-sync: 0.3.3(@astrojs/compiler@1.8.0) + astrojs-compiler-sync: 0.3.3(@astrojs/compiler@1.8.1) debug: 4.3.4 eslint-visitor-keys: 3.4.2 espree: 9.6.1 @@ -2021,13 +2002,13 @@ packages: - supports-color dev: true - /astrojs-compiler-sync@0.3.3(@astrojs/compiler@1.8.0): + /astrojs-compiler-sync@0.3.3(@astrojs/compiler@1.8.1): resolution: {integrity: sha512-LbhchWgsvjvRBb5n5ez8/Q/f9ZKViuox27VxMDOdTUm8MRv9U7phzOiLue5KluqTmC0z1LId4gY2SekvoDrkuw==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: '@astrojs/compiler': '>=0.27.0' dependencies: - '@astrojs/compiler': 1.8.0 + '@astrojs/compiler': 1.8.1 synckit: 0.8.5 dev: true @@ -2050,6 +2031,7 @@ packages: /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: true /available-typed-arrays@1.0.5: resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} @@ -2356,6 +2338,7 @@ packages: engines: {node: '>= 0.8'} dependencies: delayed-stream: 1.0.0 + dev: true /commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -2568,6 +2551,7 @@ packages: /delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} + dev: true /delegates@1.0.0: resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} @@ -2708,8 +2692,8 @@ packages: jake: 10.8.7 dev: true - /element-plus@2.3.8(vue@3.3.4): - resolution: {integrity: sha512-yHQR0/tG2LvPkpGUt7Te/hPmP2XW/BytBNUbx+EFO54VnGCOE3upmQcVffNp1PLgwg9sthYDXontUWpnpmLPJw==} + /element-plus@2.3.9(vue@3.3.4): + resolution: {integrity: sha512-TIOLnPl4cnoCPXqK3QYh+jpkthUBQnAM21O7o3Lhbse8v9pfrRXRTaBJtoEKnYNa8GZ4lZptUfH0PeZgDCNLUg==} peerDependencies: vue: ^3.2.0 dependencies: @@ -3685,6 +3669,7 @@ packages: asynckit: 0.4.0 combined-stream: 1.0.8 mime-types: 2.1.35 + dev: true /fs-extra@10.1.0: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} @@ -4409,12 +4394,14 @@ packages: /mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} + dev: true /mime-types@2.1.35: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} dependencies: mime-db: 1.52.0 + dev: true /mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} @@ -5236,8 +5223,8 @@ packages: fsevents: 2.3.2 dev: true - /rollup@3.27.1: - resolution: {integrity: sha512-tXNDFwOkN6C2w5Blj1g6ForKeFw6c1mDu5jxoeDO3/pmYjgt+8yvIFjKzH5FQUq70OKZBkOt0zzv0THXL7vwzQ==} + /rollup@3.27.2: + resolution: {integrity: sha512-YGwmHf7h2oUHkVBT248x0yt6vZkYQ3/rvE5iQuVBh3WO8GcJ6BNeOkpoX1yMHIiBm18EMLjBPIoUDkhgnyxGOQ==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} hasBin: true optionalDependencies: @@ -5982,7 +5969,7 @@ packages: - supports-color dev: true - /vite-node@0.34.1(@types/node@18.17.1)(stylus@0.59.0): + /vite-node@0.34.1(@types/node@18.17.2)(stylus@0.59.0): resolution: {integrity: sha512-odAZAL9xFMuAg8aWd7nSPT+hU8u2r9gU3LRm9QKjxBEF2rRdWpMuqkrkjvyVQEdNFiBctqr2Gg4uJYizm5Le6w==} engines: {node: '>=v14.18.0'} hasBin: true @@ -5992,7 +5979,7 @@ packages: mlly: 1.4.0 pathe: 1.1.1 picocolors: 1.0.0 - vite: 4.4.8(@types/node@18.17.1)(stylus@0.59.0) + vite: 4.4.8(@types/node@18.17.2)(stylus@0.59.0) transitivePeerDependencies: - '@types/node' - less @@ -6021,7 +6008,7 @@ packages: html-minifier-terser: 6.1.0 node-html-parser: 5.4.2 pathe: 0.2.0 - vite: 4.4.8(@types/node@18.17.1)(stylus@0.59.0) + vite: 4.4.8(@types/node@18.17.2)(stylus@0.59.0) dev: true /vite-plugin-node-polyfills@0.8.2(vite@4.4.8): @@ -6031,12 +6018,12 @@ packages: dependencies: '@rollup/plugin-inject': 5.0.3 node-stdlib-browser: 1.2.0 - vite: 4.4.8(@types/node@18.17.1)(stylus@0.59.0) + vite: 4.4.8(@types/node@18.17.2)(stylus@0.59.0) transitivePeerDependencies: - rollup dev: true - /vite@4.4.8(@types/node@18.17.1)(stylus@0.59.0): + /vite@4.4.8(@types/node@18.17.2)(stylus@0.59.0): resolution: {integrity: sha512-LONawOUUjxQridNWGQlNizfKH89qPigK36XhMI7COMGztz8KNY0JHim7/xDd71CZwGT4HtSRgI7Hy+RlhG0Gvg==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true @@ -6064,10 +6051,10 @@ packages: terser: optional: true dependencies: - '@types/node': 18.17.1 + '@types/node': 18.17.2 esbuild: 0.18.17 postcss: 8.4.27 - rollup: 3.27.1 + rollup: 3.27.2 stylus: 0.59.0 optionalDependencies: fsevents: 2.3.2 @@ -6106,7 +6093,7 @@ packages: dependencies: '@types/chai': 4.3.5 '@types/chai-subset': 1.3.3 - '@types/node': 18.17.1 + '@types/node': 18.17.2 '@vitest/expect': 0.34.1 '@vitest/runner': 0.34.1 '@vitest/snapshot': 0.34.1 @@ -6125,8 +6112,8 @@ packages: strip-literal: 1.3.0 tinybench: 2.5.0 tinypool: 0.7.0 - vite: 4.4.8(@types/node@18.17.1)(stylus@0.59.0) - vite-node: 0.34.1(@types/node@18.17.1)(stylus@0.59.0) + vite: 4.4.8(@types/node@18.17.2)(stylus@0.59.0) + vite-node: 0.34.1(@types/node@18.17.2)(stylus@0.59.0) why-is-node-running: 2.2.2 transitivePeerDependencies: - less @@ -6370,8 +6357,8 @@ packages: engines: {node: '>=12.20'} dev: true - /zhi-blog-api@1.20.4: - resolution: {integrity: sha512-DXGP+XPbFIIC00dCyJ4vadGWZbhTvi0udbX1NSZSQyuCyhpHnPGxqdTtbQ530RlVtaKqwiERgTJSsPeqaSP7Ww==} + /zhi-blog-api@1.20.8: + resolution: {integrity: sha512-dUcvdEbr2matntqvQFECT0xQxRwPU9RAExxMu6qDQgmzFucv4VsKY9FKEqsDO+0dp74AcJUjwjyTq8Rhd+Klnw==} dependencies: zhi-lib-base: 0.4.3 dev: false @@ -6407,10 +6394,10 @@ packages: resolution: {integrity: sha512-jahOcJ4MjJ9gAPM/nwgF65p2dPyggRgKFJPT0WDtyoabQw4sCUSOJ1Cps18Rq6lt4agH5yqAObz/mPdVz/bHWw==} dev: false - /zhi-siyuan-api@1.29.4: - resolution: {integrity: sha512-tQ8ZoIAlK5oSfddo7phP+uDmHRgnqiwYRyAWGHe48nIQpp1sPFOvcx8D9XkO2j8oWAcN58fv4ZNqtVY/EwyXiw==} + /zhi-siyuan-api@1.29.9: + resolution: {integrity: sha512-PoGLbjNDTvjqmh6x3A4FsbU2jCbEe3ilfPtMFmY6RymSryOEBaSuPlmoLwyaNbFw71zWPrkcORjD/kBOKcd17g==} dependencies: - zhi-blog-api: 1.20.4 + zhi-blog-api: 1.20.8 zhi-common: 1.11.7 zhi-lib-base: 0.4.3 dev: false diff --git a/src/adaptors/api/base/baseBlogApi.ts b/src/adaptors/api/base/baseBlogApi.ts new file mode 100644 index 00000000..2f211275 --- /dev/null +++ b/src/adaptors/api/base/baseBlogApi.ts @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2023, Terwer . All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Terwer designates this + * particular file as subject to the "Classpath" exception as provided + * by Terwer in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Terwer, Shenzhen, Guangdong, China, youweics@163.com + * or visit www.terwer.space if you need additional information or have any + * questions. + */ +import { BlogApi, BlogConfig } from "zhi-blog-api" +import { SiyuanKernelApi } from "zhi-siyuan-api" +import { CommonFetchClient } from "zhi-fetch-middleware" +import { AppInstance } from "~/src/appInstance.ts" +import { createAppLogger } from "~/src/utils/appLogger.ts" +import { useSiyuanApi } from "~/src/composables/useSiyuanApi.ts" +import { useSiyuanDevice } from "~/src/composables/useSiyuanDevice.ts" +import { JsonUtil } from "zhi-common" + +/** + * API授权统一封装基类 + * + * @author terwer + * @version 0.9.0 + * @since 0.9.0 + */ +export class BaseBlogApi extends BlogApi { + protected logger + protected cfg: BlogConfig + private readonly kernelApi: SiyuanKernelApi + private readonly commonFetchClient: CommonFetchClient + private isInChromeExtension + private isInSiyuanWidget + private isStorageViaSiyuanApi + + /** + * 初始化API授权适配器 + * + * @param appInstance 应用实例 + * @param cfg 配置项 + */ + constructor(appInstance: AppInstance, cfg: BlogConfig) { + super() + + this.cfg = cfg + this.logger = createAppLogger("base-blog-api") + const { kernelApi, isStorageViaSiyuanApi } = useSiyuanApi() + const { isInChromeExtension, isInSiyuanWidget } = useSiyuanDevice() + this.kernelApi = kernelApi + this.commonFetchClient = new CommonFetchClient(appInstance) + this.isInChromeExtension = isInChromeExtension() + this.isInSiyuanWidget = isInSiyuanWidget() + this.isStorageViaSiyuanApi = isStorageViaSiyuanApi() + } + + // ================ + // private methods + // ================ + /** + * 网页授权通用的请求代理 + * + * @param url - url + * @param headers - headers + * @param params - 参数 + * @param method - method + @param contentType - + * @param contentType - + */ + protected async proxyFetch( + url: string, + headers: any[], + params: any = {}, + method: "GET" | "POST" = "GET", + contentType: string = "application/json" + ): Promise { + if (this.isInChromeExtension) { + this.logger.info("using chrome background") + const fetchOptions = { + method: method, + headers: headers, + body: params, + } + this.logger.info("commonFetchClient from proxyFetch url =>", url) + this.logger.info("commonFetchClient from proxyFetch fetchOptions =>", fetchOptions) + const res = await this.commonFetchClient.fetchCall(url, fetchOptions) + this.logger.debug("commonFetchClient res from proxyFetch =>", res) + return res + } else if (this.isInSiyuanWidget) { + this.logger.info("using siyuan electron api") + const apiUrl = `${this.cfg.apiUrl}${url}` + let header = {} + if (headers.length > 0) { + header = headers[0] + } + const fetchOptions = { + method: method, + headers: header, + body: params, + } + this.logger.info("commonFetchClient from electron url =>", apiUrl) + this.logger.info("commonFetchClient from electron fetchOptions =>", fetchOptions) + const res = await this.commonFetchClient.fetchCall(apiUrl, fetchOptions) + this.logger.debug("commonFetchClient res from electron =>", res) + return res + } else if (this.isStorageViaSiyuanApi) { + this.logger.info("using siyuan forwardProxy") + const apiUrl = `${this.cfg.apiUrl}${url}` + this.logger.info("commonFetchClient from forwardProxy url =>", apiUrl) + this.logger.info("commonFetchClient from forwardProxy fetchOptions =>", { + headers, + params, + method, + contentType, + }) + const fetchResult = await this.kernelApi.forwardProxy(apiUrl, headers, params, method, contentType, 7000) + this.logger.debug("proxyFetch result=>", fetchResult) + const resText = fetchResult?.body + const res = JsonUtil.safeParse(resText, {} as any) + return res + } else { + this.logger.info("using middleware proxy") + const fetchOptions = { + method: method, + headers: headers, + body: params, + } + this.logger.info("commonFetchClient from proxyFetch url =>", url) + this.logger.info("commonFetchClient from proxyFetch fetchOptions =>", fetchOptions) + const res = await this.commonFetchClient.fetchCall(url, fetchOptions, this.cfg.middlewareUrl) + this.logger.debug("commonFetchClient res from proxyFetch =>", res) + return res + } + } +} diff --git a/src/adaptors/api/notion/adaptor/notionApiAdaptor.ts b/src/adaptors/api/notion/adaptor/notionApiAdaptor.ts index b2479a06..cee396c9 100644 --- a/src/adaptors/api/notion/adaptor/notionApiAdaptor.ts +++ b/src/adaptors/api/notion/adaptor/notionApiAdaptor.ts @@ -23,25 +23,62 @@ * questions. */ -import { BlogApi, UserBlog } from "zhi-blog-api" -import { createAppLogger } from "~/src/utils/appLogger.ts" +import { UserBlog } from "zhi-blog-api" +import { BaseBlogApi } from "~/src/adaptors/api/base/baseBlogApi.ts" import { NotionConfig } from "~/src/adaptors/api/notion/config/notionConfig.ts" +import { createAppLogger } from "~/src/utils/appLogger.ts" /** * Notion API 适配器 */ -class NotionApiAdaptor extends BlogApi { - private readonly logger - private readonly cfg - +class NotionApiAdaptor extends BaseBlogApi { constructor(appInstance: any, cfg: NotionConfig) { - super() + super(appInstance, cfg) this.logger = createAppLogger("notion-api-adaptor") - this.cfg = cfg } public async getUsersBlogs(): Promise { - return [] + const result: UserBlog[] = [] + + // https://developers.notion.com/reference/post-search + const params = { + page_size: 10, + filter: { + value: "page", + property: "object", + }, + } + const headers = { + Authorization: `Bearer ${this.cfg.password}`, + "Notion-Version": "2022-06-28", + } + const searchResp = await this.proxyFetch("/search", [headers], params, "POST", "application/json") + this.logger.debug("notion searchResp results=>", searchResp) + if (searchResp.status === 401) { + throw new Error(searchResp.message) + } + const pages = searchResp.results as any + this.logger.debug("notion database results=>", pages) + + // https://stackoverflow.com/a/75537092/4037224 + if (pages.length === 0) { + throw new Error( + "no shared page linked to your connection, you must have at least one page as root page, see more at: https://stackoverflow.com/a/75537092/4037224" + ) + } + + // 数据适配 + pages.forEach((item: any) => { + const userblog: UserBlog = new UserBlog() + userblog.blogid = item.id + const titles = item?.properties?.title?.title ?? [] + userblog.blogName = titles.map((x: any) => x.plain_text).join("") + userblog.url = item.public_url + result.push(userblog) + }) + this.logger.debug("get usersBlogs result=>", result) + + return result } } diff --git a/src/adaptors/api/notion/config/notionConfig.ts b/src/adaptors/api/notion/config/notionConfig.ts index b06e9595..0178f79e 100644 --- a/src/adaptors/api/notion/config/notionConfig.ts +++ b/src/adaptors/api/notion/config/notionConfig.ts @@ -37,6 +37,8 @@ class NotionConfig extends CommonblogConfig { this.previewUrl = "/[postid]" this.pageType = PageTypeEnum.Markdown this.passwordType = PasswordType.PasswordType_Token + this.knowledgeSpaceTitle = "根页面" + this.enableKnowledgeSpace = true } } diff --git a/src/adaptors/api/yuque/config/yuqueConfig.ts b/src/adaptors/api/yuque/config/yuqueConfig.ts index 06759f45..57c08e84 100644 --- a/src/adaptors/api/yuque/config/yuqueConfig.ts +++ b/src/adaptors/api/yuque/config/yuqueConfig.ts @@ -38,6 +38,7 @@ class YuqueConfig extends CommonblogConfig { this.pageType = PageTypeEnum.Markdown this.usernameEnabled = true this.passwordType = PasswordType.PasswordType_Token + this.knowledgeSpaceTitle = "知识库" this.enableKnowledgeSpace = true } } diff --git a/src/adaptors/web/base/web/WebAuthApi.ts b/src/adaptors/web/base/baseWebApi.ts similarity index 95% rename from src/adaptors/web/base/web/WebAuthApi.ts rename to src/adaptors/web/base/baseWebApi.ts index 9599292a..1a0f505f 100644 --- a/src/adaptors/web/base/web/WebAuthApi.ts +++ b/src/adaptors/web/base/baseWebApi.ts @@ -29,7 +29,6 @@ import { AppInstance } from "~/src/appInstance.ts" import { createAppLogger } from "~/src/utils/appLogger.ts" import { useSiyuanApi } from "~/src/composables/useSiyuanApi.ts" import { useSiyuanDevice } from "~/src/composables/useSiyuanDevice.ts" -import { ZhihuConfig } from "~/src/adaptors/web/zhihu/config/zhihuConfig.ts" import { JsonUtil } from "zhi-common" /** @@ -39,7 +38,7 @@ import { JsonUtil } from "zhi-common" * @version 0.9.0 * @since 0.9.0 */ -export class WebAuthApi extends WebApi { +class BaseWebApi extends WebApi { protected logger protected cfg: WebConfig private readonly kernelApi: SiyuanKernelApi @@ -57,7 +56,7 @@ export class WebAuthApi extends WebApi { super() this.cfg = cfg - this.logger = createAppLogger("web-auth-api") + this.logger = createAppLogger("base-web-api") const { kernelApi } = useSiyuanApi() const { isInSiyuanWidget, isInChromeExtension } = useSiyuanDevice() this.kernelApi = kernelApi @@ -66,7 +65,7 @@ export class WebAuthApi extends WebApi { this.isInChromeExtension = isInChromeExtension() } - public updateCfg(cfg: ZhihuConfig) { + public updateCfg(cfg: WebConfig) { this.cfg = cfg } @@ -133,3 +132,5 @@ export class WebAuthApi extends WebApi { } } } + +export { BaseWebApi } diff --git a/src/adaptors/web/base/web/config/CommonWebConfig.ts b/src/adaptors/web/base/config/CommonWebConfig.ts similarity index 100% rename from src/adaptors/web/base/web/config/CommonWebConfig.ts rename to src/adaptors/web/base/config/CommonWebConfig.ts diff --git a/src/adaptors/web/base/web/config/CommonWebPlaceholder.ts b/src/adaptors/web/base/config/CommonWebPlaceholder.ts similarity index 100% rename from src/adaptors/web/base/web/config/CommonWebPlaceholder.ts rename to src/adaptors/web/base/config/CommonWebPlaceholder.ts diff --git a/src/adaptors/web/csdn/adaptor/csdnWebAdaptor.ts b/src/adaptors/web/csdn/adaptor/csdnWebAdaptor.ts index 88b1e5c2..f84b8bc5 100644 --- a/src/adaptors/web/csdn/adaptor/csdnWebAdaptor.ts +++ b/src/adaptors/web/csdn/adaptor/csdnWebAdaptor.ts @@ -23,7 +23,7 @@ * questions. */ -import { WebAuthApi } from "~/src/adaptors/web/base/web/WebAuthApi.ts" +import { BaseWebApi } from "~/src/adaptors/web/base/baseWebApi.ts" /** * CSDN网页授权适配器 @@ -33,7 +33,7 @@ import { WebAuthApi } from "~/src/adaptors/web/base/web/WebAuthApi.ts" * @version 0.9.0 * @since 0.9.0 */ -class CsdnWebAdaptor extends WebAuthApi { +class CsdnWebAdaptor extends BaseWebApi { public async getMetaData(): Promise { const res = await this.proxyFetch("https://bizapi.csdn.net/blog-console-api/v1/user/info") const flag = !!res.data.csdnid diff --git a/src/adaptors/web/csdn/config/csdnConfig.ts b/src/adaptors/web/csdn/config/csdnConfig.ts index a63a5bcb..87d07b23 100644 --- a/src/adaptors/web/csdn/config/csdnConfig.ts +++ b/src/adaptors/web/csdn/config/csdnConfig.ts @@ -23,7 +23,7 @@ * questions. */ -import { CommonWebConfig } from "~/src/adaptors/web/base/web/config/CommonWebConfig.ts" +import { CommonWebConfig } from "~/src/adaptors/web/base/config/CommonWebConfig.ts" /** * CSDN配置 diff --git a/src/adaptors/web/jianshu/adaptor/jianshuWebAdaptor.ts b/src/adaptors/web/jianshu/adaptor/jianshuWebAdaptor.ts index 8d290b52..de7715b2 100644 --- a/src/adaptors/web/jianshu/adaptor/jianshuWebAdaptor.ts +++ b/src/adaptors/web/jianshu/adaptor/jianshuWebAdaptor.ts @@ -23,7 +23,7 @@ * questions. */ -import { WebAuthApi } from "~/src/adaptors/web/base/web/WebAuthApi.ts" +import { BaseWebApi } from "~/src/adaptors/web/base/baseWebApi.ts" /** * 简书网页授权适配器 @@ -33,7 +33,7 @@ import { WebAuthApi } from "~/src/adaptors/web/base/web/WebAuthApi.ts" * @version 0.9.0 * @since 0.9.0 */ -class JianshuWebAdaptor extends WebAuthApi { +class JianshuWebAdaptor extends BaseWebApi { public async getMetaData(): Promise { const res = await this.proxyFetch("https://www.jianshu.com/settings/basic.json") const notebooks = await this.proxyFetch("https://www.jianshu.com/author/notebooks") diff --git a/src/adaptors/web/jianshu/config/JianshuConfig.ts b/src/adaptors/web/jianshu/config/JianshuConfig.ts index e3fe1ea5..0556dbea 100644 --- a/src/adaptors/web/jianshu/config/JianshuConfig.ts +++ b/src/adaptors/web/jianshu/config/JianshuConfig.ts @@ -23,7 +23,7 @@ * questions. */ -import { CommonWebConfig } from "~/src/adaptors/web/base/web/config/CommonWebConfig.ts" +import { CommonWebConfig } from "~/src/adaptors/web/base/config/CommonWebConfig.ts" /** * 简书配置 diff --git a/src/adaptors/web/juejin/adaptor/juejinWebAdaptor.ts b/src/adaptors/web/juejin/adaptor/juejinWebAdaptor.ts index ef2293cc..784dfe9e 100644 --- a/src/adaptors/web/juejin/adaptor/juejinWebAdaptor.ts +++ b/src/adaptors/web/juejin/adaptor/juejinWebAdaptor.ts @@ -23,7 +23,7 @@ * questions. */ -import { WebAuthApi } from "~/src/adaptors/web/base/web/WebAuthApi.ts" +import { BaseWebApi } from "~/src/adaptors/web/base/baseWebApi.ts" /** * 掘金网页授权适配器 @@ -33,7 +33,7 @@ import { WebAuthApi } from "~/src/adaptors/web/base/web/WebAuthApi.ts" * @version 0.9.0 * @since 0.9.0 */ -class JuejinWebAdaptor extends WebAuthApi { +class JuejinWebAdaptor extends BaseWebApi { public async getMetaData(): Promise { const res = await this.proxyFetch("https://api.juejin.cn/user_api/v1/user/get") const flag = !!res.data.user_id @@ -43,12 +43,12 @@ class JuejinWebAdaptor extends WebAuthApi { uid: res.data.user_id, title: res.data.user_name, avatar: res.data.avatar_large, - type: 'juejin', - displayName: '掘金', + type: "juejin", + displayName: "掘金", raw: res.data, - supportTypes: ['markdown', 'html'], - home: 'https://juejin.cn/editor/drafts', - icon: 'https://juejin.cn/favicon.ico', + supportTypes: ["markdown", "html"], + home: "https://juejin.cn/editor/drafts", + icon: "https://juejin.cn/favicon.ico", } } } diff --git a/src/adaptors/web/juejin/config/JuejinConfig.ts b/src/adaptors/web/juejin/config/JuejinConfig.ts index 9ff7dfdd..1cf8b3b3 100644 --- a/src/adaptors/web/juejin/config/JuejinConfig.ts +++ b/src/adaptors/web/juejin/config/JuejinConfig.ts @@ -23,7 +23,7 @@ * questions. */ -import { CommonWebConfig } from "~/src/adaptors/web/base/web/config/CommonWebConfig.ts" +import { CommonWebConfig } from "~/src/adaptors/web/base/config/CommonWebConfig.ts" /** * 掘金配置 diff --git a/src/adaptors/web/notion/useNotionWeb.ts b/src/adaptors/web/notion/useNotionWeb.ts new file mode 100644 index 00000000..fbf31bc1 --- /dev/null +++ b/src/adaptors/web/notion/useNotionWeb.ts @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023, Terwer . All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Terwer designates this + * particular file as subject to the "Classpath" exception as provided + * by Terwer in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Terwer, Shenzhen, Guangdong, China, youweics@163.com + * or visit www.terwer.space if you need additional information or have any + * questions. + */ + +// TODO +// 网页授权版 Notion +// https://github.com/NotionX/react-notion-x/tree/master/packages/notion-client +// https://github.com/NotionX/react-notion-x/issues/115 diff --git a/src/adaptors/web/wechat/adaptor/wechatWebAdaptor.ts b/src/adaptors/web/wechat/adaptor/wechatWebAdaptor.ts index 093da919..c4c1ed81 100644 --- a/src/adaptors/web/wechat/adaptor/wechatWebAdaptor.ts +++ b/src/adaptors/web/wechat/adaptor/wechatWebAdaptor.ts @@ -23,7 +23,7 @@ * questions. */ -import { WebAuthApi } from "~/src/adaptors/web/base/web/WebAuthApi.ts" +import {BaseWebApi} from "~/src/adaptors/web/base/baseWebApi.ts"; /** * 掘金网页授权适配器 @@ -33,7 +33,7 @@ import { WebAuthApi } from "~/src/adaptors/web/base/web/WebAuthApi.ts" * @version 0.9.0 * @since 0.9.0 */ -class WechatWebAdaptor extends WebAuthApi { +class WechatWebAdaptor extends BaseWebApi { public async getMetaData(): Promise { const res = await this.proxyFetch("https://mp.weixin.qq.com/") console.log("WechatWebAdaptor res=>", res) diff --git a/src/adaptors/web/wechat/config/WechatConfig.ts b/src/adaptors/web/wechat/config/WechatConfig.ts index 2d907178..74a6ec50 100644 --- a/src/adaptors/web/wechat/config/WechatConfig.ts +++ b/src/adaptors/web/wechat/config/WechatConfig.ts @@ -23,7 +23,7 @@ * questions. */ -import { CommonWebConfig } from "~/src/adaptors/web/base/web/config/CommonWebConfig.ts" +import { CommonWebConfig } from "~/src/adaptors/web/base/config/CommonWebConfig.ts" /** * 微信公众号配置 diff --git a/src/adaptors/web/yuque/useYuqueWeb.ts b/src/adaptors/web/yuque/useYuqueWeb.ts new file mode 100644 index 00000000..9dc56e6b --- /dev/null +++ b/src/adaptors/web/yuque/useYuqueWeb.ts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023, Terwer . All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Terwer designates this + * particular file as subject to the "Classpath" exception as provided + * by Terwer in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Terwer, Shenzhen, Guangdong, China, youweics@163.com + * or visit www.terwer.space if you need additional information or have any + * questions. + */ + +// TODO +// 网页授权版 Yuque \ No newline at end of file diff --git a/src/adaptors/web/zhihu/adaptor/zhihuWebAdaptor.ts b/src/adaptors/web/zhihu/adaptor/zhihuWebAdaptor.ts index 533ef3c6..99bb953b 100644 --- a/src/adaptors/web/zhihu/adaptor/zhihuWebAdaptor.ts +++ b/src/adaptors/web/zhihu/adaptor/zhihuWebAdaptor.ts @@ -23,7 +23,7 @@ * questions. */ -import { WebAuthApi } from "~/src/adaptors/web/base/web/WebAuthApi.ts" +import { BaseWebApi } from "~/src/adaptors/web/base/baseWebApi.ts" /** * 知乎网页授权适配器 @@ -33,7 +33,7 @@ import { WebAuthApi } from "~/src/adaptors/web/base/web/WebAuthApi.ts" * @version 0.9.0 * @since 0.9.0 */ -class ZhihuWebAdaptor extends WebAuthApi { +class ZhihuWebAdaptor extends BaseWebApi { // /** // * 初始化知乎 API 适配器 // * diff --git a/src/adaptors/web/zhihu/config/zhihuConfig.ts b/src/adaptors/web/zhihu/config/zhihuConfig.ts index 794f9e86..7e43deb4 100644 --- a/src/adaptors/web/zhihu/config/zhihuConfig.ts +++ b/src/adaptors/web/zhihu/config/zhihuConfig.ts @@ -23,7 +23,7 @@ * questions. */ -import { CommonWebConfig } from "~/src/adaptors/web/base/web/config/CommonWebConfig.ts" +import { CommonWebConfig } from "~/src/adaptors/web/base/config/CommonWebConfig.ts" /** * 知乎配置 diff --git a/src/components/set/publish/singleplatform/CommonBlogSetting.vue b/src/components/set/publish/singleplatform/CommonBlogSetting.vue index 744775fb..bba6683c 100644 --- a/src/components/set/publish/singleplatform/CommonBlogSetting.vue +++ b/src/components/set/publish/singleplatform/CommonBlogSetting.vue @@ -28,7 +28,7 @@ import { createAppLogger } from "~/src/utils/appLogger.ts" import { AppInstance } from "~/src/appInstance.ts" import { useVueI18n } from "~/src/composables/useVueI18n.ts" import { useSettingStore } from "~/src/stores/useSettingStore.ts" -import { computed, reactive, ref, toRaw } from "vue" +import { onMounted, reactive, ref } from "vue" import { DynamicConfig, DynamicJsonCfg, @@ -37,20 +37,22 @@ import { } from "~/src/components/set/publish/platform/dynamicConfig.ts" import { SypConfig } from "~/syp.config.ts" import { CommonblogConfig } from "~/src/adaptors/api/base/commonblog/config/CommonblogConfig.ts" -import { onMounted } from "vue" import { JsonUtil, ObjectUtil, StrUtil } from "zhi-common" import { DYNAMIC_CONFIG_KEY } from "~/src/utils/constants.ts" import { PageTypeEnum, PasswordType } from "zhi-blog-api" import Adaptors from "~/src/adaptors" import { Utils } from "~/src/utils/utils.ts" import { ElMessage } from "element-plus" +import { useSiyuanApi } from "~/src/composables/useSiyuanApi.ts" const logger = createAppLogger("commonblog-setting") // appInstance const appInstance = new AppInstance() +// uses const { t } = useVueI18n() const { getSetting, updateSetting } = useSettingStore() +const { isStorageViaSiyuanApi } = useSiyuanApi() const props = defineProps({ apiType: { @@ -87,6 +89,7 @@ const formData = reactive({ setting: {} as typeof SypConfig, dynamicConfigArray: [] as DynamicConfig[], + useSiyuanApi: false, isInit: false, }) @@ -100,12 +103,26 @@ const valiConf = async () => { const api = Utils.blogApi(appInstance, commonblogApiAdaptor) const usersBlogs = await api.getUsersBlogs() if (usersBlogs && usersBlogs.length > 0) { - const userBlog = usersBlogs[0] - // 首次未保存验证的时候才去更新 if (StrUtil.isEmptyString(formData.cfg?.blogid)) { + // 首次验证需要初始化下拉选择 + if (formData.kwSpaces.length == 0) { + usersBlogs.forEach((item) => { + const kwItem = { + label: item.blogName, + value: item.blogid, + } + formData.kwSpaces.push(kwItem) + }) + } + + // 初始化选中 + const userBlog = usersBlogs[0] formData.cfg.blogid = userBlog.blogid formData.cfg.blogName = userBlog.blogName + + // 初始化顶部提示 + formData.settingTips = getSettingTips() } formData.cfg.apiStatus = true @@ -120,7 +137,7 @@ const valiConf = async () => { } if (!formData.cfg.apiStatus) { - logger.error(errMsg.toString(),"") + logger.error(errMsg.toString(), "") ElMessage.error(t("setting.blog.vali.error") + "=>" + errMsg) } else { ElMessage.success(t("main.opt.success")) @@ -197,12 +214,15 @@ const initConf = async () => { await initKwSpaces() } formData.settingTips = getSettingTips() + } else { + ElMessage.error("Read init config error, your config may not work") } } onMounted(async () => { // 初始化 await initConf() + formData.useSiyuanApi = isStorageViaSiyuanApi() formData.isInit = true }) @@ -262,7 +282,7 @@ onMounted(async () => { - + { - +