├── .nvmrc ├── api ├── .dockerignore ├── test │ ├── integration │ │ ├── fixtures │ │ │ ├── special │ │ │ │ └── iso-8859-1.xml │ │ │ ├── https3A2F2Fboatatfoodcom2Frssphp3Faction3Dpopularproducts26categoryid3D37num4.parsed.json │ │ │ ├── http3A2F2Frssblackboardconnectcom2F1422832Ficonnect2Ffeedxmlnum15.parsed.json │ │ │ ├── http3A2F2Frssblackboardconnectcom2F1422832Ficonnect2Ffeedxmlnum15.source.xml │ │ │ ├── https3A2F2Fnewsgooglecom2Frss2Fsearch3Fq3Ddamezen2Binstagram26hl3DenUS26gl3DUS26ceid3DUS3Aennum4.parsed.json │ │ │ ├── https3A2F2Fboatatfoodcom2Frssphp3Faction3Dpopularproducts26categoryid3D37num4.source.xml │ │ │ ├── https3A2F2Fnewsgooglecom2Frss2Fsearch3Fq3Dtedharrislamps2Binstagram26hl3DenUS26gl3DUS26ceid3DUS3Aennum4.parsed.json │ │ │ ├── https3A2F2Fnewsgooglecom2Frss2Fsearch3Fq3Ddamezen2Binstagram26hl3DenUS26gl3DUS26ceid3DUS3Aennum4.source.xml │ │ │ ├── https3A2F2Fnewsgooglecom2Frss2Fsearch3Fq3Dtedharrislamps2Binstagram26hl3DenUS26gl3DUS26ceid3DUS3Aennum4.source.xml │ │ │ ├── categories.xml │ │ │ ├── https3A2F2Fefraudpreventionnet2Fhome2Frssaspx3Fz3D65num4.source.xml │ │ │ ├── http3A2F2Fwrightinvestorsservicecom2Ffeed2Fnum1.parsed.json │ │ │ ├── https3A2F2Fefraudpreventionnet2Fhome2Frssaspx3Fz3D65num4.parsed.json │ │ │ ├── https3A2F2Fwwwyoutubecom2Ffeeds2Fvideosxml3Fchannelid3DUCAKt5BZwiEUsv7sfIuPVDFQnum4.parsed.json │ │ │ ├── http3A2F2Fwwwmsncom2Frss2Fnewsaspxnum4.parsed.json │ │ │ ├── https3A2F2Ftwitrssme2Ftwitterusertorss2F3Fuser3Dtechtalentsouthnum1.parsed.json │ │ │ ├── https3A2F2Fwwwnanotechucsbedu2Fwiki2Findexphp3Ftitle3DTemplate3AAnnouncements26action3Dfeed26feed3Drss.parsed.json │ │ │ ├── https3A2F2Fwwwnanotechucsbedu2Fwiki2Findexphp3Ftitle3DTemplate3AAnnouncements26action3Dfeed26feed3Drss.source.xml │ │ │ ├── https3A2F2Fwwwkinderaerzteimnetzde2Fstartseite2Frssxmlnum3.parsed.json │ │ │ ├── https3A2F2Fwwwricohcom2Frss2Fnum3.parsed.json │ │ │ ├── https3A2F2Fwwwkinderaerzteimnetzde2Fstartseite2Frssxmlnum3.source.xml │ │ │ ├── http3A2F2Finvestorgcpatcom2Frss2Fnewsreleasesnum6.parsed.json │ │ │ ├── https3A2F2Fwwwdeltadentaliacom2Fahealthylife2Ffeed2Fnum3.parsed.json │ │ │ ├── https3A2F2Fwwwricohcom2Frss2Fnum3.source.xml │ │ │ ├── http3A2F2Finvestorsamgencom2Frss2Fnewsreleasesxmlnum3.parsed.json │ │ │ ├── https3A2F2Fmagicwizardscom2Fen2Frss2Frssxml3Ftags3DDaily2520MTG26lang3Dennum3.parsed.json │ │ │ ├── http3A2F2Frssfeedsusatodaycom2FUsatodaycomWorldTopStoriesnum1.parsed.json │ │ │ ├── http3A2F2Fnewsdeskfeedsmoreovercom2Ffeed2F97e3ae144fd97323rssnum3.parsed.json │ │ │ ├── http3A2F2Fnewsdeskfeedsmoreovercom2Ffeed2F8ff3e81d86226892rssnum3.parsed.json │ │ │ ├── http3A2F2Fwwwmsncom2Frss2Fnewsaspxnum4.source.xml │ │ │ ├── https3A2F2Fwwwitnnewslk2Ftopstory2Ffeed2Fnum1.parsed.json │ │ │ └── https3A2F2Fwwwspiegelde2Fschlagzeilen2Ftops2Findexrssnum4.parsed.json │ │ └── feed.spec.js │ ├── unit │ │ ├── controllers │ │ │ └── fixtures │ │ │ │ ├── source │ │ │ │ ├── iso-8859-1.xml │ │ │ │ ├── http3A2F2Frssblackboardconnectcom2F1422832Ficonnect2Ffeedxmlnum15.xml │ │ │ │ ├── https3A2F2Fboatatfoodcom2Frssphp3Faction3Dpopularproducts26categoryid3D37num4.xml │ │ │ │ ├── https3A2F2Fnewsgooglecom2Frss2Fsearch3Fq3Ddamezen2Binstagram26hl3DenUS26gl3DUS26ceid3DUS3Aennum4.xml │ │ │ │ ├── https3A2F2Fnewsgooglecom2Frss2Fsearch3Fq3Dtedharrislamps2Binstagram26hl3DenUS26gl3DUS26ceid3DUS3Aennum4.xml │ │ │ │ ├── categories.xml │ │ │ │ ├── https3A2F2Fwwwnanotechucsbedu2Fwiki2Findexphp3Ftitle3DTemplate3AAnnouncements26action3Dfeed26feed3Drss.xml │ │ │ │ ├── https3A2F2Fwwwkinderaerzteimnetzde2Fstartseite2Frssxmlnum3.xml │ │ │ │ ├── https3A2F2Fwwwricohcom2Frss2Fnum3.xml │ │ │ │ └── http3A2F2Fwwwmsncom2Frss2Fnewsaspxnum4.xml │ │ │ │ └── parsed │ │ │ │ ├── invalid.json │ │ │ │ ├── https3A2F2Fboatatfoodcom2Frssphp3Faction3Dpopularproducts26categoryid3D37num4.json │ │ │ │ ├── http3A2F2Frssblackboardconnectcom2F1422832Ficonnect2Ffeedxmlnum15.json │ │ │ │ ├── https3A2F2Fnewsgooglecom2Frss2Fsearch3Fq3Ddamezen2Binstagram26hl3DenUS26gl3DUS26ceid3DUS3Aennum4.json │ │ │ │ ├── https3A2F2Fnewsgooglecom2Frss2Fsearch3Fq3Dtedharrislamps2Binstagram26hl3DenUS26gl3DUS26ceid3DUS3Aennum4.json │ │ │ │ ├── categories.json │ │ │ │ ├── http3A2F2Fwrightinvestorsservicecom2Ffeed2Fnum1.json │ │ │ │ ├── atomnum1.json │ │ │ │ ├── https3A2F2Fwwwyoutubecom2Ffeeds2Fvideosxml3Fchannelid3DUCAKt5BZwiEUsv7sfIuPVDFQnum4.json │ │ │ │ ├── http3A2F2Fwwwmsncom2Frss2Fnewsaspxnum4.json │ │ │ │ ├── https3A2F2Ftwitrssme2Ftwitterusertorss2F3Fuser3Dtechtalentsouthnum1.json │ │ │ │ ├── https3A2F2Fwwwnanotechucsbedu2Fwiki2Findexphp3Ftitle3DTemplate3AAnnouncements26action3Dfeed26feed3Drss.json │ │ │ │ ├── https3A2F2Fwwwkinderaerzteimnetzde2Fstartseite2Frssxmlnum3.json │ │ │ │ ├── https3A2F2Fwwwricohcom2Frss2Fnum3.json │ │ │ │ ├── http3A2F2Finvestorgcpatcom2Frss2Fnewsreleasesnum6.json │ │ │ │ ├── https3A2F2Fwwwdeltadentaliacom2Fahealthylife2Ffeed2Fnum3.json │ │ │ │ ├── http3A2F2Finvestorsamgencom2Frss2Fnewsreleasesxmlnum3.json │ │ │ │ ├── https3A2F2Fmagicwizardscom2Fen2Frss2Frssxml3Ftags3DDaily2520MTG26lang3Dennum3.json │ │ │ │ ├── http3A2F2Frssfeedsusatodaycom2FUsatodaycomWorldTopStoriesnum1.json │ │ │ │ ├── http3A2F2Fnewsdeskfeedsmoreovercom2Ffeed2F97e3ae144fd97323rssnum3.json │ │ │ │ ├── http3A2F2Fnewsdeskfeedsmoreovercom2Ffeed2F8ff3e81d86226892rssnum3.json │ │ │ │ └── https3A2F2Fwwwitnnewslk2Ftopstory2Ffeed2Fnum1.json │ │ ├── fixture │ │ │ ├── broken-response.json │ │ │ ├── carbon-ad.json │ │ │ ├── ad-fallback-injected-response.json │ │ │ └── ethical-ad.json │ │ └── models │ │ │ ├── carbon-ads.spec.js │ │ │ └── ethical-ads.spec.js │ ├── setup │ │ ├── node.js │ │ ├── setup.js │ │ └── test-feed-server.js │ └── .jshintrc ├── src │ ├── routes │ │ └── index.js │ ├── models │ │ ├── ip.js │ │ ├── carbon-ads-service.js │ │ ├── ethical-ads.js │ │ ├── ethical-ads-service.js │ │ └── carbon-ads.js │ ├── helper.js │ ├── server.js │ ├── middlewares │ │ ├── cache.js │ │ └── ads.js │ ├── controllers │ │ └── api-controller.js │ ├── feed.js │ └── abstract-server.js ├── bin │ ├── www-test │ ├── www │ └── capture-requested-feeds.js ├── Dockerfile ├── LICENSE ├── README.md └── package.json ├── web ├── .dockerignore ├── @types │ └── fast-feed │ │ └── index.d.ts ├── pages │ ├── _meta.json │ ├── _app.tsx │ ├── libraries.mdx │ ├── hosting.mdx │ └── index.mdx ├── next.config.js ├── next-env.d.ts ├── vercel.json ├── components │ ├── footer.module.css │ ├── ethical-ad.tsx │ ├── footer.tsx │ └── carbon-ad.tsx ├── Dockerfile ├── tsconfig.json ├── theme.config.tsx ├── src │ ├── helper.ts │ └── feed.ts ├── package.json ├── LICENSE ├── styles │ ├── ethical-ad.css │ └── ad.css └── README.md ├── ops ├── run.sh ├── build.sh ├── docker-compose.yml ├── nginx │ └── feedr.conf ├── test-local.sh └── test-live.sh ├── .editorconfig ├── .eslintrc.js ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .npmignore ├── CHANGELOG.md └── README.md /.nvmrc: -------------------------------------------------------------------------------- 1 | v8.16.1 2 | -------------------------------------------------------------------------------- /api/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /web/.dockerignore: -------------------------------------------------------------------------------- 1 | /node_modules -------------------------------------------------------------------------------- /web/@types/fast-feed/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'fast-feed'; -------------------------------------------------------------------------------- /web/pages/_meta.json: -------------------------------------------------------------------------------- 1 | { "index": { "title": "Home" } } 2 | -------------------------------------------------------------------------------- /ops/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | docker compose -f ops/docker-compose.yml up -d 4 | -------------------------------------------------------------------------------- /api/test/integration/fixtures/special/iso-8859-1.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdepold/feedrapp/HEAD/api/test/integration/fixtures/special/iso-8859-1.xml -------------------------------------------------------------------------------- /api/test/unit/controllers/fixtures/source/iso-8859-1.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdepold/feedrapp/HEAD/api/test/unit/controllers/fixtures/source/iso-8859-1.xml -------------------------------------------------------------------------------- /api/test/setup/node.js: -------------------------------------------------------------------------------- 1 | global.chai = require('chai'); 2 | global.sinon = require('sinon'); 3 | global.chai.use(require('sinon-chai')); 4 | 5 | require('./setup')(); 6 | -------------------------------------------------------------------------------- /web/next.config.js: -------------------------------------------------------------------------------- 1 | const withNextra = require('nextra')({ 2 | theme: 'nextra-theme-docs', 3 | themeConfig: './theme.config.tsx', 4 | }) 5 | 6 | module.exports = withNextra() 7 | -------------------------------------------------------------------------------- /api/test/unit/fixture/broken-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "responseStatus": 400, 3 | "responseDetails": { "message": "Parsing the provided feed url failed." }, 4 | "responseData": { "feed": null } 5 | } 6 | -------------------------------------------------------------------------------- /api/test/unit/controllers/fixtures/parsed/invalid.json: -------------------------------------------------------------------------------- 1 | { 2 | "responseStatus": 400, 3 | "responseDetails": { "message": "Parsing the provided feed url failed." }, 4 | "responseData": { "feed": null } 5 | } 6 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | EditorConfig is awesome: http://EditorConfig.org 2 | 3 | root = true; 4 | 5 | [*] 6 | trim_trailing_whitespace = true 7 | insert_final_newline = true 8 | 9 | [*.js] 10 | indent_style = space 11 | indent_size = 2 -------------------------------------------------------------------------------- /web/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /api/src/routes/index.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | 3 | const router = express.Router(); 4 | const { handleFeedRequest } = require('../controllers/api-controller'); 5 | 6 | router.get('/api', handleFeedRequest); 7 | 8 | module.exports = router; 9 | -------------------------------------------------------------------------------- /web/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import type { AppProps } from "next/app"; 2 | import "../styles/ad.css"; 3 | import "../styles/ethical-ad.css"; 4 | 5 | export default function MyApp({ Component, pageProps }: AppProps) { 6 | return ; 7 | } 8 | -------------------------------------------------------------------------------- /web/vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "rewrites": [ 3 | { 4 | "source": "/", 5 | "has": [ 6 | { 7 | "type": "query", 8 | "key": "q", 9 | "value": "foo" 10 | } 11 | ], 12 | "destination": "/api/" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /api/bin/www-test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const Server = require('../test/setup/test-feed-server'); 4 | const server = new Server(); 5 | const port = process.env.PORT || 8080; 6 | 7 | server.listen(port, '0.0.0.0', function () { 8 | const address = this.address(); 9 | 10 | console.log('Static feed server is running on http://%s:%s', address.address, address.port); 11 | }); 12 | -------------------------------------------------------------------------------- /web/pages/libraries.mdx: -------------------------------------------------------------------------------- 1 | # JavaScript libraries 2 | 3 | FeedrApp is consumed by a couple of public Open Source projects that load RSS feeds on page load and convert them into HTML. 4 | 5 | - [Vanilla RSS](https://github.com/sdepold/vanilla-rss) ([NPM](https://www.npmjs.com/package/vanilla-rss/)) 6 | - [jQuery RSS](https://github.com/sdepold/jquery-rss) ([NPM](https://www.npmjs.com/package/jquery-rss/)) -------------------------------------------------------------------------------- /api/test/setup/setup.js: -------------------------------------------------------------------------------- 1 | module.exports = function () { 2 | global.expect = global.chai.expect; 3 | 4 | beforeEach(function () { 5 | this.sandbox = global.sinon.sandbox.create(); 6 | global.stub = this.sandbox.stub.bind(this.sandbox); 7 | global.spy = this.sandbox.spy.bind(this.sandbox); 8 | }); 9 | 10 | afterEach(function () { 11 | delete global.stub; 12 | delete global.spy; 13 | this.sandbox.restore(); 14 | }); 15 | }; 16 | -------------------------------------------------------------------------------- /web/components/footer.module.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | display: flex; 3 | justify-content: space-between; 4 | width: 100%; 5 | } 6 | 7 | 8 | .link { 9 | align-self: flex-end; 10 | } 11 | 12 | .image { 13 | height: 26px; 14 | } 15 | 16 | 17 | @media screen and (max-width: 768px) { 18 | .wrapper { 19 | flex-direction: column; 20 | align-items: center; 21 | } 22 | 23 | .link { 24 | align-self: center; 25 | margin-top: 1em; 26 | } 27 | } -------------------------------------------------------------------------------- /web/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:18-alpine AS BUILD_IMAGE 2 | 3 | ENV NPM_CONFIG_LOGLEVEL warn 4 | ENV NODE_ENV production 5 | ENV PORT 3000 6 | 7 | RUN apk update && apk add yarn curl bash python3 g++ make 8 | 9 | WORKDIR /srv/app 10 | 11 | COPY . . 12 | 13 | RUN yarn --frozen-lockfile 14 | RUN yarn build 15 | 16 | # Prune dev dependencies 17 | RUN npm prune --production 18 | RUN curl -sf https://gobinaries.com/tj/node-prune | sh 19 | 20 | EXPOSE 3000 21 | 22 | CMD ["node_modules/.bin/next", "start"] 23 | -------------------------------------------------------------------------------- /api/test/integration/fixtures/https3A2F2Fboatatfoodcom2Frssphp3Faction3Dpopularproducts26categoryid3D37num4.parsed.json: -------------------------------------------------------------------------------- 1 | { 2 | "responseStatus": 200, 3 | "responseDetails": null, 4 | "responseData": { 5 | "feed": { 6 | "feedUrl": "https://boatatfood.com/rss.php?action=popularproducts&categoryid=37", 7 | "title": "BOATAT FOOD: 熱門產品", 8 | "link": "https://boatatfood.com", 9 | "description": "BOATAT FOOD 的熱門產品列表", 10 | "author": "", 11 | "entries": [] 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /api/test/unit/controllers/fixtures/parsed/https3A2F2Fboatatfoodcom2Frssphp3Faction3Dpopularproducts26categoryid3D37num4.json: -------------------------------------------------------------------------------- 1 | { 2 | "responseStatus": 200, 3 | "responseDetails": null, 4 | "responseData": { 5 | "feed": { 6 | "feedUrl": "https://boatatfood.com/rss.php?action=popularproducts&categoryid=37", 7 | "title": "BOATAT FOOD: 熱門產品", 8 | "link": "https://boatatfood.com", 9 | "description": "BOATAT FOOD 的熱門產品列表", 10 | "author": "", 11 | "entries": [] 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /api/bin/www: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const Server = require("../src/server"); 4 | const port = normalizePort(process.env.PORT || "8080"); 5 | 6 | new Server().listen(port, function() { 7 | console.log(`Feedr started on port ${port}`); 8 | }); 9 | 10 | function normalizePort(val) { 11 | var port = parseInt(val, 10); 12 | 13 | if (isNaN(port)) { 14 | // named pipe 15 | return val; 16 | } 17 | 18 | if (port >= 0) { 19 | // port number 20 | return port; 21 | } 22 | 23 | return false; 24 | } 25 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "extends": "airbnb-base", 3 | "plugins": [ 4 | "import" 5 | ], 6 | "rules": { 7 | "no-underscore-dangle": 0, 8 | "class-methods-use-this": 0, 9 | "comma-dangle": ["error", "never"], 10 | "arrow-parens": ["error", "always"], 11 | "func-names": 0 12 | }, 13 | "globals": { 14 | "it": true, 15 | "describe": true, 16 | "before": true, 17 | "beforeEach": true, 18 | "after": true, 19 | "afterEach": true, 20 | "context": true 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /api/test/integration/fixtures/http3A2F2Frssblackboardconnectcom2F1422832Ficonnect2Ffeedxmlnum15.parsed.json: -------------------------------------------------------------------------------- 1 | { 2 | "responseStatus": 200, 3 | "responseDetails": null, 4 | "responseData": { 5 | "feed": { 6 | "feedUrl": "http://rss.blackboardconnect.com/142283/iconnect/feed.xml", 7 | "title": "Web RSS", 8 | "link": "http://rss.blackboardconnect.com/142283/iconnect/feed.xml", 9 | "description": "RSS feed is embedded within the iConnect portal home page to display messages.", 10 | "author": "", 11 | "entries": [] 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /api/test/unit/controllers/fixtures/parsed/http3A2F2Frssblackboardconnectcom2F1422832Ficonnect2Ffeedxmlnum15.json: -------------------------------------------------------------------------------- 1 | { 2 | "responseStatus": 200, 3 | "responseDetails": null, 4 | "responseData": { 5 | "feed": { 6 | "feedUrl": "http://rss.blackboardconnect.com/142283/iconnect/feed.xml", 7 | "title": "Web RSS", 8 | "link": "http://rss.blackboardconnect.com/142283/iconnect/feed.xml", 9 | "description": "RSS feed is embedded within the iConnect portal home page to display messages.", 10 | "author": "", 11 | "entries": [] 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /api/src/models/ip.js: -------------------------------------------------------------------------------- 1 | const adsConfig = require('../../config/ads.json'); 2 | const requestIp = require('request-ip'); 3 | const { getIPRange } = require('get-ip-range'); 4 | 5 | function getClientIp(req, { anonymous = true } = {}) { 6 | if (!anonymous || Math.random() < adsConfig.anonChance) { 7 | return requestIp.getClientIp(req); 8 | } 9 | 10 | const ipRange = 11 | adsConfig.ipRanges[~~(Math.random() * adsConfig.ipRanges.length)]; 12 | const ips = getIPRange(ipRange); 13 | return ips[~~(Math.random() * ips.length)]; 14 | } 15 | 16 | module.exports = { getClientIp }; 17 | -------------------------------------------------------------------------------- /api/test/integration/fixtures/http3A2F2Frssblackboardconnectcom2F1422832Ficonnect2Ffeedxmlnum15.source.xml: -------------------------------------------------------------------------------- 1 | Web RSShttp://rss.blackboardconnect.com/142283/iconnect/feed.xmlRSS feed is embedded within the iConnect portal home page to display messages.Sun, 08 Sep 2019 21:00:14 GMTen-Us -------------------------------------------------------------------------------- /api/test/integration/fixtures/https3A2F2Fnewsgooglecom2Frss2Fsearch3Fq3Ddamezen2Binstagram26hl3DenUS26gl3DUS26ceid3DUS3Aennum4.parsed.json: -------------------------------------------------------------------------------- 1 | { 2 | "responseStatus": 200, 3 | "responseDetails": null, 4 | "responseData": { 5 | "feed": { 6 | "feedUrl": "https://news.google.com/rss/search?q=damezen+instagram&hl=en-US&gl=US&ceid=US:en", 7 | "title": "\"damezen instagram\" - Google News", 8 | "link": "https://news.google.com/search?q=damezen+instagram&hl=en-US&gl=US&ceid=US:en", 9 | "description": "Google News", 10 | "author": "", 11 | "entries": [] 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": false, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "incremental": true, 11 | "esModuleInterop": true, 12 | "module": "esnext", 13 | "moduleResolution": "node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "jsx": "preserve" 17 | }, 18 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 19 | "exclude": ["node_modules"] 20 | } 21 | -------------------------------------------------------------------------------- /api/test/integration/fixtures/https3A2F2Fboatatfoodcom2Frssphp3Faction3Dpopularproducts26categoryid3D37num4.source.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <![CDATA[BOATAT FOOD: 熱門產品]]> 5 | https://boatatfood.com 6 | 7 | Fri, 18 Oct 2019 18:50:59 +0000 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /api/test/unit/controllers/fixtures/parsed/https3A2F2Fnewsgooglecom2Frss2Fsearch3Fq3Ddamezen2Binstagram26hl3DenUS26gl3DUS26ceid3DUS3Aennum4.json: -------------------------------------------------------------------------------- 1 | { 2 | "responseStatus": 200, 3 | "responseDetails": null, 4 | "responseData": { 5 | "feed": { 6 | "feedUrl": "https://news.google.com/rss/search?q=damezen+instagram&hl=en-US&gl=US&ceid=US:en", 7 | "title": "\"damezen instagram\" - Google News", 8 | "link": "https://news.google.com/search?q=damezen+instagram&hl=en-US&gl=US&ceid=US:en", 9 | "description": "Google News", 10 | "author": "", 11 | "entries": [] 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /api/test/unit/controllers/fixtures/source/http3A2F2Frssblackboardconnectcom2F1422832Ficonnect2Ffeedxmlnum15.xml: -------------------------------------------------------------------------------- 1 | Web RSShttp://rss.blackboardconnect.com/142283/iconnect/feed.xmlRSS feed is embedded within the iConnect portal home page to display messages.Sun, 08 Sep 2019 21:00:14 GMTen-Us -------------------------------------------------------------------------------- /api/test/unit/controllers/fixtures/source/https3A2F2Fboatatfoodcom2Frssphp3Faction3Dpopularproducts26categoryid3D37num4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <![CDATA[BOATAT FOOD: 熱門產品]]> 5 | https://boatatfood.com 6 | 7 | Fri, 18 Oct 2019 18:50:59 +0000 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /api/test/integration/fixtures/https3A2F2Fnewsgooglecom2Frss2Fsearch3Fq3Dtedharrislamps2Binstagram26hl3DenUS26gl3DUS26ceid3DUS3Aennum4.parsed.json: -------------------------------------------------------------------------------- 1 | { 2 | "responseStatus": 200, 3 | "responseDetails": null, 4 | "responseData": { 5 | "feed": { 6 | "feedUrl": "https://news.google.com/rss/search?q=ted_harris_lamps+instagram&hl=en-US&gl=US&ceid=US:en", 7 | "title": "\"ted_harris_lamps instagram\" - Google News", 8 | "link": "https://news.google.com/search?q=ted_harris_lamps+instagram&hl=en-US&gl=US&ceid=US:en", 9 | "description": "Google News", 10 | "author": "", 11 | "entries": [] 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /api/test/unit/controllers/fixtures/parsed/https3A2F2Fnewsgooglecom2Frss2Fsearch3Fq3Dtedharrislamps2Binstagram26hl3DenUS26gl3DUS26ceid3DUS3Aennum4.json: -------------------------------------------------------------------------------- 1 | { 2 | "responseStatus": 200, 3 | "responseDetails": null, 4 | "responseData": { 5 | "feed": { 6 | "feedUrl": "https://news.google.com/rss/search?q=ted_harris_lamps+instagram&hl=en-US&gl=US&ceid=US:en", 7 | "title": "\"ted_harris_lamps instagram\" - Google News", 8 | "link": "https://news.google.com/search?q=ted_harris_lamps+instagram&hl=en-US&gl=US&ceid=US:en", 9 | "description": "Google News", 10 | "author": "", 11 | "entries": [] 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /api/test/integration/fixtures/https3A2F2Fnewsgooglecom2Frss2Fsearch3Fq3Ddamezen2Binstagram26hl3DenUS26gl3DUS26ceid3DUS3Aennum4.source.xml: -------------------------------------------------------------------------------- 1 | NFE/5.0"damezen instagram" - Google Newshttps://news.google.com/search?q=damezen+instagram&hl=en-US&gl=US&ceid=US:enen-USnews-webmaster@google.com2019 Google Inc.Fri, 18 Oct 2019 18:50:59 GMTGoogle News -------------------------------------------------------------------------------- /api/test/unit/controllers/fixtures/source/https3A2F2Fnewsgooglecom2Frss2Fsearch3Fq3Ddamezen2Binstagram26hl3DenUS26gl3DUS26ceid3DUS3Aennum4.xml: -------------------------------------------------------------------------------- 1 | NFE/5.0"damezen instagram" - Google Newshttps://news.google.com/search?q=damezen+instagram&hl=en-US&gl=US&ceid=US:enen-USnews-webmaster@google.com2019 Google Inc.Fri, 18 Oct 2019 18:50:59 GMTGoogle News -------------------------------------------------------------------------------- /web/theme.config.tsx: -------------------------------------------------------------------------------- 1 | import { DocsThemeConfig } from "nextra-theme-docs"; 2 | import { Footer } from "./components/footer"; 3 | import { EthicalAd } from "./components/ethical-ad"; 4 | 5 | const config: DocsThemeConfig = { 6 | logo: Feedr App, 7 | project: { 8 | link: "https://github.com/sdepold/feedrapp", 9 | }, 10 | docsRepositoryBase: "https://github.com/sdepold/feedrapp", 11 | footer: { text: