From 47d09468fcbada2928dc1ebd15022cc24ec763fa Mon Sep 17 00:00:00 2001 From: Stephen Zhou Date: Fri, 13 Sep 2024 08:37:01 +0800 Subject: [PATCH] feat: integration with follow --- package.json | 7 +- pnpm-lock.yaml | 159 +++++------------- .../settings/general/page-component.tsx | 33 ++++ src/app/[locale]/site/[site]/feed/route.ts | 87 +++++++++- src/lib/expand-unit.ts | 7 + src/lib/server-helper.ts | 5 +- src/lib/types.ts | 4 + src/queries/site.ts | 5 + 8 files changed, 178 insertions(+), 129 deletions(-) diff --git a/package.json b/package.json index 5b9a50aee8..664b0a47af 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,6 @@ "isomorphic-dompurify": "2.11.0", "js-yaml": "4.1.0", "jsdom": "24.0.0", - "jsonfeed-to-rss": "3.0.8", "katex": "0.16.10", "langchain": "0.1.37", "lottie-react": "2.4.0", @@ -141,6 +140,7 @@ "remark-parse": "11.0.0", "remark-rehype": "11.1.0", "remove-markdown": "0.5.0", + "rss": "^1.2.2", "rss-parser": "3.13.0", "serialize-javascript": "6.0.2", "server-only": "0.0.1", @@ -176,6 +176,7 @@ "@types/react": "18.3.3", "@types/react-dom": "18.3.0", "@types/remove-markdown": "^0.3.4", + "@types/rss": "^0.0.32", "@types/serialize-javascript": "5.0.4", "@types/sortablejs": "1.15.8", "autoprefixer": "10.4.19", @@ -184,8 +185,8 @@ "eslint-config-next": "14.2.3", "eslint-plugin-import": "2.29.1", "eslint-plugin-react": "7.34.1", - "eslint-plugin-tailwindcss": "3.17.0", "eslint-plugin-react-hooks": "4.6.2", + "eslint-plugin-tailwindcss": "3.17.0", "eslint-plugin-unused-imports": "3.2.0", "husky": "9.0.11", "lint-staged": "15.2.4", @@ -219,4 +220,4 @@ "tailwindcss-variable-colors@0.0.2": "patches/tailwindcss-variable-colors@0.0.2.patch" } } -} \ No newline at end of file +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c0c103ed34..97c24c6b71 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -206,9 +206,6 @@ importers: jsdom: specifier: 24.0.0 version: 24.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) - jsonfeed-to-rss: - specifier: 3.0.8 - version: 3.0.8 katex: specifier: 0.16.10 version: 0.16.10 @@ -350,6 +347,9 @@ importers: remove-markdown: specifier: 0.5.0 version: 0.5.0 + rss: + specifier: ^1.2.2 + version: 1.2.2 rss-parser: specifier: 3.13.0 version: 3.13.0 @@ -450,6 +450,9 @@ importers: '@types/remove-markdown': specifier: ^0.3.4 version: 0.3.4 + '@types/rss': + specifier: ^0.0.32 + version: 0.0.32 '@types/serialize-javascript': specifier: 5.0.4 version: 5.0.4 @@ -665,9 +668,6 @@ packages: '@braintree/sanitize-url@6.0.4': resolution: {integrity: sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==} - '@bret/truthy@1.0.1': - resolution: {integrity: sha512-mFVhqy/yrh+BZwzqQQptGcTq5SJ+T0uhWQ/hmBkU0RFV3YN2UkcDhxvAzUuMDibOi6s66YM01BUGAi1y/92QGw==} - '@codemirror/autocomplete@6.16.0': resolution: {integrity: sha512-P/LeCTtZHRTCU4xQsa89vSKWecYv1ZqwzOd5topheGRf+qtacFgBeIMQi3eL8Kt/BUNvxUWkx+5qP2jlGoARrg==} peerDependencies: @@ -2124,9 +2124,6 @@ packages: '@tanstack/virtual-core@3.5.0': resolution: {integrity: sha512-KnPRCkQTyqhanNC0K63GBG3wA8I+D1fQuVnAvcBF8f13akOKeQp1gSbu6f77zCxhEk727iV5oQnbHLYzHrECLg==} - '@textlint/ast-node-types@13.4.1': - resolution: {integrity: sha512-qrZyhCh8Ekk6nwArx3BROybm9BnX6vF7VcZbijetV/OM3yfS4rTYhoMWISmhVEP2H2re0CtWEyMl/XF+WdvVLQ==} - '@tianfeng98/hls.js@1.0.2': resolution: {integrity: sha512-IHSLEBxlAllx5oecRfCvzsd23yuBuiSU2BmrNKDBwAf4dLjYcZW8TASG5i+SZg/rFyzXm4OWrLJKwPgwvSg5uA==} @@ -2223,6 +2220,9 @@ packages: '@types/retry@0.12.0': resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} + '@types/rss@0.0.32': + resolution: {integrity: sha512-2oKNqKyUY4RSdvl5eZR1n2Q9yvw3XTe3mQHsFPn9alaNBxfPnbXBtGP8R0SV8pK1PrVnLul0zx7izbm5/gF5Qw==} + '@types/serialize-javascript@5.0.4': resolution: {integrity: sha512-Z2R7UKFuNWCP8eoa2o9e5rkD3hmWxx/1L0CYz0k2BZzGh0PhEVMp9kfGiqEml/0IglwNERXZ2hwNzIrSz/KHTA==} @@ -2491,9 +2491,6 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - add-zero@1.0.0: - resolution: {integrity: sha512-WpPiUgy7h9Kd7NY0aTuhfx7vjub3XYbZCq1W2e/LMvUsEmYK/hz8xgFDmd0GnKpk44HXFwIFu1hEOivc+MzJ0Q==} - aes-js@3.1.2: resolution: {integrity: sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==} @@ -2735,9 +2732,6 @@ packages: borsh@0.7.0: resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} - boundary@2.0.0: - resolution: {integrity: sha512-rJKn5ooC9u8q13IMCrW0RSp31pxBCHE3y9V/tp3TdWSLf8Em3p6Di4NBpfzbJge9YjjFEsD0RtFEjtvHL5VyEA==} - brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} @@ -2873,10 +2867,6 @@ packages: classnames@2.5.1: resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} - clean-deep@3.4.0: - resolution: {integrity: sha512-Lo78NV5ItJL/jl+B5w0BycAisaieJGXK1qYi/9m4SjR8zbqmrUtO7Yhro40wEShGmmxs/aJLI/A+jNhdkXK8mw==} - engines: {node: '>=4'} - clear-module@4.1.2: resolution: {integrity: sha512-LWAxzHqdHsAZlPlEyJ2Poz6AIs384mPeqLVCru2p0BrP9G/kVGuhNyZYClLO6cXlnuJjzC8xtsJIuMjKqLXoAw==} engines: {node: '>=8'} @@ -3715,9 +3705,6 @@ packages: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} - existy@1.0.1: - resolution: {integrity: sha512-YeYTp9rIyoArnYubrTXHUOpuxwSdlQEctcw9zUgViSof/uJE+LlsiZb9BpIrCqLRcjiCCeF5cxX3wcfKZMqVzg==} - expand-template@2.0.3: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} @@ -4545,9 +4532,6 @@ packages: engines: {node: '>=6'} hasBin: true - jsonfeed-to-rss@3.0.8: - resolution: {integrity: sha512-KW5qhFGZxGyrT+oaAfS/xxiVindm406x0L6rsQLwG4nXSB4tcXebwXmXuUvg7FDfBniBTB8HgDRUTgZ67BE2rQ==} - jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} @@ -4834,27 +4818,15 @@ packages: lodash.defaults@4.2.0: resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} - lodash.get@4.4.2: - resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} - lodash.isarguments@3.1.0: resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} - lodash.isempty@4.4.0: - resolution: {integrity: sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg==} - lodash.isequal@4.5.0: resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} - lodash.isplainobject@4.0.6: - resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} - lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - lodash.transform@4.6.0: - resolution: {integrity: sha512-LO37ZnhmBVx0GvOU/caQuipEh4GN82TcWv3yHlebGDgOxbxiwwzW5Pcx2AcvpIv2WmvmSMoC492yQFNhy/l/UQ==} - lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} @@ -5146,10 +5118,18 @@ packages: resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} engines: {node: '>=8.6'} + mime-db@1.25.0: + resolution: {integrity: sha512-5k547tI4Cy+Lddr/hdjNbBEWBwSl8EBc5aSdKvedav8DReADgWJzcYiktaRIw3GtGC1jjwldXtTzvqJZmtvC7w==} + engines: {node: '>= 0.6'} + mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} + mime-types@2.1.13: + resolution: {integrity: sha512-ryBDp1Z/6X90UvjUK3RksH0IBPM137T7cmg4OgD5wQBojlAiUwuok0QeELkim/72EtcYuNlmbkrcGuxj3Kl0YQ==} + engines: {node: '>= 0.6'} + mime-types@2.1.35: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} @@ -5621,9 +5601,6 @@ packages: resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} engines: {node: '>=10.13.0'} - podcast-categories@2.0.0: - resolution: {integrity: sha512-WcntiTmj4ERPwaevHeR59Lc6yk37YVwksflBaCu7/J2ChjPA02J703rZMVq4gnoa+XHFHqpjK+qSc8Fv6N62EA==} - possible-typed-array-names@1.0.0: resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} engines: {node: '>= 0.4'} @@ -6145,6 +6122,9 @@ packages: rss-parser@3.13.0: resolution: {integrity: sha512-7jWUBV5yGN3rqMMj7CZufl/291QAhvrrGpDNE4k/02ZchL0npisiYYqULF71jCEKoIiHvK/Q2e6IkDwPziT7+w==} + rss@1.2.2: + resolution: {integrity: sha512-xUhRTgslHeCBeHAqaWSbOYTydN2f0tAzNXvzh3stjz7QDhQMzdgHf3pfgNIngeytQflrFPfy6axHilTETr6gDg==} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -6208,9 +6188,6 @@ packages: engines: {node: '>=10'} hasBin: true - sentence-splitter@5.0.0: - resolution: {integrity: sha512-9Mvf7L8vwpPzkH0/HtXzCbmVkyj4aQXdeG7h8ighRvO0hvcZEy2OUEjeIlnM/z4EX4vBacEfpESC65Oa2rWOig==} - serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} @@ -6415,12 +6392,6 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - striptags@3.2.0: - resolution: {integrity: sha512-g45ZOGzHDMe2bdYMdIvdAfCQkCTDMGBazSw1ypMowwGIee7ZQ5dU0rBJ8Jqgl+jAKIv4dbeE1jscZq9wid1Tkw==} - - structured-source@4.0.0: - resolution: {integrity: sha512-qGzRFNJDjFieQkl/sVOI2dUjHKRyL9dAJi2gCPGJLbJHBIkyOHxjuocpIEfbLioX+qSJpvbYdT49/YCdMznKxA==} - style-mod@4.1.2: resolution: {integrity: sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==} @@ -6581,17 +6552,9 @@ packages: resolution: {integrity: sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==} engines: {node: '>=18'} - trim-left@1.0.1: - resolution: {integrity: sha512-quyxKUsLsY7+lgue8TQ6R8C4kwTe5No3/fvliPNTZd8CIK1KXFaIw+Z7SwAWiWUF5Ge5j7ppbjml3EKa02uPWA==} - engines: {node: '>=0.10.0'} - trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} - trim-right@1.0.1: - resolution: {integrity: sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw==} - engines: {node: '>=0.10.0'} - trough@2.2.0: resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} @@ -7089,14 +7052,13 @@ packages: resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==} engines: {node: '>=4.0.0'} + xml@1.0.1: + resolution: {integrity: sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==} + xmlbuilder@11.0.1: resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} engines: {node: '>=4.0'} - xmlbuilder@15.1.1: - resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} - engines: {node: '>=8.0'} - xmlchars@2.2.0: resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} @@ -7353,10 +7315,6 @@ snapshots: '@braintree/sanitize-url@6.0.4': {} - '@bret/truthy@1.0.1': - dependencies: - existy: 1.0.1 - '@codemirror/autocomplete@6.16.0(@codemirror/language@6.10.1)(@codemirror/state@6.4.1)(@codemirror/view@6.26.3)(@lezer/common@1.2.1)': dependencies: '@codemirror/language': 6.10.1 @@ -9069,8 +9027,6 @@ snapshots: '@tanstack/virtual-core@3.5.0': {} - '@textlint/ast-node-types@13.4.1': {} - '@tianfeng98/hls.js@1.0.2': {} '@types/async-lock@1.4.2': {} @@ -9165,6 +9121,8 @@ snapshots: '@types/retry@0.12.0': {} + '@types/rss@0.0.32': {} + '@types/serialize-javascript@5.0.4': {} '@types/shimmer@1.0.5': {} @@ -9747,8 +9705,6 @@ snapshots: acorn@8.11.3: {} - add-zero@1.0.0: {} - aes-js@3.1.2: {} agent-base@7.1.1: @@ -10041,8 +9997,6 @@ snapshots: bs58: 4.0.1 text-encoding-utf-8: 1.0.2 - boundary@2.0.0: {} - brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 @@ -10190,12 +10144,6 @@ snapshots: classnames@2.5.1: {} - clean-deep@3.4.0: - dependencies: - lodash.isempty: 4.4.0 - lodash.isplainobject: 4.0.6 - lodash.transform: 4.6.0 - clear-module@4.1.2: dependencies: parent-module: 2.0.0 @@ -11226,8 +11174,6 @@ snapshots: signal-exit: 4.1.0 strip-final-newline: 3.0.0 - existy@1.0.1: {} - expand-template@2.0.3: {} exponential-backoff@3.1.1: {} @@ -12159,21 +12105,6 @@ snapshots: json5@2.2.3: {} - jsonfeed-to-rss@3.0.8: - dependencies: - '@bret/truthy': 1.0.1 - add-zero: 1.0.0 - clean-deep: 3.4.0 - existy: 1.0.1 - lodash.get: 4.4.2 - lodash.merge: 4.6.2 - podcast-categories: 2.0.0 - sentence-splitter: 5.0.0 - striptags: 3.2.0 - trim-left: 1.0.1 - trim-right: 1.0.1 - xmlbuilder: 15.1.1 - jsonfile@6.1.0: dependencies: universalify: 2.0.1 @@ -12426,20 +12357,12 @@ snapshots: lodash.defaults@4.2.0: {} - lodash.get@4.4.2: {} - lodash.isarguments@3.1.0: {} - lodash.isempty@4.4.0: {} - lodash.isequal@4.5.0: {} - lodash.isplainobject@4.0.6: {} - lodash.merge@4.6.2: {} - lodash.transform@4.6.0: {} - lodash@4.17.21: {} log-update@6.0.0: @@ -13106,8 +13029,14 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 + mime-db@1.25.0: {} + mime-db@1.52.0: {} + mime-types@2.1.13: + dependencies: + mime-db: 1.25.0 + mime-types@2.1.35: dependencies: mime-db: 1.52.0 @@ -13575,8 +13504,6 @@ snapshots: pngjs@5.0.0: {} - podcast-categories@2.0.0: {} - possible-typed-array-names@1.0.0: {} postcss-import@15.1.0(postcss@8.4.38): @@ -14197,6 +14124,11 @@ snapshots: entities: 2.2.0 xml2js: 0.5.0 + rss@1.2.2: + dependencies: + mime-types: 2.1.13 + xml: 1.0.1 + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 @@ -14254,11 +14186,6 @@ snapshots: semver@7.6.2: {} - sentence-splitter@5.0.0: - dependencies: - '@textlint/ast-node-types': 13.4.1 - structured-source: 4.0.0 - serialize-javascript@6.0.2: dependencies: randombytes: 2.1.0 @@ -14483,12 +14410,6 @@ snapshots: strip-json-comments@3.1.1: {} - striptags@3.2.0: {} - - structured-source@4.0.0: - dependencies: - boundary: 2.0.0 - style-mod@4.1.2: {} style-to-object@1.0.6: @@ -14663,12 +14584,8 @@ snapshots: dependencies: punycode: 2.3.1 - trim-left@1.0.1: {} - trim-lines@3.0.1: {} - trim-right@1.0.1: {} - trough@2.2.0: {} ts-api-utils@1.3.0(typescript@5.4.5): @@ -15210,9 +15127,9 @@ snapshots: sax: 1.3.0 xmlbuilder: 11.0.1 - xmlbuilder@11.0.1: {} + xml@1.0.1: {} - xmlbuilder@15.1.1: {} + xmlbuilder@11.0.1: {} xmlchars@2.2.0: {} diff --git a/src/app/[locale]/dashboard/[subdomain]/settings/general/page-component.tsx b/src/app/[locale]/dashboard/[subdomain]/settings/general/page-component.tsx index 898a0a7ce8..b5124479ea 100644 --- a/src/app/[locale]/dashboard/[subdomain]/settings/general/page-component.tsx +++ b/src/app/[locale]/dashboard/[subdomain]/settings/general/page-component.tsx @@ -36,6 +36,8 @@ export default function SiteSettingsGeneralPage() { uh: "", code_theme_light: "", code_theme_dark: "", + follow_feed_id: undefined, + follow_user_id: undefined, } as { icon?: string banner?: { @@ -51,6 +53,8 @@ export default function SiteSettingsGeneralPage() { uh: string code_theme_light: string code_theme_dark: string + follow_feed_id?: string + follow_user_id?: string }, }) @@ -70,6 +74,10 @@ export default function SiteSettingsGeneralPage() { light: values.code_theme_light, dark: values.code_theme_dark, }, + follow: { + feed_id: values.follow_feed_id, + user_id: values.follow_user_id, + }, }) }) @@ -126,6 +134,16 @@ export default function SiteSettingsGeneralPage() { site.data.metadata?.content?.code_theme?.dark || "github-dark-default", ) + !form.getValues("follow_feed_id") && + form.setValue( + "follow_feed_id", + site.data.metadata?.content?.follow?.feed_id, + ) + !form.getValues("follow_user_id") && + form.setValue( + "follow_user_id", + site.data.metadata?.content?.follow?.user_id, + ) } }, [site.data, form]) @@ -248,6 +266,21 @@ export default function SiteSettingsGeneralPage() { {...form.register("code_theme_dark")} /> +
+

Follow

+
+ + +
+
({ id: page.characterId + "-" + page.noteId, title: page.metadata?.content?.title || "Untitled", @@ -84,13 +98,84 @@ export async function GET( })), } + const feed = new RSS({ + title: + site?.metadata?.content?.site_name || + site?.metadata?.content?.name || + "Untitled", + description: site?.metadata?.content?.bio, + image_url: site?.metadata?.content?.avatars?.[0], + site_url: link, + feed_url: `${link}/feed`, + custom_namespaces: { + itunes: "http://www.itunes.com/dtds/podcast-1.0.dtd", + }, + custom_elements: [ + ...(hasAudio + ? [ + { "itunes:image": site?.metadata?.content?.avatars?.[0] }, + { + "itunes:author": + site?.metadata?.content?.site_name || + site?.metadata?.content?.name, + }, + { "itunes:summary": site?.metadata?.content?.bio }, + { + "itunes:owner": [ + { + "itunes:email": email, + }, + { + "itunes:name": site?.metadata?.content?.name, + }, + ], + }, + ] + : []), + ...(followFeedId && followUserId + ? [ + { + follow_challenge: [ + { feedId: followFeedId }, + { userId: followUserId }, + ], + }, + , + ] + : []), + ], + }) + + pages.list.forEach((page) => { + feed.item({ + guid: page.characterId + "-" + page.noteId, + title: page.metadata?.content?.title || "Untitled", + description: page.metadata?.content?.summary, + custom_elements: [ + { + "content:encoded": page.metadata?.content?.contentHTML, + }, + ], + url: `${SITE_URL}/api/redirection?characterId=${page.characterId}¬eId=${page.noteId}`, + date: new Date(page.metadata?.content?.date_published), + categories: page.metadata?.content?.tags, + author: site?.metadata?.content?.name, + enclosure: hasAudio + ? { + url: page.metadata?.content?.audio, + type: "audio/mpeg", + } + : undefined, + }) + }) + const format = new URLSearchParams(request.url.split("?")[1]).get("format") === "json" ? "json" : "xml" const res = new NextServerResponse() - return res.status(200).rss(data, format) + return res.status(200).rss(format === "json" ? data : feed.xml(), format) } export const dynamic = "force-dynamic" diff --git a/src/lib/expand-unit.ts b/src/lib/expand-unit.ts index 0a786b6ba5..eb776a6c63 100644 --- a/src/lib/expand-unit.ts +++ b/src/lib/expand-unit.ts @@ -277,6 +277,13 @@ export const expandCrossbellCharacter = async (site: CharacterEntity) => { dark: "github-dark-default", } + expandedCharacter.metadata.content.follow = + JSON.parse( + (expandedCharacter.metadata?.content?.attributes?.find( + (a: any) => a.trait_type === "xlog_follow", + )?.value as string) || "null", + ) || undefined + const getArribute = (outputKey: string, typeKey: string) => { ;(expandedCharacter.metadata.content as any)[outputKey] = expandedCharacter.metadata?.content?.attributes?.find( diff --git a/src/lib/server-helper.ts b/src/lib/server-helper.ts index 09904ce6d1..d5792a0a33 100644 --- a/src/lib/server-helper.ts +++ b/src/lib/server-helper.ts @@ -1,6 +1,3 @@ -// @ts-ignore -import jsonfeedToRSS from "jsonfeed-to-rss" - export const getQuery = (req: Request) => { const url = new URL(req.url) const searchParams = url.searchParams @@ -69,7 +66,7 @@ export class NextServerResponse { rss(data: any, format = "json") { if (format === "xml") { - return new Response(jsonfeedToRSS(data), { + return new Response(data, { status: this.#status, headers: { "Content-Type": "application/xml; charset=utf-8", diff --git a/src/lib/types.ts b/src/lib/types.ts index 0b2740dbd2..23b3a3fe0a 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -132,6 +132,10 @@ export type ExpandedCharacter = CharacterEntity & { light?: BundledTheme dark?: BundledTheme } + follow?: { + feed_id?: string + user_id?: string + } } } } diff --git a/src/queries/site.ts b/src/queries/site.ts index b2a9729dad..85297590a3 100644 --- a/src/queries/site.ts +++ b/src/queries/site.ts @@ -152,6 +152,10 @@ export function useUpdateSite() { light?: string dark?: string } + follow?: { + feed_id?: string + user_id?: string + } }) => { if (!input.characterId) { throw new Error("characterId are required") @@ -222,6 +226,7 @@ export function useUpdateSite() { } setAttribute("navigation", "navigation", true) setAttribute("code_theme", "code_theme", true) + setAttribute("follow", "follow", true) setAttribute("css", "css") setAttribute("ga", "ga") setAttribute("ua", "ua")