### What problem does this PR solve? feat: API access key management #2846 feat: Render markdown file with remark-loader #2846 ### Type of change - [ ] Bug Fix (non-breaking change which fixes an issue) - [x] New Feature (non-breaking change which adds functionality) - [ ] Documentation Update - [ ] Refactoring - [ ] Performance Improvement - [ ] Other (please describe):tags/v0.13.0
| hack: `true; @import "~@/less/index.less";`, | hack: `true; @import "~@/less/index.less";`, | ||||
| }, | }, | ||||
| }, | }, | ||||
| mdx: { | |||||
| loader: 'remark-loader', | |||||
| }, | |||||
| devtool: 'source-map', | devtool: 'source-map', | ||||
| copy: ['src/conf.json'], | copy: ['src/conf.json'], | ||||
| proxy: { | proxy: { | ||||
| // pathRewrite: { '^/v1': '/v1' }, | // pathRewrite: { '^/v1': '/v1' }, | ||||
| }, | }, | ||||
| }, | }, | ||||
| chainWebpack(memo, args) { | |||||
| memo.module | |||||
| .rule('markdown') | |||||
| .test(/\.md$/) | |||||
| .use('html-loader') | |||||
| .loader('html-loader') | |||||
| .end() | |||||
| .use('remark-loader') | |||||
| .loader('remark-loader'); | |||||
| return memo; | |||||
| }, | |||||
| }); | }); |
| "@umijs/lint": "^4.1.1", | "@umijs/lint": "^4.1.1", | ||||
| "@umijs/plugins": "^4.1.0", | "@umijs/plugins": "^4.1.0", | ||||
| "cross-env": "^7.0.3", | "cross-env": "^7.0.3", | ||||
| "html-loader": "^5.1.0", | |||||
| "husky": "^9.0.11", | "husky": "^9.0.11", | ||||
| "jest": "^29.7.0", | "jest": "^29.7.0", | ||||
| "jest-environment-jsdom": "^29.7.0", | "jest-environment-jsdom": "^29.7.0", | ||||
| "prettier-plugin-organize-imports": "^3.2.4", | "prettier-plugin-organize-imports": "^3.2.4", | ||||
| "prettier-plugin-packagejson": "^2.4.9", | "prettier-plugin-packagejson": "^2.4.9", | ||||
| "react-dev-inspector": "^2.0.1", | "react-dev-inspector": "^2.0.1", | ||||
| "remark-loader": "^6.0.0", | |||||
| "ts-node": "^10.9.2", | "ts-node": "^10.9.2", | ||||
| "typescript": "^5.0.3", | "typescript": "^5.0.3", | ||||
| "umi-plugin-icons": "^0.1.1" | "umi-plugin-icons": "^0.1.1" | ||||
| } | } | ||||
| ] | ] | ||||
| }, | }, | ||||
| "node_modules/front-matter": { | |||||
| "version": "4.0.2", | |||||
| "resolved": "https://registry.npmmirror.com/front-matter/-/front-matter-4.0.2.tgz", | |||||
| "integrity": "sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==", | |||||
| "dev": true, | |||||
| "dependencies": { | |||||
| "js-yaml": "^3.13.1" | |||||
| } | |||||
| }, | |||||
| "node_modules/fs-extra": { | "node_modules/fs-extra": { | ||||
| "version": "10.1.0", | "version": "10.1.0", | ||||
| "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.1.0.tgz", | "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.1.0.tgz", | ||||
| "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", | "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", | ||||
| "devOptional": true | "devOptional": true | ||||
| }, | }, | ||||
| "node_modules/html-loader": { | |||||
| "version": "5.1.0", | |||||
| "resolved": "https://registry.npmmirror.com/html-loader/-/html-loader-5.1.0.tgz", | |||||
| "integrity": "sha512-Jb3xwDbsm0W3qlXrCZwcYqYGnYz55hb6aoKQTlzyZPXsPpi6tHXzAfqalecglMQgNvtEfxrCQPaKT90Irt5XDA==", | |||||
| "dev": true, | |||||
| "dependencies": { | |||||
| "html-minifier-terser": "^7.2.0", | |||||
| "parse5": "^7.1.2" | |||||
| }, | |||||
| "engines": { | |||||
| "node": ">= 18.12.0" | |||||
| }, | |||||
| "funding": { | |||||
| "type": "opencollective", | |||||
| "url": "https://opencollective.com/webpack" | |||||
| }, | |||||
| "peerDependencies": { | |||||
| "webpack": "^5.0.0" | |||||
| } | |||||
| }, | |||||
| "node_modules/html-loader/node_modules/commander": { | |||||
| "version": "10.0.1", | |||||
| "resolved": "https://registry.npmmirror.com/commander/-/commander-10.0.1.tgz", | |||||
| "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", | |||||
| "dev": true, | |||||
| "engines": { | |||||
| "node": ">=14" | |||||
| } | |||||
| }, | |||||
| "node_modules/html-loader/node_modules/html-minifier-terser": { | |||||
| "version": "7.2.0", | |||||
| "resolved": "https://registry.npmmirror.com/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", | |||||
| "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", | |||||
| "dev": true, | |||||
| "dependencies": { | |||||
| "camel-case": "^4.1.2", | |||||
| "clean-css": "~5.3.2", | |||||
| "commander": "^10.0.0", | |||||
| "entities": "^4.4.0", | |||||
| "param-case": "^3.0.4", | |||||
| "relateurl": "^0.2.7", | |||||
| "terser": "^5.15.1" | |||||
| }, | |||||
| "bin": { | |||||
| "html-minifier-terser": "cli.js" | |||||
| }, | |||||
| "engines": { | |||||
| "node": "^14.13.1 || >=16.0.0" | |||||
| } | |||||
| }, | |||||
| "node_modules/html-minifier-terser": { | "node_modules/html-minifier-terser": { | ||||
| "version": "6.1.0", | "version": "6.1.0", | ||||
| "resolved": "https://registry.npmmirror.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", | "resolved": "https://registry.npmmirror.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", | ||||
| "node": "*" | "node": "*" | ||||
| } | } | ||||
| }, | }, | ||||
| "node_modules/mri": { | |||||
| "version": "1.2.0", | |||||
| "resolved": "https://registry.npmmirror.com/mri/-/mri-1.2.0.tgz", | |||||
| "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", | |||||
| "dev": true, | |||||
| "peer": true, | |||||
| "engines": { | |||||
| "node": ">=4" | |||||
| } | |||||
| }, | |||||
| "node_modules/ms": { | "node_modules/ms": { | ||||
| "version": "2.1.2", | "version": "2.1.2", | ||||
| "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz", | "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz", | ||||
| "node": ">= 0.10" | "node": ">= 0.10" | ||||
| } | } | ||||
| }, | }, | ||||
| "node_modules/remark": { | |||||
| "version": "14.0.3", | |||||
| "resolved": "https://registry.npmmirror.com/remark/-/remark-14.0.3.tgz", | |||||
| "integrity": "sha512-bfmJW1dmR2LvaMJuAnE88pZP9DktIFYXazkTfOIKZzi3Knk9lT0roItIA24ydOucI3bV/g/tXBA6hzqq3FV9Ew==", | |||||
| "dev": true, | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "@types/mdast": "^3.0.0", | |||||
| "remark-parse": "^10.0.0", | |||||
| "remark-stringify": "^10.0.0", | |||||
| "unified": "^10.0.0" | |||||
| }, | |||||
| "funding": { | |||||
| "type": "opencollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark-gfm": { | "node_modules/remark-gfm": { | ||||
| "version": "4.0.0", | "version": "4.0.0", | ||||
| "resolved": "https://registry.npmmirror.com/remark-gfm/-/remark-gfm-4.0.0.tgz", | "resolved": "https://registry.npmmirror.com/remark-gfm/-/remark-gfm-4.0.0.tgz", | ||||
| "unified": "^11.0.0" | "unified": "^11.0.0" | ||||
| } | } | ||||
| }, | }, | ||||
| "node_modules/remark-loader": { | |||||
| "version": "6.0.0", | |||||
| "resolved": "https://registry.npmmirror.com/remark-loader/-/remark-loader-6.0.0.tgz", | |||||
| "integrity": "sha512-3Z4WLyVYbI1F6TQNnA9/iuHsoRcu8ruH2ABixLpgSWiSiYdNgURgLdpbdze8jTm2+VWWcAq9xIH7maWSpi2sSw==", | |||||
| "dev": true, | |||||
| "dependencies": { | |||||
| "front-matter": "^4.0.2" | |||||
| }, | |||||
| "engines": { | |||||
| "node": ">= 18.12.0" | |||||
| }, | |||||
| "funding": { | |||||
| "type": "opencollective", | |||||
| "url": "https://opencollective.com/webpack" | |||||
| }, | |||||
| "peerDependencies": { | |||||
| "remark": "^14.0.0", | |||||
| "webpack": "^5.0.0" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark-parse": { | "node_modules/remark-parse": { | ||||
| "version": "11.0.0", | "version": "11.0.0", | ||||
| "resolved": "https://registry.npmmirror.com/remark-parse/-/remark-parse-11.0.0.tgz", | "resolved": "https://registry.npmmirror.com/remark-parse/-/remark-parse-11.0.0.tgz", | ||||
| "unified": "^11.0.0" | "unified": "^11.0.0" | ||||
| } | } | ||||
| }, | }, | ||||
| "node_modules/remark/node_modules/@types/mdast": { | |||||
| "version": "3.0.15", | |||||
| "resolved": "https://registry.npmmirror.com/@types/mdast/-/mdast-3.0.15.tgz", | |||||
| "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", | |||||
| "dev": true, | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "@types/unist": "^2" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/@types/unist": { | |||||
| "version": "2.0.11", | |||||
| "resolved": "https://registry.npmmirror.com/@types/unist/-/unist-2.0.11.tgz", | |||||
| "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", | |||||
| "dev": true, | |||||
| "peer": true | |||||
| }, | |||||
| "node_modules/remark/node_modules/is-buffer": { | |||||
| "version": "2.0.5", | |||||
| "resolved": "https://registry.npmmirror.com/is-buffer/-/is-buffer-2.0.5.tgz", | |||||
| "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", | |||||
| "dev": true, | |||||
| "funding": [ | |||||
| { | |||||
| "type": "github", | |||||
| "url": "https://github.com/sponsors/feross" | |||||
| }, | |||||
| { | |||||
| "type": "patreon", | |||||
| "url": "https://www.patreon.com/feross" | |||||
| }, | |||||
| { | |||||
| "type": "consulting", | |||||
| "url": "https://feross.org/support" | |||||
| } | |||||
| ], | |||||
| "peer": true, | |||||
| "engines": { | |||||
| "node": ">=4" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/mdast-util-from-markdown": { | |||||
| "version": "1.3.1", | |||||
| "resolved": "https://registry.npmmirror.com/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", | |||||
| "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", | |||||
| "dev": true, | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "@types/mdast": "^3.0.0", | |||||
| "@types/unist": "^2.0.0", | |||||
| "decode-named-character-reference": "^1.0.0", | |||||
| "mdast-util-to-string": "^3.1.0", | |||||
| "micromark": "^3.0.0", | |||||
| "micromark-util-decode-numeric-character-reference": "^1.0.0", | |||||
| "micromark-util-decode-string": "^1.0.0", | |||||
| "micromark-util-normalize-identifier": "^1.0.0", | |||||
| "micromark-util-symbol": "^1.0.0", | |||||
| "micromark-util-types": "^1.0.0", | |||||
| "unist-util-stringify-position": "^3.0.0", | |||||
| "uvu": "^0.5.0" | |||||
| }, | |||||
| "funding": { | |||||
| "type": "opencollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/mdast-util-phrasing": { | |||||
| "version": "3.0.1", | |||||
| "resolved": "https://registry.npmmirror.com/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz", | |||||
| "integrity": "sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==", | |||||
| "dev": true, | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "@types/mdast": "^3.0.0", | |||||
| "unist-util-is": "^5.0.0" | |||||
| }, | |||||
| "funding": { | |||||
| "type": "opencollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/mdast-util-to-markdown": { | |||||
| "version": "1.5.0", | |||||
| "resolved": "https://registry.npmmirror.com/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz", | |||||
| "integrity": "sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==", | |||||
| "dev": true, | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "@types/mdast": "^3.0.0", | |||||
| "@types/unist": "^2.0.0", | |||||
| "longest-streak": "^3.0.0", | |||||
| "mdast-util-phrasing": "^3.0.0", | |||||
| "mdast-util-to-string": "^3.0.0", | |||||
| "micromark-util-decode-string": "^1.0.0", | |||||
| "unist-util-visit": "^4.0.0", | |||||
| "zwitch": "^2.0.0" | |||||
| }, | |||||
| "funding": { | |||||
| "type": "opencollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/mdast-util-to-string": { | |||||
| "version": "3.2.0", | |||||
| "resolved": "https://registry.npmmirror.com/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", | |||||
| "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", | |||||
| "dev": true, | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "@types/mdast": "^3.0.0" | |||||
| }, | |||||
| "funding": { | |||||
| "type": "opencollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/micromark": { | |||||
| "version": "3.2.0", | |||||
| "resolved": "https://registry.npmmirror.com/micromark/-/micromark-3.2.0.tgz", | |||||
| "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", | |||||
| "dev": true, | |||||
| "funding": [ | |||||
| { | |||||
| "type": "GitHub Sponsors", | |||||
| "url": "https://github.com/sponsors/unifiedjs" | |||||
| }, | |||||
| { | |||||
| "type": "OpenCollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| ], | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "@types/debug": "^4.0.0", | |||||
| "debug": "^4.0.0", | |||||
| "decode-named-character-reference": "^1.0.0", | |||||
| "micromark-core-commonmark": "^1.0.1", | |||||
| "micromark-factory-space": "^1.0.0", | |||||
| "micromark-util-character": "^1.0.0", | |||||
| "micromark-util-chunked": "^1.0.0", | |||||
| "micromark-util-combine-extensions": "^1.0.0", | |||||
| "micromark-util-decode-numeric-character-reference": "^1.0.0", | |||||
| "micromark-util-encode": "^1.0.0", | |||||
| "micromark-util-normalize-identifier": "^1.0.0", | |||||
| "micromark-util-resolve-all": "^1.0.0", | |||||
| "micromark-util-sanitize-uri": "^1.0.0", | |||||
| "micromark-util-subtokenize": "^1.0.0", | |||||
| "micromark-util-symbol": "^1.0.0", | |||||
| "micromark-util-types": "^1.0.1", | |||||
| "uvu": "^0.5.0" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/micromark-core-commonmark": { | |||||
| "version": "1.1.0", | |||||
| "resolved": "https://registry.npmmirror.com/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", | |||||
| "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", | |||||
| "dev": true, | |||||
| "funding": [ | |||||
| { | |||||
| "type": "GitHub Sponsors", | |||||
| "url": "https://github.com/sponsors/unifiedjs" | |||||
| }, | |||||
| { | |||||
| "type": "OpenCollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| ], | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "decode-named-character-reference": "^1.0.0", | |||||
| "micromark-factory-destination": "^1.0.0", | |||||
| "micromark-factory-label": "^1.0.0", | |||||
| "micromark-factory-space": "^1.0.0", | |||||
| "micromark-factory-title": "^1.0.0", | |||||
| "micromark-factory-whitespace": "^1.0.0", | |||||
| "micromark-util-character": "^1.0.0", | |||||
| "micromark-util-chunked": "^1.0.0", | |||||
| "micromark-util-classify-character": "^1.0.0", | |||||
| "micromark-util-html-tag-name": "^1.0.0", | |||||
| "micromark-util-normalize-identifier": "^1.0.0", | |||||
| "micromark-util-resolve-all": "^1.0.0", | |||||
| "micromark-util-subtokenize": "^1.0.0", | |||||
| "micromark-util-symbol": "^1.0.0", | |||||
| "micromark-util-types": "^1.0.1", | |||||
| "uvu": "^0.5.0" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/micromark-factory-destination": { | |||||
| "version": "1.1.0", | |||||
| "resolved": "https://registry.npmmirror.com/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", | |||||
| "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", | |||||
| "dev": true, | |||||
| "funding": [ | |||||
| { | |||||
| "type": "GitHub Sponsors", | |||||
| "url": "https://github.com/sponsors/unifiedjs" | |||||
| }, | |||||
| { | |||||
| "type": "OpenCollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| ], | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "micromark-util-character": "^1.0.0", | |||||
| "micromark-util-symbol": "^1.0.0", | |||||
| "micromark-util-types": "^1.0.0" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/micromark-factory-label": { | |||||
| "version": "1.1.0", | |||||
| "resolved": "https://registry.npmmirror.com/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", | |||||
| "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", | |||||
| "dev": true, | |||||
| "funding": [ | |||||
| { | |||||
| "type": "GitHub Sponsors", | |||||
| "url": "https://github.com/sponsors/unifiedjs" | |||||
| }, | |||||
| { | |||||
| "type": "OpenCollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| ], | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "micromark-util-character": "^1.0.0", | |||||
| "micromark-util-symbol": "^1.0.0", | |||||
| "micromark-util-types": "^1.0.0", | |||||
| "uvu": "^0.5.0" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/micromark-factory-space": { | |||||
| "version": "1.1.0", | |||||
| "resolved": "https://registry.npmmirror.com/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", | |||||
| "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", | |||||
| "dev": true, | |||||
| "funding": [ | |||||
| { | |||||
| "type": "GitHub Sponsors", | |||||
| "url": "https://github.com/sponsors/unifiedjs" | |||||
| }, | |||||
| { | |||||
| "type": "OpenCollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| ], | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "micromark-util-character": "^1.0.0", | |||||
| "micromark-util-types": "^1.0.0" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/micromark-factory-title": { | |||||
| "version": "1.1.0", | |||||
| "resolved": "https://registry.npmmirror.com/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", | |||||
| "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", | |||||
| "dev": true, | |||||
| "funding": [ | |||||
| { | |||||
| "type": "GitHub Sponsors", | |||||
| "url": "https://github.com/sponsors/unifiedjs" | |||||
| }, | |||||
| { | |||||
| "type": "OpenCollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| ], | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "micromark-factory-space": "^1.0.0", | |||||
| "micromark-util-character": "^1.0.0", | |||||
| "micromark-util-symbol": "^1.0.0", | |||||
| "micromark-util-types": "^1.0.0" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/micromark-factory-whitespace": { | |||||
| "version": "1.1.0", | |||||
| "resolved": "https://registry.npmmirror.com/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", | |||||
| "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", | |||||
| "dev": true, | |||||
| "funding": [ | |||||
| { | |||||
| "type": "GitHub Sponsors", | |||||
| "url": "https://github.com/sponsors/unifiedjs" | |||||
| }, | |||||
| { | |||||
| "type": "OpenCollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| ], | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "micromark-factory-space": "^1.0.0", | |||||
| "micromark-util-character": "^1.0.0", | |||||
| "micromark-util-symbol": "^1.0.0", | |||||
| "micromark-util-types": "^1.0.0" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/micromark-util-character": { | |||||
| "version": "1.2.0", | |||||
| "resolved": "https://registry.npmmirror.com/micromark-util-character/-/micromark-util-character-1.2.0.tgz", | |||||
| "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", | |||||
| "dev": true, | |||||
| "funding": [ | |||||
| { | |||||
| "type": "GitHub Sponsors", | |||||
| "url": "https://github.com/sponsors/unifiedjs" | |||||
| }, | |||||
| { | |||||
| "type": "OpenCollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| ], | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "micromark-util-symbol": "^1.0.0", | |||||
| "micromark-util-types": "^1.0.0" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/micromark-util-chunked": { | |||||
| "version": "1.1.0", | |||||
| "resolved": "https://registry.npmmirror.com/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", | |||||
| "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", | |||||
| "dev": true, | |||||
| "funding": [ | |||||
| { | |||||
| "type": "GitHub Sponsors", | |||||
| "url": "https://github.com/sponsors/unifiedjs" | |||||
| }, | |||||
| { | |||||
| "type": "OpenCollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| ], | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "micromark-util-symbol": "^1.0.0" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/micromark-util-classify-character": { | |||||
| "version": "1.1.0", | |||||
| "resolved": "https://registry.npmmirror.com/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", | |||||
| "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", | |||||
| "dev": true, | |||||
| "funding": [ | |||||
| { | |||||
| "type": "GitHub Sponsors", | |||||
| "url": "https://github.com/sponsors/unifiedjs" | |||||
| }, | |||||
| { | |||||
| "type": "OpenCollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| ], | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "micromark-util-character": "^1.0.0", | |||||
| "micromark-util-symbol": "^1.0.0", | |||||
| "micromark-util-types": "^1.0.0" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/micromark-util-combine-extensions": { | |||||
| "version": "1.1.0", | |||||
| "resolved": "https://registry.npmmirror.com/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", | |||||
| "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", | |||||
| "dev": true, | |||||
| "funding": [ | |||||
| { | |||||
| "type": "GitHub Sponsors", | |||||
| "url": "https://github.com/sponsors/unifiedjs" | |||||
| }, | |||||
| { | |||||
| "type": "OpenCollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| ], | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "micromark-util-chunked": "^1.0.0", | |||||
| "micromark-util-types": "^1.0.0" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/micromark-util-decode-numeric-character-reference": { | |||||
| "version": "1.1.0", | |||||
| "resolved": "https://registry.npmmirror.com/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", | |||||
| "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", | |||||
| "dev": true, | |||||
| "funding": [ | |||||
| { | |||||
| "type": "GitHub Sponsors", | |||||
| "url": "https://github.com/sponsors/unifiedjs" | |||||
| }, | |||||
| { | |||||
| "type": "OpenCollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| ], | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "micromark-util-symbol": "^1.0.0" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/micromark-util-decode-string": { | |||||
| "version": "1.1.0", | |||||
| "resolved": "https://registry.npmmirror.com/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", | |||||
| "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", | |||||
| "dev": true, | |||||
| "funding": [ | |||||
| { | |||||
| "type": "GitHub Sponsors", | |||||
| "url": "https://github.com/sponsors/unifiedjs" | |||||
| }, | |||||
| { | |||||
| "type": "OpenCollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| ], | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "decode-named-character-reference": "^1.0.0", | |||||
| "micromark-util-character": "^1.0.0", | |||||
| "micromark-util-decode-numeric-character-reference": "^1.0.0", | |||||
| "micromark-util-symbol": "^1.0.0" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/micromark-util-encode": { | |||||
| "version": "1.1.0", | |||||
| "resolved": "https://registry.npmmirror.com/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", | |||||
| "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", | |||||
| "dev": true, | |||||
| "funding": [ | |||||
| { | |||||
| "type": "GitHub Sponsors", | |||||
| "url": "https://github.com/sponsors/unifiedjs" | |||||
| }, | |||||
| { | |||||
| "type": "OpenCollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| ], | |||||
| "peer": true | |||||
| }, | |||||
| "node_modules/remark/node_modules/micromark-util-html-tag-name": { | |||||
| "version": "1.2.0", | |||||
| "resolved": "https://registry.npmmirror.com/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", | |||||
| "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", | |||||
| "dev": true, | |||||
| "funding": [ | |||||
| { | |||||
| "type": "GitHub Sponsors", | |||||
| "url": "https://github.com/sponsors/unifiedjs" | |||||
| }, | |||||
| { | |||||
| "type": "OpenCollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| ], | |||||
| "peer": true | |||||
| }, | |||||
| "node_modules/remark/node_modules/micromark-util-normalize-identifier": { | |||||
| "version": "1.1.0", | |||||
| "resolved": "https://registry.npmmirror.com/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", | |||||
| "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", | |||||
| "dev": true, | |||||
| "funding": [ | |||||
| { | |||||
| "type": "GitHub Sponsors", | |||||
| "url": "https://github.com/sponsors/unifiedjs" | |||||
| }, | |||||
| { | |||||
| "type": "OpenCollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| ], | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "micromark-util-symbol": "^1.0.0" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/micromark-util-resolve-all": { | |||||
| "version": "1.1.0", | |||||
| "resolved": "https://registry.npmmirror.com/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", | |||||
| "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", | |||||
| "dev": true, | |||||
| "funding": [ | |||||
| { | |||||
| "type": "GitHub Sponsors", | |||||
| "url": "https://github.com/sponsors/unifiedjs" | |||||
| }, | |||||
| { | |||||
| "type": "OpenCollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| ], | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "micromark-util-types": "^1.0.0" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/micromark-util-sanitize-uri": { | |||||
| "version": "1.2.0", | |||||
| "resolved": "https://registry.npmmirror.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", | |||||
| "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", | |||||
| "dev": true, | |||||
| "funding": [ | |||||
| { | |||||
| "type": "GitHub Sponsors", | |||||
| "url": "https://github.com/sponsors/unifiedjs" | |||||
| }, | |||||
| { | |||||
| "type": "OpenCollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| ], | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "micromark-util-character": "^1.0.0", | |||||
| "micromark-util-encode": "^1.0.0", | |||||
| "micromark-util-symbol": "^1.0.0" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/micromark-util-subtokenize": { | |||||
| "version": "1.1.0", | |||||
| "resolved": "https://registry.npmmirror.com/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", | |||||
| "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", | |||||
| "dev": true, | |||||
| "funding": [ | |||||
| { | |||||
| "type": "GitHub Sponsors", | |||||
| "url": "https://github.com/sponsors/unifiedjs" | |||||
| }, | |||||
| { | |||||
| "type": "OpenCollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| ], | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "micromark-util-chunked": "^1.0.0", | |||||
| "micromark-util-symbol": "^1.0.0", | |||||
| "micromark-util-types": "^1.0.0", | |||||
| "uvu": "^0.5.0" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/micromark-util-symbol": { | |||||
| "version": "1.1.0", | |||||
| "resolved": "https://registry.npmmirror.com/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", | |||||
| "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", | |||||
| "dev": true, | |||||
| "funding": [ | |||||
| { | |||||
| "type": "GitHub Sponsors", | |||||
| "url": "https://github.com/sponsors/unifiedjs" | |||||
| }, | |||||
| { | |||||
| "type": "OpenCollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| ], | |||||
| "peer": true | |||||
| }, | |||||
| "node_modules/remark/node_modules/micromark-util-types": { | |||||
| "version": "1.1.0", | |||||
| "resolved": "https://registry.npmmirror.com/micromark-util-types/-/micromark-util-types-1.1.0.tgz", | |||||
| "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", | |||||
| "dev": true, | |||||
| "funding": [ | |||||
| { | |||||
| "type": "GitHub Sponsors", | |||||
| "url": "https://github.com/sponsors/unifiedjs" | |||||
| }, | |||||
| { | |||||
| "type": "OpenCollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| ], | |||||
| "peer": true | |||||
| }, | |||||
| "node_modules/remark/node_modules/remark-parse": { | |||||
| "version": "10.0.2", | |||||
| "resolved": "https://registry.npmmirror.com/remark-parse/-/remark-parse-10.0.2.tgz", | |||||
| "integrity": "sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==", | |||||
| "dev": true, | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "@types/mdast": "^3.0.0", | |||||
| "mdast-util-from-markdown": "^1.0.0", | |||||
| "unified": "^10.0.0" | |||||
| }, | |||||
| "funding": { | |||||
| "type": "opencollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/remark-stringify": { | |||||
| "version": "10.0.3", | |||||
| "resolved": "https://registry.npmmirror.com/remark-stringify/-/remark-stringify-10.0.3.tgz", | |||||
| "integrity": "sha512-koyOzCMYoUHudypbj4XpnAKFbkddRMYZHwghnxd7ue5210WzGw6kOBwauJTRUMq16jsovXx8dYNvSSWP89kZ3A==", | |||||
| "dev": true, | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "@types/mdast": "^3.0.0", | |||||
| "mdast-util-to-markdown": "^1.0.0", | |||||
| "unified": "^10.0.0" | |||||
| }, | |||||
| "funding": { | |||||
| "type": "opencollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/unified": { | |||||
| "version": "10.1.2", | |||||
| "resolved": "https://registry.npmmirror.com/unified/-/unified-10.1.2.tgz", | |||||
| "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", | |||||
| "dev": true, | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "@types/unist": "^2.0.0", | |||||
| "bail": "^2.0.0", | |||||
| "extend": "^3.0.0", | |||||
| "is-buffer": "^2.0.0", | |||||
| "is-plain-obj": "^4.0.0", | |||||
| "trough": "^2.0.0", | |||||
| "vfile": "^5.0.0" | |||||
| }, | |||||
| "funding": { | |||||
| "type": "opencollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/unist-util-is": { | |||||
| "version": "5.2.1", | |||||
| "resolved": "https://registry.npmmirror.com/unist-util-is/-/unist-util-is-5.2.1.tgz", | |||||
| "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", | |||||
| "dev": true, | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "@types/unist": "^2.0.0" | |||||
| }, | |||||
| "funding": { | |||||
| "type": "opencollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/unist-util-stringify-position": { | |||||
| "version": "3.0.3", | |||||
| "resolved": "https://registry.npmmirror.com/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", | |||||
| "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", | |||||
| "dev": true, | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "@types/unist": "^2.0.0" | |||||
| }, | |||||
| "funding": { | |||||
| "type": "opencollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/unist-util-visit": { | |||||
| "version": "4.1.2", | |||||
| "resolved": "https://registry.npmmirror.com/unist-util-visit/-/unist-util-visit-4.1.2.tgz", | |||||
| "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", | |||||
| "dev": true, | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "@types/unist": "^2.0.0", | |||||
| "unist-util-is": "^5.0.0", | |||||
| "unist-util-visit-parents": "^5.1.1" | |||||
| }, | |||||
| "funding": { | |||||
| "type": "opencollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/unist-util-visit-parents": { | |||||
| "version": "5.1.3", | |||||
| "resolved": "https://registry.npmmirror.com/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", | |||||
| "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", | |||||
| "dev": true, | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "@types/unist": "^2.0.0", | |||||
| "unist-util-is": "^5.0.0" | |||||
| }, | |||||
| "funding": { | |||||
| "type": "opencollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/vfile": { | |||||
| "version": "5.3.7", | |||||
| "resolved": "https://registry.npmmirror.com/vfile/-/vfile-5.3.7.tgz", | |||||
| "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", | |||||
| "dev": true, | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "@types/unist": "^2.0.0", | |||||
| "is-buffer": "^2.0.0", | |||||
| "unist-util-stringify-position": "^3.0.0", | |||||
| "vfile-message": "^3.0.0" | |||||
| }, | |||||
| "funding": { | |||||
| "type": "opencollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| }, | |||||
| "node_modules/remark/node_modules/vfile-message": { | |||||
| "version": "3.1.4", | |||||
| "resolved": "https://registry.npmmirror.com/vfile-message/-/vfile-message-3.1.4.tgz", | |||||
| "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==", | |||||
| "dev": true, | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "@types/unist": "^2.0.0", | |||||
| "unist-util-stringify-position": "^3.0.0" | |||||
| }, | |||||
| "funding": { | |||||
| "type": "opencollective", | |||||
| "url": "https://opencollective.com/unified" | |||||
| } | |||||
| }, | |||||
| "node_modules/remove-accents": { | "node_modules/remove-accents": { | ||||
| "version": "0.4.2", | "version": "0.4.2", | ||||
| "resolved": "https://registry.npmmirror.com/remove-accents/-/remove-accents-0.4.2.tgz", | "resolved": "https://registry.npmmirror.com/remove-accents/-/remove-accents-0.4.2.tgz", | ||||
| "queue-microtask": "^1.2.2" | "queue-microtask": "^1.2.2" | ||||
| } | } | ||||
| }, | }, | ||||
| "node_modules/sade": { | |||||
| "version": "1.8.1", | |||||
| "resolved": "https://registry.npmmirror.com/sade/-/sade-1.8.1.tgz", | |||||
| "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", | |||||
| "dev": true, | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "mri": "^1.1.0" | |||||
| }, | |||||
| "engines": { | |||||
| "node": ">=6" | |||||
| } | |||||
| }, | |||||
| "node_modules/safe-array-concat": { | "node_modules/safe-array-concat": { | ||||
| "version": "1.1.2", | "version": "1.1.2", | ||||
| "resolved": "https://registry.npmmirror.com/safe-array-concat/-/safe-array-concat-1.1.2.tgz", | "resolved": "https://registry.npmmirror.com/safe-array-concat/-/safe-array-concat-1.1.2.tgz", | ||||
| "uuid": "dist/bin/uuid" | "uuid": "dist/bin/uuid" | ||||
| } | } | ||||
| }, | }, | ||||
| "node_modules/uvu": { | |||||
| "version": "0.5.6", | |||||
| "resolved": "https://registry.npmmirror.com/uvu/-/uvu-0.5.6.tgz", | |||||
| "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", | |||||
| "dev": true, | |||||
| "peer": true, | |||||
| "dependencies": { | |||||
| "dequal": "^2.0.0", | |||||
| "diff": "^5.0.0", | |||||
| "kleur": "^4.0.3", | |||||
| "sade": "^1.7.3" | |||||
| }, | |||||
| "bin": { | |||||
| "uvu": "bin.js" | |||||
| }, | |||||
| "engines": { | |||||
| "node": ">=8" | |||||
| } | |||||
| }, | |||||
| "node_modules/uvu/node_modules/diff": { | |||||
| "version": "5.2.0", | |||||
| "resolved": "https://registry.npmmirror.com/diff/-/diff-5.2.0.tgz", | |||||
| "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", | |||||
| "dev": true, | |||||
| "peer": true, | |||||
| "engines": { | |||||
| "node": ">=0.3.1" | |||||
| } | |||||
| }, | |||||
| "node_modules/uvu/node_modules/kleur": { | |||||
| "version": "4.1.5", | |||||
| "resolved": "https://registry.npmmirror.com/kleur/-/kleur-4.1.5.tgz", | |||||
| "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", | |||||
| "dev": true, | |||||
| "peer": true, | |||||
| "engines": { | |||||
| "node": ">=6" | |||||
| } | |||||
| }, | |||||
| "node_modules/v8-compile-cache": { | "node_modules/v8-compile-cache": { | ||||
| "version": "2.4.0", | "version": "2.4.0", | ||||
| "resolved": "https://registry.npmmirror.com/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", | "resolved": "https://registry.npmmirror.com/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", |
| "@umijs/lint": "^4.1.1", | "@umijs/lint": "^4.1.1", | ||||
| "@umijs/plugins": "^4.1.0", | "@umijs/plugins": "^4.1.0", | ||||
| "cross-env": "^7.0.3", | "cross-env": "^7.0.3", | ||||
| "html-loader": "^5.1.0", | |||||
| "husky": "^9.0.11", | "husky": "^9.0.11", | ||||
| "jest": "^29.7.0", | "jest": "^29.7.0", | ||||
| "jest-environment-jsdom": "^29.7.0", | "jest-environment-jsdom": "^29.7.0", | ||||
| "prettier-plugin-organize-imports": "^3.2.4", | "prettier-plugin-organize-imports": "^3.2.4", | ||||
| "prettier-plugin-packagejson": "^2.4.9", | "prettier-plugin-packagejson": "^2.4.9", | ||||
| "react-dev-inspector": "^2.0.1", | "react-dev-inspector": "^2.0.1", | ||||
| "remark-loader": "^6.0.0", | |||||
| "ts-node": "^10.9.2", | "ts-node": "^10.9.2", | ||||
| "typescript": "^5.0.3", | "typescript": "^5.0.3", | ||||
| "umi-plugin-icons": "^0.1.1" | "umi-plugin-icons": "^0.1.1" |
| <svg t="1727608362384" class="icon" viewBox="0 0 1025 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4306" | |||||
| width="24" height="24"> | |||||
| <path | |||||
| d="M1019.520374 56.394706L966.393742 3.257862c-2.001695-2.001695-4.503815-2.87999-7.1387-2.879991s-5.137004 1.000848-7.148912 2.879991L856.749851 98.61414C814.520204 69.916363 765.396963 55.638964 716.283935 55.638964c-64.156382 0-128.312765 24.428855-177.30324 73.429543L411.280694 256.758295c-3.880838 3.880838-3.880838 10.274008 0 14.154847L751.74254 611.364776c2.001695 2.001695 4.514028 2.890203 7.1387 2.890203 2.512332 0 5.137004-1.000848 7.1387-2.890203l127.689788-127.689788c86.338436-86.460989 96.489892-220.166077 30.454367-317.646604l95.356279-95.366491c3.880838-3.993178 3.880838-10.386348 0-14.267187zM833.321844 423.409656l-74.430391 74.440604-234.075818-234.075818 74.430391-74.430391c31.199896-31.199896 72.806566-48.490052 117.037909-48.490051 44.231342 0 85.705247 17.167603 117.037909 48.490051 31.199896 31.199896 48.490052 72.806566 48.490051 117.037909 0 44.231342-17.290155 85.705247-48.490051 117.027696zM594.987317 554.980283c-3.880838-3.880838-10.274008-3.880838-14.154847 0l-83.458446 83.458446-113.15707-113.146858 83.580998-83.580999c3.891051-3.891051 3.891051-10.284221 0-14.165059l-45.610061-45.610061c-3.880838-3.891051-10.274008-3.891051-14.154846 0l-83.580999 83.580998-53.882374-53.882374c-2.001695-2.001695-4.514028-2.87999-7.1387-2.87999-2.512332 0-5.137004 1.000848-7.138699 2.87999L128.725037 539.313952C42.386601 625.774941 32.235145 759.480028 98.27067 856.970768L2.914392 952.33726c-3.880838 3.880838-3.880838 10.274008 0 14.154846l53.136844 53.126632c2.001695 2.001695 4.514028 2.87999 7.1387 2.87999 2.634885 0 5.137004-1.000848 7.1387-2.87999l95.366491-95.356279c42.219434 28.697777 91.352888 42.985389 140.465916 42.985389 64.156382 0 128.312765-24.439068 177.30324-73.429543l127.689789-127.689788c3.880838-3.891051 3.880838-10.274008 0-14.154847l-53.882374-53.882374 83.580998-83.580998c3.880838-3.880838 3.880838-10.274008 0-14.154847l-45.865379-45.375168zM423.066186 833.665314c-31.199896 31.199896-72.806566 48.490052-117.037908 48.490051-44.231342 0-85.705247-17.167603-117.037909-48.490051-31.199896-31.199896-48.490052-72.806566-48.490052-117.037909 0-44.231342 17.167603-85.71546 48.490052-117.037909l74.430391-74.430391 234.075817 234.075818-74.430391 74.430391z m0 0" | |||||
| fill="#2C2C2C" p-id="4307"></path> | |||||
| </svg> |
| dialogId, | dialogId, | ||||
| hideModal, | hideModal, | ||||
| idKey, | idKey, | ||||
| }: IModalProps<any> & { dialogId: string; idKey: string }) => { | |||||
| }: IModalProps<any> & { dialogId?: string; idKey: string }) => { | |||||
| const { createToken, removeToken, tokenList, listLoading, creatingLoading } = | const { createToken, removeToken, tokenList, listLoading, creatingLoading } = | ||||
| useOperateApiKey(dialogId, idKey); | |||||
| useOperateApiKey(idKey, dialogId); | |||||
| const { t } = useTranslate('chat'); | const { t } = useTranslate('chat'); | ||||
| const columns: TableProps<IToken>['columns'] = [ | const columns: TableProps<IToken>['columns'] = [ | ||||
| render: (_, record) => ( | render: (_, record) => ( | ||||
| <Space size="middle"> | <Space size="middle"> | ||||
| <CopyToClipboard text={record.token}></CopyToClipboard> | <CopyToClipboard text={record.token}></CopyToClipboard> | ||||
| <DeleteOutlined | |||||
| onClick={() => removeToken(record.token, record.tenant_id)} | |||||
| /> | |||||
| <DeleteOutlined onClick={() => removeToken(record.token)} /> | |||||
| </Space> | </Space> | ||||
| ), | ), | ||||
| }, | }, | ||||
| dataSource={tokenList} | dataSource={tokenList} | ||||
| rowKey={'token'} | rowKey={'token'} | ||||
| loading={listLoading} | loading={listLoading} | ||||
| pagination={false} | |||||
| /> | /> | ||||
| <Button onClick={createToken} loading={creatingLoading}> | |||||
| <Button | |||||
| onClick={createToken} | |||||
| loading={creatingLoading} | |||||
| disabled={tokenList.length > 0} | |||||
| > | |||||
| {t('createNewKey')} | {t('createNewKey')} | ||||
| </Button> | </Button> | ||||
| </Modal> | </Modal> |
| import HightLightMarkdown from '@/components/highlight-markdown'; | |||||
| import { useSetModalState, useTranslate } from '@/hooks/common-hooks'; | |||||
| import { Button, Card, Flex, Space } from 'antd'; | |||||
| import apiDoc from '../../../../../docs/references/api.md'; | |||||
| import ChatApiKeyModal from '../chat-api-key-modal'; | |||||
| import EmbedModal from '../embed-modal'; | |||||
| import { usePreviewChat, useShowEmbedModal } from '../hooks'; | |||||
| import BackendServiceApi from './backend-service-api'; | |||||
| const ApiContent = ({ | |||||
| id, | |||||
| idKey, | |||||
| hideChatPreviewCard = false, | |||||
| }: { | |||||
| id?: string; | |||||
| idKey: string; | |||||
| hideChatPreviewCard?: boolean; | |||||
| }) => { | |||||
| const { t } = useTranslate('chat'); | |||||
| const { | |||||
| visible: apiKeyVisible, | |||||
| hideModal: hideApiKeyModal, | |||||
| showModal: showApiKeyModal, | |||||
| } = useSetModalState(); | |||||
| const { embedVisible, hideEmbedModal, showEmbedModal, embedToken } = | |||||
| useShowEmbedModal(idKey, id); | |||||
| const { handlePreview } = usePreviewChat(idKey, id); | |||||
| return ( | |||||
| <div> | |||||
| <Flex vertical gap={'middle'}> | |||||
| <BackendServiceApi show={showApiKeyModal}></BackendServiceApi> | |||||
| {!hideChatPreviewCard && ( | |||||
| <Card title={`${name} Web App`}> | |||||
| <Flex gap={8} vertical> | |||||
| <Space size={'middle'}> | |||||
| <Button onClick={handlePreview}>{t('preview')}</Button> | |||||
| <Button onClick={showEmbedModal}>{t('embedded')}</Button> | |||||
| </Space> | |||||
| </Flex> | |||||
| </Card> | |||||
| )} | |||||
| <HightLightMarkdown>{apiDoc}</HightLightMarkdown> | |||||
| </Flex> | |||||
| {apiKeyVisible && ( | |||||
| <ChatApiKeyModal | |||||
| hideModal={hideApiKeyModal} | |||||
| dialogId={id} | |||||
| idKey={idKey} | |||||
| ></ChatApiKeyModal> | |||||
| )} | |||||
| {embedVisible && ( | |||||
| <EmbedModal | |||||
| token={embedToken} | |||||
| visible={embedVisible} | |||||
| hideModal={hideEmbedModal} | |||||
| ></EmbedModal> | |||||
| )} | |||||
| </div> | |||||
| ); | |||||
| }; | |||||
| export default ApiContent; |
| import { Button, Card, Flex, Space, Typography } from 'antd'; | |||||
| import { useTranslate } from '@/hooks/common-hooks'; | |||||
| import styles from './index.less'; | |||||
| const { Paragraph } = Typography; | |||||
| const BackendServiceApi = ({ show }: { show(): void }) => { | |||||
| const { t } = useTranslate('chat'); | |||||
| return ( | |||||
| <Card | |||||
| title={ | |||||
| <Space size={'large'}> | |||||
| <span>RAGFlow API</span> | |||||
| <Button onClick={show} type="primary"> | |||||
| {t('apiKey')} | |||||
| </Button> | |||||
| </Space> | |||||
| } | |||||
| > | |||||
| <Flex gap={8} align="center"> | |||||
| <b>{t('backendServiceApi')}</b> | |||||
| <Paragraph | |||||
| copyable={{ text: `${location.origin}/v1/api/` }} | |||||
| className={styles.apiLinkText} | |||||
| > | |||||
| {location.origin}/v1/api/ | |||||
| </Paragraph> | |||||
| </Flex> | |||||
| </Card> | |||||
| ); | |||||
| }; | |||||
| export default BackendServiceApi; |
| padding-left: 60px; | padding-left: 60px; | ||||
| padding-bottom: 20px; | padding-bottom: 20px; | ||||
| } | } | ||||
| .linkText { | |||||
| border-radius: 6px; | |||||
| padding: 6px 10px; | |||||
| background-color: #eff8ff; | |||||
| border: 1px; | |||||
| .apiLinkText { | |||||
| .linkText(); | |||||
| margin: 0 !important; | |||||
| } | } |
| import LineChart from '@/components/line-chart'; | |||||
| import { useFetchNextStats } from '@/hooks/chat-hooks'; | |||||
| import { useSetModalState, useTranslate } from '@/hooks/common-hooks'; | |||||
| import { useTranslate } from '@/hooks/common-hooks'; | |||||
| import { IModalProps } from '@/interfaces/common'; | import { IModalProps } from '@/interfaces/common'; | ||||
| import { IStats } from '@/interfaces/database/chat'; | |||||
| import { formatDate } from '@/utils/date'; | |||||
| import { Button, Card, DatePicker, Flex, Modal, Space, Typography } from 'antd'; | |||||
| import { RangePickerProps } from 'antd/es/date-picker'; | |||||
| import dayjs from 'dayjs'; | |||||
| import camelCase from 'lodash/camelCase'; | |||||
| import ChatApiKeyModal from '../chat-api-key-modal'; | |||||
| import EmbedModal from '../embed-modal'; | |||||
| import { | |||||
| usePreviewChat, | |||||
| useSelectChartStatsList, | |||||
| useShowEmbedModal, | |||||
| } from '../hooks'; | |||||
| import styles from './index.less'; | |||||
| const { Paragraph } = Typography; | |||||
| const { RangePicker } = DatePicker; | |||||
| const StatsLineChart = ({ statsType }: { statsType: keyof IStats }) => { | |||||
| const { t } = useTranslate('chat'); | |||||
| const chartList = useSelectChartStatsList(); | |||||
| const list = | |||||
| chartList[statsType]?.map((x) => ({ | |||||
| ...x, | |||||
| xAxis: formatDate(x.xAxis), | |||||
| })) ?? []; | |||||
| return ( | |||||
| <div className={styles.chartItem}> | |||||
| <b className={styles.chartLabel}>{t(camelCase(statsType))}</b> | |||||
| <LineChart data={list}></LineChart> | |||||
| </div> | |||||
| ); | |||||
| }; | |||||
| import { Modal } from 'antd'; | |||||
| import ApiContent from './api-content'; | |||||
| const ChatOverviewModal = ({ | const ChatOverviewModal = ({ | ||||
| visible, | visible, | ||||
| hideModal, | hideModal, | ||||
| id, | id, | ||||
| name = '', | |||||
| idKey, | idKey, | ||||
| }: IModalProps<any> & { id: string; name?: string; idKey: string }) => { | }: IModalProps<any> & { id: string; name?: string; idKey: string }) => { | ||||
| const { t } = useTranslate('chat'); | const { t } = useTranslate('chat'); | ||||
| const { | |||||
| visible: apiKeyVisible, | |||||
| hideModal: hideApiKeyModal, | |||||
| showModal: showApiKeyModal, | |||||
| } = useSetModalState(); | |||||
| const { embedVisible, hideEmbedModal, showEmbedModal, embedToken } = | |||||
| useShowEmbedModal(id, idKey); | |||||
| const { pickerValue, setPickerValue } = useFetchNextStats(); | |||||
| const disabledDate: RangePickerProps['disabledDate'] = (current) => { | |||||
| return current && current > dayjs().endOf('day'); | |||||
| }; | |||||
| const { handlePreview } = usePreviewChat(id, idKey); | |||||
| return ( | return ( | ||||
| <> | <> | ||||
| width={'100vw'} | width={'100vw'} | ||||
| okText={t('close', { keyPrefix: 'common' })} | okText={t('close', { keyPrefix: 'common' })} | ||||
| > | > | ||||
| <Flex vertical gap={'middle'}> | |||||
| <Card title={t('backendServiceApi')}> | |||||
| <Flex gap={8} vertical> | |||||
| {t('serviceApiEndpoint')} | |||||
| <Paragraph | |||||
| copyable={{ text: `${location.origin}/v1/api/` }} | |||||
| className={styles.linkText} | |||||
| > | |||||
| {location.origin}/v1/api/ | |||||
| </Paragraph> | |||||
| </Flex> | |||||
| <Space size={'middle'}> | |||||
| <Button onClick={showApiKeyModal}>{t('apiKey')}</Button> | |||||
| <a | |||||
| href={ | |||||
| 'https://github.com/infiniflow/ragflow/blob/main/docs/references/api.md' | |||||
| } | |||||
| target="_blank" | |||||
| rel="noreferrer" | |||||
| > | |||||
| <Button>{t('apiReference')}</Button> | |||||
| </a> | |||||
| </Space> | |||||
| </Card> | |||||
| <Card title={`${name} Web App`}> | |||||
| <Flex gap={8} vertical> | |||||
| <Space size={'middle'}> | |||||
| <Button onClick={handlePreview}>{t('preview')}</Button> | |||||
| <Button onClick={showEmbedModal}>{t('embedded')}</Button> | |||||
| </Space> | |||||
| </Flex> | |||||
| </Card> | |||||
| <Space> | |||||
| <b>{t('dateRange')}</b> | |||||
| <RangePicker | |||||
| disabledDate={disabledDate} | |||||
| value={pickerValue} | |||||
| onChange={setPickerValue} | |||||
| allowClear={false} | |||||
| /> | |||||
| </Space> | |||||
| <div className={styles.chartWrapper}> | |||||
| <StatsLineChart statsType={'pv'}></StatsLineChart> | |||||
| <StatsLineChart statsType={'round'}></StatsLineChart> | |||||
| <StatsLineChart statsType={'speed'}></StatsLineChart> | |||||
| <StatsLineChart statsType={'thumb_up'}></StatsLineChart> | |||||
| <StatsLineChart statsType={'tokens'}></StatsLineChart> | |||||
| <StatsLineChart statsType={'uv'}></StatsLineChart> | |||||
| </div> | |||||
| </Flex> | |||||
| {apiKeyVisible && ( | |||||
| <ChatApiKeyModal | |||||
| hideModal={hideApiKeyModal} | |||||
| dialogId={id} | |||||
| idKey={idKey} | |||||
| ></ChatApiKeyModal> | |||||
| )} | |||||
| <EmbedModal | |||||
| token={embedToken} | |||||
| visible={embedVisible} | |||||
| hideModal={hideEmbedModal} | |||||
| ></EmbedModal> | |||||
| <ApiContent id={id} idKey={idKey}></ApiContent> | |||||
| </Modal> | </Modal> | ||||
| </> | </> | ||||
| ); | ); |
| import LineChart from '@/components/line-chart'; | |||||
| import { useTranslate } from '@/hooks/common-hooks'; | |||||
| import { IStats } from '@/interfaces/database/chat'; | |||||
| import { formatDate } from '@/utils/date'; | |||||
| import camelCase from 'lodash/camelCase'; | |||||
| import { useSelectChartStatsList } from '../hooks'; | |||||
| import styles from './index.less'; | |||||
| const StatsLineChart = ({ statsType }: { statsType: keyof IStats }) => { | |||||
| const { t } = useTranslate('chat'); | |||||
| const chartList = useSelectChartStatsList(); | |||||
| const list = | |||||
| chartList[statsType]?.map((x) => ({ | |||||
| ...x, | |||||
| xAxis: formatDate(x.xAxis), | |||||
| })) ?? []; | |||||
| return ( | |||||
| <div className={styles.chartItem}> | |||||
| <b className={styles.chartLabel}>{t(camelCase(statsType))}</b> | |||||
| <LineChart data={list}></LineChart> | |||||
| </div> | |||||
| ); | |||||
| }; | |||||
| const StatsChart = () => { | |||||
| return ( | |||||
| <div className={styles.chartWrapper}> | |||||
| <StatsLineChart statsType={'pv'}></StatsLineChart> | |||||
| <StatsLineChart statsType={'round'}></StatsLineChart> | |||||
| <StatsLineChart statsType={'speed'}></StatsLineChart> | |||||
| <StatsLineChart statsType={'thumb_up'}></StatsLineChart> | |||||
| <StatsLineChart statsType={'tokens'}></StatsLineChart> | |||||
| <StatsLineChart statsType={'uv'}></StatsLineChart> | |||||
| </div> | |||||
| ); | |||||
| }; | |||||
| export default StatsChart; |
| import { SharedFrom } from '@/constants/chat'; | import { SharedFrom } from '@/constants/chat'; | ||||
| import { | |||||
| useCreateNextToken, | |||||
| useFetchTokenList, | |||||
| useRemoveNextToken, | |||||
| } from '@/hooks/chat-hooks'; | |||||
| import { | import { | ||||
| useSetModalState, | useSetModalState, | ||||
| useShowDeleteConfirm, | useShowDeleteConfirm, | ||||
| useTranslate, | useTranslate, | ||||
| } from '@/hooks/common-hooks'; | } from '@/hooks/common-hooks'; | ||||
| import { | |||||
| useCreateSystemToken, | |||||
| useFetchSystemTokenList, | |||||
| useRemoveSystemToken, | |||||
| } from '@/hooks/user-setting-hooks'; | |||||
| import { IStats } from '@/interfaces/database/chat'; | import { IStats } from '@/interfaces/database/chat'; | ||||
| import { useQueryClient } from '@tanstack/react-query'; | import { useQueryClient } from '@tanstack/react-query'; | ||||
| import { message } from 'antd'; | import { message } from 'antd'; | ||||
| import { useCallback } from 'react'; | import { useCallback } from 'react'; | ||||
| export const useOperateApiKey = (dialogId: string, idKey: string) => { | |||||
| const { removeToken } = useRemoveNextToken(); | |||||
| const { createToken, loading: creatingLoading } = useCreateNextToken(); | |||||
| const { data: tokenList, loading: listLoading } = useFetchTokenList({ | |||||
| export const useOperateApiKey = (idKey: string, dialogId?: string) => { | |||||
| const { removeToken } = useRemoveSystemToken(); | |||||
| const { createToken, loading: creatingLoading } = useCreateSystemToken(); | |||||
| const { data: tokenList, loading: listLoading } = useFetchSystemTokenList({ | |||||
| [idKey]: dialogId, | [idKey]: dialogId, | ||||
| }); | }); | ||||
| const showDeleteConfirm = useShowDeleteConfirm(); | const showDeleteConfirm = useShowDeleteConfirm(); | ||||
| const onRemoveToken = (token: string, tenantId: string) => { | |||||
| const onRemoveToken = (token: string) => { | |||||
| showDeleteConfirm({ | showDeleteConfirm({ | ||||
| onOk: () => removeToken({ dialogId, tokens: [token], tenantId }), | |||||
| onOk: () => removeToken(token), | |||||
| }); | }); | ||||
| }; | }; | ||||
| export const useSelectChartStatsList = (): ChartStatsType => { | export const useSelectChartStatsList = (): ChartStatsType => { | ||||
| const queryClient = useQueryClient(); | const queryClient = useQueryClient(); | ||||
| const data = queryClient.getQueriesData({ queryKey: ['fetchStats'] }); | const data = queryClient.getQueriesData({ queryKey: ['fetchStats'] }); | ||||
| const stats: IStats = data[0][1] as IStats; | |||||
| const stats: IStats = (data.length > 0 ? data[0][1] : {}) as IStats; | |||||
| return Object.keys(stats).reduce((pre, cur) => { | return Object.keys(stats).reduce((pre, cur) => { | ||||
| const item = stats[cur as keyof IStats]; | const item = stats[cur as keyof IStats]; | ||||
| return `${protocol}//${host}/chat/share?shared_id=${token}&from=${from}`; | return `${protocol}//${host}/chat/share?shared_id=${token}&from=${from}`; | ||||
| }; | }; | ||||
| const useFetchTokenListBeforeOtherStep = (dialogId: string, idKey: string) => { | |||||
| const useFetchTokenListBeforeOtherStep = (idKey: string, dialogId?: string) => { | |||||
| const { showTokenEmptyError } = useShowTokenEmptyError(); | const { showTokenEmptyError } = useShowTokenEmptyError(); | ||||
| const { data: tokenList, refetch } = useFetchTokenList({ [idKey]: dialogId }); | |||||
| const { data: tokenList, refetch } = useFetchSystemTokenList({ | |||||
| [idKey]: dialogId, | |||||
| }); | |||||
| const token = | const token = | ||||
| Array.isArray(tokenList) && tokenList.length > 0 ? tokenList[0].token : ''; | Array.isArray(tokenList) && tokenList.length > 0 ? tokenList[0].token : ''; | ||||
| }; | }; | ||||
| }; | }; | ||||
| export const useShowEmbedModal = (dialogId: string, idKey: string) => { | |||||
| export const useShowEmbedModal = (idKey: string, dialogId?: string) => { | |||||
| const { | const { | ||||
| visible: embedVisible, | visible: embedVisible, | ||||
| hideModal: hideEmbedModal, | hideModal: hideEmbedModal, | ||||
| } = useSetModalState(); | } = useSetModalState(); | ||||
| const { handleOperate, token } = useFetchTokenListBeforeOtherStep( | const { handleOperate, token } = useFetchTokenListBeforeOtherStep( | ||||
| dialogId, | |||||
| idKey, | idKey, | ||||
| dialogId, | |||||
| ); | ); | ||||
| const handleShowEmbedModal = useCallback(async () => { | const handleShowEmbedModal = useCallback(async () => { | ||||
| }; | }; | ||||
| }; | }; | ||||
| export const usePreviewChat = (dialogId: string, idKey: string) => { | |||||
| const { handleOperate } = useFetchTokenListBeforeOtherStep(dialogId, idKey); | |||||
| export const usePreviewChat = (idKey: string, dialogId?: string) => { | |||||
| const { handleOperate } = useFetchTokenListBeforeOtherStep(idKey, dialogId); | |||||
| const open = useCallback( | const open = useCallback( | ||||
| (t: string) => { | (t: string) => { |
| .text { | .text { | ||||
| white-space: pre-wrap; // https://stackoverflow.com/questions/60332183/new-line-with-react-markdown | |||||
| .chunkText; | .chunkText; | ||||
| font-size: 16px; | |||||
| li { | |||||
| padding: 4px 0px; | |||||
| } | |||||
| p { | |||||
| white-space: pre-wrap; // https://stackoverflow.com/questions/60332183/new-line-with-react-markdown | |||||
| } | |||||
| } | |||||
| .code { | |||||
| padding: 3px 6px 6px; | |||||
| margin: 0; | |||||
| white-space: break-spaces; | |||||
| background-color: rgba(129, 139, 152, 0.12); | |||||
| border-radius: 4px; | |||||
| color: rgb(31, 35, 40); | |||||
| } | } |
| import classNames from 'classnames'; | import classNames from 'classnames'; | ||||
| import Markdown from 'react-markdown'; | import Markdown from 'react-markdown'; | ||||
| import SyntaxHighlighter from 'react-syntax-highlighter'; | |||||
| import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; | |||||
| import rehypeRaw from 'rehype-raw'; | import rehypeRaw from 'rehype-raw'; | ||||
| import remarkGfm from 'remark-gfm'; | import remarkGfm from 'remark-gfm'; | ||||
| const { children, className, node, ...rest } = props; | const { children, className, node, ...rest } = props; | ||||
| const match = /language-(\w+)/.exec(className || ''); | const match = /language-(\w+)/.exec(className || ''); | ||||
| return match ? ( | return match ? ( | ||||
| <SyntaxHighlighter {...rest} PreTag="div" language={match[1]}> | |||||
| <SyntaxHighlighter | |||||
| {...rest} | |||||
| PreTag="div" | |||||
| language={match[1]} | |||||
| // style={dark} | |||||
| > | |||||
| {String(children).replace(/\n$/, '')} | {String(children).replace(/\n$/, '')} | ||||
| </SyntaxHighlighter> | </SyntaxHighlighter> | ||||
| ) : ( | ) : ( | ||||
| <code {...rest} className={className}> | |||||
| <code {...rest} className={`${className} ${styles.code}`}> | |||||
| {children} | {children} | ||||
| </code> | </code> | ||||
| ); | ); |
| export const LanguageList = ['English', 'Chinese', 'Traditional Chinese']; | export const LanguageList = ['English', 'Chinese', 'Traditional Chinese']; | ||||
| export const LanguageMap = { | |||||
| English: 'English', | |||||
| Chinese: '简体中文', | |||||
| 'Traditional Chinese': '繁體中文', | |||||
| }; | |||||
| export const LanguageTranslationMap = { | export const LanguageTranslationMap = { | ||||
| English: 'en', | English: 'en', | ||||
| Chinese: 'zh', | Chinese: 'zh', |
| Password = 'password', | Password = 'password', | ||||
| Model = 'model', | Model = 'model', | ||||
| System = 'system', | System = 'system', | ||||
| Api = 'api', | |||||
| Team = 'team', | Team = 'team', | ||||
| Logout = 'logout', | Logout = 'logout', | ||||
| } | } |
| mutationKey: ['removeToken'], | mutationKey: ['removeToken'], | ||||
| mutationFn: async (params: { | mutationFn: async (params: { | ||||
| tenantId: string; | tenantId: string; | ||||
| dialogId: string; | |||||
| dialogId?: string; | |||||
| tokens: string[]; | tokens: string[]; | ||||
| }) => { | }) => { | ||||
| const { data } = await chatService.removeToken(params); | const { data } = await chatService.removeToken(params); |
| import { LanguageTranslationMap } from '@/constants/common'; | import { LanguageTranslationMap } from '@/constants/common'; | ||||
| import { ResponseGetType } from '@/interfaces/database/base'; | import { ResponseGetType } from '@/interfaces/database/base'; | ||||
| import { IToken } from '@/interfaces/database/chat'; | |||||
| import { ITenantInfo } from '@/interfaces/database/knowledge'; | import { ITenantInfo } from '@/interfaces/database/knowledge'; | ||||
| import { ISystemStatus, IUserInfo } from '@/interfaces/database/user-setting'; | import { ISystemStatus, IUserInfo } from '@/interfaces/database/user-setting'; | ||||
| import userService from '@/services/user-service'; | import userService from '@/services/user-service'; | ||||
| loading, | loading, | ||||
| }; | }; | ||||
| }; | }; | ||||
| export const useFetchSystemTokenList = (params: Record<string, any>) => { | |||||
| const { | |||||
| data, | |||||
| isFetching: loading, | |||||
| refetch, | |||||
| } = useQuery<IToken[]>({ | |||||
| queryKey: ['fetchSystemTokenList', params], | |||||
| initialData: [], | |||||
| gcTime: 0, | |||||
| queryFn: async () => { | |||||
| const { data } = await userService.listToken(params); | |||||
| return data?.data ?? []; | |||||
| }, | |||||
| }); | |||||
| return { data, loading, refetch }; | |||||
| }; | |||||
| export const useRemoveSystemToken = () => { | |||||
| const queryClient = useQueryClient(); | |||||
| const { t } = useTranslation(); | |||||
| const { | |||||
| data, | |||||
| isPending: loading, | |||||
| mutateAsync, | |||||
| } = useMutation({ | |||||
| mutationKey: ['removeSystemToken'], | |||||
| mutationFn: async (token: string) => { | |||||
| const { data } = await userService.removeToken({}, token); | |||||
| if (data.retcode === 0) { | |||||
| message.success(t('message.deleted')); | |||||
| queryClient.invalidateQueries({ queryKey: ['fetchSystemTokenList'] }); | |||||
| } | |||||
| return data?.data ?? []; | |||||
| }, | |||||
| }); | |||||
| return { data, loading, removeToken: mutateAsync }; | |||||
| }; | |||||
| export const useCreateSystemToken = () => { | |||||
| const queryClient = useQueryClient(); | |||||
| const { | |||||
| data, | |||||
| isPending: loading, | |||||
| mutateAsync, | |||||
| } = useMutation({ | |||||
| mutationKey: ['createSystemToken'], | |||||
| mutationFn: async (params: Record<string, any>) => { | |||||
| const { data } = await userService.createToken(params); | |||||
| if (data.retcode === 0) { | |||||
| queryClient.invalidateQueries({ queryKey: ['fetchSystemTokenList'] }); | |||||
| } | |||||
| return data?.data ?? []; | |||||
| }, | |||||
| }); | |||||
| return { data, loading, createToken: mutateAsync }; | |||||
| }; |
| import React from 'react'; | import React from 'react'; | ||||
| import User from '../user'; | import User from '../user'; | ||||
| import { LanguageList } from '@/constants/common'; | |||||
| import { LanguageList, LanguageMap } from '@/constants/common'; | |||||
| import { useChangeLanguage } from '@/hooks/logic-hooks'; | import { useChangeLanguage } from '@/hooks/logic-hooks'; | ||||
| import { useFetchUserInfo } from '@/hooks/user-setting-hooks'; | import { useFetchUserInfo } from '@/hooks/user-setting-hooks'; | ||||
| import styled from './index.less'; | import styled from './index.less'; | ||||
| const items: MenuProps['items'] = LanguageList.map((x) => ({ | const items: MenuProps['items'] = LanguageList.map((x) => ({ | ||||
| key: x, | key: x, | ||||
| label: <span>{t(camelCase(x))}</span>, | |||||
| label: <span>{LanguageMap[x as keyof typeof LanguageMap]}</span>, | |||||
| })).reduce<MenuProps['items']>((pre, cur) => { | })).reduce<MenuProps['items']>((pre, cur) => { | ||||
| return [...pre!, { type: 'divider' }, cur]; | return [...pre!, { type: 'divider' }, cur]; | ||||
| }, []); | }, []); |
| .tableCell() { | |||||
| padding: 6px 13px; | |||||
| border: 1px solid #d1d9e0; | |||||
| } | |||||
| .chunkText() { | .chunkText() { | ||||
| em { | em { | ||||
| color: red; | color: red; | ||||
| } | } | ||||
| table { | table { | ||||
| width: 100%; | width: 100%; | ||||
| box-sizing: border-box; | |||||
| border-collapse: collapse; | |||||
| } | } | ||||
| caption { | caption { | ||||
| } | } | ||||
| th { | th { | ||||
| color: #fff; | |||||
| background-color: @blurBackground; | |||||
| // color: #fff; | |||||
| // background-color: @blurBackground; | |||||
| .tableCell; | |||||
| } | |||||
| td { | |||||
| .tableCell; | |||||
| } | } | ||||
| td:hover { | td:hover { | ||||
| overflow: hidden; | overflow: hidden; | ||||
| text-overflow: ellipsis; | text-overflow: ellipsis; | ||||
| } | } | ||||
| .linkText() { | |||||
| border-radius: 6px; | |||||
| padding: 6px 10px; | |||||
| background-color: #eff8ff; | |||||
| border: 1px; | |||||
| } |
| quoteTip: 'Should the source of the original text be displayed?', | quoteTip: 'Should the source of the original text be displayed?', | ||||
| selfRag: 'Self-RAG', | selfRag: 'Self-RAG', | ||||
| selfRagTip: 'Please refer to: https://huggingface.co/papers/2310.11511', | selfRagTip: 'Please refer to: https://huggingface.co/papers/2310.11511', | ||||
| overview: 'Chat Bot API', | |||||
| overview: 'Chat ID', | |||||
| pv: 'Number of messages', | pv: 'Number of messages', | ||||
| uv: 'Active user number', | uv: 'Active user number', | ||||
| speed: 'Token output speed', | speed: 'Token output speed', | ||||
| apiKey: 'API Key', | apiKey: 'API Key', | ||||
| apiReference: 'API Documents', | apiReference: 'API Documents', | ||||
| dateRange: 'Date Range:', | dateRange: 'Date Range:', | ||||
| backendServiceApi: 'Backend service API', | |||||
| backendServiceApi: 'API Server', | |||||
| createNewKey: 'Create new key', | createNewKey: 'Create new key', | ||||
| created: 'Created', | created: 'Created', | ||||
| action: 'Action', | action: 'Action', | ||||
| team: 'Team', | team: 'Team', | ||||
| system: 'System', | system: 'System', | ||||
| logout: 'Log out', | logout: 'Log out', | ||||
| api: 'API', | |||||
| username: 'Username', | username: 'Username', | ||||
| usernameMessage: 'Please input your username!', | usernameMessage: 'Please input your username!', | ||||
| photo: 'Your photo', | photo: 'Your photo', |
| quoteTip: '是否應該顯示原文出處?', | quoteTip: '是否應該顯示原文出處?', | ||||
| selfRag: 'Self-RAG', | selfRag: 'Self-RAG', | ||||
| selfRagTip: '請參考: https://huggingface.co/papers/2310.11511', | selfRagTip: '請參考: https://huggingface.co/papers/2310.11511', | ||||
| overview: '聊天 API', | |||||
| overview: '聊天 ID', | |||||
| pv: '消息數', | pv: '消息數', | ||||
| uv: '活躍用戶數', | uv: '活躍用戶數', | ||||
| speed: 'Token 輸出速度', | speed: 'Token 輸出速度', | ||||
| apiKey: 'API 鍵', | apiKey: 'API 鍵', | ||||
| apiReference: 'API 文檔', | apiReference: 'API 文檔', | ||||
| dateRange: '日期範圍:', | dateRange: '日期範圍:', | ||||
| backendServiceApi: '後端服務 API', | |||||
| backendServiceApi: 'API 伺服器', | |||||
| createNewKey: '創建新密鑰', | createNewKey: '創建新密鑰', | ||||
| created: '創建於', | created: '創建於', | ||||
| action: '操作', | action: '操作', |
| quoteTip: '是否应该显示原文出处?', | quoteTip: '是否应该显示原文出处?', | ||||
| selfRag: 'Self-RAG', | selfRag: 'Self-RAG', | ||||
| selfRagTip: '请参考: https://huggingface.co/papers/2310.11511', | selfRagTip: '请参考: https://huggingface.co/papers/2310.11511', | ||||
| overview: '聊天 API', | |||||
| overview: '聊天 ID', | |||||
| pv: '消息数', | pv: '消息数', | ||||
| uv: '活跃用户数', | uv: '活跃用户数', | ||||
| speed: 'Token 输出速度', | speed: 'Token 输出速度', | ||||
| apiKey: 'API 键', | apiKey: 'API 键', | ||||
| apiReference: 'API 文档', | apiReference: 'API 文档', | ||||
| dateRange: '日期范围:', | dateRange: '日期范围:', | ||||
| backendServiceApi: '后端服务 API', | |||||
| backendServiceApi: 'API 服务器', | |||||
| createNewKey: '创建新密钥', | createNewKey: '创建新密钥', | ||||
| created: '创建于', | created: '创建于', | ||||
| action: '操作', | action: '操作', |
| import ApiContent from '@/components/api-service/chat-overview-modal/api-content'; | |||||
| const ApiPage = () => { | |||||
| return ( | |||||
| <div> | |||||
| <ApiContent idKey="dialogId"></ApiContent> | |||||
| </div> | |||||
| ); | |||||
| }; | |||||
| export default ApiPage; |
| .id { | |||||
| .linkText(); | |||||
| } |
| import { useTranslate } from '@/hooks/common-hooks'; | |||||
| import { IModalProps } from '@/interfaces/common'; | |||||
| import { Modal, Typography } from 'antd'; | |||||
| import styles from './index.less'; | |||||
| const { Paragraph } = Typography; | |||||
| const ChatIdModal = ({ | |||||
| visible, | |||||
| hideModal, | |||||
| id, | |||||
| }: IModalProps<any> & { id: string; name?: string; idKey: string }) => { | |||||
| const { t } = useTranslate('chat'); | |||||
| return ( | |||||
| <> | |||||
| <Modal | |||||
| title={t('overview')} | |||||
| open={visible} | |||||
| onCancel={hideModal} | |||||
| cancelButtonProps={{ style: { display: 'none' } }} | |||||
| onOk={hideModal} | |||||
| okText={t('close', { keyPrefix: 'common' })} | |||||
| > | |||||
| <Paragraph copyable={{ text: id }} className={styles.id}> | |||||
| {id} | |||||
| </Paragraph> | |||||
| </Modal> | |||||
| </> | |||||
| ); | |||||
| }; | |||||
| export default ChatIdModal; |
| import { ReactComponent as ChatAppCube } from '@/assets/svg/chat-app-cube.svg'; | import { ReactComponent as ChatAppCube } from '@/assets/svg/chat-app-cube.svg'; | ||||
| import RenameModal from '@/components/rename-modal'; | import RenameModal from '@/components/rename-modal'; | ||||
| import { CloudOutlined, DeleteOutlined, EditOutlined } from '@ant-design/icons'; | |||||
| import { DeleteOutlined, EditOutlined, KeyOutlined } from '@ant-design/icons'; | |||||
| import { | import { | ||||
| Avatar, | Avatar, | ||||
| Button, | Button, | ||||
| useSelectDerivedConversationList, | useSelectDerivedConversationList, | ||||
| } from './hooks'; | } from './hooks'; | ||||
| import ChatOverviewModal from '@/components/api-service/chat-overview-modal'; | |||||
| import SvgIcon from '@/components/svg-icon'; | import SvgIcon from '@/components/svg-icon'; | ||||
| import { | import { | ||||
| useClickConversationCard, | useClickConversationCard, | ||||
| import { useSetModalState, useTranslate } from '@/hooks/common-hooks'; | import { useSetModalState, useTranslate } from '@/hooks/common-hooks'; | ||||
| import { useSetSelectedRecord } from '@/hooks/logic-hooks'; | import { useSetSelectedRecord } from '@/hooks/logic-hooks'; | ||||
| import { IDialog } from '@/interfaces/database/chat'; | import { IDialog } from '@/interfaces/database/chat'; | ||||
| import ChatIdModal from './chat-id-modal'; | |||||
| import styles from './index.less'; | import styles from './index.less'; | ||||
| const { Text } = Typography; | const { Text } = Typography; | ||||
| onClick: handleShowOverviewModal(dialog), | onClick: handleShowOverviewModal(dialog), | ||||
| label: ( | label: ( | ||||
| <Space> | <Space> | ||||
| <CloudOutlined /> | |||||
| <KeyOutlined /> | |||||
| {t('overview')} | {t('overview')} | ||||
| </Space> | </Space> | ||||
| ), | ), | ||||
| loading={conversationRenameLoading} | loading={conversationRenameLoading} | ||||
| ></RenameModal> | ></RenameModal> | ||||
| {overviewVisible && ( | {overviewVisible && ( | ||||
| <ChatOverviewModal | |||||
| <ChatIdModal | |||||
| visible={overviewVisible} | visible={overviewVisible} | ||||
| hideModal={hideOverviewModal} | hideModal={hideOverviewModal} | ||||
| id={currentRecord.id} | id={currentRecord.id} | ||||
| name={currentRecord.name} | name={currentRecord.name} | ||||
| idKey="dialogId" | idKey="dialogId" | ||||
| ></ChatOverviewModal> | |||||
| ></ChatIdModal> | |||||
| )} | )} | ||||
| </Flex> | </Flex> | ||||
| ); | ); |
| import { ReactComponent as ApiIcon } from '@/assets/svg/api.svg'; | |||||
| import { ReactComponent as LogoutIcon } from '@/assets/svg/logout.svg'; | import { ReactComponent as LogoutIcon } from '@/assets/svg/logout.svg'; | ||||
| import { ReactComponent as ModelIcon } from '@/assets/svg/model-providers.svg'; | import { ReactComponent as ModelIcon } from '@/assets/svg/model-providers.svg'; | ||||
| import { ReactComponent as PasswordIcon } from '@/assets/svg/password.svg'; | import { ReactComponent as PasswordIcon } from '@/assets/svg/password.svg'; | ||||
| [UserSettingRouteKey.System]: <MonitorOutlined style={{ fontSize: 24 }} />, | [UserSettingRouteKey.System]: <MonitorOutlined style={{ fontSize: 24 }} />, | ||||
| [UserSettingRouteKey.Team]: <TeamIcon />, | [UserSettingRouteKey.Team]: <TeamIcon />, | ||||
| [UserSettingRouteKey.Logout]: <LogoutIcon />, | [UserSettingRouteKey.Logout]: <LogoutIcon />, | ||||
| [UserSettingRouteKey.Api]: <ApiIcon />, | |||||
| }; | }; | ||||
| export * from '@/constants/setting'; | export * from '@/constants/setting'; |
| .apiWrapper { | |||||
| width: 100%; | |||||
| div[class^='chartWrapper'] { | |||||
| height: auto !important; | |||||
| } | |||||
| } |
| import ApiContent from '@/components/api-service/chat-overview-modal/api-content'; | |||||
| import styles from './index.less'; | |||||
| const ApiPage = () => { | |||||
| return ( | |||||
| <div className={styles.apiWrapper}> | |||||
| <ApiContent idKey="dialogId" hideChatPreviewCard></ApiContent> | |||||
| </div> | |||||
| ); | |||||
| }; | |||||
| export default ApiPage; |
| path: '/user-setting/system', | path: '/user-setting/system', | ||||
| component: '@/pages/user-setting/setting-system', | component: '@/pages/user-setting/setting-system', | ||||
| }, | }, | ||||
| { | |||||
| path: '/user-setting/api', | |||||
| component: '@/pages/user-setting/setting-api', | |||||
| }, | |||||
| ], | ], | ||||
| }, | }, | ||||
| { | { |
| deleteFactory, | deleteFactory, | ||||
| getSystemStatus, | getSystemStatus, | ||||
| getSystemVersion, | getSystemVersion, | ||||
| getSystemTokenList, | |||||
| removeSystemToken, | |||||
| createSystemToken, | |||||
| } = api; | } = api; | ||||
| const methods = { | const methods = { | ||||
| url: deleteFactory, | url: deleteFactory, | ||||
| method: 'post', | method: 'post', | ||||
| }, | }, | ||||
| listToken: { | |||||
| url: getSystemTokenList, | |||||
| method: 'get', | |||||
| }, | |||||
| createToken: { | |||||
| url: createSystemToken, | |||||
| method: 'post', | |||||
| }, | |||||
| removeToken: { | |||||
| url: removeSystemToken, | |||||
| method: 'delete', | |||||
| }, | |||||
| } as const; | } as const; | ||||
| const userService = registerServer<keyof typeof methods>(methods, request); | const userService = registerServer<keyof typeof methods>(methods, request); |
| // system | // system | ||||
| getSystemVersion: `${api_host}/system/version`, | getSystemVersion: `${api_host}/system/version`, | ||||
| getSystemStatus: `${api_host}/system/status`, | getSystemStatus: `${api_host}/system/status`, | ||||
| getSystemTokenList: `${api_host}/system/token_list`, | |||||
| createSystemToken: `${api_host}/system/new_token`, | |||||
| listSystemToken: `${api_host}/system/token_list`, | |||||
| removeSystemToken: `${api_host}/system/token`, | |||||
| // flow | // flow | ||||
| listTemplates: `${api_host}/canvas/templates`, | listTemplates: `${api_host}/canvas/templates`, |