diff --git a/.eslintrc b/.eslintrc index 144882c..2f40d26 100644 --- a/.eslintrc +++ b/.eslintrc @@ -8,7 +8,8 @@ "plugin:node/recommended", "plugin:optimize-regex/all", "plugin:ramda/recommended", - "plugin:security/recommended" + "plugin:security/recommended", + "plugin:sonarjs/recommended" ], "plugins": [ "anti-trojan-source", @@ -21,6 +22,7 @@ "optimize-regex", "ramda", "security", + "sonarjs", "xss" ], "env": { @@ -37,10 +39,12 @@ }, "rules": { "anti-trojan-source/no-bidi": "error", - "ava/no-only-test": 0, "camelcase": 0, "consistent-return": ["warn", { "treatUndefinedAsUnspecified": false }], + "eslint-comments/no-use": 0, + "filenames/match-regex": 0, "global-require": 0, + "import/no-commonjs": 0, "import/no-dynamic-require": 0, "import/no-extraneous-dependencies": [ "error", { @@ -76,9 +80,12 @@ "node/no-unpublished-require": 0, "object-curly-newline": 0, "optimize-regex/optimize-regex": "warn", + "prettier/prettier": 0, "security/detect-non-literal-fs-filename": 0, "security/detect-non-literal-require": 0, - "security/detect-object-injection": 0 + "security/detect-object-injection": 0, + "sonarjs/cognitive-complexity": 0, + "sonarjs/no-duplicate-string": 0 }, "settings": { "jsdoc": { diff --git a/CHANGELOG.md b/CHANGELOG.md index c3712b9..7e0868a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [5.2.1](https://github.com/uttori/uttori-wiki/compare/v5.2.0...v5.2.1) - 2023-04-13 + +- ๐Ÿงน Regenerate docs and readme with new updates. +- ๐Ÿ›  Clean up some types that were outdated. +- ๐Ÿ›  Clean up a `forEach` use that should have been `for of`. +- ๐Ÿ›  Clean up an uneeded check of `document`. + ## [5.2.0](https://github.com/uttori/uttori-wiki/compare/v5.1.0...v5.2.0) - 2023-04-12 - ๐Ÿงฐ Add support for per route middleware through the configuration. diff --git a/README.md b/README.md index 813aec7..f203aa3 100644 --- a/README.md +++ b/README.md @@ -270,6 +270,25 @@ const config = { historyRestoreRoute: (request, response, next) => { ... }, notFoundRoute: (request, response, next) => { ... }, saveValidRoute: (request, response, next) => { ... }, + + // Custom per route middleware, in the order they should be used + routeMiddleware: { + home: [], + tagIndex: [], + tag: [], + search: [], + notFound: [], + create: [], + saveNew: [], + preview: [], + edit: [], + delete: [], + historyIndex: [], + historyDetail: [], + historyRestore: [], + save: [], + detail: [], + }, }; module.exports = config; diff --git a/docs/config.md b/docs/config.md index bbde4e8..9d45b7e 100644 --- a/docs/config.md +++ b/docs/config.md @@ -69,6 +69,7 @@ | [historyRestoreRoute] | function | | A replacement route handler for the history restore route. | | [notFoundRoute] | function | | A replacement route handler for the 404 not found route. | | [saveValidRoute] | function | | A replacement route handler for the save valid route. | +| [routeMiddleware] | object | | A collection of middleware for each route. | | plugins | Array | | Collection of Uttori Plugins. Storage Plugins should come before other plugins. | | [middleware] | Array | | Middleware Configuration to be passed along to Express in the format of ['use', layouts], ['set', 'layout extractScripts', true], ['engine', 'html', ejs.renderFile]. | diff --git a/package-lock.json b/package-lock.json index 38ab1b9..21f026a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,6 +32,7 @@ "eslint-plugin-react": "^7.32.2", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-security": "^1.7.1", + "eslint-plugin-sonarjs": "^0.19.0", "eslint-plugin-xss": "^0.1.12", "express": "^4.18.2", "express-ejs-layouts": "^2.5.1", @@ -4401,6 +4402,18 @@ "safe-regex": "^2.1.1" } }, + "node_modules/eslint-plugin-sonarjs": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.19.0.tgz", + "integrity": "sha512-6+s5oNk5TFtVlbRxqZN7FIGmjdPCYQKaTzFPmqieCmsU1kBYDzndTeQav0xtQNwZJWu5awWfTGe8Srq9xFOGnw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, "node_modules/eslint-plugin-xss": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/eslint-plugin-xss/-/eslint-plugin-xss-0.1.12.tgz", @@ -15180,6 +15193,13 @@ "safe-regex": "^2.1.1" } }, + "eslint-plugin-sonarjs": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.19.0.tgz", + "integrity": "sha512-6+s5oNk5TFtVlbRxqZN7FIGmjdPCYQKaTzFPmqieCmsU1kBYDzndTeQav0xtQNwZJWu5awWfTGe8Srq9xFOGnw==", + "dev": true, + "requires": {} + }, "eslint-plugin-xss": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/eslint-plugin-xss/-/eslint-plugin-xss-0.1.12.tgz", diff --git a/package.json b/package.json index 375c9f8..0a5a11c 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "eslint-plugin-react": "^7.32.2", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-security": "^1.7.1", + "eslint-plugin-sonarjs": "^0.19.0", "eslint-plugin-xss": "^0.1.12", "express": "^4.18.2", "express-ejs-layouts": "^2.5.1", diff --git a/rm.hbs b/rm.hbs index 6137a5b..7ac83b8 100644 --- a/rm.hbs +++ b/rm.hbs @@ -270,6 +270,25 @@ const config = { historyRestoreRoute: (request, response, next) => { ... }, notFoundRoute: (request, response, next) => { ... }, saveValidRoute: (request, response, next) => { ... }, + + // Custom per route middleware, in the order they should be used + routeMiddleware: { + home: [], + tagIndex: [], + tag: [], + search: [], + notFound: [], + create: [], + saveNew: [], + preview: [], + edit: [], + delete: [], + historyIndex: [], + historyDetail: [], + historyRestore: [], + save: [], + detail: [], + }, }; module.exports = config; diff --git a/src/middleware.js b/src/middleware.js index 79ec3fb..5a418d4 100644 --- a/src/middleware.js +++ b/src/middleware.js @@ -14,13 +14,13 @@ module.exports = function middleware(config) { // Apply middleware configuration if (config.middleware && Array.isArray(config.middleware)) { // console.log('config.middleware', config.middleware); - config.middleware.forEach((item) => { + for (const item of config.middleware) { const fn = item.shift(); if (fn && app[fn] && typeof app[fn] === 'function') { debug(`app.${fn}(${JSON.stringify(item)})`); app[fn].call(app, ...item); } - }); + } } // https://expressjs.com/en/4x/api.html#express.static diff --git a/src/wiki.js b/src/wiki.js index 0f742d7..968a837 100644 --- a/src/wiki.js +++ b/src/wiki.js @@ -159,7 +159,7 @@ class UttoriWiki { let image = ''; if (document) { - description = document && document.excerpt ? document.excerpt : ''; + description = document.excerpt ? document.excerpt : ''; if (document.content && !description) { description = document.content.slice(0, 160); description = await this.hooks.filter('render-content', description, this); diff --git a/test/_helpers/server.js b/test/_helpers/server.js index cc574ec..34719a6 100644 --- a/test/_helpers/server.js +++ b/test/_helpers/server.js @@ -88,7 +88,7 @@ const serverSetup = () => { return server; }; -const next = function next() {}; +const next = () => {}; // Seed some example documents as requests to be saved const seed = async (uttori) => { const response = { set: () => {}, render: () => {}, redirect: () => {} }; diff --git a/test/preview.test.js b/test/preview.test.js index 7d911ca..d60d85e 100644 --- a/test/preview.test.js +++ b/test/preview.test.js @@ -1,5 +1,3 @@ -// @ts-nocheck -/* eslint-disable ramda/prefer-ramda-boolean */ const test = require('ava'); const sinon = require('sinon'); const request = require('supertest'); diff --git a/test/save.test.js b/test/save.test.js index c544e7f..8392716 100644 --- a/test/save.test.js +++ b/test/save.test.js @@ -1,5 +1,3 @@ -// @ts-nocheck -/* eslint-disable ramda/prefer-ramda-boolean */ const test = require('ava'); const request = require('supertest'); const sinon = require('sinon'); diff --git a/types/index.d.ts b/types/index.d.ts index 593f688..1f7bb0f 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -7,6 +7,7 @@ declare module "config" { export { UttoriWikiConfig }; } type UttoriWikiConfig = { + production?: boolean; site_title?: string; site_header?: string; site_footer?: string; @@ -18,7 +19,7 @@ declare module "config" { home_page?: string; ignore_slugs: string[]; excerpt_length?: number; - site_url: string; + site_url?: string; theme_dir?: string; public_dir?: string; use_delete_key?: boolean; @@ -52,7 +53,7 @@ declare module "config" { historyRestoreRoute?: Function; notFoundRoute?: Function; saveValidRoute?: Function; - routeMiddleware: { + routeMiddleware?: { home: Function[]; tagIndex: Function[]; tag: Function[]; @@ -85,9 +86,9 @@ declare module "wiki" { bindRoutes(server: Application): void; home(request: Request, response: Response, next: Function): Promise; homepageRedirect(request: Request, response: Response, _next: Function): void; - tagIndex(request: Request, response: Response, _next: Function): Promise; + tagIndex(request: Request, response: Response, next: Function): Promise; tag(request: Request, response: Response, next: Function): Promise; - search(request: Request, response: Response, _next: Function): Promise; + search(request: Request, response: Response, next: Function): Promise; edit(request: Request, response: Response, next: Function): Promise; delete(request: Request, response: Response, next: Function): Promise; save(request: Request, response: Response, next: Function): Promise; @@ -98,8 +99,8 @@ declare module "wiki" { historyIndex(request: Request, response: Response, next: Function): Promise; historyDetail(request: Request, response: Response, next: Function): Promise; historyRestore(request: Request, response: Response, next: Function): Promise; - notFound(request: Request, response: Response, _next: Function): Promise; - saveValid(request: Request, response: Response, _next: Function): Promise; + notFound(request: Request, response: Response, next: Function): Promise; + saveValid(request: Request, response: Response, next: Function): Promise; getTaggedDocuments(tag: string, limit?: number): Promise; } namespace UttoriWiki { @@ -113,8 +114,8 @@ declare module "wiki" { excerpt: string; content: string; html?: string; - createDate?: number; - updateDate?: number; + createDate: number; + updateDate: number; tags: string[]; redirects?: string[]; };