diff --git a/.eslintrc.json b/.eslintrc.json index f6e2bc341..f86ea69c2 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,24 +1,21 @@ { - "extends": ["eslint:recommended", "plugin:n/recommended", "plugin:prettier/recommended", "plugin:yml/recommended"], - "plugins": ["prettier", "@stylistic/js"], + "extends": ["eslint:recommended", "plugin:n/recommended", "plugin:unicorn/recommended", "plugin:prettier/recommended", "plugin:yml/recommended"], + "plugins": ["prettier", "@stylistic/js", "unicorn"], "parserOptions": { "ecmaVersion": "latest", "sourceType": "module" }, "env": { "node": true, - "es6": true, + "es2024": true, "browser": true }, "rules": { // possible problems - "array-callback-return": 2, + "array-callback-return": ["error", { "allowImplicit": true }], "no-await-in-loop": 2, "no-control-regex": 0, "no-duplicate-imports": 2, - "no-prototype-builtins": 0, - "no-unsafe-negation": 2, - "require-atomic-updates": 0, // suggestions "arrow-body-style": 2, "block-scoped-var": 2, @@ -29,16 +26,7 @@ "no-eval": 2, "no-extend-native": 2, "no-extra-label": 2, - "no-global-assign": 2, - "no-implicit-coercion": [ - "error", - { - "boolean": false, - "number": false, - "string": false, - "disallowTemplateShorthand": true - } - ], + "no-implicit-coercion": ["error", { "boolean": false, "number": false, "string": false, "disallowTemplateShorthand": true }], "no-implicit-globals": 2, "no-labels": 2, "no-multi-str": 2, @@ -52,9 +40,49 @@ "object-shorthand": 2, "prefer-arrow-callback": 2, "prefer-const": 2, - "prefer-regex-literals": 1, + "prefer-object-has-own": 2, + "prefer-regex-literals": ["error", { "disallowRedundantWrapping": true }], "require-await": 2, // plugin specific + "unicorn/consistent-destructuring": 1, + "unicorn/consistent-function-scoping": 1, + "unicorn/explicit-length-check": 0, + "unicorn/filename-case": ["error", { "case": "kebabCase", "ignore": [".*\\.(yaml|yml)$", "RequestInProgress\\.js$"] }], + "unicorn/new-for-builtins": 0, + "unicorn/no-array-callback-reference": 0, + "unicorn/no-array-reduce": 1, + "unicorn/no-await-expression-member": 1, + "unicorn/no-empty-file": 1, + "unicorn/no-hex-escape": 1, + "unicorn/no-null": 0, + "unicorn/no-object-as-default-parameter": 1, + "unicorn/no-process-exit": 0, + "unicorn/no-useless-switch-case": 0, + "unicorn/no-useless-undefined": ["error", { "checkArguments": false }], + "unicorn/numeric-separators-style": [ + "warn", + { + "onlyIfContainsSeparator": false, + "number": { "minimumDigits": 7, "groupLength": 3 }, + "binary": { "minimumDigits": 9, "groupLength": 4 }, + "octal": { "minimumDigits": 9, "groupLength": 4 }, + "hexadecimal": { "minimumDigits": 5, "groupLength": 2 } + } + ], + "unicorn/prefer-code-point": 1, + "unicorn/prefer-logical-operator-over-ternary": 1, + "unicorn/prefer-module": 0, + "unicorn/prefer-node-protocol": 0, + "unicorn/prefer-number-properties": ["warn", { "checkInfinity": false }], + "unicorn/prefer-object-from-entries": 1, + "unicorn/prefer-regexp-test": 1, + "unicorn/prefer-string-replace-all": 1, + "unicorn/prefer-string-slice": 0, + "unicorn/prefer-switch": ["error", { "emptyDefaultCase": "do-nothing-comment" }], + "unicorn/prefer-top-level-await": 0, + "unicorn/prevent-abbreviations": 0, + "unicorn/switch-case-braces": ["error", "avoid"], + "unicorn/text-encoding-identifier-case": 0, // previous eslint formatting rules "@stylistic/js/arrow-parens": 2, "@stylistic/js/arrow-spacing": 2, @@ -74,40 +102,20 @@ "@stylistic/js/space-unary-ops": 2, "@stylistic/js/spaced-comment": 2, // https://github.com/eslint-community/eslint-plugin-n - "n/no-extraneous-require": [ - "error", - { - "allowModules": ["puppeteer-extra-plugin-user-preferences", "puppeteer-extra-plugin-user-data-dir"] - } - ], + "n/no-extraneous-require": ["error", { "allowModules": ["puppeteer-extra-plugin-user-preferences", "puppeteer-extra-plugin-user-data-dir"] }], "n/no-deprecated-api": 1, "n/no-missing-require": 0, "n/no-process-exit": 0, - "n/no-unpublished-require": [ - "error", - { - "allowModules": ["tosource"] - } - ], + "n/no-unpublished-require": ["error", { "allowModules": ["tosource"] }], "prettier/prettier": 0, - "yml/quotes": [ - "error", - { - "prefer": "single" - } - ] + "yml/quotes": ["error", { "prefer": "single" }] }, "overrides": [ { "files": ["*.yaml", "*.yml"], "parser": "yaml-eslint-parser", "rules": { - "lines-around-comment": [ - "error", - { - "beforeBlockComment": false - } - ] + "lines-around-comment": ["error", { "beforeBlockComment": false }] } } ] diff --git a/assets/radar-rules.js b/assets/radar-rules.js index 43bcbba21..1b1724529 100644 --- a/assets/radar-rules.js +++ b/assets/radar-rules.js @@ -167,7 +167,7 @@ docs: 'https://docs.rsshub.app/routes/multimedia#onejav', source: '/', target: (params, url, document) => { - const today = document.querySelector('div.card.mb-1.card-overview').getAttribute('data-date').replace(/-/g, ''); + const today = document.querySelector('div.card.mb-1.card-overview').dataset.date.replaceAll('-', ''); return `/onejav/day/${today}`; }, }, @@ -215,7 +215,7 @@ } else { return false; } - return `/sexinsex/${pid}/${typeid ? typeid : ''}`; + return `/sexinsex/${pid}/${typeid ?? ''}`; }, }, ], @@ -230,7 +230,7 @@ target: (params, url) => { const id = new URL(url).searchParams.get('fid'); const type = new URL(url).searchParams.get('type'); - return `/t66y/${id}/${type ? type : ''}`; + return `/t66y/${id}/${type ?? ''}`; }, }, ], diff --git a/lib/api_router.js b/lib/api-router.js similarity index 88% rename from lib/api_router.js rename to lib/api-router.js index b452d6066..bed73e393 100644 --- a/lib/api_router.js +++ b/lib/api-router.js @@ -6,8 +6,7 @@ router.get('/routes/:name?', (ctx) => { let counter = 0; const maintainer = require('./maintainer'); - Object.keys(maintainer).forEach((i) => { - const path = i; + for (const path of Object.keys(maintainer)) { const top = path.split('/')[1]; if (!ctx.params.name || top === ctx.params.name) { @@ -18,7 +17,7 @@ router.get('/routes/:name?', (ctx) => { } counter++; } - }); + } ctx.body = { counter, result }; }); diff --git a/lib/app.js b/lib/app.js index 39b91f574..720da7f71 100644 --- a/lib/app.js +++ b/lib/app.js @@ -20,13 +20,13 @@ const antiHotlink = require('./middleware/anti-hotlink'); const loadOnDemand = require('./middleware/load-on-demand'); const router = require('./router'); -const core_router = require('./core_router'); -const protected_router = require('./protected_router'); +const core_router = require('./core-router'); +const protected_router = require('./protected-router'); const mount = require('koa-mount'); // API related const apiTemplate = require('./middleware/api-template'); -const api_router = require('./api_router'); +const api_router = require('./api-router'); const apiResponseHandler = require('./middleware/api-response-handler'); process.on('uncaughtException', (e) => { @@ -37,8 +37,8 @@ const app = new Koa(); app.proxy = true; // favicon -app.use(favicon(__dirname + '/favicon.png', { maxAge: 31536000000 })); -app.use(serve(__dirname + '/static', { maxage: 31536000000 })); +app.use(favicon(__dirname + '/favicon.png', { maxAge: 31_536_000_000 })); +app.use(serve(__dirname + '/static', { maxage: 31_536_000_000 })); // global error handing app.use(onerror); diff --git a/lib/config.js b/lib/config.js index 81f9b2c6c..13f781236 100644 --- a/lib/config.js +++ b/lib/config.js @@ -45,21 +45,21 @@ const calculateValue = () => { socket: envs.SOCKET || null, // 监听 Unix Socket, null 为禁用 }, listenInaddrAny: envs.LISTEN_INADDR_ANY || 1, // 是否允许公网连接,取值 0 1 - requestRetry: parseInt(envs.REQUEST_RETRY) || 2, // 请求失败重试次数 - requestTimeout: parseInt(envs.REQUEST_TIMEOUT) || 30000, // Milliseconds to wait for the server to end the response before aborting the request - ua: envs.UA ? envs.UA : envs.NO_RANDOM_UA === 'true' || envs.NO_RANDOM_UA === '1' ? TRUE_UA : randUserAgent({ browser: 'chrome', os: 'mac os', device: 'desktop' }), + requestRetry: Number.parseInt(envs.REQUEST_RETRY) || 2, // 请求失败重试次数 + requestTimeout: Number.parseInt(envs.REQUEST_TIMEOUT) || 30000, // Milliseconds to wait for the server to end the response before aborting the request + ua: envs.UA ?? (envs.NO_RANDOM_UA === 'true' || envs.NO_RANDOM_UA === '1' ? TRUE_UA : randUserAgent({ browser: 'chrome', os: 'mac os', device: 'desktop' })), trueUA: TRUE_UA, // cors request allowOrigin: envs.ALLOW_ORIGIN, // cache cache: { - type: typeof envs.CACHE_TYPE === 'undefined' ? 'memory' : envs.CACHE_TYPE, // 缓存类型,支持 'memory' 和 'redis',设为空可以禁止缓存 - requestTimeout: parseInt(envs.CACHE_REQUEST_TIMEOUT) || 60, - routeExpire: parseInt(envs.CACHE_EXPIRE) || 5 * 60, // 路由缓存时间,单位为秒 - contentExpire: parseInt(envs.CACHE_CONTENT_EXPIRE) || 1 * 60 * 60, // 不变内容缓存时间,单位为秒 + type: envs.CACHE_TYPE === undefined ? 'memory' : envs.CACHE_TYPE, // 缓存类型,支持 'memory' 和 'redis',设为空可以禁止缓存 + requestTimeout: Number.parseInt(envs.CACHE_REQUEST_TIMEOUT) || 60, + routeExpire: Number.parseInt(envs.CACHE_EXPIRE) || 5 * 60, // 路由缓存时间,单位为秒 + contentExpire: Number.parseInt(envs.CACHE_CONTENT_EXPIRE) || 1 * 60 * 60, // 不变内容缓存时间,单位为秒 }, memory: { - max: parseInt(envs.MEMORY_MAX) || Math.pow(2, 8), // The maximum number of items that remain in the cache. This must be a positive finite intger. + max: Number.parseInt(envs.MEMORY_MAX) || Math.pow(2, 8), // The maximum number of items that remain in the cache. This must be a positive finite intger. // https://github.com/isaacs/node-lru-cache#options }, redis: { @@ -96,7 +96,7 @@ const calculateValue = () => { showLoggerTimestamp: envs.SHOW_LOGGER_TIMESTAMP, sentry: { dsn: envs.SENTRY, - routeTimeout: parseInt(envs.SENTRY_ROUTE_TIMEOUT) || 30000, + routeTimeout: Number.parseInt(envs.SENTRY_ROUTE_TIMEOUT) || 30000, }, // feed config hotlink: { @@ -110,7 +110,7 @@ const calculateValue = () => { allow_user_supply_unsafe_domain: envs.ALLOW_USER_SUPPLY_UNSAFE_DOMAIN === 'true', }, suffix: envs.SUFFIX, - titleLengthLimit: parseInt(envs.TITLE_LENGTH_LIMIT) || 150, + titleLengthLimit: Number.parseInt(envs.TITLE_LENGTH_LIMIT) || 150, openai: { apiKey: envs.OPENAI_API_KEY, model: envs.OPENAI_MODEL || 'gpt-3.5-turbo-16k', diff --git a/lib/core_router.js b/lib/core-router.js similarity index 100% rename from lib/core_router.js rename to lib/core-router.js diff --git a/lib/index.js b/lib/index.js index cf7e0f63f..730a73c09 100644 --- a/lib/index.js +++ b/lib/index.js @@ -16,7 +16,7 @@ if (config.enableCluster && cluster.isMaster && process.env.NODE_ENV !== 'test' if (fs.existsSync(config.connect.socket)) { fs.unlinkSync(config.connect.socket); } - server = app.listen(config.connect.socket, parseInt(config.listenInaddrAny) ? null : '127.0.0.1'); + server = app.listen(config.connect.socket, Number.parseInt(config.listenInaddrAny) ? null : '127.0.0.1'); logger.info('Listening Unix Socket ' + config.connect.socket); process.on('SIGINT', () => { fs.unlinkSync(config.connect.socket); @@ -24,7 +24,7 @@ if (config.enableCluster && cluster.isMaster && process.env.NODE_ENV !== 'test' }); } if (config.connect.port) { - server = app.listen(config.connect.port, parseInt(config.listenInaddrAny) ? null : '127.0.0.1'); + server = app.listen(config.connect.port, Number.parseInt(config.listenInaddrAny) ? null : '127.0.0.1'); logger.info('Listening Port ' + config.connect.port); } diff --git a/lib/maintainer.js b/lib/maintainer.js index 41592e812..5417992ef 100644 --- a/lib/maintainer.js +++ b/lib/maintainer.js @@ -1,12 +1,12 @@ const dirname = __dirname + '/v2'; const fs = require('fs'); -const { join } = require('path'); +const path = require('path'); // Presence Check for (const dir of fs.readdirSync(dirname)) { - const dirPath = join(dirname, dir); - if (fs.existsSync(join(dirPath, 'router.js')) && !fs.existsSync(join(dirPath, 'maintainer.js'))) { - throw Error(`No maintainer.js in "${dirPath}".`); + const dirPath = path.join(dirname, dir); + if (fs.existsSync(path.join(dirPath, 'router.js')) && !fs.existsSync(path.join(dirPath, 'maintainer.js'))) { + throw new Error(`No maintainer.js in "${dirPath}".`); } } @@ -24,15 +24,15 @@ for (const dir in maintainerPath) { // typo check e.g., ✘ module.export, ✔ module.exports if (!Object.keys(routes).length) { - throw Error(`No maintainer in "${dir}".`); + throw new Error(`No maintainer in "${dir}".`); } for (const author of Object.values(routes)) { if (!Array.isArray(author)) { - throw Error(`Maintainers' name should be an array in "${dir}".`); + throw new TypeError(`Maintainers' name should be an array in "${dir}".`); } // check for [], [''] or ['Someone', ''] if (author.length < 1 || author.includes('')) { - throw Error(`Empty maintainer in "${dir}".`); + throw new Error(`Empty maintainer in "${dir}".`); } } @@ -43,11 +43,11 @@ for (const dir in maintainerPath) { // 兼容旧版路由 const router = require('./router'); -router.stack.forEach((e) => { +for (const e of router.stack) { if (!maintainers[e.path]) { maintainers[e.path] = []; } -}); +} module.exports = Object.keys(maintainers) .sort() diff --git a/lib/middleware/access-control.js b/lib/middleware/access-control.js index 277362689..a7b4ab2ba 100644 --- a/lib/middleware/access-control.js +++ b/lib/middleware/access-control.js @@ -5,11 +5,11 @@ const isLocalhost = require('is-localhost-ip'); const reject = (ctx) => { ctx.response.status = 403; - throw Error('Authentication failed. Access denied.'); + throw new Error('Authentication failed. Access denied.'); }; const ipv4Pattern = /^(\d{1,3}\.){3}\d{1,3}$/; -const cidrPattern = /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\/(\d{1,2})/; +const cidrPattern = /((?:\d{1,3}\.){3}\d{1,3})\/(\d{1,2})/; const ipInCidr = (cidr, ip) => { const cidrMatch = cidr.match(cidrPattern); @@ -17,7 +17,7 @@ const ipInCidr = (cidr, ip) => { if (!cidrMatch || !ipMatch) { return false; } - const subnetMask = parseInt(cidrMatch[2]); + const subnetMask = Number.parseInt(cidrMatch[2]); const cidrIpBits = ipv4ToBitsring(cidrMatch[1]).substring(0, subnetMask); const ipBits = ipv4ToBitsring(ip).substring(0, subnetMask); return cidrIpBits === ipBits; @@ -26,7 +26,7 @@ const ipInCidr = (cidr, ip) => { const ipv4ToBitsring = (ip) => ip .split('.') - .map((part) => ('00000000' + parseInt(part).toString(2)).slice(-8)) + .map((part) => ('00000000' + Number.parseInt(part).toString(2)).slice(-8)) .join(''); module.exports = async (ctx, next) => { @@ -53,22 +53,16 @@ module.exports = async (ctx, next) => { return grant(); } - if (config.accessKey) { - if (config.accessKey === accessKey || accessCode === md5(requestPath + config.accessKey)) { - return grant(); - } + if (config.accessKey && (config.accessKey === accessKey || accessCode === md5(requestPath + config.accessKey))) { + return grant(); } - if (config.allowlist) { - if (config.allowlist.find((item) => ip.includes(item) || ipInCidr(item, ip) || requestPath.includes(item) || requestUA.includes(item))) { - return grant(); - } + if (config.allowlist && config.allowlist.some((item) => ip.includes(item) || ipInCidr(item, ip) || requestPath.includes(item) || requestUA.includes(item))) { + return grant(); } - if (config.denylist) { - if (!config.denylist.find((item) => ip.includes(item) || ipInCidr(item, ip) || requestPath.includes(item) || requestUA.includes(item))) { - return grant(); - } + if (config.denylist && !config.denylist.some((item) => ip.includes(item) || ipInCidr(item, ip) || requestPath.includes(item) || requestUA.includes(item))) { + return grant(); } reject(ctx); diff --git a/lib/middleware/anti-hotlink.js b/lib/middleware/anti-hotlink.js index 049487010..9a216126a 100644 --- a/lib/middleware/anti-hotlink.js +++ b/lib/middleware/anti-hotlink.js @@ -4,8 +4,8 @@ const logger = require('@/utils/logger'); const path = require('path'); const { art } = require('@/utils/render'); -const templateRegex = /\$\{([^{}]+)}/g; -const allowedUrlProperties = ['hash', 'host', 'hostname', 'href', 'origin', 'password', 'pathname', 'port', 'protocol', 'search', 'searchParams', 'username']; +const templateRegex = /\${([^{}]+)}/g; +const allowedUrlProperties = new Set(['hash', 'host', 'hostname', 'href', 'origin', 'password', 'pathname', 'port', 'protocol', 'search', 'searchParams', 'username']); const IframeWrapperTemplate = path.join(__dirname, 'templates/iframe.art'); // match path or sub-path @@ -26,7 +26,7 @@ const filterPath = (path) => { }; const interpolate = (str, obj) => - str.replace(templateRegex, (_, prop) => { + str.replaceAll(templateRegex, (_, prop) => { let needEncode = false; if (prop.endsWith('_ue')) { // url encode @@ -39,7 +39,7 @@ const parseUrl = (str) => { let url; try { url = new URL(str); - } catch (e) { + } catch { logger.error(`Failed to parse ${str}`); } @@ -87,12 +87,12 @@ const validateTemplate = (template) => { if (!template) { return; } - [...template.matchAll(templateRegex)].forEach((match) => { + for (const match of template.matchAll(templateRegex)) { const prop = match[1].endsWith('_ue') ? match[1].slice(0, -3) : match[1]; - if (!allowedUrlProperties.includes(prop)) { + if (!allowedUrlProperties.has(prop)) { throw new Error(`Invalid URL property: ${prop}`); } - }); + } }; module.exports = async (ctx, next) => { @@ -115,11 +115,7 @@ module.exports = async (ctx, next) => { // Force config hotlink template on conflict if (config.hotlink.template) { - if (!filterPath(ctx.request.path)) { - image_hotlink_template = undefined; - } else { - image_hotlink_template = config.hotlink.template; - } + image_hotlink_template = filterPath(ctx.request.path) ? config.hotlink.template : undefined; } if (!image_hotlink_template && !multimedia_hotlink_template && !shouldWrapInIframe) { @@ -138,11 +134,12 @@ module.exports = async (ctx, next) => { ctx.state.data.description = process(ctx.state.data.description, image_hotlink_template, multimedia_hotlink_template, shouldWrapInIframe); } - ctx.state.data.item && - ctx.state.data.item.forEach((item) => { + if (ctx.state.data.item) { + for (const item of ctx.state.data.item) { if (item.description) { item.description = process(item.description, image_hotlink_template, multimedia_hotlink_template, shouldWrapInIframe); } - }); + } + } } }; diff --git a/lib/middleware/cache/index.js b/lib/middleware/cache/index.js index 4c715b85a..bde7cdc0a 100644 --- a/lib/middleware/cache/index.js +++ b/lib/middleware/cache/index.js @@ -57,22 +57,22 @@ module.exports = function (app) { ...cacheModule, tryGet: async (key, getValueFunc, maxAge = config.cache.contentExpire, refresh = true) => { if (typeof key !== 'string') { - throw Error('Cache key must be a string'); + throw new TypeError('Cache key must be a string'); } let v = await get(key, refresh); - if (!v) { - v = await getValueFunc(); - set(key, v, maxAge); - } else { + if (v) { let parsed; try { parsed = JSON.parse(v); - } catch (e) { + } catch { parsed = null; } if (parsed) { v = parsed; } + } else { + v = await getValueFunc(); + set(key, v, maxAge); } return v; @@ -112,7 +112,7 @@ module.exports = function (app) { ctx.state.data = JSON.parse(value); return; } - } catch (e) { + } catch { // } @@ -121,9 +121,9 @@ module.exports = function (app) { try { await next(); - } catch (e) { + } catch (error) { await globalCache.set(controlKey, '0', config.cache.requestTimeout); - throw e; + throw error; } if (ctx.response.get('Cache-Control') !== 'no-cache' && ctx.state && ctx.state.data) { diff --git a/lib/middleware/cache/redis.js b/lib/middleware/cache/redis.js index 2234dd866..b7d57b974 100644 --- a/lib/middleware/cache/redis.js +++ b/lib/middleware/cache/redis.js @@ -20,7 +20,7 @@ redisClient.on('connect', () => { const getCacheTtlKey = (key) => { if (key.startsWith('rsshub:cacheTtl:')) { - throw Error('"rsshub:cacheTtl:" prefix is reserved for the internal usage, please change your cache key'); // blocking any attempt to get/set the cacheTtl + throw new Error('"rsshub:cacheTtl:" prefix is reserved for the internal usage, please change your cache key'); // blocking any attempt to get/set the cacheTtl } return `rsshub:cacheTtl:${key}`; }; @@ -31,13 +31,13 @@ module.exports = { const cacheTtlKey = getCacheTtlKey(key); let [value, cacheTtl] = await redisClient.mget(key, cacheTtlKey); if (value && refresh) { - if (!cacheTtl) { + if (cacheTtl) { + redisClient.expire(cacheTtlKey, cacheTtl); + } else { // if cacheTtl is not set, that means the cache expire time is contentExpire cacheTtl = config.cache.contentExpire; // dont save cacheTtl to Redis, as it is the default value // redisClient.set(cacheTtlKey, cacheTtl, 'EX', cacheTtl); - } else { - redisClient.expire(cacheTtlKey, cacheTtl); } redisClient.expire(key, cacheTtl); value = value + ''; diff --git a/lib/middleware/header.js b/lib/middleware/header.js index 2292ddbed..762363f9d 100644 --- a/lib/middleware/header.js +++ b/lib/middleware/header.js @@ -24,7 +24,7 @@ module.exports = async (ctx, next) => { return; } - const status = (ctx.status / 100) | 0; + const status = Math.trunc(ctx.status / 100); if (2 !== status) { return; } diff --git a/lib/middleware/load-on-demand.js b/lib/middleware/load-on-demand.js index 0c15bb423..837a17cc7 100644 --- a/lib/middleware/load-on-demand.js +++ b/lib/middleware/load-on-demand.js @@ -11,7 +11,9 @@ module.exports = function (app) { if (p.length > 0) { modName = p[0]; - if (!loadedRoutes.has(modName)) { + if (loadedRoutes.has(modName)) { + mounted = true; + } else { const mod = routes[modName]; // Mount module if (mod) { @@ -21,8 +23,6 @@ module.exports = function (app) { mod(router); app.use(mount(`/${modName}`, router.routes())).use(router.allowedMethods()); } - } else { - mounted = true; } } diff --git a/lib/middleware/onerror.js b/lib/middleware/onerror.js index 3f2c3a04b..a4272b0aa 100644 --- a/lib/middleware/onerror.js +++ b/lib/middleware/onerror.js @@ -20,15 +20,15 @@ if (config.sentry.dsn) { try { gitHash = require('git-rev-sync').short(); -} catch (e) { +} catch { gitHash = (process.env.HEROKU_SLUG_COMMIT && process.env.HEROKU_SLUG_COMMIT.slice(0, 7)) || (process.env.VERCEL_GIT_COMMIT_SHA && process.env.VERCEL_GIT_COMMIT_SHA.slice(0, 7)) || 'unknown'; } module.exports = async (ctx, next) => { try { - const time = +new Date(); + const time = Date.now(); await next(); - if (config.sentry.dsn && +new Date() - time >= config.sentry.routeTimeout) { + if (config.sentry.dsn && Date.now() - time >= config.sentry.routeTimeout) { Sentry.withScope((scope) => { scope.setTag('route', ctx._matchedRoute); scope.setTag('name', ctx.request.path.split('/')[1]); @@ -36,8 +36,8 @@ module.exports = async (ctx, next) => { Sentry.captureException(new Error('Route Timeout')); }); } - } catch (err) { - if (err instanceof Error && !err.stack.split('\n')[1].includes('lib/middleware/parameter.js')) { + } catch (error) { + if (error instanceof Error && !error.stack.split('\n')[1].includes('lib/middleware/parameter.js')) { // Append v2 route path if a route throws an error // since koa-mount will remove the mount path from ctx.request.path // https://github.com/koajs/mount/issues/62 @@ -45,11 +45,11 @@ module.exports = async (ctx, next) => { ctx._matchedRoute = ctx._matchedRoute ? (ctx.mountPath ?? '') + ctx._matchedRoute : ctx._matchedRoute; } - let message = err; - if (err.name && (err.name === 'HTTPError' || err.name === 'RequestError')) { - message = `${err.message}: target website might be blocking our access, you can host your own RSSHub instance for a better usability.`; - } else if (err instanceof Error) { - message = process.env.NODE_ENV === 'production' ? err.message : err.stack; + let message = error; + if (error.name && (error.name === 'HTTPError' || error.name === 'RequestError')) { + message = `${error.message}: target website might be blocking our access, you can host your own RSSHub instance for a better usability.`; + } else if (error instanceof Error) { + message = process.env.NODE_ENV === 'production' ? error.message : error.stack; } logger.error(`Error in ${ctx.request.path}: ${message}`); @@ -57,7 +57,7 @@ module.exports = async (ctx, next) => { if (config.isPackage) { ctx.body = { error: { - message: err.message ? err.message : err, + message: error.message ?? error, }, }; } else { @@ -65,12 +65,12 @@ module.exports = async (ctx, next) => { 'Content-Type': 'text/html; charset=UTF-8', }); - if (err instanceof RequestInProgressError) { + if (error instanceof RequestInProgressError) { ctx.status = 503; - message = err.message; + message = error.message; ctx.set('Cache-Control', `public, max-age=${config.cache.requestTimeout}`); } else if (ctx.status === 403) { - message = err.message; + message = error.message; } else { ctx.status = 404; } @@ -112,7 +112,7 @@ module.exports = async (ctx, next) => { scope.setTag('route', ctx._matchedRoute); scope.setTag('name', ctx.request.path.split('/')[1]); scope.addEventProcessor((event) => Sentry.Handlers.parseRequest(event, ctx.request)); - Sentry.captureException(err); + Sentry.captureException(error); }); } } diff --git a/lib/middleware/parameter.js b/lib/middleware/parameter.js index bd37d3510..86f5fa85e 100644 --- a/lib/middleware/parameter.js +++ b/lib/middleware/parameter.js @@ -21,7 +21,7 @@ const resolveRelativeLink = ($, elem, attr, baseUrl) => { // e.g. should leave unchanged $elem.attr(attr, new URL(oldAttr, baseUrl).href); } - } catch (e) { + } catch { // no-empty } } @@ -51,12 +51,12 @@ module.exports = async (ctx, next) => { await next(); if (!ctx.state.data && !ctx._matchedRoute) { - throw Error('wrong path'); + throw new Error('wrong path'); } if (ctx.state.data) { if ((!ctx.state.data.item || ctx.state.data.item.length === 0) && !ctx.state.data.allowEmpty) { - throw Error('this route is empty, please check the original site or create an issue'); + throw new Error('this route is empty, please check the original site or create an issue'); } // fix allowEmpty @@ -82,12 +82,8 @@ module.exports = async (ctx, next) => { // handle link if (item.link) { let baseUrl = ctx.state.data.link; - if (baseUrl && !baseUrl.match(/^https?:\/\//)) { - if (baseUrl.match(/^\/\//)) { - baseUrl = 'http:' + baseUrl; - } else { - baseUrl = 'http://' + baseUrl; - } + if (baseUrl && !/^https?:\/\//.test(baseUrl)) { + baseUrl = /^\/\//.test(baseUrl) ? 'http:' + baseUrl : 'http://' + baseUrl; } item.link = new URL(item.link, baseUrl).href; @@ -98,12 +94,8 @@ module.exports = async (ctx, next) => { const $ = cheerio.load(item.description); let baseUrl = item.link || ctx.state.data.link; - if (baseUrl && !baseUrl.match(/^https?:\/\//)) { - if (baseUrl.match(/^\/\//)) { - baseUrl = 'http:' + baseUrl; - } else { - baseUrl = 'http://' + baseUrl; - } + if (baseUrl && !/^https?:\/\//.test(baseUrl)) { + baseUrl = /^\/\//.test(baseUrl) ? 'http:' + baseUrl : 'http://' + baseUrl; } $('script').remove(); @@ -128,9 +120,9 @@ module.exports = async (ctx, next) => { } // redundant attributes - ['onclick', 'onerror', 'onload'].forEach((e) => { + for (const e of ['onclick', 'onerror', 'onload']) { $ele.removeAttr(e); - }); + } }); // resolve relative link & fix referrer policy @@ -170,7 +162,7 @@ module.exports = async (ctx, next) => { return item; }; - ctx.state.data.item = await Promise.all(ctx.state.data.item.map(handleItem)); + ctx.state.data.item = await Promise.all(ctx.state.data.item.map((itm) => handleItem(itm))); if (ctx.query) { // filter @@ -187,7 +179,7 @@ module.exports = async (ctx, next) => { case 're2': return RE2JS.compile(string, insensitive ? RE2JS.CASE_INSENSITIVE : 0); default: - throw Error(`Invalid Engine Value: ${engine}, please check your config.`); + throw new Error(`Invalid Engine Value: ${engine}, please check your config.`); } }; @@ -262,8 +254,8 @@ module.exports = async (ctx, next) => { ctx.state.data.item = ctx.state.data.item.filter(({ pubDate }) => { let isFilter = true; try { - isFilter = !pubDate || now - new Date(pubDate).getTime() <= parseInt(ctx.query.filter_time) * 1000; - } catch (err) { + isFilter = !pubDate || now - new Date(pubDate).getTime() <= Number.parseInt(ctx.query.filter_time) * 1000; + } catch { // no-empty } return isFilter; @@ -272,7 +264,7 @@ module.exports = async (ctx, next) => { // limit if (ctx.query.limit) { - ctx.state.data.item = ctx.state.data.item.slice(0, parseInt(ctx.query.limit)); + ctx.state.data.item = ctx.state.data.item.slice(0, Number.parseInt(ctx.query.limit)); } // telegram instant view @@ -299,7 +291,7 @@ module.exports = async (ctx, next) => { html: $.html(), }); return result; - } catch (e) { + } catch { // no-empty } }); @@ -328,7 +320,7 @@ module.exports = async (ctx, next) => { if (summary !== '') { item.description = summary + '' + item.description; } - } catch (e) { + } catch { // when openai failed, return default description and not write cache } } @@ -347,32 +339,28 @@ module.exports = async (ctx, next) => { // opencc if (ctx.query.opencc) { - ctx.state.data.item.forEach((item) => { + for (const item of ctx.state.data.item) { item.title = simplecc(item.title ?? item.link, ctx.query.opencc); item.description = simplecc(item.description ?? item.title ?? item.link, ctx.query.opencc); - }); + } } // brief if (ctx.query.brief) { const num = /[1-9]\d{2,}/; if (num.test(ctx.query.brief)) { - ctx.query.brief = parseInt(ctx.query.brief); - ctx.state.data.item.forEach((item) => { + ctx.query.brief = Number.parseInt(ctx.query.brief); + for (const item of ctx.state.data.item) { let text; if (item.description) { - text = item.description.replace(/<\/?[^>]+(>|$)/g, ''); + text = item.description.replaceAll(/<\/?[^>]+(>|$)/g, ''); } if (text?.length) { - if (text.length > ctx.query.brief) { - item.description = `${text.substring(0, ctx.query.brief)}…`; - } else { - item.description = `${text}`; - } + item.description = text.length > ctx.query.brief ? `${text.substring(0, ctx.query.brief)}…` : `${text}`; } - }); + } } else { - throw Error(`Invalid parameter brief. Please check the doc https://docs.rsshub.app/parameter#shu-chu-jian-xun`); + throw new Error(`Invalid parameter brief. Please check the doc https://docs.rsshub.app/parameter#shu-chu-jian-xun`); } } diff --git a/lib/middleware/template.js b/lib/middleware/template.js index 9865b5bda..98bac888a 100644 --- a/lib/middleware/template.js +++ b/lib/middleware/template.js @@ -22,11 +22,7 @@ module.exports = async (ctx, next) => { ctx.set({ 'Content-Type': 'application/json; charset=UTF-8', }); - if (ctx.state.json) { - ctx.body = JSON.stringify(ctx.state.json, null, 4); - } else { - ctx.body = JSON.stringify({ message: 'plugin does not set debug json' }); - } + ctx.body = ctx.state.json ? JSON.stringify(ctx.state.json, null, 4) : JSON.stringify({ message: 'plugin does not set debug json' }); } if (outputType.endsWith('.debug.html')) { @@ -34,12 +30,8 @@ module.exports = async (ctx, next) => { 'Content-Type': 'text/html; charset=UTF-8', }); - const index = parseInt(outputType.match(/(\d+)\.debug\.html$/)[1]); - if (!(ctx.state.data && ctx.state.data.item && ctx.state.data.item[index])) { - ctx.body = `ctx.state.data.item[${index}] not found`; - } else { - ctx.body = ctx.state.data.item[index].description; - } + const index = Number.parseInt(outputType.match(/(\d+)\.debug\.html$/)[1]); + ctx.body = ctx.state.data && ctx.state.data.item && ctx.state.data.item[index] ? ctx.state.data.item[index].description : `ctx.state.data.item[${index}] not found`; } } @@ -49,55 +41,59 @@ module.exports = async (ctx, next) => { if (ctx.state.data) { const collapseWhitespaceForProperties = (properties, obj) => { - properties.forEach((prop) => { + for (const prop of properties) { if (obj[prop]) { obj[prop] = collapseWhitespace(obj[prop]); } - }); + } }; collapseWhitespaceForProperties(['title', 'subtitle', 'author'], ctx.state.data); - ctx.state.data.item?.forEach((item) => { - if (item.title) { - item.title = collapseWhitespace(item.title); - // trim title length - for (let length = 0, i = 0; i < item.title.length; i++) { - length += Buffer.from(item.title[i]).length !== 1 ? 2 : 1; - if (length > config.titleLengthLimit) { - item.title = `${item.title.slice(0, i)}...`; - break; + if (ctx.state.data.item) { + for (const item of ctx.state.data.item) { + if (item.title) { + item.title = collapseWhitespace(item.title); + // trim title length + for (let length = 0, i = 0; i < item.title.length; i++) { + length += Buffer.from(item.title[i]).length === 1 ? 1 : 2; + if (length > config.titleLengthLimit) { + item.title = `${item.title.slice(0, i)}...`; + break; + } } } - } - if (typeof item.author === 'string') { - item.author = collapseWhitespace(item.author); - } else if (typeof item.author === 'object' && item.author !== null) { - item.author.forEach((a) => (a.name = collapseWhitespace(a.name))); - if (outputType !== 'json') { - item.author = item.author.map((a) => a.name).join(', '); + if (typeof item.author === 'string') { + item.author = collapseWhitespace(item.author); + } else if (typeof item.author === 'object' && item.author !== null) { + for (const a of item.author) { + a.name = collapseWhitespace(a.name); + } + if (outputType !== 'json') { + item.author = item.author.map((a) => a.name).join(', '); + } + } + + if (item.itunes_duration && ((typeof item.itunes_duration === 'string' && !item.itunes_duration.includes(':')) || (typeof item.itunes_duration === 'number' && !isNaN(item.itunes_duration)))) { + item.itunes_duration = +item.itunes_duration; + item.itunes_duration = + Math.floor(item.itunes_duration / 3600) + ':' + (Math.floor((item.itunes_duration % 3600) / 60) / 100).toFixed(2).slice(-2) + ':' + (((item.itunes_duration % 3600) % 60) / 100).toFixed(2).slice(-2); + } + + if (outputType !== 'rss') { + item.pubDate = convertDateToISO8601(item.pubDate); + item.updated = convertDateToISO8601(item.updated); } } - - if (item.itunes_duration && ((typeof item.itunes_duration === 'string' && item.itunes_duration.indexOf(':') === -1) || (typeof item.itunes_duration === 'number' && !isNaN(item.itunes_duration)))) { - item.itunes_duration = +item.itunes_duration; - item.itunes_duration = - Math.floor(item.itunes_duration / 3600) + ':' + (Math.floor((item.itunes_duration % 3600) / 60) / 100).toFixed(2).slice(-2) + ':' + (((item.itunes_duration % 3600) % 60) / 100).toFixed(2).slice(-2); - } - - if (outputType !== 'rss') { - item.pubDate = convertDateToISO8601(item.pubDate); - item.updated = convertDateToISO8601(item.updated); - } - }); + } } const currentDate = new Date(); const data = { lastBuildDate: currentDate.toUTCString(), updated: currentDate.toISOString(), - ttl: (config.cache.routeExpire / 60) | 0, + ttl: Math.trunc(config.cache.routeExpire / 60), atomlink: ctx.request.href, ...ctx.state.data, }; diff --git a/lib/middleware/utf8.js b/lib/middleware/utf8.js index 51e12ce20..57890897f 100644 --- a/lib/middleware/utf8.js +++ b/lib/middleware/utf8.js @@ -2,5 +2,5 @@ // https://stackoverflow.com/questions/1497885/remove-control-characters-from-php-string/1497928#1497928 module.exports = async (ctx, next) => { await next(); - ctx.body = typeof ctx.body !== 'object' ? ctx.body.replace(/[\x00-\x09\x0B\x0C\x0E-\x1F\x7F]/g, '') : ctx.body; + ctx.body = typeof ctx.body === 'object' ? ctx.body : ctx.body.replaceAll(/[\u0000-\u0009\u000B\u000C\u000E-\u001F\u007F]/g, ''); }; diff --git a/lib/protected_router.js b/lib/protected-router.js similarity index 100% rename from lib/protected_router.js rename to lib/protected-router.js diff --git a/lib/radar-rules.js b/lib/radar-rules.js index 1040ea02e..13055c349 100644 --- a/lib/radar-rules.js +++ b/lib/radar-rules.js @@ -461,7 +461,7 @@ module.exports = { docs: 'https://docs.rsshub.app/routes/multimedia#onejav', source: '/', target: (params, url, document) => { - const today = document.querySelector('div.card.mb-1.card-overview').getAttribute('data-date').replace(/-/g, ''); + const today = document.querySelector('div.card.mb-1.card-overview').dataset.date.replaceAll('-', ''); return `/onejav/day/${today}`; }, }, @@ -509,7 +509,7 @@ module.exports = { } else { return false; } - return `/sexinsex/${pid}/${typeid ? typeid : ''}`; + return `/sexinsex/${pid}/${typeid ?? ''}`; }, }, ], @@ -524,7 +524,7 @@ module.exports = { target: (params, url) => { const id = new URL(url).searchParams.get('fid'); const type = new URL(url).searchParams.get('type'); - return `/t66y/${id}/${type ? type : ''}`; + return `/t66y/${id}/${type ?? ''}`; }, }, ], diff --git a/lib/radar.js b/lib/radar.js index 032027ed7..bb5444f34 100644 --- a/lib/radar.js +++ b/lib/radar.js @@ -1,75 +1,75 @@ const dirname = __dirname + '/v2'; const fs = require('fs'); const toSource = require('tosource'); -const { join } = require('path'); +const path = require('path'); // Namespaces that do not require radar.js -const allowNamespace = ['discourse', 'discuz', 'ehentai', 'lemmy', 'mail', 'test']; +const allowNamespace = new Set(['discourse', 'discuz', 'ehentai', 'lemmy', 'mail', 'test']); // Check if a radar.js file is exist under each folder of dirname for (const dir of fs.readdirSync(dirname)) { - const dirPath = join(dirname, dir); - if (!fs.existsSync(join(dirPath, 'radar.js')) && !allowNamespace.includes(dir)) { - throw Error(`No radar.js in "${dirPath}".`); + const dirPath = path.join(dirname, dir); + if (!fs.existsSync(path.join(dirPath, 'radar.js')) && !allowNamespace.has(dir)) { + throw new Error(`No radar.js in "${dirPath}".`); } } const validateRadarRules = (rule, dir) => { - const allowDomains = ['www.gov.cn']; + const allowDomains = new Set(['www.gov.cn']); const blockWords = ['/', 'http', 'www']; const domain = Object.keys(rule); - if (!domain.length && !allowNamespace.includes(dir)) { + if (!domain.length && !allowNamespace.has(dir)) { // typo check e.g., ✘ module.export, ✔ module.exports - throw Error(`No Radar rule in "${dir}".`); + throw new Error(`No Radar rule in "${dir}".`); } for (const [d, r] of Object.entries(rule)) { - if (blockWords.some((word) => d.startsWith(word)) && !allowDomains.includes(d)) { - throw Error(`Domain name "${d}" should not contain any of ${blockWords.join(', ')}.`); + if (blockWords.some((word) => d.startsWith(word)) && !allowDomains.has(d)) { + throw new Error(`Domain name "${d}" should not contain any of ${blockWords.join(', ')}.`); } - if (!r.hasOwnProperty('_name')) { - throw Error(`No _name in "${dir}".`); + if (!Object.hasOwn(r, '_name')) { + throw new Error(`No _name in "${dir}".`); } // property check for (const [host, items] of Object.entries(r)) { if (host !== '_name') { if (!Array.isArray(items)) { - throw Error(`Radar rules for domain "${host}" in "${dir}" should be placed in an array.`); + throw new TypeError(`Radar rules for domain "${host}" in "${dir}" should be placed in an array.`); } for (const item of items) { - if (!item.hasOwnProperty('title') || !item.hasOwnProperty('docs')) { - throw Error(`Radar rules for "${host}" in "${dir}" should have at least "title" and "docs".`); + if (!Object.hasOwn(item, 'title') || !Object.hasOwn(item, 'docs')) { + throw new Error(`Radar rules for "${host}" in "${dir}" should have at least "title" and "docs".`); } if (!item.title || !item.docs) { - throw Error(`Radar rules for "${host}" in "${dir}" should not be empty.`); + throw new Error(`Radar rules for "${host}" in "${dir}" should not be empty.`); } if (!item.docs.startsWith('https://docs.rsshub.app/')) { - throw Error(`Radar rules for "${host}" in "${dir}" should start with 'https://docs.rsshub.app/'.`); + throw new Error(`Radar rules for "${host}" in "${dir}" should start with 'https://docs.rsshub.app/'.`); } if (Array.isArray(item.source)) { if (!item.source.length) { // check for [] - throw Error(`Radar rule of "${item.title}" for subdomain "${host}" in "${dir}" should not be empty.`); + throw new Error(`Radar rule of "${item.title}" for subdomain "${host}" in "${dir}" should not be empty.`); } if (item.source.some((s) => s.includes('#') || s.includes('='))) { // Some will try to match '/some/path?a=1' which is not supported - throw Error(`Radar rule of "${item.title}" for subdomain "${host}" in "${dir}" cannot match URL hash or URL search parameters.`); + throw new Error(`Radar rule of "${item.title}" for subdomain "${host}" in "${dir}" cannot match URL hash or URL search parameters.`); } if (item.source.some((s) => !s.length)) { // check for ['/some/thing', ''] and [''] - throw Error(`Radar rule of "${item.title}" for subdomain "${host}" in "${dir}" should not be empty.`); + throw new Error(`Radar rule of "${item.title}" for subdomain "${host}" in "${dir}" should not be empty.`); } } if (typeof item.source === 'string') { if (!item.source.length) { // check for '' - throw Error(`Radar rule of "${item.title}" for subdomain "${host}" in "${dir}" should not be empty.`); + throw new Error(`Radar rule of "${item.title}" for subdomain "${host}" in "${dir}" should not be empty.`); } if (item.source.includes('#') || item.source.includes('=')) { - throw Error(`Radar rule of "${item.title}" for subdomain "${host}" in "${dir}" cannot match URL hash or URL search parameters.`); + throw new Error(`Radar rule of "${item.title}" for subdomain "${host}" in "${dir}" cannot match URL hash or URL search parameters.`); } } for (const key in item) { if (key !== 'title' && key !== 'docs' && key !== 'source' && key !== 'target') { - throw Error(`Radar rules for "${host}" in "${dir}" should not have property "${key}".`); + throw new Error(`Radar rules for "${host}" in "${dir}" should not have property "${key}".`); } } } diff --git a/lib/router.js b/lib/router.js index 09b80aaeb..6790e8d0f 100644 --- a/lib/router.js +++ b/lib/router.js @@ -53,12 +53,12 @@ router.get('/huya/live/:id', lazyloadRouteHandler('./routes/huya/live')); router.get('/fdroid/apprelease/:app', lazyloadRouteHandler('./routes/fdroid/apprelease')); // konachan -router.get('/konachan/post/popular_recent', lazyloadRouteHandler('./routes/konachan/post_popular_recent')); -router.get('/konachan.com/post/popular_recent', lazyloadRouteHandler('./routes/konachan/post_popular_recent')); -router.get('/konachan.net/post/popular_recent', lazyloadRouteHandler('./routes/konachan/post_popular_recent')); -router.get('/konachan/post/popular_recent/:period', lazyloadRouteHandler('./routes/konachan/post_popular_recent')); -router.get('/konachan.com/post/popular_recent/:period', lazyloadRouteHandler('./routes/konachan/post_popular_recent')); -router.get('/konachan.net/post/popular_recent/:period', lazyloadRouteHandler('./routes/konachan/post_popular_recent')); +router.get('/konachan/post/popular_recent', lazyloadRouteHandler('./routes/konachan/post-popular-recent')); +router.get('/konachan.com/post/popular_recent', lazyloadRouteHandler('./routes/konachan/post-popular-recent')); +router.get('/konachan.net/post/popular_recent', lazyloadRouteHandler('./routes/konachan/post-popular-recent')); +router.get('/konachan/post/popular_recent/:period', lazyloadRouteHandler('./routes/konachan/post-popular-recent')); +router.get('/konachan.com/post/popular_recent/:period', lazyloadRouteHandler('./routes/konachan/post-popular-recent')); +router.get('/konachan.net/post/popular_recent/:period', lazyloadRouteHandler('./routes/konachan/post-popular-recent')); // PornHub // router.get('/pornhub/category/:caty', lazyloadRouteHandler('./routes/pornhub/category')); @@ -69,8 +69,8 @@ router.get('/konachan.net/post/popular_recent/:period', lazyloadRouteHandler('./ // router.get('/pornhub/:language?/pornstar/:username/:sort?', lazyloadRouteHandler('./routes/pornhub/pornstar')); // yande.re -router.get('/yande.re/post/popular_recent', lazyloadRouteHandler('./routes/yande.re/post_popular_recent')); -router.get('/yande.re/post/popular_recent/:period', lazyloadRouteHandler('./routes/yande.re/post_popular_recent')); +router.get('/yande.re/post/popular_recent', lazyloadRouteHandler('./routes/yande.re/post-popular-recent')); +router.get('/yande.re/post/popular_recent/:period', lazyloadRouteHandler('./routes/yande.re/post-popular-recent')); // EZTV router.get('/eztv/torrents/:imdb_id', lazyloadRouteHandler('./routes/eztv/imdb')); @@ -173,9 +173,9 @@ router.get('/dpu/wlfw/news/:type?', lazyloadRouteHandler('./routes/universities/ router.get('/njtech/jwc', lazyloadRouteHandler('./routes/universities/njtech/jwc')); // 河海大学 -router.get('/hhu/libNews', lazyloadRouteHandler('./routes/universities/hhu/libNews')); +router.get('/hhu/libNews', lazyloadRouteHandler('./routes/universities/hhu/lib-news')); // 河海大学常州校区 -router.get('/hhu/libNewsc', lazyloadRouteHandler('./routes/universities/hhu/libNewsc')); +router.get('/hhu/libNewsc', lazyloadRouteHandler('./routes/universities/hhu/lib-newsc')); // 上海科技大学 router.get('/shanghaitech/activity', lazyloadRouteHandler('./routes/universities/shanghaitech/activity')); @@ -197,8 +197,8 @@ router.get('/thu/:type', lazyloadRouteHandler('./routes/universities/thu/index') router.get('/shou/www/:type', lazyloadRouteHandler('./routes/universities/shou/www')); // 西南科技大学 -router.get('/swust/jwc/news', lazyloadRouteHandler('./routes/universities/swust/jwc_news')); -router.get('/swust/jwc/notice/:type?', lazyloadRouteHandler('./routes/universities/swust/jwc_notice')); +router.get('/swust/jwc/news', lazyloadRouteHandler('./routes/universities/swust/jwc-news')); +router.get('/swust/jwc/notice/:type?', lazyloadRouteHandler('./routes/universities/swust/jwc-notice')); router.get('/swust/cs/:type?', lazyloadRouteHandler('./routes/universities/swust/cs')); // UTdallas ISSO @@ -308,7 +308,7 @@ router.get('/lyu/news/:type', lazyloadRouteHandler('./routes/universities/lyu/ne // 福州大学 router.get('/fzu/:type', lazyloadRouteHandler('./routes/universities/fzu/news')); -router.get('/fzu_min/:type', lazyloadRouteHandler('./routes/universities/fzu/news_min')); +router.get('/fzu_min/:type', lazyloadRouteHandler('./routes/universities/fzu/news-min')); // 厦门大学 router.get('/xmu/aero/:type', lazyloadRouteHandler('./routes/universities/xmu/aero')); @@ -358,7 +358,7 @@ router.get('/parcel/hermesuk/:tracking', lazyloadRouteHandler('./routes/parcel/h // 数字尾巴 router.get('/dgtle', lazyloadRouteHandler('./routes/dgtle/index')); router.get('/dgtle/whale/category/:category', lazyloadRouteHandler('./routes/dgtle/whale')); -router.get('/dgtle/whale/rank/:type/:rule', lazyloadRouteHandler('./routes/dgtle/whale_rank')); +router.get('/dgtle/whale/rank/:type/:rule', lazyloadRouteHandler('./routes/dgtle/whale-rank')); router.get('/dgtle/trade/:typeId?', lazyloadRouteHandler('./routes/dgtle/trade')); router.get('/dgtle/trade/search/:keyword', lazyloadRouteHandler('./routes/dgtle/keyword')); @@ -429,11 +429,11 @@ router.get('/testerhome/newest', lazyloadRouteHandler('./routes/testerhome/newes router.get('/coolbuy/newest', lazyloadRouteHandler('./routes/coolbuy/newest')); // MiniFlux -router.get('/miniflux/subscription/:parameters?', lazyloadRouteHandler('./routes/miniflux/get_feeds')); -router.get('/miniflux/:feeds/:parameters?', lazyloadRouteHandler('./routes/miniflux/get_entries')); +router.get('/miniflux/subscription/:parameters?', lazyloadRouteHandler('./routes/miniflux/get-feeds')); +router.get('/miniflux/:feeds/:parameters?', lazyloadRouteHandler('./routes/miniflux/get-entries')); // 動畫瘋 -router.get('/anigamer/new_anime', lazyloadRouteHandler('./routes/anigamer/new_anime')); +router.get('/anigamer/new_anime', lazyloadRouteHandler('./routes/anigamer/new-anime')); router.get('/anigamer/anime/:sn', lazyloadRouteHandler('./routes/anigamer/anime')); // 中国药科大学 @@ -567,7 +567,7 @@ router.get('/ui-cn/user/:id', lazyloadRouteHandler('./routes/ui-cn/user')); // 一些博客 // 敬维-以认真的态度做完美的事情: https://jingwei.link/ -router.get('/blogs/jingwei.link', lazyloadRouteHandler('./routes/blogs/jingwei_link')); +router.get('/blogs/jingwei.link', lazyloadRouteHandler('./routes/blogs/jingwei-link')); // 王垠的博客-当然我在扯淡 router.get('/blogs/wangyin', lazyloadRouteHandler('./routes/blogs/wangyin')); @@ -695,7 +695,7 @@ router.get('/aqicn/:city/:pollution?', lazyloadRouteHandler('./routes/aqicn/inde // 猫眼电影 router.get('/maoyan/hot', lazyloadRouteHandler('./routes/maoyan/hot')); router.get('/maoyan/upcoming', lazyloadRouteHandler('./routes/maoyan/upcoming')); -router.get('/maoyan/hotComplete/:orderby?/:ascOrDesc?/:top?', lazyloadRouteHandler('./routes/maoyan/hotComplete')); +router.get('/maoyan/hotComplete/:orderby?/:ascOrDesc?/:top?', lazyloadRouteHandler('./routes/maoyan/hot-complete')); // 国家退伍士兵信息 router.get('/gov/veterans/:type', lazyloadRouteHandler('./routes/gov/veterans/china')); @@ -779,8 +779,8 @@ router.get('/simonsfoundation/recommend', lazyloadRouteHandler('./routes/simonsf router.get('/siren/news', lazyloadRouteHandler('./routes/siren/index')); // 学堂在线 -router.get('/xuetangx/course/:cid/:type', lazyloadRouteHandler('./routes/xuetangx/course_info')); -router.get('/xuetangx/course/list/:mode/:credential/:status/:type?', lazyloadRouteHandler('./routes/xuetangx/course_list')); +router.get('/xuetangx/course/:cid/:type', lazyloadRouteHandler('./routes/xuetangx/course-info')); +router.get('/xuetangx/course/list/:mode/:credential/:status/:type?', lazyloadRouteHandler('./routes/xuetangx/course-list')); // 正版中国 // router.get('/getitfree/category/:category?', lazyloadRouteHandler('./routes/getitfree/category.js')); @@ -951,11 +951,11 @@ router.get('/emi-nitta/:type', lazyloadRouteHandler('./routes/emi-nitta/home')); router.get('/vscode/marketplace/:type?', lazyloadRouteHandler('./routes/vscode/marketplace')); // 饭否 -router.get('/fanfou/user_timeline/:uid', lazyloadRouteHandler('./routes/fanfou/user_timeline')); -router.get('/fanfou/home_timeline', lazyloadRouteHandler('./routes/fanfou/home_timeline')); +router.get('/fanfou/user_timeline/:uid', lazyloadRouteHandler('./routes/fanfou/user-timeline')); +router.get('/fanfou/home_timeline', lazyloadRouteHandler('./routes/fanfou/home-timeline')); router.get('/fanfou/favorites/:uid', lazyloadRouteHandler('./routes/fanfou/favorites')); router.get('/fanfou/trends', lazyloadRouteHandler('./routes/fanfou/trends')); -router.get('/fanfou/public_timeline/:keyword', lazyloadRouteHandler('./routes/fanfou/public_timeline')); +router.get('/fanfou/public_timeline/:keyword', lazyloadRouteHandler('./routes/fanfou/public-timeline')); // Remote Work router.get('/remote-work/:caty?', lazyloadRouteHandler('./routes/remote-work/index')); @@ -965,7 +965,7 @@ router.get('/chocolatey/software/:name?', lazyloadRouteHandler('./routes/chocola // 巴哈姆特 router.get('/bahamut/creation/:author/:category?', lazyloadRouteHandler('./routes/bahamut/creation')); -router.get('/bahamut/creation_index/:category?/:subcategory?/:type?', lazyloadRouteHandler('./routes/bahamut/creation_index')); +router.get('/bahamut/creation_index/:category?/:subcategory?/:type?', lazyloadRouteHandler('./routes/bahamut/creation-index')); // CentBrowser router.get('/centbrowser/history', lazyloadRouteHandler('./routes/centbrowser/history')); @@ -1065,7 +1065,7 @@ router.get('/haohaozhu/discover/:keyword?', lazyloadRouteHandler('./routes/haoha // 魔法纪录 router.get('/magireco/announcements', lazyloadRouteHandler('./routes/magireco/announcements')); -router.get('/magireco/event_banner', lazyloadRouteHandler('./routes/magireco/event_banner')); +router.get('/magireco/event_banner', lazyloadRouteHandler('./routes/magireco/event-banner')); // 我有一片芝麻地 router.get('/blogs/hedwig/:type', lazyloadRouteHandler('./routes/blogs/hedwig')); @@ -1450,7 +1450,7 @@ router.get('/dw/:lang?/:caty?', lazyloadRouteHandler('./routes/dw/index')); router.get('/citavi/:caty?', lazyloadRouteHandler('./routes/citavi/index')); // Sesame -router.get('/sesame/release_notes', lazyloadRouteHandler('./routes/sesame/release_notes')); +router.get('/sesame/release_notes', lazyloadRouteHandler('./routes/sesame/release-notes')); // QNAP router.get('/qnap/release-notes/:id', lazyloadRouteHandler('./routes/qnap/release-notes')); @@ -1475,7 +1475,7 @@ router.get('/grandchallenge/challenges', lazyloadRouteHandler('./routes/grandcha router.get('/nwpu/:column', lazyloadRouteHandler('./routes/nwpu/index')); // 美国联邦最高法院 -router.get('/us/supremecourt/argument_audio/:year?', lazyloadRouteHandler('./routes/us/supremecourt/argument_audio')); +router.get('/us/supremecourt/argument_audio/:year?', lazyloadRouteHandler('./routes/us/supremecourt/argument-audio')); // 优设网 router.get('/uisdc/hangye/:caty?', lazyloadRouteHandler('./routes/uisdc/hangye')); @@ -1574,7 +1574,7 @@ router.get('/marginnote/tag/:id?', lazyloadRouteHandler('./routes/marginnote/tag router.get('/asml/press-releases', lazyloadRouteHandler('./routes/asml/press-releases')); // 有趣天文奇观 -router.get('/interesting-sky/astronomical_events/:year?', lazyloadRouteHandler('./routes/interesting-sky/astronomical_events')); +router.get('/interesting-sky/astronomical_events/:year?', lazyloadRouteHandler('./routes/interesting-sky/astronomical-events')); router.get('/interesting-sky/recent-interesting', lazyloadRouteHandler('./routes/interesting-sky/recent-interesting')); router.get('/interesting-sky', lazyloadRouteHandler('./routes/interesting-sky/index')); @@ -1704,8 +1704,8 @@ router.get('/furaffinity/journals/:username', lazyloadRouteHandler('./routes/fur router.get('/furaffinity/gallery/:username/:nsfw?', lazyloadRouteHandler('./routes/furaffinity/gallery')); router.get('/furaffinity/scraps/:username/:nsfw?', lazyloadRouteHandler('./routes/furaffinity/scraps')); router.get('/furaffinity/favorites/:username/:nsfw?', lazyloadRouteHandler('./routes/furaffinity/favorites')); -router.get('/furaffinity/submission_comments/:id', lazyloadRouteHandler('./routes/furaffinity/submission_comments')); -router.get('/furaffinity/journal_comments/:id', lazyloadRouteHandler('./routes/furaffinity/journal_comments')); +router.get('/furaffinity/submission_comments/:id', lazyloadRouteHandler('./routes/furaffinity/submission-comments')); +router.get('/furaffinity/journal_comments/:id', lazyloadRouteHandler('./routes/furaffinity/journal-comments')); // Trakt.tv router.get('/trakt/collection/:username/:type?', lazyloadRouteHandler('./routes/trakt/collection')); diff --git a/lib/routes/005tv/zx.js b/lib/routes/005tv/zx.js index e60db0ce4..007546baa 100644 --- a/lib/routes/005tv/zx.js +++ b/lib/routes/005tv/zx.js @@ -17,7 +17,7 @@ module.exports = async (ctx) => { description: ` ${$(item).find('div.p-row').text()}`, link: $(item).find('h3 > a').attr('href'), - pubDate: new Date($(item).find('span.fr.time').text().trim().substr(0, 4), $(item).find('span.fr.time').text().trim().substr(5, 2), $(item).find('span.fr.time').text().trim().substr(8, 4)).toUTCString(), + pubDate: new Date($(item).find('span.fr.time').text().trim().slice(0, 4), $(item).find('span.fr.time').text().trim().slice(5, 7), $(item).find('span.fr.time').text().trim().slice(8, 12)).toUTCString(), })) .get(), }; diff --git a/lib/routes/10000link/news.js b/lib/routes/10000link/news.js index fca81d9bf..aab5de98d 100644 --- a/lib/routes/10000link/news.js +++ b/lib/routes/10000link/news.js @@ -32,7 +32,7 @@ module.exports = async (ctx) => { const cache = await ctx.cache.get(link); if (cache) { - return Promise.resolve(JSON.parse(cache)); + return JSON.parse(cache); } const description = await ProcessFeed(link); @@ -46,7 +46,7 @@ module.exports = async (ctx) => { }; ctx.cache.set(link, JSON.stringify(single)); - return Promise.resolve(single); + return single; }) ); diff --git a/lib/routes/12379/index.js b/lib/routes/12379/index.js index a9a5e8e41..05fc4e295 100644 --- a/lib/routes/12379/index.js +++ b/lib/routes/12379/index.js @@ -6,7 +6,7 @@ module.exports = async (ctx) => { method: 'get', url: currentUrl, }); - const data = JSON.parse(response.data.substr('var alertData ='.length, response.data.length + 1)); + const data = JSON.parse(response.data.slice('var alertData ='.length, 'var alertData ='.length + response.data.length + 1)); const list = data.map((item) => ({ title: item.headline, diff --git a/lib/routes/21caijing/channel.js b/lib/routes/21caijing/channel.js index 148c9b6fb..1a6729f50 100644 --- a/lib/routes/21caijing/channel.js +++ b/lib/routes/21caijing/channel.js @@ -22,7 +22,7 @@ module.exports = async (ctx) => { list.map(async (link) => { const cache = await ctx.cache.get(link); if (cache) { - return Promise.resolve(JSON.parse(cache)); + return JSON.parse(cache); } const response = await got({ @@ -47,7 +47,7 @@ module.exports = async (ctx) => { const $el = $(element); const img_original_data = $el.attr('data-original'); const img_src = $el.attr('src'); - if (typeof img_src === 'undefined' && img_original_data) { + if (img_src === undefined && img_original_data) { $el.attr('src', img_original_data); } }); @@ -62,7 +62,7 @@ module.exports = async (ctx) => { }; ctx.cache.set(link, JSON.stringify(single)); - return Promise.resolve(single); + return single; }) ); diff --git a/lib/routes/60s-science/transcript.js b/lib/routes/60s-science/transcript.js index a609b9b70..5c9308d6a 100644 --- a/lib/routes/60s-science/transcript.js +++ b/lib/routes/60s-science/transcript.js @@ -17,7 +17,7 @@ module.exports = async (ctx) => { const address = $(item).attr('href'); const cache = await ctx.cache.get(address); if (cache) { - return Promise.resolve(JSON.parse(cache)); + return JSON.parse(cache); } const res = await got.get(address); const capture = cheerio.load(res.data); @@ -33,7 +33,7 @@ module.exports = async (ctx) => { intro + capture('.transcript__inner') .html() - .replace(/\[?\(?The above text.*this podcast.*?em.*?p>/g, ''); + .replaceAll(/\[?\(?The above text.*this podcast.*?em.*?p>/g, ''); const track = capture('.podcasts__media > div > a').attr('href'); const single = { title, @@ -46,7 +46,7 @@ module.exports = async (ctx) => { pubDate: new Date(time).toUTCString(), }; ctx.cache.set(address, JSON.stringify(single)); - return Promise.resolve(single); + return single; }) ); ctx.state.data = { diff --git a/lib/routes/755/user.js b/lib/routes/755/user.js index c544e64c8..aa59f130c 100644 --- a/lib/routes/755/user.js +++ b/lib/routes/755/user.js @@ -29,13 +29,13 @@ module.exports = async (ctx) => { .map((item) => { switch (item.bodyType) { case 1: - return `${item.text.replace(/\n/gm, '')}`; + return `${item.text.replaceAll(/\n/gm, '')}`; case 2: return ``; case 3: return ``; case 4: - return `${item.comment.user.name}:${item.comment.comment.body.replace(/\n/gm, '')}`; + return `${item.comment.user.name}:${item.comment.comment.body.replaceAll(/\n/gm, '')}`; case 7: return `${item.talk.name}:${GetContent(item.post)}`; case 8: @@ -49,7 +49,7 @@ module.exports = async (ctx) => { const GetTitle = (post) => { const texts = post.body.filter((s) => s.bodyType === 1); const type_name = postTypes[post.postType]; - return texts.length !== 0 ? texts[0].text.split('\n')[0] : type_name; + return texts.length === 0 ? type_name : texts[0].text.split('\n')[0]; }; const ProcessFeed = (data) => diff --git a/lib/routes/99percentinvisible/transcript.js b/lib/routes/99percentinvisible/transcript.js index dd8274a4f..bbb17f9b0 100644 --- a/lib/routes/99percentinvisible/transcript.js +++ b/lib/routes/99percentinvisible/transcript.js @@ -20,7 +20,7 @@ module.exports = async (ctx) => { .map(async (itemUrl) => { const cache = await ctx.cache.get(itemUrl); if (cache) { - return Promise.resolve(JSON.parse(cache)); + return JSON.parse(cache); } const response = await got.get(itemUrl); @@ -34,7 +34,7 @@ module.exports = async (ctx) => { pubDate: new Date($('article header .entry-meta time').text()).toUTCString(), }; ctx.cache.set(itemUrl, JSON.stringify(single)); - return Promise.resolve(single); + return single; }) ); diff --git a/lib/routes/acm/amturingaward.js b/lib/routes/acm/amturingaward.js index 297ea0298..57377aca5 100644 --- a/lib/routes/acm/amturingaward.js +++ b/lib/routes/acm/amturingaward.js @@ -17,7 +17,7 @@ module.exports = async (ctx) => { .map(async (_, item) => { item = $(item); - const year = item.find('span').text().replace(/\(|\)/g, ''); + const year = item.find('span').text().replaceAll(/\(|\)/g, ''); const pubDate = new Date(`${year}-12-31`).toUTCString(); const winnersUrls = []; @@ -47,7 +47,7 @@ module.exports = async (ctx) => { winnerDescription += image + column.html(); } - return Promise.resolve(winnerDescription); + return winnerDescription; }); return { diff --git a/lib/routes/acwifi/index.js b/lib/routes/acwifi/index.js index 26cb23050..7894c0503 100644 --- a/lib/routes/acwifi/index.js +++ b/lib/routes/acwifi/index.js @@ -25,7 +25,7 @@ module.exports = async (ctx) => { const cache = await ctx.cache.get(link); if (cache) { - return Promise.resolve(JSON.parse(cache)); + return JSON.parse(cache); } const response = await got({ @@ -41,7 +41,7 @@ module.exports = async (ctx) => { link, }; ctx.cache.set(link, JSON.stringify(single)); - return Promise.resolve(single); + return single; }) ); ctx.state.data = { title: '路由器交流', link: baseUrl, item: out }; diff --git a/lib/routes/adquan/index.js b/lib/routes/adquan/index.js index abe707aed..9a361292a 100644 --- a/lib/routes/adquan/index.js +++ b/lib/routes/adquan/index.js @@ -18,12 +18,7 @@ const config = { }; module.exports = async (ctx) => { - let cfg; - if (ctx.params.type) { - cfg = config[ctx.params.type]; - } else { - cfg = config.index; - } + const cfg = ctx.params.type ? config[ctx.params.type] : config.index; const response = await got({ method: 'get', diff --git a/lib/routes/aiyanxishe/home.js b/lib/routes/aiyanxishe/home.js index eeefc6b3e..1003321e6 100644 --- a/lib/routes/aiyanxishe/home.js +++ b/lib/routes/aiyanxishe/home.js @@ -6,11 +6,7 @@ module.exports = async (ctx) => { let url = 'https://api.yanxishe.com/api?page=1&size=30&parent_tag='; - if (id === 'all') { - url += '&tag='; - } else { - url += `&tag=${id}`; - } + url += id === 'all' ? '&tag=' : `&tag=${id}`; if (sort === 'hot') { url += '&is_hot=1&is_recommend=0'; } else if (sort === 'recommend') { @@ -35,11 +31,7 @@ module.exports = async (ctx) => { case 'blog': // 博客 description = data.content; author = data.user.nickname; - if (data.relation_special) { - link = `https://www.yanxishe.com/columnDetail/${id}`; - } else { - link = `https://www.yanxishe.com/blogDetail/${id}`; - } + link = data.relation_special ? `https://www.yanxishe.com/columnDetail/${id}` : `https://www.yanxishe.com/blogDetail/${id}`; break; case 'question': // 问答 description = data.content; @@ -48,9 +40,9 @@ module.exports = async (ctx) => { break; case 'article': // 翻译 description = ` ${data.title} ${data.zh_title} `; - data.paragraphs.forEach((element) => { + for (const element of data.paragraphs) { description += ` ${element.content} ${element.zh_content.content} `; - }); + } description += `
${text.substring(0, ctx.query.brief)}…
${text}
\[?\(?The above text.*this podcast.*?em.*?p>/g, ''); + .replaceAll(/\[?\(?The above text.*this podcast.*?em.*?p>/g, ''); const track = capture('.podcasts__media > div > a').attr('href'); const single = { title, @@ -46,7 +46,7 @@ module.exports = async (ctx) => { pubDate: new Date(time).toUTCString(), }; ctx.cache.set(address, JSON.stringify(single)); - return Promise.resolve(single); + return single; }) ); ctx.state.data = { diff --git a/lib/routes/755/user.js b/lib/routes/755/user.js index c544e64c8..aa59f130c 100644 --- a/lib/routes/755/user.js +++ b/lib/routes/755/user.js @@ -29,13 +29,13 @@ module.exports = async (ctx) => { .map((item) => { switch (item.bodyType) { case 1: - return `${item.text.replace(/\n/gm, '')}`; + return `${item.text.replaceAll(/\n/gm, '')}`; case 2: return ``; case 3: return ``; case 4: - return `${item.comment.user.name}:${item.comment.comment.body.replace(/\n/gm, '')}`; + return `${item.comment.user.name}:${item.comment.comment.body.replaceAll(/\n/gm, '')}`; case 7: return `${item.talk.name}:${GetContent(item.post)}`; case 8: @@ -49,7 +49,7 @@ module.exports = async (ctx) => { const GetTitle = (post) => { const texts = post.body.filter((s) => s.bodyType === 1); const type_name = postTypes[post.postType]; - return texts.length !== 0 ? texts[0].text.split('\n')[0] : type_name; + return texts.length === 0 ? type_name : texts[0].text.split('\n')[0]; }; const ProcessFeed = (data) => diff --git a/lib/routes/99percentinvisible/transcript.js b/lib/routes/99percentinvisible/transcript.js index dd8274a4f..bbb17f9b0 100644 --- a/lib/routes/99percentinvisible/transcript.js +++ b/lib/routes/99percentinvisible/transcript.js @@ -20,7 +20,7 @@ module.exports = async (ctx) => { .map(async (itemUrl) => { const cache = await ctx.cache.get(itemUrl); if (cache) { - return Promise.resolve(JSON.parse(cache)); + return JSON.parse(cache); } const response = await got.get(itemUrl); @@ -34,7 +34,7 @@ module.exports = async (ctx) => { pubDate: new Date($('article header .entry-meta time').text()).toUTCString(), }; ctx.cache.set(itemUrl, JSON.stringify(single)); - return Promise.resolve(single); + return single; }) ); diff --git a/lib/routes/acm/amturingaward.js b/lib/routes/acm/amturingaward.js index 297ea0298..57377aca5 100644 --- a/lib/routes/acm/amturingaward.js +++ b/lib/routes/acm/amturingaward.js @@ -17,7 +17,7 @@ module.exports = async (ctx) => { .map(async (_, item) => { item = $(item); - const year = item.find('span').text().replace(/\(|\)/g, ''); + const year = item.find('span').text().replaceAll(/\(|\)/g, ''); const pubDate = new Date(`${year}-12-31`).toUTCString(); const winnersUrls = []; @@ -47,7 +47,7 @@ module.exports = async (ctx) => { winnerDescription += image + column.html(); } - return Promise.resolve(winnerDescription); + return winnerDescription; }); return { diff --git a/lib/routes/acwifi/index.js b/lib/routes/acwifi/index.js index 26cb23050..7894c0503 100644 --- a/lib/routes/acwifi/index.js +++ b/lib/routes/acwifi/index.js @@ -25,7 +25,7 @@ module.exports = async (ctx) => { const cache = await ctx.cache.get(link); if (cache) { - return Promise.resolve(JSON.parse(cache)); + return JSON.parse(cache); } const response = await got({ @@ -41,7 +41,7 @@ module.exports = async (ctx) => { link, }; ctx.cache.set(link, JSON.stringify(single)); - return Promise.resolve(single); + return single; }) ); ctx.state.data = { title: '路由器交流', link: baseUrl, item: out }; diff --git a/lib/routes/adquan/index.js b/lib/routes/adquan/index.js index abe707aed..9a361292a 100644 --- a/lib/routes/adquan/index.js +++ b/lib/routes/adquan/index.js @@ -18,12 +18,7 @@ const config = { }; module.exports = async (ctx) => { - let cfg; - if (ctx.params.type) { - cfg = config[ctx.params.type]; - } else { - cfg = config.index; - } + const cfg = ctx.params.type ? config[ctx.params.type] : config.index; const response = await got({ method: 'get', diff --git a/lib/routes/aiyanxishe/home.js b/lib/routes/aiyanxishe/home.js index eeefc6b3e..1003321e6 100644 --- a/lib/routes/aiyanxishe/home.js +++ b/lib/routes/aiyanxishe/home.js @@ -6,11 +6,7 @@ module.exports = async (ctx) => { let url = 'https://api.yanxishe.com/api?page=1&size=30&parent_tag='; - if (id === 'all') { - url += '&tag='; - } else { - url += `&tag=${id}`; - } + url += id === 'all' ? '&tag=' : `&tag=${id}`; if (sort === 'hot') { url += '&is_hot=1&is_recommend=0'; } else if (sort === 'recommend') { @@ -35,11 +31,7 @@ module.exports = async (ctx) => { case 'blog': // 博客 description = data.content; author = data.user.nickname; - if (data.relation_special) { - link = `https://www.yanxishe.com/columnDetail/${id}`; - } else { - link = `https://www.yanxishe.com/blogDetail/${id}`; - } + link = data.relation_special ? `https://www.yanxishe.com/columnDetail/${id}` : `https://www.yanxishe.com/blogDetail/${id}`; break; case 'question': // 问答 description = data.content; @@ -48,9 +40,9 @@ module.exports = async (ctx) => { break; case 'article': // 翻译 description = ` ${data.title} ${data.zh_title} `; - data.paragraphs.forEach((element) => { + for (const element of data.paragraphs) { description += ` ${element.content} ${element.zh_content.content} `; - }); + } description += `
\[?\(?The above text.*this podcast.*?em.*?p>/g, ''); const track = capture('.podcasts__media > div > a').attr('href'); const single = { title, @@ -46,7 +46,7 @@ module.exports = async (ctx) => { pubDate: new Date(time).toUTCString(), }; ctx.cache.set(address, JSON.stringify(single)); - return Promise.resolve(single); + return single; }) ); ctx.state.data = { diff --git a/lib/routes/755/user.js b/lib/routes/755/user.js index c544e64c8..aa59f130c 100644 --- a/lib/routes/755/user.js +++ b/lib/routes/755/user.js @@ -29,13 +29,13 @@ module.exports = async (ctx) => { .map((item) => { switch (item.bodyType) { case 1: - return `${item.text.replace(/\n/gm, '')}`; + return `${item.text.replaceAll(/\n/gm, '')}`; case 2: return ``; case 3: return ``; case 4: - return `${item.comment.user.name}:${item.comment.comment.body.replace(/\n/gm, '')}`; + return `${item.comment.user.name}:${item.comment.comment.body.replaceAll(/\n/gm, '')}`; case 7: return `${item.talk.name}:${GetContent(item.post)}`; case 8: @@ -49,7 +49,7 @@ module.exports = async (ctx) => { const GetTitle = (post) => { const texts = post.body.filter((s) => s.bodyType === 1); const type_name = postTypes[post.postType]; - return texts.length !== 0 ? texts[0].text.split('\n')[0] : type_name; + return texts.length === 0 ? type_name : texts[0].text.split('\n')[0]; }; const ProcessFeed = (data) => diff --git a/lib/routes/99percentinvisible/transcript.js b/lib/routes/99percentinvisible/transcript.js index dd8274a4f..bbb17f9b0 100644 --- a/lib/routes/99percentinvisible/transcript.js +++ b/lib/routes/99percentinvisible/transcript.js @@ -20,7 +20,7 @@ module.exports = async (ctx) => { .map(async (itemUrl) => { const cache = await ctx.cache.get(itemUrl); if (cache) { - return Promise.resolve(JSON.parse(cache)); + return JSON.parse(cache); } const response = await got.get(itemUrl); @@ -34,7 +34,7 @@ module.exports = async (ctx) => { pubDate: new Date($('article header .entry-meta time').text()).toUTCString(), }; ctx.cache.set(itemUrl, JSON.stringify(single)); - return Promise.resolve(single); + return single; }) ); diff --git a/lib/routes/acm/amturingaward.js b/lib/routes/acm/amturingaward.js index 297ea0298..57377aca5 100644 --- a/lib/routes/acm/amturingaward.js +++ b/lib/routes/acm/amturingaward.js @@ -17,7 +17,7 @@ module.exports = async (ctx) => { .map(async (_, item) => { item = $(item); - const year = item.find('span').text().replace(/\(|\)/g, ''); + const year = item.find('span').text().replaceAll(/\(|\)/g, ''); const pubDate = new Date(`${year}-12-31`).toUTCString(); const winnersUrls = []; @@ -47,7 +47,7 @@ module.exports = async (ctx) => { winnerDescription += image + column.html(); } - return Promise.resolve(winnerDescription); + return winnerDescription; }); return { diff --git a/lib/routes/acwifi/index.js b/lib/routes/acwifi/index.js index 26cb23050..7894c0503 100644 --- a/lib/routes/acwifi/index.js +++ b/lib/routes/acwifi/index.js @@ -25,7 +25,7 @@ module.exports = async (ctx) => { const cache = await ctx.cache.get(link); if (cache) { - return Promise.resolve(JSON.parse(cache)); + return JSON.parse(cache); } const response = await got({ @@ -41,7 +41,7 @@ module.exports = async (ctx) => { link, }; ctx.cache.set(link, JSON.stringify(single)); - return Promise.resolve(single); + return single; }) ); ctx.state.data = { title: '路由器交流', link: baseUrl, item: out }; diff --git a/lib/routes/adquan/index.js b/lib/routes/adquan/index.js index abe707aed..9a361292a 100644 --- a/lib/routes/adquan/index.js +++ b/lib/routes/adquan/index.js @@ -18,12 +18,7 @@ const config = { }; module.exports = async (ctx) => { - let cfg; - if (ctx.params.type) { - cfg = config[ctx.params.type]; - } else { - cfg = config.index; - } + const cfg = ctx.params.type ? config[ctx.params.type] : config.index; const response = await got({ method: 'get', diff --git a/lib/routes/aiyanxishe/home.js b/lib/routes/aiyanxishe/home.js index eeefc6b3e..1003321e6 100644 --- a/lib/routes/aiyanxishe/home.js +++ b/lib/routes/aiyanxishe/home.js @@ -6,11 +6,7 @@ module.exports = async (ctx) => { let url = 'https://api.yanxishe.com/api?page=1&size=30&parent_tag='; - if (id === 'all') { - url += '&tag='; - } else { - url += `&tag=${id}`; - } + url += id === 'all' ? '&tag=' : `&tag=${id}`; if (sort === 'hot') { url += '&is_hot=1&is_recommend=0'; } else if (sort === 'recommend') { @@ -35,11 +31,7 @@ module.exports = async (ctx) => { case 'blog': // 博客 description = data.content; author = data.user.nickname; - if (data.relation_special) { - link = `https://www.yanxishe.com/columnDetail/${id}`; - } else { - link = `https://www.yanxishe.com/blogDetail/${id}`; - } + link = data.relation_special ? `https://www.yanxishe.com/columnDetail/${id}` : `https://www.yanxishe.com/blogDetail/${id}`; break; case 'question': // 问答 description = data.content; @@ -48,9 +40,9 @@ module.exports = async (ctx) => { break; case 'article': // 翻译 description = ` ${data.title} ${data.zh_title} `; - data.paragraphs.forEach((element) => { + for (const element of data.paragraphs) { description += ` ${element.content} ${element.zh_content.content} `; - }); + } description += `
${item.text.replace(/\n/gm, '')}
${item.text.replaceAll(/\n/gm, '')}
${item.comment.user.name}:${item.comment.comment.body.replace(/\n/gm, '')}
${item.comment.user.name}:${item.comment.comment.body.replaceAll(/\n/gm, '')}
${item.talk.name}:${GetContent(item.post)}