From 2cb5b6f8f9240030c959a665fe9259273344ce72 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Fri, 30 Apr 2021 11:54:50 +0200 Subject: [PATCH 01/11] Replace node-sass with sass --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8ab5fd2..228fad8 100644 --- a/package.json +++ b/package.json @@ -48,8 +48,8 @@ "jest": "^26.1.0", "maildev": "^1.1.0", "mini-css-extract-plugin": "^1.2.1", - "node-sass": "^5.0.0", "nodemon": "^2.0.3", + "sass": "^1.32.12", "sass-loader": "^11.0.1", "terser-webpack-plugin": "^5.0.3", "ts-jest": "^26.1.1", From efbc895ba3a2973f84bd8476e33b2b29916562d0 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Fri, 30 Apr 2021 11:55:37 +0200 Subject: [PATCH 02/11] Bump @types/node --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 228fad8..291b48d 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "@types/formidable": "^1.0.31", "@types/jest": "^26.0.4", "@types/mysql": "^2.15.15", - "@types/node": "^14.6.3", + "@types/node": "^15.0.1", "@types/nodemailer": "^6.4.0", "@types/nunjucks": "^3.1.3", "@types/ws": "^7.2.6", From 7e260ebde23ecd7ea0f5164595765a24b526a70e Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Mon, 7 Jun 2021 11:21:43 +0200 Subject: [PATCH 03/11] Upgrade dependencies, replace img-loader with image-minimizer-webpack-plugin --- package.json | 12 ++++++------ webpack.config.js | 48 +++++++++++++++++++++++++++++++++-------------- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index 291b48d..34cc701 100644 --- a/package.json +++ b/package.json @@ -39,20 +39,20 @@ "eslint": "^7.10.0", "feather-icons": "^4.28.0", "file-loader": "^6.0.0", - "imagemin": "^7.0.0", + "image-minimizer-webpack-plugin": "^2.2.0", "imagemin-gifsicle": "^7.0.0", "imagemin-mozjpeg": "^9.0.0", - "imagemin-pngquant": "^9.0.0", + "imagemin-pngquant": "^9.0.2", "imagemin-svgo": "^9.0.0", - "img-loader": "^3.0.1", - "jest": "^26.1.0", + "jest": "^27.0.4", "maildev": "^1.1.0", "mini-css-extract-plugin": "^1.2.1", "nodemon": "^2.0.3", "sass": "^1.32.12", - "sass-loader": "^11.0.1", + "sass-loader": "^12.0.0", + "svgo": "^2.3.0", "terser-webpack-plugin": "^5.0.3", - "ts-jest": "^26.1.1", + "ts-jest": "^27.0.3", "ts-loader": "^9.1.0", "typescript": "^4.0.2", "webpack": "^5.3.2", diff --git a/webpack.config.js b/webpack.config.js index 598acfd..20449a8 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,5 +1,7 @@ const path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin"); +const { extendDefaultPlugins } = require("svgo"); const TerserPlugin = require('terser-webpack-plugin'); const dev = process.env.NODE_ENV === 'development'; @@ -62,19 +64,8 @@ const config = { test: /\.(png|jpe?g|gif|svg)$/i, use: [ 'file-loader?name=../img/[name].[ext]', - { - loader: 'img-loader', - options: { - enabled: !dev, - plugins: [ - require('imagemin-gifsicle')({}), - require('imagemin-mozjpeg')({}), - require('imagemin-pngquant')({}), - require('imagemin-svgo')({}), - ] - } - } - ] + ], + type: 'asset', } ], }, @@ -85,6 +76,35 @@ const config = { new MiniCssExtractPlugin({ filename: '../css/[name].css', }), + new ImageMinimizerPlugin({ + minimizerOptions: { + // Lossless optimization with custom option + // Feel free to experiment with options for better result for you + plugins: [ + ["gifsicle", {}], + ["mozjpeg", {}], + ["pngquant", {}], + // Svgo configuration here https://github.com/svg/svgo#configuration + [ + "svgo", + { + plugins: extendDefaultPlugins([ + { + name: "removeViewBox", + active: false, + }, + { + name: "addAttributesToSVGElement", + params: { + attributes: [{ xmlns: "http://www.w3.org/2000/svg" }], + }, + }, + ]), + }, + ], + ], + }, + }), ] }; @@ -97,4 +117,4 @@ if (!dev) { }; } -module.exports = config; \ No newline at end of file +module.exports = config; From 938e8b4ebb1178f81dfea5b4ce2f9702863dcb1d Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Mon, 7 Jun 2021 11:24:52 +0200 Subject: [PATCH 04/11] Add imagemin-webp --- package.json | 1 + webpack.config.js | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 34cc701..b283146 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "imagemin-mozjpeg": "^9.0.0", "imagemin-pngquant": "^9.0.2", "imagemin-svgo": "^9.0.0", + "imagemin-webp": "^6.0.0", "jest": "^27.0.4", "maildev": "^1.1.0", "mini-css-extract-plugin": "^1.2.1", diff --git a/webpack.config.js b/webpack.config.js index 20449a8..b624595 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,7 +1,7 @@ const path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin"); -const { extendDefaultPlugins } = require("svgo"); +const {extendDefaultPlugins} = require("svgo"); const TerserPlugin = require('terser-webpack-plugin'); const dev = process.env.NODE_ENV === 'development'; @@ -84,6 +84,7 @@ const config = { ["gifsicle", {}], ["mozjpeg", {}], ["pngquant", {}], + ["webp", {quality: 90}], // Svgo configuration here https://github.com/svg/svgo#configuration [ "svgo", @@ -96,7 +97,7 @@ const config = { { name: "addAttributesToSVGElement", params: { - attributes: [{ xmlns: "http://www.w3.org/2000/svg" }], + attributes: [{xmlns: "http://www.w3.org/2000/svg"}], }, }, ]), From 569a50e43a9af7907b96f848e7350b7afe2f9e3e Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sat, 20 Nov 2021 19:54:59 +0100 Subject: [PATCH 05/11] Upgrade swaf and dependencies --- .gitignore | 3 + assets/config.json | 10 -- assets/ts/font-awesome.ts | 4 - package.json | 40 +++--- scripts/_functions.js | 22 ++++ scripts/clean.js | 2 + scripts/dist.js | 22 ++++ scripts/prepare-sources.js | 26 +++- src/App.ts | 34 +++-- {assets => src/assets}/img/logo.svg | 0 {assets => src/assets}/img/logox1024.png | Bin {assets => src/assets}/img/logox128.png | Bin src/assets/package.json | 3 + {assets => src/assets}/sass/_fonts.scss | 0 {assets => src/assets}/sass/_vars.scss | 0 {assets => src/assets}/sass/app.scss | 0 {assets => src/assets}/sass/error.scss | 0 {assets => src/assets}/sass/layout.scss | 100 --------------- .../assets}/sass/responsivity_tools.scss | 0 .../assets}/ts/PersistentWebSocket.ts | 0 {assets => src/assets}/ts/app.ts | 0 {assets => src/assets}/ts/copyable_text.ts | 0 {assets => src/assets}/ts/external_links.ts | 0 src/assets/ts/font-awesome.ts | 4 + {assets => src/assets}/ts/forms.ts | 0 {assets => src/assets}/ts/main_menu.ts | 0 {assets => src/assets}/ts/message_icons.ts | 0 .../assets}/ts/tooltips-and-dropdowns.ts | 0 src/assets/ts/tsconfig.eslint.json | 6 + src/assets/ts/tsconfig.json | 27 ++++ {views => src/assets/views}/about.njk | 0 {views => src/assets/views}/home.njk | 0 {views => src/assets/views}/layouts/base.njk | 0 src/assets/views/tsconfig.json | 15 +++ src/common/dummy.ts | 1 + src/common/package.json | 3 + src/common/tsconfig.json | 20 +++ src/controllers/HomeController.ts | 3 +- src/main.ts | 9 +- src/tsconfig.json | 30 +++++ {public => src/types}/.gitkeep | 0 tsconfig.frontend.json | 19 --- tsconfig.json | 47 +++++-- tsconfig.test.json | 2 +- webpack.config.js | 121 ------------------ 45 files changed, 276 insertions(+), 297 deletions(-) delete mode 100644 assets/config.json delete mode 100644 assets/ts/font-awesome.ts create mode 100644 scripts/_functions.js create mode 100644 scripts/dist.js rename {assets => src/assets}/img/logo.svg (100%) rename {assets => src/assets}/img/logox1024.png (100%) rename {assets => src/assets}/img/logox128.png (100%) create mode 100644 src/assets/package.json rename {assets => src/assets}/sass/_fonts.scss (100%) rename {assets => src/assets}/sass/_vars.scss (100%) rename {assets => src/assets}/sass/app.scss (100%) rename {assets => src/assets}/sass/error.scss (100%) rename {assets => src/assets}/sass/layout.scss (89%) rename {assets => src/assets}/sass/responsivity_tools.scss (100%) rename {assets => src/assets}/ts/PersistentWebSocket.ts (100%) rename {assets => src/assets}/ts/app.ts (100%) rename {assets => src/assets}/ts/copyable_text.ts (100%) rename {assets => src/assets}/ts/external_links.ts (100%) create mode 100644 src/assets/ts/font-awesome.ts rename {assets => src/assets}/ts/forms.ts (100%) rename {assets => src/assets}/ts/main_menu.ts (100%) rename {assets => src/assets}/ts/message_icons.ts (100%) rename {assets => src/assets}/ts/tooltips-and-dropdowns.ts (100%) create mode 100644 src/assets/ts/tsconfig.eslint.json create mode 100644 src/assets/ts/tsconfig.json rename {views => src/assets/views}/about.njk (100%) rename {views => src/assets/views}/home.njk (100%) rename {views => src/assets/views}/layouts/base.njk (100%) create mode 100644 src/assets/views/tsconfig.json create mode 100644 src/common/dummy.ts create mode 100644 src/common/package.json create mode 100644 src/common/tsconfig.json create mode 100644 src/tsconfig.json rename {public => src/types}/.gitkeep (100%) delete mode 100644 tsconfig.frontend.json delete mode 100644 webpack.config.js diff --git a/.gitignore b/.gitignore index 570ee35..873a5d8 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,6 @@ dist yarn-error.log src/package.json + +intermediates/ +dist/ \ No newline at end of file diff --git a/assets/config.json b/assets/config.json deleted file mode 100644 index 6bcf54c..0000000 --- a/assets/config.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "bundles": { - "app": "ts/app.ts", - "layout": "sass/layout.scss", - "error": "sass/error.scss", - "logo": "img/logo.svg", - "logo_png": "img/logox128.png", - "logo_png_xxl": "img/logox1024.png" - } -} \ No newline at end of file diff --git a/assets/ts/font-awesome.ts b/assets/ts/font-awesome.ts deleted file mode 100644 index 5ce65ff..0000000 --- a/assets/ts/font-awesome.ts +++ /dev/null @@ -1,4 +0,0 @@ -import '../../node_modules/@fortawesome/fontawesome-free/scss/fontawesome.scss'; -import '../../node_modules/@fortawesome/fontawesome-free/scss/regular.scss'; -import '../../node_modules/@fortawesome/fontawesome-free/scss/solid.scss'; -import '../../node_modules/@fortawesome/fontawesome-free/scss/brands.scss'; diff --git a/package.json b/package.json index b283146..b74ecdc 100644 --- a/package.json +++ b/package.json @@ -10,47 +10,53 @@ "test": "jest --verbose --runInBand", "clean": "node scripts/clean.js", "prepare-sources": "node scripts/prepare-sources.js", - "compile": "yarn clean && tsc", - "build": "yarn prepare-sources && yarn compile && webpack --mode production", - "dev": "yarn prepare-sources && concurrently -k -n \"Typescript,Node,Webpack,Maildev\" -p \"[{name}]\" -c \"blue,green,red,yellow\" \"tsc --watch\" \"nodemon\" \"webpack --watch --mode development\" \"maildev\"", - "start": "yarn build && node", - "lint": "eslint ." + "compile": "yarn clean && yarn prepare-sources && tsc --build", + "build": "yarn compile && node . pre-compile-views && node scripts/dist.js", + "build-production": "NODE_ENV=production yarn build", + "dev": "yarn compile && concurrently -k -n \"Maildev,Typescript,ViewPreCompile,Node\" -p \"[{name}]\" -c \"yellow,blue,red,green\" \"maildev\" \"tsc --build --watch --preserveWatchOutput\" \"nodemon -i public -i intermediates -- pre-compile-views --watch\" \"nodemon -i public -i intermediates\"", + "lint": "eslint .", + "start": "yarn build-production && node ." }, "devDependencies": { "@babel/core": "^7.9.0", "@babel/preset-env": "^7.9.5", "@fortawesome/fontawesome-free": "^5.14.0", - "@types/config": "^0.0.38", + "@tsconfig/svelte": "^2.0.1", + "@types/config": "^0.0.40", "@types/express": "^4.17.6", "@types/express-session": "^1.17.0", "@types/feather-icons": "^4.7.0", - "@types/formidable": "^1.0.31", - "@types/jest": "^26.0.4", + "@types/formidable": "^2.0.0", + "@types/jest": "^27.0.3", "@types/mysql": "^2.15.15", - "@types/node": "^15.0.1", + "@types/node": "^16.11.9", "@types/nodemailer": "^6.4.0", "@types/nunjucks": "^3.1.3", - "@types/ws": "^7.2.6", - "@typescript-eslint/eslint-plugin": "^4.3.0", - "@typescript-eslint/parser": "^4.3.0", + "@types/ws": "^8.2.0", + "@typescript-eslint/eslint-plugin": "^5.4.0", + "@typescript-eslint/parser": "^5.4.0", "babel-loader": "^8.1.0", + "clear-module": "^4.1.2", "concurrently": "^6.0.0", - "css-loader": "^5.0.0", - "eslint": "^7.10.0", + "css-loader": "^6.5.1", + "eslint": "^8.2.0", "feather-icons": "^4.28.0", "file-loader": "^6.0.0", "image-minimizer-webpack-plugin": "^2.2.0", "imagemin-gifsicle": "^7.0.0", "imagemin-mozjpeg": "^9.0.0", "imagemin-pngquant": "^9.0.2", - "imagemin-svgo": "^9.0.0", + "imagemin-svgo": "^10.0.0", "imagemin-webp": "^6.0.0", "jest": "^27.0.4", "maildev": "^1.1.0", - "mini-css-extract-plugin": "^1.2.1", + "mini-css-extract-plugin": "^2.4.5", "nodemon": "^2.0.3", + "normalize.css": "^8.0.1", "sass": "^1.32.12", "sass-loader": "^12.0.0", + "svelte": "^3.44.2", + "svelte-preprocess": "^4.9.8", "svgo": "^2.3.0", "terser-webpack-plugin": "^5.0.3", "ts-jest": "^27.0.3", @@ -62,6 +68,6 @@ "dependencies": { "config": "^3.3.1", "express": "^4.17.1", - "swaf": "^0.23.0" + "swaf": "^0.24.4" } } diff --git a/scripts/_functions.js b/scripts/_functions.js new file mode 100644 index 0000000..0fea1c4 --- /dev/null +++ b/scripts/_functions.js @@ -0,0 +1,22 @@ +const fs = require('fs'); +const path = require('path'); + +function copyRecursively(file, destination) { + const target = path.join(destination, path.basename(file)); + if (fs.statSync(file).isDirectory()) { + console.log('mkdir', target); + + fs.mkdirSync(target, {recursive: true}); + fs.readdirSync(file).forEach(f => { + copyRecursively(path.join(file, f), target); + }); + } else { + console.log('> cp ', target); + + fs.copyFileSync(file, target); + } +} + +module.exports = { + copyRecursively, +}; \ No newline at end of file diff --git a/scripts/clean.js b/scripts/clean.js index d5ef093..32ebb24 100644 --- a/scripts/clean.js +++ b/scripts/clean.js @@ -1,7 +1,9 @@ const fs = require('fs'); [ + 'intermediates', 'dist', + 'public', ].forEach(file => { if (fs.existsSync(file)) { console.log('Cleaning', file, '...'); diff --git a/scripts/dist.js b/scripts/dist.js new file mode 100644 index 0000000..a0ead2a --- /dev/null +++ b/scripts/dist.js @@ -0,0 +1,22 @@ +const fs = require('fs'); +const path = require('path'); +const {copyRecursively} = require('./_functions.js'); + + +[ + 'yarn.lock', + 'README.md', + 'config/', +].forEach(file => { + copyRecursively(file, 'dist'); +}); + +fs.mkdirSync('dist/types', {recursive: true}); + +fs.readdirSync('src/types').forEach(file => { + copyRecursively(path.join('src/types', file), 'dist/types'); +}); + +fs.readdirSync('src/assets').forEach(file => { + copyRecursively(path.join('src/assets', file), 'dist/assets'); +}); diff --git a/scripts/prepare-sources.js b/scripts/prepare-sources.js index a78c2f3..c8ee7b9 100644 --- a/scripts/prepare-sources.js +++ b/scripts/prepare-sources.js @@ -1,4 +1,28 @@ const fs = require('fs'); const path = require('path'); -fs.copyFileSync('package.json', path.join('src', 'package.json')); +// These folders must exist for nodemon not to loop indefinitely. +[ + 'public', + 'dist', + 'intermediates', + 'intermediates/assets', +].forEach(dir => { + if (!fs.existsSync(dir)) fs.mkdirSync(dir); +}); + +// Symlink to build/common +const commonLocalSymlink = path.resolve('intermediates/common-local'); +if (!fs.existsSync(commonLocalSymlink)) { + const target = path.resolve('dist/common-local'); + fs.symlinkSync(target, commonLocalSymlink); +} + +const commonSymlink = path.resolve('intermediates/common'); +if (!fs.existsSync(commonSymlink)) { + const target = path.resolve('node_modules/swaf/common'); + fs.symlinkSync(target, commonSymlink); +} + +// Copy package.json +fs.copyFileSync('package.json', 'dist/package.json'); diff --git a/src/App.ts b/src/App.ts index 6272da0..768d322 100644 --- a/src/App.ts +++ b/src/App.ts @@ -2,7 +2,6 @@ import Application from "swaf/Application"; import Migration, {MigrationType} from "swaf/db/Migration"; import CreateMigrationsTable from "swaf/migrations/CreateMigrationsTable"; import ExpressAppComponent from "swaf/components/ExpressAppComponent"; -import NunjucksComponent from "swaf/components/NunjucksComponent"; import MysqlComponent from "swaf/components/MysqlComponent"; import LogRequestsComponent from "swaf/components/LogRequestsComponent"; import RedisComponent from "swaf/components/RedisComponent"; @@ -18,14 +17,22 @@ import AutoUpdateComponent from "swaf/components/AutoUpdateComponent"; import DummyMigration from "swaf/migrations/DummyMigration"; import DropLegacyLogsTable from "swaf/migrations/DropLegacyLogsTable"; import PreviousUrlComponent from "swaf/components/PreviousUrlComponent"; -import packageJson = require('./package.json'); +import MailViewEngine from "swaf/frontend/MailViewEngine"; +import AssetCompiler from "swaf/frontend/AssetCompiler"; +import FrontendToolsComponent from "swaf/components/FrontendToolsComponent"; +import CopyAssetPreCompiler from "swaf/frontend/CopyAssetPreCompiler"; +import ScssAssetPreCompiler from "swaf/frontend/ScssAssetPreCompiler"; +import TypeScriptPreCompiler from "swaf/frontend/TypeScriptPreCompiler"; +import SvelteViewEngine from "swaf/frontend/SvelteViewEngine"; +import NunjucksViewEngine from "swaf/frontend/NunjucksViewEngine"; export default class App extends Application { public constructor( + version: string, private readonly addr: string, private readonly port: number, ) { - super(packageJson.version); + super(version); } protected getMigrations(): MigrationType[] { @@ -52,18 +59,27 @@ export default class App extends Application { this.use(new ServeStaticDirectoryComponent('node_modules/feather-icons/dist', '/icons')); // Dynamic views and routes - this.use(new NunjucksComponent()); + const intermediateDirectory = 'intermediates/assets'; + const assetCompiler = new AssetCompiler(intermediateDirectory, 'public'); + const additionalViewPaths = ['test/assets']; + this.use(new FrontendToolsComponent( + assetCompiler, + new CopyAssetPreCompiler(intermediateDirectory, '', 'json', additionalViewPaths, false), + new ScssAssetPreCompiler(intermediateDirectory, assetCompiler.targetDir, 'scss', additionalViewPaths), + new CopyAssetPreCompiler(intermediateDirectory, 'img', 'svg', additionalViewPaths, true), + new TypeScriptPreCompiler(intermediateDirectory, additionalViewPaths), + new SvelteViewEngine(intermediateDirectory, ...additionalViewPaths), + new NunjucksViewEngine(intermediateDirectory, ...additionalViewPaths), + )); this.use(new PreviousUrlComponent()); // Maintenance - this.use(new MaintenanceComponent(this, () => { - return this.as(RedisComponent).canServe() && this.as(MysqlComponent).canServe(); - })); + this.use(new MaintenanceComponent()); this.use(new AutoUpdateComponent()); // Services this.use(new MysqlComponent()); - this.use(new MailComponent()); + this.use(new MailComponent(new MailViewEngine(intermediateDirectory, ...additionalViewPaths))); // Session this.use(new RedisComponent()); @@ -76,7 +92,7 @@ export default class App extends Application { this.use(new CsrfProtectionComponent()); // WebSocket server - this.use(new WebSocketServerComponent(this, this.as(ExpressAppComponent), this.as(RedisComponent))); + this.use(new WebSocketServerComponent()); } private registerWebSocketListeners() { diff --git a/assets/img/logo.svg b/src/assets/img/logo.svg similarity index 100% rename from assets/img/logo.svg rename to src/assets/img/logo.svg diff --git a/assets/img/logox1024.png b/src/assets/img/logox1024.png similarity index 100% rename from assets/img/logox1024.png rename to src/assets/img/logox1024.png diff --git a/assets/img/logox128.png b/src/assets/img/logox128.png similarity index 100% rename from assets/img/logox128.png rename to src/assets/img/logox128.png diff --git a/src/assets/package.json b/src/assets/package.json new file mode 100644 index 0000000..1cd945a --- /dev/null +++ b/src/assets/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/assets/sass/_fonts.scss b/src/assets/sass/_fonts.scss similarity index 100% rename from assets/sass/_fonts.scss rename to src/assets/sass/_fonts.scss diff --git a/assets/sass/_vars.scss b/src/assets/sass/_vars.scss similarity index 100% rename from assets/sass/_vars.scss rename to src/assets/sass/_vars.scss diff --git a/assets/sass/app.scss b/src/assets/sass/app.scss similarity index 100% rename from assets/sass/app.scss rename to src/assets/sass/app.scss diff --git a/assets/sass/error.scss b/src/assets/sass/error.scss similarity index 100% rename from assets/sass/error.scss rename to src/assets/sass/error.scss diff --git a/assets/sass/layout.scss b/src/assets/sass/layout.scss similarity index 89% rename from assets/sass/layout.scss rename to src/assets/sass/layout.scss index 3d791fd..cf1f7c1 100644 --- a/assets/sass/layout.scss +++ b/src/assets/sass/layout.scss @@ -682,33 +682,6 @@ td.actions { } } -.data-table { - width: 100%; - text-align: left; - border-collapse: collapse; - - th, td { - padding: 8px; - } - - th { - border-bottom: 1px solid #39434a; - white-space: nowrap; - } - - tr:nth-child(even) { - background-color: rgba(255, 255, 255, 0.03); - } - - tr:hover { - background-color: rgba(255, 255, 255, 0.09); - } - - thead tr:hover { - background-color: transparent; - } -} - // --- // --- Breadcrumb widget @@ -766,82 +739,9 @@ td.actions { } -// --- -// --- Feather -// --- -.feather { - display: inline-flex; - justify-content: center; - align-items: center; - - flex-shrink: 0; - width: var(--icon-size); - height: var(--icon-size); - - --icon-size: 16px; - font-size: var(--icon-size); - stroke: currentColor; - stroke-width: 2; - stroke-linecap: square; - stroke-linejoin: miter; - fill: none; - vertical-align: middle; - - h1 > &, h2 > &, h3 > & { - --icon-size: 24px; - } -} - // --- // --- Helper classes // --- -.message { - display: flex; - flex-direction: row; - align-items: center; - - padding: 8px 16px; - - border-radius: 5px; - - .feather { - --icon-size: 24px; - margin-right: 8px; - } - - &:not(&-discreet) { - background-color: rgba(255, 255, 255, 0.33); - - &[data-type=info], &[data-type=question] { - background-color: $infoColor; - } - - &[data-type=success] { - background-color: $successColor; - } - - &[data-type=warning] { - background-color: $warningColor; - } - - &[data-type=error] { - background-color: $errorColor; - } - } - - &-discreet { - color: mix($panelBackground, #fff, 35%); - - .feather { - --icon-size: 20px; - } - } -} - -.messages .message:not(:last-child) { - margin-bottom: 8px; -} - .container > .messages:first-child { margin-top: 16px; } diff --git a/assets/sass/responsivity_tools.scss b/src/assets/sass/responsivity_tools.scss similarity index 100% rename from assets/sass/responsivity_tools.scss rename to src/assets/sass/responsivity_tools.scss diff --git a/assets/ts/PersistentWebSocket.ts b/src/assets/ts/PersistentWebSocket.ts similarity index 100% rename from assets/ts/PersistentWebSocket.ts rename to src/assets/ts/PersistentWebSocket.ts diff --git a/assets/ts/app.ts b/src/assets/ts/app.ts similarity index 100% rename from assets/ts/app.ts rename to src/assets/ts/app.ts diff --git a/assets/ts/copyable_text.ts b/src/assets/ts/copyable_text.ts similarity index 100% rename from assets/ts/copyable_text.ts rename to src/assets/ts/copyable_text.ts diff --git a/assets/ts/external_links.ts b/src/assets/ts/external_links.ts similarity index 100% rename from assets/ts/external_links.ts rename to src/assets/ts/external_links.ts diff --git a/src/assets/ts/font-awesome.ts b/src/assets/ts/font-awesome.ts new file mode 100644 index 0000000..0409cfe --- /dev/null +++ b/src/assets/ts/font-awesome.ts @@ -0,0 +1,4 @@ +import '@fortawesome/fontawesome-free/scss/fontawesome.scss'; +import '@fortawesome/fontawesome-free/scss/regular.scss'; +import '@fortawesome/fontawesome-free/scss/solid.scss'; +import '@fortawesome/fontawesome-free/scss/brands.scss'; diff --git a/assets/ts/forms.ts b/src/assets/ts/forms.ts similarity index 100% rename from assets/ts/forms.ts rename to src/assets/ts/forms.ts diff --git a/assets/ts/main_menu.ts b/src/assets/ts/main_menu.ts similarity index 100% rename from assets/ts/main_menu.ts rename to src/assets/ts/main_menu.ts diff --git a/assets/ts/message_icons.ts b/src/assets/ts/message_icons.ts similarity index 100% rename from assets/ts/message_icons.ts rename to src/assets/ts/message_icons.ts diff --git a/assets/ts/tooltips-and-dropdowns.ts b/src/assets/ts/tooltips-and-dropdowns.ts similarity index 100% rename from assets/ts/tooltips-and-dropdowns.ts rename to src/assets/ts/tooltips-and-dropdowns.ts diff --git a/src/assets/ts/tsconfig.eslint.json b/src/assets/ts/tsconfig.eslint.json new file mode 100644 index 0000000..a12ab8a --- /dev/null +++ b/src/assets/ts/tsconfig.eslint.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "include": [ + "./**/*" + ] +} diff --git a/src/assets/ts/tsconfig.json b/src/assets/ts/tsconfig.json new file mode 100644 index 0000000..a9dfc8d --- /dev/null +++ b/src/assets/ts/tsconfig.json @@ -0,0 +1,27 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "target": "ESNext", + "module": "CommonJS", + "baseUrl": "../../../intermediates/assets", + "rootDir": "../../../intermediates/assets/ts-source", + "sourceRoot": "../../../intermediates/assets/ts-source", + "outDir": "../../../intermediates/assets/ts", + "declaration": false, + + "typeRoots": [], + "resolveJsonModule": false, + "lib": [ + "es2020", + "DOM" + ] + }, + "include": [ + "../../../intermediates/assets/ts-source/**/*" + ], + "references": [ + { + "path": "../../common" + } + ] +} diff --git a/views/about.njk b/src/assets/views/about.njk similarity index 100% rename from views/about.njk rename to src/assets/views/about.njk diff --git a/views/home.njk b/src/assets/views/home.njk similarity index 100% rename from views/home.njk rename to src/assets/views/home.njk diff --git a/views/layouts/base.njk b/src/assets/views/layouts/base.njk similarity index 100% rename from views/layouts/base.njk rename to src/assets/views/layouts/base.njk diff --git a/src/assets/views/tsconfig.json b/src/assets/views/tsconfig.json new file mode 100644 index 0000000..bc808e8 --- /dev/null +++ b/src/assets/views/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "@tsconfig/svelte/tsconfig.json", + "compilerOptions": { + "outDir": "public/js", + "rootDir": "../../../intermediates/assets", + }, + "include": [ + "src/assets/ts/**/*" + ], + "references": [ + { + "path": "../../common" + } + ] +} diff --git a/src/common/dummy.ts b/src/common/dummy.ts new file mode 100644 index 0000000..c58f5a5 --- /dev/null +++ b/src/common/dummy.ts @@ -0,0 +1 @@ +console.log('common code between back and front'); \ No newline at end of file diff --git a/src/common/package.json b/src/common/package.json new file mode 100644 index 0000000..1cd945a --- /dev/null +++ b/src/common/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/src/common/tsconfig.json b/src/common/tsconfig.json new file mode 100644 index 0000000..60705a9 --- /dev/null +++ b/src/common/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + + "module": "CommonJS", + + "baseUrl": "../../dist/common-local", + "rootDir": "./", + "sourceRoot": "./", + "outDir": "../../dist/common-local", + + "typeRoots": [ + "src/types" + ], + }, + "include": [ + "./**/*" + ] +} diff --git a/src/controllers/HomeController.ts b/src/controllers/HomeController.ts index b5e1740..027d83d 100644 --- a/src/controllers/HomeController.ts +++ b/src/controllers/HomeController.ts @@ -1,5 +1,6 @@ import Controller from "swaf/Controller"; import {Request, Response} from "express"; +import {route} from "swaf/common/Routing"; export default class HomeController extends Controller { public routes(): void { @@ -20,6 +21,6 @@ export default class HomeController extends Controller { * This is to test and assert that swaf extended types are available */ protected async goBack(req: Request, res: Response): Promise { - res.redirect(req.getPreviousUrl() || Controller.route('home')); + res.redirect(req.getPreviousUrl() || route('home')); } } diff --git a/src/main.ts b/src/main.ts index babc7df..ff2f443 100644 --- a/src/main.ts +++ b/src/main.ts @@ -9,11 +9,18 @@ process.env['NODE_CONFIG_DIR'] = import {logger} from "swaf/Logger"; import App from "./App"; import config from "config"; +import {promises as fs} from "fs"; (async () => { logger.debug('Config path:', process.env['NODE_CONFIG_DIR']); - const app = new App(config.get('listen_addr'), config.get('port')); + const packageJson = JSON.parse((await fs.readFile('package.json')).toString()); + + const app = new App( + packageJson.version, + config.get('app.listen_addr'), + config.get('app.port'), + ); await app.start(); })().catch(err => { logger.error(err); diff --git a/src/tsconfig.json b/src/tsconfig.json new file mode 100644 index 0000000..890991d --- /dev/null +++ b/src/tsconfig.json @@ -0,0 +1,30 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "composite": true, + + "module": "CommonJS", + + "baseUrl": "../dist", + "rootDir": "./", + "sourceRoot": "./", + "outDir": "../dist", + + "typeRoots": [ + "src/types" + ] + }, + "include": [ + "./**/*", + "../node_modules/swaf/types" + ], + "exclude": [ + "./assets/**/*", + "./common/**/*" + ], + "references": [ + { + "path": "./common" + } + ] +} diff --git a/public/.gitkeep b/src/types/.gitkeep similarity index 100% rename from public/.gitkeep rename to src/types/.gitkeep diff --git a/tsconfig.frontend.json b/tsconfig.frontend.json deleted file mode 100644 index ad74720..0000000 --- a/tsconfig.frontend.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "public/js", - "rootDir": "./assets", - "target": "ES6", - "strict": true, - "lib": [ - "es2020", - "DOM" - ], - "typeRoots": [ - "./node_modules/@types" - ] - }, - "include": [ - "assets/ts/**/*" - ] -} diff --git a/tsconfig.json b/tsconfig.json index 12eec0a..6a82f14 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,22 +1,43 @@ { "compilerOptions": { - "module": "CommonJS", - "esModuleInterop": true, - "outDir": "dist", - "rootDir": "./src", - "target": "ES6", + "target": "ESNext", + "module": "ESNext", + "declaration": true, + "stripInternal": true, + "strict": true, + "allowSyntheticDefaultImports": true, + "strictNullChecks": true, + + "moduleResolution": "Node", + "esModuleInterop": true, + "baseUrl": "dist", + "inlineSourceMap": true, + "inlineSources": true, + "outDir": "dist", + + "typeRoots": [ + "node_modules/@types", + "src/types" + ], "lib": [ "es2020", - "DOM" + "dom" ], - "typeRoots": [ - "./node_modules/@types" - ], - "resolveJsonModule": true + "resolveJsonModule": true, + "skipLibCheck": true, + "allowJs": true }, - "include": [ - "src/**/*", - "node_modules/swaf/types" + "include": [], + "references": [ + { + "path": "src", + }, + { + "path": "src/assets/ts", + }, + { + "path": "src/assets/views", + } ] } diff --git a/tsconfig.test.json b/tsconfig.test.json index 897a6b4..fce2399 100644 --- a/tsconfig.test.json +++ b/tsconfig.test.json @@ -11,4 +11,4 @@ "src/types/**/*", "test/**/*" ] -} \ No newline at end of file +} diff --git a/webpack.config.js b/webpack.config.js deleted file mode 100644 index b624595..0000000 --- a/webpack.config.js +++ /dev/null @@ -1,121 +0,0 @@ -const path = require('path'); -const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin"); -const {extendDefaultPlugins} = require("svgo"); -const TerserPlugin = require('terser-webpack-plugin'); - -const dev = process.env.NODE_ENV === 'development'; - -const userConfig = require('./assets/config.json'); -for (const b in userConfig.bundles) { - if (userConfig.bundles.hasOwnProperty(b)) { - userConfig.bundles[b] = `./assets/${userConfig.bundles[b]}`; - } -} - -const config = { - entry: userConfig.bundles, - output: { - path: path.resolve(__dirname, 'public/js'), - filename: '[name].js' - }, - devtool: dev ? 'eval-source-map' : undefined, - module: { - rules: [ - { - test: /\.js$/i, - use: [ - { - loader: 'babel-loader', - options: { - presets: ['@babel/preset-env'], - } - } - ] - }, - { - test: /\.s[ac]ss$/i, - use: [ - { - loader: MiniCssExtractPlugin.loader, - options: { - publicPath: '/', - } - }, - 'css-loader', - 'sass-loader', - ] - }, - { - test: /\.(woff2?|eot|ttf|otf)$/i, - use: 'file-loader?name=../fonts/[name].[ext]', - }, - { - test: /\.tsx?$/i, - use: { - loader: 'ts-loader', - options: { - configFile: 'tsconfig.frontend.json', - } - }, - exclude: '/node_modules/' - }, - { - test: /\.(png|jpe?g|gif|svg)$/i, - use: [ - 'file-loader?name=../img/[name].[ext]', - ], - type: 'asset', - } - ], - }, - resolve: { - extensions: ['.tsx', '.ts', '.js'], - }, - plugins: [ - new MiniCssExtractPlugin({ - filename: '../css/[name].css', - }), - new ImageMinimizerPlugin({ - minimizerOptions: { - // Lossless optimization with custom option - // Feel free to experiment with options for better result for you - plugins: [ - ["gifsicle", {}], - ["mozjpeg", {}], - ["pngquant", {}], - ["webp", {quality: 90}], - // Svgo configuration here https://github.com/svg/svgo#configuration - [ - "svgo", - { - plugins: extendDefaultPlugins([ - { - name: "removeViewBox", - active: false, - }, - { - name: "addAttributesToSVGElement", - params: { - attributes: [{xmlns: "http://www.w3.org/2000/svg"}], - }, - }, - ]), - }, - ], - ], - }, - }), - ] -}; - -if (!dev) { - config.optimization = { - minimize: true, - minimizer: [ - new TerserPlugin(), - ] - }; -} - -module.exports = config; From 257a407faf0d6cb9b4def3651f32817d7ea040db Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sat, 20 Nov 2021 22:26:22 +0100 Subject: [PATCH 06/11] Remove unused old assets --- package.json | 1 - src/assets/sass/.gitkeep | 0 src/assets/sass/_fonts.scss | 81 --- src/assets/sass/_vars.scss | 33 - src/assets/sass/app.scss | 1 - src/assets/sass/error.scss | 90 --- src/assets/sass/layout.scss | 843 ------------------------ src/assets/sass/responsivity_tools.scss | 19 - src/assets/ts/PersistentWebSocket.ts | 39 -- src/assets/ts/app.ts | 10 - src/assets/ts/copyable_text.ts | 15 - src/assets/ts/external_links.ts | 11 - src/assets/ts/font-awesome.ts | 4 - src/assets/ts/forms.ts | 43 -- src/assets/ts/main_menu.ts | 21 - src/assets/ts/message_icons.ts | 26 - src/assets/ts/tooltips-and-dropdowns.ts | 31 - src/assets/views/about.njk | 14 - src/assets/views/home.njk | 7 - src/assets/views/layouts/base.njk | 41 -- 20 files changed, 1330 deletions(-) create mode 100644 src/assets/sass/.gitkeep delete mode 100644 src/assets/sass/_fonts.scss delete mode 100644 src/assets/sass/_vars.scss delete mode 100644 src/assets/sass/app.scss delete mode 100644 src/assets/sass/error.scss delete mode 100644 src/assets/sass/layout.scss delete mode 100644 src/assets/sass/responsivity_tools.scss delete mode 100644 src/assets/ts/PersistentWebSocket.ts delete mode 100644 src/assets/ts/app.ts delete mode 100644 src/assets/ts/copyable_text.ts delete mode 100644 src/assets/ts/external_links.ts delete mode 100644 src/assets/ts/font-awesome.ts delete mode 100644 src/assets/ts/forms.ts delete mode 100644 src/assets/ts/main_menu.ts delete mode 100644 src/assets/ts/message_icons.ts delete mode 100644 src/assets/ts/tooltips-and-dropdowns.ts delete mode 100644 src/assets/views/about.njk delete mode 100644 src/assets/views/home.njk delete mode 100644 src/assets/views/layouts/base.njk diff --git a/package.json b/package.json index b74ecdc..b83dc74 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,6 @@ "devDependencies": { "@babel/core": "^7.9.0", "@babel/preset-env": "^7.9.5", - "@fortawesome/fontawesome-free": "^5.14.0", "@tsconfig/svelte": "^2.0.1", "@types/config": "^0.0.40", "@types/express": "^4.17.6", diff --git a/src/assets/sass/.gitkeep b/src/assets/sass/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/assets/sass/_fonts.scss b/src/assets/sass/_fonts.scss deleted file mode 100644 index 6c26b55..0000000 --- a/src/assets/sass/_fonts.scss +++ /dev/null @@ -1,81 +0,0 @@ -/* vietnamese */ -@font-face { - font-family: 'Nunito Sans'; - font-style: normal; - font-weight: 300; - font-display: swap; - src: local('Nunito Sans Light'), local('NunitoSans-Light'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe03MImSLYBIv1o4X1M8cc8WAc5iU1EQVg.woff2) format('woff2'); - unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; -} -/* latin-ext */ -@font-face { - font-family: 'Nunito Sans'; - font-style: normal; - font-weight: 300; - font-display: swap; - src: local('Nunito Sans Light'), local('NunitoSans-Light'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe03MImSLYBIv1o4X1M8cc8WAc5jU1EQVg.woff2) format('woff2'); - unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; -} -/* latin */ -@font-face { - font-family: 'Nunito Sans'; - font-style: normal; - font-weight: 300; - font-display: swap; - src: local('Nunito Sans Light'), local('NunitoSans-Light'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe03MImSLYBIv1o4X1M8cc8WAc5tU1E.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; -} -/* vietnamese */ -@font-face { - font-family: 'Nunito Sans'; - font-style: normal; - font-weight: 400; - font-display: swap; - src: local('Nunito Sans Regular'), local('NunitoSans-Regular'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe0qMImSLYBIv1o4X1M8cceyI9tScg.woff2) format('woff2'); - unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; -} -/* latin-ext */ -@font-face { - font-family: 'Nunito Sans'; - font-style: normal; - font-weight: 400; - font-display: swap; - src: local('Nunito Sans Regular'), local('NunitoSans-Regular'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe0qMImSLYBIv1o4X1M8ccezI9tScg.woff2) format('woff2'); - unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; -} -/* latin */ -@font-face { - font-family: 'Nunito Sans'; - font-style: normal; - font-weight: 400; - font-display: swap; - src: local('Nunito Sans Regular'), local('NunitoSans-Regular'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe0qMImSLYBIv1o4X1M8cce9I9s.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; -} -/* vietnamese */ -@font-face { - font-family: 'Nunito Sans'; - font-style: normal; - font-weight: 700; - font-display: swap; - src: local('Nunito Sans Bold'), local('NunitoSans-Bold'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe03MImSLYBIv1o4X1M8cc8GBs5iU1EQVg.woff2) format('woff2'); - unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; -} -/* latin-ext */ -@font-face { - font-family: 'Nunito Sans'; - font-style: normal; - font-weight: 700; - font-display: swap; - src: local('Nunito Sans Bold'), local('NunitoSans-Bold'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe03MImSLYBIv1o4X1M8cc8GBs5jU1EQVg.woff2) format('woff2'); - unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; -} -/* latin */ -@font-face { - font-family: 'Nunito Sans'; - font-style: normal; - font-weight: 700; - font-display: swap; - src: local('Nunito Sans Bold'), local('NunitoSans-Bold'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe03MImSLYBIv1o4X1M8cc8GBs5tU1E.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; -} diff --git a/src/assets/sass/_vars.scss b/src/assets/sass/_vars.scss deleted file mode 100644 index 478fca3..0000000 --- a/src/assets/sass/_vars.scss +++ /dev/null @@ -1,33 +0,0 @@ -$primary: darken(#242b33, 2%); -$primaryForeground: #f0f0f0; -$secondary: lighten(#00766c, 10%); -$secondaryForeground: $primaryForeground; - -$backgroundColor: darken($primary, 4%); -$defaultTextColor: #ffffff; - -$headerBackground: transparent; -$headerContainer: true; -$footerBackground: transparent; -$panelBackground: darken($backgroundColor, 3.2%); -$inputBackground: darken($panelBackground, 4%); - -$info: #4499ff; -$infoText: darken($info, 42%); -$infoColor: desaturate($infoText, 50%); - -$success: #55ff55; -$successText: darken($success, 45%); -$successColor: desaturate($successText, 50%); - -$warning: #ffcc00; -$warningText: darken($warning, 30%); -$warningColor: desaturate($warningText, 50%); - -$error: #ff0000; -$errorText: darken($error, 30%); -$errorColor: desaturate($errorText, 50%); - -// Responsivity -$mobileThreshold: 632px; -$desktopThreshold: 940px; diff --git a/src/assets/sass/app.scss b/src/assets/sass/app.scss deleted file mode 100644 index 933fea1..0000000 --- a/src/assets/sass/app.scss +++ /dev/null @@ -1 +0,0 @@ -@import "layout"; \ No newline at end of file diff --git a/src/assets/sass/error.scss b/src/assets/sass/error.scss deleted file mode 100644 index d36ad0b..0000000 --- a/src/assets/sass/error.scss +++ /dev/null @@ -1,90 +0,0 @@ -@import "layout"; - -header, footer { - margin: 0; - padding: 0; - height: 0; -} - -main { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - - .messages { - margin-bottom: 32px; - } - - .error-code { - font-size: 36px; - } - - .error-message { - font-size: 32px; - } - - .error-instructions { - margin-top: 32px; - font-size: 20px; - } - - nav { - margin-top: 32px; - } - - &::before { - content: "Oops"; - position: absolute; - z-index: -1; - - font-size: #{'min(50vh, 40vw)'}; - opacity: 0.025; - } -} - -.contact { - text-align: center; - padding: 8px; -} - -.logo { - position: absolute; - top: 0; - left: 0; - width: 100%; - margin-top: 24px; - text-align: center; - - a { - position: relative; - padding: 16px; - - color: $defaultTextColor; - - &:hover { - color: #fff; - - &::before { - opacity: 0.2; - } - } - - &::before { - content: ""; - position: absolute; - width: 100%; - height: 100%; - top: 0; - left: 0; - - background-image: url(../img/logo.svg); - background-repeat: no-repeat; - background-position: center; - background-size: 64px; - - opacity: 0.075; - filter: contrast(0); - } - } -} \ No newline at end of file diff --git a/src/assets/sass/layout.scss b/src/assets/sass/layout.scss deleted file mode 100644 index cf1f7c1..0000000 --- a/src/assets/sass/layout.scss +++ /dev/null @@ -1,843 +0,0 @@ -@import "vars"; -@import 'fonts'; -@import "responsivity_tools"; - -* { - box-sizing: border-box; -} - -html, body { - height: 100%; -} - -body { - display: flex; - flex-direction: column; - - margin: 0; - font-family: "Nunito Sans", sans-serif; - font-size: 16px; - - color: $defaultTextColor; - background-color: $backgroundColor; -} - -@mixin tip { - position: relative; - - .tip { - visibility: hidden; - position: absolute; - z-index: 10000; - pointer-events: none; - display: block; - width: max-content; - height: 30px; - padding: 4px 8px; - line-height: 22px; - top: calc(100% + 8px); - left: 50%; - transform: translateX(-50%); - - text-align: center; - font-size: 18px; - color: $defaultTextColor; - opacity: 0; - transition: opacity ease-out 100ms, visibility step-end 150ms; - transition-delay: 0ms; - background-color: #000; - border-radius: 5px; - - text-transform: initial; - font-weight: initial; - - &.top { - top: auto; - bottom: calc(100% + 8px); - } - } - - &:hover, &:active { - .tip { - visibility: visible; - opacity: 1; - transition: opacity ease-out 100ms; - transition-delay: 150ms; - } - } -} - -body > header { - z-index: 50; - display: flex; - flex-direction: row-reverse; - justify-content: space-between; - align-items: center; - - $headerHeight: 64px; - height: $headerHeight; - line-height: $headerHeight; - - background: $headerBackground; - - @if $headerContainer { - @include container; - } - - @media (max-width: $mobileThreshold) { - padding: 0; - } - - .logo { - display: flex; - flex-direction: row; - align-items: center; - - padding: 0 16px 0 8px; - font-size: 24px; - color: $defaultTextColor; - - &:hover { - color: lighten($defaultTextColor, 10%); - } - - img { - width: initial; - height: calc(#{$headerHeight} - 16px); - margin-right: 8px; - flex-shrink: 0; - } - } - - nav { - > ul { - position: fixed; - z-index: -1; - top: 0; - left: 0; - height: 100%; - transform: translateX(-100%); - transition: transform ease-out 150ms; - - display: flex; - flex-direction: column; - margin: 0; - padding: $headerHeight 8px 8px; - - font-size: 20px; - - background: $panelBackground; - - li { - position: relative; - list-style: none; - margin-top: 8px; - - a, button { - position: relative; - margin: 0; - - display: flex; - flex-direction: row; - align-items: center; - height: auto; - padding: 8px; - - border-radius: 3px; - - &:hover, &:active { - &:not(button) { - background-color: rgba(255, 255, 255, 0.07); - } - } - - .feather { - --icon-size: 16px; - } - - .tip { - position: static; - visibility: visible; - opacity: 1; - display: block; - height: auto; - margin-left: 8px; - padding: 0 0 0 4px; - transform: none; - - font-size: 16px; - line-height: 16px; - - color: inherit; - text-transform: uppercase; - font-weight: inherit; - background: transparent; - } - } - - button { - margin: 0; - height: 32px; - - .feather { - margin-right: 0; - } - } - - form { - display: flex; - justify-content: center; - align-items: center; - padding: 0; - } - - &.auth-user { - img { - width: 48px; - height: 48px; - border-radius: 3px; - margin-right: 8px; - } - } - - .dropdown { - position: initial; - display: block; - padding-left: 0; - } - } - - > li:not(:first-child) { - border-top: 1px solid transparentize($defaultTextColor, 0.8); - padding-top: 8px; - } - - &.open { - transform: translateX(0%); - box-shadow: 0 0 5px darken($panelBackground, 20%); - } - } - - #menu-button { - position: fixed; - top: 0; - left: 0; - display: block; - margin: 0; - padding: 0 16px; - line-height: $headerHeight; - - cursor: pointer; - background: transparent; - border-radius: 0; - - .feather { - --icon-size: 28px; - margin: 0 8px; - } - } - - hr { - border: 0; - border-bottom: 1px solid $defaultTextColor; - opacity: 0.2; - } - } - - @media (min-width: $mobileThreshold) { - flex-direction: row; - - nav { - #menu-button { - display: none; - } - - ul { - position: static; - flex-direction: row; - transform: none; - padding: 0; - background: transparent; - - li { - margin-top: 0; - margin-left: 8px; - - &:last-child { - a, button, .button { - .tip { - left: unset; - right: 4px; - transform: none; - } - } - } - - .dropdown { - position: absolute; - z-index: -1; - top: 100%; - right: 0; - display: none; - padding: 8px; - - white-space: nowrap; - background: $panelBackground; - border-radius: 0 0 3px 3px; - - box-shadow: 0 2px 2px transparentize(darken($panelBackground, 20%), 0.75); - border-top: 4px solid lighten($panelBackground, 5%); - - li { - margin-left: 0; - - &:not(:first-child) { - margin-top: 8px; - } - } - } - - &:hover .dropdown { - display: block; - } - } - - > li:not(:first-child) { - border-top: 0; - padding-top: 0; - } - } - } - } -} - -body > footer { - padding: 8px; - margin-top: 8px; - text-align: center; - background-color: $footerBackground; -} - -main { - flex: 1; - padding: 8px 0; - - button, .button { - @include tip; - } -} - -h1 { - text-align: center; - font-size: 32px; - - & + p { - text-align: center; - font-size: 20px; - } -} - -h1, h2 { - font-weight: 100; -} - -h3, h4 { - font-weight: 300; -} - -section > h2, .panel > h2 { - display: flex; - flex-direction: row; - align-items: center; - position: relative; - text-align: center; - margin-top: 4px; - - font-size: 24px; - line-height: 1; - - .feather { - margin: 0 16px 0 0; - opacity: 0.1; - } - - &::after { - content: ""; - flex: 1; - margin: 0 16px; - height: 0; - border-bottom: 1px solid $defaultTextColor; - opacity: 0.1; - } -} - -section > hr, .panel > hr { - border: 0; - border-bottom: 1px solid $defaultTextColor; - opacity: 0.2; - - margin: 8px 32px; -} - -a { - color: $secondary; - text-decoration: none; - - &:hover { - color: lighten($secondary, 30%); - } - - .feather.feather-external-link { - --icon-size: 16px; - margin-left: 4px; - margin-top: -3px; - } -} - -form { - padding: 8px 16px; - text-align: center; - - .form-field:not(.hidden) { - display: flex; - flex-direction: column; - margin: 16px auto; - - .control { - position: relative; - background: $inputBackground; - border-radius: 5px; - } - - .feather.icon { - position: absolute; - top: 50%; - right: 8px; - transform: translateY(-50%); - z-index: 0; - - --icon-size: 24px; - opacity: 0.75; - } - - label { - position: absolute; - left: 8px; - top: 20px; - user-select: none; - font-size: 16px; - opacity: 0.75; - - transition-property: top, font-size; - transition-duration: 150ms; - transition-timing-function: ease-out; - - cursor: text; - } - - [disabled] { - opacity: 0.5; - - & ~ label { - opacity: 0.5; - cursor: default; - } - } - - input, select, textarea, .input-group { - z-index: 1; - border: 0; - color: $defaultTextColor; - background: transparent; - font-size: 16px; - - &:focus, &:not([value=""]), &[type="file"] { - ~ label { - top: 8px; - font-size: 14px; - } - } - } - - input, select, textarea, .form-display { - display: block; - padding: 32px 8px 8px 8px; - width: 100%; - height: 60px; - } - - select { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - - &::-ms-expand { - display: none; - } - - & + .feather { - position: absolute; - pointer-events: none; - right: 8px; - top: 30px; - - transition: transform 150ms ease-out; - } - - // Temporary - &:focus + .feather { - transform: rotateX(180deg); - } - } - - textarea { - resize: vertical; - min-height: 100px; - font-family: inherit; - } - - input[type=color] { - height: calc(32px + 8px + 32px); - } - - &.inline { - display: flex; - flex-direction: row; - - .control { - display: flex; - flex-direction: row; - align-items: center; - flex-grow: 1; - - input[type=checkbox] { - width: min-content; - height: min-content; - margin: 8px; - text-align: left; - - & ~ label { - position: static; - flex-grow: 1; - display: inline; - padding: 8px; - - font-size: 16px; - text-align: left; - } - } - } - } - - .input-group { - display: flex; - flex-grow: 1; - flex-direction: row; - - div { - position: relative; - flex: 1; - - input { - width: 100%; - border: 0; - background: transparent; - } - } - } - } - - .inline-fields { - display: flex; - flex-direction: row; - align-items: start; - margin: 16px auto; - - .form-field { - flex: 1; - margin: 0; - } - - > :not(.form-field) { - padding: 32px 8px 8px 8px; - } - - + { - .error, .hint { - margin-top: -16px; - margin-bottom: 16px; - } - } - } - - .form-field, .inline-fields + { - .error, .hint { - padding: 2px; - text-align: left; - font-size: 14px; - - .feather { - --icon-size: 14px; - } - } - - .error { - color: $error; - } - } -} - -button, .button { - display: inline-flex; - margin: 8px; - padding: 12px 16px; - border: 0; - border-radius: 5px; - cursor: pointer; - - text-transform: uppercase; - font-size: 16px; - font-weight: bolder; - - line-height: 16px; - - .feather { - --icon-size: 16px; - margin-right: 8px; - } - - .feather.last { - margin-right: 0; - margin-left: 8px; - } - - &, &.primary { - color: $primaryForeground; - background-color: darken($secondary, 10%); - - &:hover { - background-color: $secondary; - } - } - - &.info { - background-color: $infoColor; - } - - &.success { - background-color: $successColor; - } - - &.warning { - background-color: $warningColor; - - &:hover { - background-color: lighten($warningColor, 10%); - } - } - - &.error, &.danger { - background-color: $errorColor; - - &:hover { - background-color: lighten($errorColor, 10%); - } - } - - &.transparent { - background-color: transparent; - } - - &:hover { - color: $primaryForeground; - } -} - - -// --- -// --- Tables -// --- -td.actions { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - - form { - padding: 0; - display: inline; - } - - button, .button { - margin: 0; - padding: 8px; - - .feather { - margin-right: 0; - } - } - - > *:not(:first-child) { - margin-left: 8px; - } -} - - -// --- -// --- Breadcrumb widget -// --- -.breadcrumb { - list-style: none; - display: flex; - flex-direction: row; - margin: 0; - padding: 8px; - - > *:not(:first-child)::before { - content: '›'; - padding: 0 8px; - } -} - - -// --- -// --- Layout helpers -// --- -.center { - text-align: center; -} - -.panel { - position: relative; - margin: 16px 0 48px; - padding: 8px; - background-color: $panelBackground; - border-radius: 5px; - - p { - margin: 16px 8px; - } - - > .feather:first-child { - position: absolute; - --icon-size: 24px; - opacity: 0.1; - top: 8px; - left: 8px; - } -} - -.sub-panel { - margin: 32px 0; - padding: 1px 16px; - border: 2px solid lighten($panelBackground, 4%); - border-radius: 5px; - - form > & { - margin: 32px -18px; - } -} - - -// --- -// --- Helper classes -// --- -.container > .messages:first-child { - margin-top: 16px; -} - -.copyable-text { - display: flex; - flex-direction: row; - margin: 8px; - - background-color: darken($backgroundColor, 2%); - border-radius: 5px; - overflow: hidden; - - .title { - padding: 8px; - } - - .content { - width: 0; - flex-grow: 1; - overflow: hidden; - white-space: nowrap; - padding: 8px; - } - - .copy-button { - margin: 0; - padding: 0; - border-radius: 0; - - .feather { - --icon-size: 20px; - margin: 8px; - } - } -} - -.hidden { - display: none; -} - -.progress-bar { - position: relative; - display: block; - margin: 8px; - padding: 4px; - background: #fff1; - border-radius: 5px; - overflow: hidden; - text-align: center; - - .content { - position: relative; - } - - &::before { - content: ""; - display: block; - position: absolute; - left: 0; - top: 0; - width: var(--progress); - height: 100%; - transition: width ease-out 150ms; - - background: $secondary; - } -} - -.table-col-grow { - width: 100%; -} - -.pagination { - ul { - display: flex; - flex-direction: row; - list-style: none; - padding: 8px; - - justify-content: center; - - li { - a, &.active, &.ellipsis { - display: block; - min-width: 40px; - height: 40px; - padding: 4px; - - line-height: 32px; - text-align:center; - - &:hover:not(.active):not(.ellipsis) { - background-color: #fff5; - } - } - } - } -} diff --git a/src/assets/sass/responsivity_tools.scss b/src/assets/sass/responsivity_tools.scss deleted file mode 100644 index 0e3d232..0000000 --- a/src/assets/sass/responsivity_tools.scss +++ /dev/null @@ -1,19 +0,0 @@ -@import "vars"; - -@mixin container { - width: 100%; - padding: 0 8px; - - @media (min-width: $mobileThreshold) { - margin: 0 auto; - padding: 0 16px; - } - - @media (min-width: $desktopThreshold) { - width: $desktopThreshold; - } -} - -.container { - @include container; -} diff --git a/src/assets/ts/PersistentWebSocket.ts b/src/assets/ts/PersistentWebSocket.ts deleted file mode 100644 index 98e474f..0000000 --- a/src/assets/ts/PersistentWebSocket.ts +++ /dev/null @@ -1,39 +0,0 @@ -export default class PersistentWebsocket { - private webSocket?: WebSocket; - - public constructor( - protected readonly url: string, - private readonly handler: MessageHandler, - protected readonly reconnectOnClose: boolean = true, - ) { - } - - public run(): void { - const _webSocket = this.webSocket = new WebSocket(this.url); - this.webSocket.addEventListener('open', () => { - console.debug('Websocket connected'); - }); - this.webSocket.addEventListener('message', (e) => { - this.handler(_webSocket, e); - }); - this.webSocket.addEventListener('error', (e) => { - console.error('Websocket error', e); - }); - this.webSocket.addEventListener('close', (e) => { - this.webSocket = undefined; - console.debug('Websocket closed', e.code, e.reason); - - if (this.reconnectOnClose) { - setTimeout(() => this.run(), 1000); - } - }); - } - - public send(data: string): void { - if (!this.webSocket) throw new Error('WebSocket not connected'); - - this.webSocket.send(data); - } -} - -export type MessageHandler = (webSocket: WebSocket, e: MessageEvent) => void; diff --git a/src/assets/ts/app.ts b/src/assets/ts/app.ts deleted file mode 100644 index 8594552..0000000 --- a/src/assets/ts/app.ts +++ /dev/null @@ -1,10 +0,0 @@ -import './external_links'; -import './message_icons'; -import './forms'; -import './copyable_text'; -import './tooltips-and-dropdowns'; -import './main_menu'; -import './font-awesome'; - -// css -import '../sass/app.scss'; diff --git a/src/assets/ts/copyable_text.ts b/src/assets/ts/copyable_text.ts deleted file mode 100644 index 60d58ab..0000000 --- a/src/assets/ts/copyable_text.ts +++ /dev/null @@ -1,15 +0,0 @@ -document.addEventListener('DOMContentLoaded', () => { - document.querySelectorAll('.copyable-text').forEach(el => { - const contentEl = el.querySelector('.content'); - const selection = window.getSelection(); - if (contentEl && selection) { - contentEl.addEventListener('click', () => { - selection.selectAllChildren(contentEl); - }); - el.querySelector('.copy-button')?.addEventListener('click', () => { - selection.selectAllChildren(contentEl); - document.execCommand('copy'); - }); - } - }); -}); diff --git a/src/assets/ts/external_links.ts b/src/assets/ts/external_links.ts deleted file mode 100644 index bc9ba26..0000000 --- a/src/assets/ts/external_links.ts +++ /dev/null @@ -1,11 +0,0 @@ -import feather from "feather-icons"; - -document.addEventListener('DOMContentLoaded', () => { - document.querySelectorAll('a[target="_blank"]').forEach(el => { - if (!el.classList.contains('no-icon')) { - el.innerHTML += ``; - } - }); - - feather.replace(); -}); diff --git a/src/assets/ts/font-awesome.ts b/src/assets/ts/font-awesome.ts deleted file mode 100644 index 0409cfe..0000000 --- a/src/assets/ts/font-awesome.ts +++ /dev/null @@ -1,4 +0,0 @@ -import '@fortawesome/fontawesome-free/scss/fontawesome.scss'; -import '@fortawesome/fontawesome-free/scss/regular.scss'; -import '@fortawesome/fontawesome-free/scss/solid.scss'; -import '@fortawesome/fontawesome-free/scss/brands.scss'; diff --git a/src/assets/ts/forms.ts b/src/assets/ts/forms.ts deleted file mode 100644 index ece465d..0000000 --- a/src/assets/ts/forms.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* - * For labels to update their state (css selectors based on the value attribute) - */ -import {ValidationError} from "swaf/db/Validator"; - -export function updateInputs(): void { - document.querySelectorAll('input, textarea').forEach(el => { - if (!el.dataset.inputSetup) { - el.dataset.inputSetup = 'true'; - if (el.type !== 'checkbox') { - el.setAttribute('value', el.value); - el.addEventListener('change', () => { - el.setAttribute('value', el.value); - }); - } - } - }); -} - -document.addEventListener('DOMContentLoaded', () => { - updateInputs(); -}); - -export function applyFormMessages( - formElement: HTMLFormElement, - messages: { [p: string]: ValidationError }, -): void { - for (const fieldName of Object.keys(messages)) { - const field = formElement.querySelector('#field-' + fieldName); - if (!field) continue; - - let parent = field.parentElement; - while (parent && !parent.classList.contains('form-field')) parent = parent.parentElement; - - let err = field.querySelector('.error'); - if (!err) { - err = document.createElement('div'); - err.classList.add('error'); - parent?.insertBefore(err, parent.querySelector('.hint') || parent); - } - err.innerHTML = ` ${messages[fieldName].message}`; - } -} diff --git a/src/assets/ts/main_menu.ts b/src/assets/ts/main_menu.ts deleted file mode 100644 index 4e19e40..0000000 --- a/src/assets/ts/main_menu.ts +++ /dev/null @@ -1,21 +0,0 @@ -document.addEventListener('DOMContentLoaded', () => { - const menuButton = document.getElementById('menu-button'); - const mainMenu = document.getElementById('main-menu'); - - if (menuButton) { - menuButton.addEventListener('click', (e) => { - e.stopPropagation(); - mainMenu?.classList.toggle('open'); - }); - } - - if (mainMenu) { - mainMenu.addEventListener('click', (e) => { - e.stopPropagation(); - }); - - document.addEventListener('click', () => { - mainMenu.classList.remove('open'); - }); - } -}); diff --git a/src/assets/ts/message_icons.ts b/src/assets/ts/message_icons.ts deleted file mode 100644 index b737de3..0000000 --- a/src/assets/ts/message_icons.ts +++ /dev/null @@ -1,26 +0,0 @@ -import feather from "feather-icons"; - -document.addEventListener('DOMContentLoaded', () => { - const messageTypeToIcon: { [p: string]: string } = { - info: 'info', - success: 'check', - warning: 'alert-triangle', - error: 'x-circle', - question: 'help-circle', - }; - - document.querySelectorAll('.message').forEach(el => { - const icon = el.querySelector('.icon'); - const type = el.dataset['type']; - if (!icon || !type) return; - if (!messageTypeToIcon[type]) throw new Error(`No icon for type ${type}`); - - const svgContainer = document.createElement('div'); - svgContainer.innerHTML = feather.icons[messageTypeToIcon[type]].toSvg(); - - if (svgContainer.firstChild) el.insertBefore(svgContainer.firstChild, icon); - icon.remove(); - }); - - feather.replace(); -}); diff --git a/src/assets/ts/tooltips-and-dropdowns.ts b/src/assets/ts/tooltips-and-dropdowns.ts deleted file mode 100644 index 069b405..0000000 --- a/src/assets/ts/tooltips-and-dropdowns.ts +++ /dev/null @@ -1,31 +0,0 @@ -export function updateTooltips(): void { - console.debug('Updating tooltips'); - const elements = document.querySelectorAll('.tip, .dropdown'); - - // Calculate max potential displacement - let max = 0; - elements.forEach(el => { - const box = el.getBoundingClientRect(); - if (max < box.height) max = box.height; - }); - - // Prevent displacement - elements.forEach(el => { - if (!el.dataset.tooltipSetup) { - el.dataset.tooltipSetup = 'true'; - const box = el.getBoundingClientRect(); - if (box.bottom >= document.body.clientHeight - (max + 32)) { - el.classList.add('top'); - } - } - }); -} - -document.addEventListener('DOMContentLoaded', () => { - window.addEventListener('popstate', () => { - updateTooltips(); - }); - window.requestAnimationFrame(() => { - updateTooltips(); - }); -}); diff --git a/src/assets/views/about.njk b/src/assets/views/about.njk deleted file mode 100644 index f1e7a0a..0000000 --- a/src/assets/views/about.njk +++ /dev/null @@ -1,14 +0,0 @@ -{% extends 'layouts/base.njk' %} - -{% set title = app.name + ' - About us' %} - -{% block body %} -

Very interesting

- -
-
-

This is us

-

And we like swaf!

-
-
-{% endblock %} diff --git a/src/assets/views/home.njk b/src/assets/views/home.njk deleted file mode 100644 index 09adf33..0000000 --- a/src/assets/views/home.njk +++ /dev/null @@ -1,7 +0,0 @@ -{% extends 'layouts/base.njk' %} - -{% set title = app.name + ' - Hello world!' %} - -{% block body %} -

Hello world!

-{% endblock %} \ No newline at end of file diff --git a/src/assets/views/layouts/base.njk b/src/assets/views/layouts/base.njk deleted file mode 100644 index f350e8e..0000000 --- a/src/assets/views/layouts/base.njk +++ /dev/null @@ -1,41 +0,0 @@ -{% extends 'layouts/barebone.njk' %} -{% import 'macros.njk' as macros %} - -{% block _stylesheets %} - {{ super() }} - - {% block stylesheets %}{% endblock %} -{% endblock %} -{% block _scripts %} - {{ super() }} - {% block scripts %}{% endblock %} -{% endblock %} - -{% block header %} - - -{% endblock %} - -{% block _body %} -
- {{ macros.messages(flash) }} -
- -
- {% if h1 %} -

{{ h1 }}

- {% endif %} - {% if subtitle %} -

{{ subtitle }}

- {% endif %} - - {% block body %}{% endblock %} -
-{% endblock %} - -{% block footer %}{{ app.name }} v{{ app_version }} - all rights reserved.{% endblock %} \ No newline at end of file From 6002ad529090147f838542b0b7354ff834798702 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sun, 21 Nov 2021 16:59:06 +0100 Subject: [PATCH 07/11] Remove webpack and unused dependencies --- package.json | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index b83dc74..2ddb61c 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,6 @@ "start": "yarn build-production && node ." }, "devDependencies": { - "@babel/core": "^7.9.0", - "@babel/preset-env": "^7.9.5", "@tsconfig/svelte": "^2.0.1", "@types/config": "^0.0.40", "@types/express": "^4.17.6", @@ -34,14 +32,9 @@ "@types/ws": "^8.2.0", "@typescript-eslint/eslint-plugin": "^5.4.0", "@typescript-eslint/parser": "^5.4.0", - "babel-loader": "^8.1.0", - "clear-module": "^4.1.2", "concurrently": "^6.0.0", - "css-loader": "^6.5.1", "eslint": "^8.2.0", "feather-icons": "^4.28.0", - "file-loader": "^6.0.0", - "image-minimizer-webpack-plugin": "^2.2.0", "imagemin-gifsicle": "^7.0.0", "imagemin-mozjpeg": "^9.0.0", "imagemin-pngquant": "^9.0.2", @@ -49,24 +42,15 @@ "imagemin-webp": "^6.0.0", "jest": "^27.0.4", "maildev": "^1.1.0", - "mini-css-extract-plugin": "^2.4.5", "nodemon": "^2.0.3", - "normalize.css": "^8.0.1", "sass": "^1.32.12", - "sass-loader": "^12.0.0", - "svelte": "^3.44.2", - "svelte-preprocess": "^4.9.8", "svgo": "^2.3.0", - "terser-webpack-plugin": "^5.0.3", "ts-jest": "^27.0.3", - "ts-loader": "^9.1.0", - "typescript": "^4.0.2", - "webpack": "^5.3.2", - "webpack-cli": "^4.1.0" + "typescript": "^4.0.2" }, "dependencies": { "config": "^3.3.1", "express": "^4.17.1", - "swaf": "^0.24.4" + "swaf": "^0.24.7" } } From 8c1230d5017a3c396fe2967a736c6e16ff161c82 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sun, 21 Nov 2021 17:41:48 +0100 Subject: [PATCH 08/11] Remove reference to deleted tsconfig.frontend.json from eslint config --- .eslintrc.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index a506e1e..8b0a7b4 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -7,8 +7,7 @@ "parserOptions": { "project": [ "./tsconfig.json", - "./tsconfig.test.json", - "./tsconfig.frontend.json" + "./tsconfig.test.json" ] }, "extends": [ From f2f34dd00f2c4f29d7acc829d2395b9d9f891bbc Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sun, 21 Nov 2021 17:44:12 +0100 Subject: [PATCH 09/11] Update eslint config with swaf --- .eslintrc.cjs | 135 +++++++++++++++++++++++++++++++++++++++++++++++++ .eslintrc.json | 114 ----------------------------------------- 2 files changed, 135 insertions(+), 114 deletions(-) create mode 100644 .eslintrc.cjs delete mode 100644 .eslintrc.json diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..4910a0e --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,135 @@ +module.exports = { + root: true, + parser: '@typescript-eslint/parser', + plugins: [ + 'svelte3', + '@typescript-eslint', + 'import', + 'simple-import-sort', + ], + parserOptions: { + tsconfigRootDir: __dirname, + project: [ + './tsconfig.test.json', + './src/tsconfig.json', + './src/common/tsconfig.json', + './src/assets/ts/tsconfig.eslint.json', + './src/assets/views/tsconfig.json', + ] + }, + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + ], + rules: { + indent: [ + 'error', + 4, + { + SwitchCase: 1 + } + ], + 'no-trailing-spaces': 'error', + 'max-len': [ + 'error', + { + code: 120, + ignoreTemplateLiterals: true, + ignoreRegExpLiterals: true + } + ], + semi: 'off', + '@typescript-eslint/semi': [ + 'error' + ], + 'no-extra-semi': 'error', + 'eol-last': 'error', + 'comma-dangle': 'off', + 'simple-import-sort/imports': 'error', + 'no-extra-parens': 'off', + 'no-nested-ternary': 'error', + 'no-return-await': 'off', + 'no-useless-return': 'error', + 'no-useless-constructor': 'off', + 'import/extensions': ['error', 'ignorePackages'], + '@typescript-eslint/comma-dangle': [ + 'error', + { + arrays: 'always-multiline', + objects: 'always-multiline', + imports: 'always-multiline', + exports: 'always-multiline', + functions: 'always-multiline', + enums: 'always-multiline', + generics: 'always-multiline', + tuples: 'always-multiline' + } + ], + '@typescript-eslint/no-extra-parens': [ + 'error' + ], + '@typescript-eslint/no-inferrable-types': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'error', + '@typescript-eslint/no-unnecessary-condition': 'error', + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_' + } + ], + '@typescript-eslint/no-non-null-assertion': 'error', + '@typescript-eslint/no-useless-constructor': [ + 'error' + ], + '@typescript-eslint/return-await': [ + 'error', + 'always' + ], + '@typescript-eslint/explicit-member-accessibility': [ + 'error', + { + accessibility: 'explicit' + } + ], + '@typescript-eslint/no-floating-promises': 'error', + }, + ignorePatterns: [ + '.eslintrc.js', + 'rollup.config.js', + 'jest.config.js', + 'dist/**/*', + 'config/**/*', + 'intermediates/**/*', + 'public/**/*', + 'scripts/**/*', + 'src/frontend/register_svelte/register_svelte.js', + ], + overrides: [ + { + files: [ + 'test/**/*' + ], + rules: { + 'max-len': [ + 'error', + { + code: 120, + ignoreTemplateLiterals: true, + ignoreRegExpLiterals: true, + ignoreStrings: true + } + ] + } + }, + { + files: ['*.svelte'], + processor: 'svelte3/svelte3' + } + ], + settings: { + 'svelte3/typescript': require('typescript'), + 'svelte3/ignore-styles': function (attributes) { + return !!(attributes['lang'] && attributes['lang'] !== 'css'); + } + }, +} diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 8b0a7b4..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,114 +0,0 @@ -{ - "root": true, - "parser": "@typescript-eslint/parser", - "plugins": [ - "@typescript-eslint" - ], - "parserOptions": { - "project": [ - "./tsconfig.json", - "./tsconfig.test.json" - ] - }, - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended" - ], - "rules": { - "indent": [ - "error", - 4, - { - "SwitchCase": 1 - } - ], - "no-trailing-spaces": "error", - "max-len": [ - "error", - { - "code": 120, - "ignoreStrings": true, - "ignoreTemplateLiterals": true, - "ignoreRegExpLiterals": true - } - ], - "semi": "off", - "@typescript-eslint/semi": [ - "error" - ], - "no-extra-semi": "error", - "eol-last": "error", - "comma-dangle": "off", - "@typescript-eslint/comma-dangle": [ - "error", - { - "arrays": "always-multiline", - "objects": "always-multiline", - "imports": "always-multiline", - "exports": "always-multiline", - "functions": "always-multiline", - "enums": "always-multiline", - "generics": "always-multiline", - "tuples": "always-multiline" - } - ], - "no-extra-parens": "off", - "@typescript-eslint/no-extra-parens": [ - "error" - ], - "no-nested-ternary": "error", - "@typescript-eslint/no-inferrable-types": "off", - "@typescript-eslint/explicit-module-boundary-types": "error", - "@typescript-eslint/no-unnecessary-condition": "error", - "@typescript-eslint/no-unused-vars": [ - "error", - { - "argsIgnorePattern": "^_" - } - ], - "@typescript-eslint/no-non-null-assertion": "error", - "no-useless-return": "error", - "no-useless-constructor": "off", - "@typescript-eslint/no-useless-constructor": [ - "error" - ], - "no-return-await": "off", - "@typescript-eslint/return-await": [ - "error", - "always" - ], - "@typescript-eslint/explicit-member-accessibility": [ - "error", - { - "accessibility": "explicit" - } - ], - "@typescript-eslint/no-floating-promises": "error" - }, - "ignorePatterns": [ - "jest.config.js", - "scripts/**/*", - "webpack.config.js", - "dist/**/*", - "public/**/*", - "config/**/*" - ], - "overrides": [ - { - "files": [ - "test/**/*" - ], - "rules": { - "max-len": [ - "error", - { - "code": 120, - "ignoreTemplateLiterals": true, - "ignoreRegExpLiterals": true, - "ignoreStrings": true - } - ] - } - } - ] -} From eb0364a2f7e632a7e10c24702a75752bbe7eb6a8 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sun, 21 Nov 2021 17:52:56 +0100 Subject: [PATCH 10/11] Fix eslint and fix linting issues --- package.json | 6 +++++- src/App.ts | 35 ++++++++++++++++--------------- src/common/dummy.ts | 2 +- src/controllers/HomeController.ts | 2 +- src/main.ts | 5 +++-- 5 files changed, 28 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index 2ddb61c..5057cc4 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,10 @@ "@typescript-eslint/eslint-plugin": "^5.4.0", "@typescript-eslint/parser": "^5.4.0", "concurrently": "^6.0.0", - "eslint": "^8.2.0", + "eslint": "^8.3.0", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-simple-import-sort": "^7.0.0", + "eslint-plugin-svelte3": "^3.2.1", "feather-icons": "^4.28.0", "imagemin-gifsicle": "^7.0.0", "imagemin-mozjpeg": "^9.0.0", @@ -44,6 +47,7 @@ "maildev": "^1.1.0", "nodemon": "^2.0.3", "sass": "^1.32.12", + "svelte": "^3.44.2", "svgo": "^2.3.0", "ts-jest": "^27.0.3", "typescript": "^4.0.2" diff --git a/src/App.ts b/src/App.ts index 768d322..09ffde9 100644 --- a/src/App.ts +++ b/src/App.ts @@ -1,30 +1,31 @@ import Application from "swaf/Application"; -import Migration, {MigrationType} from "swaf/db/Migration"; -import CreateMigrationsTable from "swaf/migrations/CreateMigrationsTable"; +import AutoUpdateComponent from "swaf/components/AutoUpdateComponent"; +import CsrfProtectionComponent from "swaf/components/CsrfProtectionComponent"; import ExpressAppComponent from "swaf/components/ExpressAppComponent"; -import MysqlComponent from "swaf/components/MysqlComponent"; +import FormHelperComponent from "swaf/components/FormHelperComponent"; +import FrontendToolsComponent from "swaf/components/FrontendToolsComponent"; import LogRequestsComponent from "swaf/components/LogRequestsComponent"; +import MailComponent from "swaf/components/MailComponent"; +import MaintenanceComponent from "swaf/components/MaintenanceComponent"; +import MysqlComponent from "swaf/components/MysqlComponent"; +import PreviousUrlComponent from "swaf/components/PreviousUrlComponent"; import RedisComponent from "swaf/components/RedisComponent"; import ServeStaticDirectoryComponent from "swaf/components/ServeStaticDirectoryComponent"; -import MaintenanceComponent from "swaf/components/MaintenanceComponent"; -import MailComponent from "swaf/components/MailComponent"; import SessionComponent from "swaf/components/SessionComponent"; -import FormHelperComponent from "swaf/components/FormHelperComponent"; -import CsrfProtectionComponent from "swaf/components/CsrfProtectionComponent"; import WebSocketServerComponent from "swaf/components/WebSocketServerComponent"; -import HomeController from "./controllers/HomeController"; -import AutoUpdateComponent from "swaf/components/AutoUpdateComponent"; -import DummyMigration from "swaf/migrations/DummyMigration"; -import DropLegacyLogsTable from "swaf/migrations/DropLegacyLogsTable"; -import PreviousUrlComponent from "swaf/components/PreviousUrlComponent"; -import MailViewEngine from "swaf/frontend/MailViewEngine"; +import Migration, {MigrationType} from "swaf/db/Migration"; import AssetCompiler from "swaf/frontend/AssetCompiler"; -import FrontendToolsComponent from "swaf/components/FrontendToolsComponent"; import CopyAssetPreCompiler from "swaf/frontend/CopyAssetPreCompiler"; -import ScssAssetPreCompiler from "swaf/frontend/ScssAssetPreCompiler"; -import TypeScriptPreCompiler from "swaf/frontend/TypeScriptPreCompiler"; -import SvelteViewEngine from "swaf/frontend/SvelteViewEngine"; +import MailViewEngine from "swaf/frontend/MailViewEngine"; import NunjucksViewEngine from "swaf/frontend/NunjucksViewEngine"; +import ScssAssetPreCompiler from "swaf/frontend/ScssAssetPreCompiler"; +import SvelteViewEngine from "swaf/frontend/SvelteViewEngine"; +import TypeScriptPreCompiler from "swaf/frontend/TypeScriptPreCompiler"; +import CreateMigrationsTable from "swaf/migrations/CreateMigrationsTable"; +import DropLegacyLogsTable from "swaf/migrations/DropLegacyLogsTable"; +import DummyMigration from "swaf/migrations/DummyMigration"; + +import HomeController from "./controllers/HomeController.js"; export default class App extends Application { public constructor( diff --git a/src/common/dummy.ts b/src/common/dummy.ts index c58f5a5..4f6d24e 100644 --- a/src/common/dummy.ts +++ b/src/common/dummy.ts @@ -1 +1 @@ -console.log('common code between back and front'); \ No newline at end of file +console.log('common code between back and front'); diff --git a/src/controllers/HomeController.ts b/src/controllers/HomeController.ts index 027d83d..825b619 100644 --- a/src/controllers/HomeController.ts +++ b/src/controllers/HomeController.ts @@ -1,6 +1,6 @@ -import Controller from "swaf/Controller"; import {Request, Response} from "express"; import {route} from "swaf/common/Routing"; +import Controller from "swaf/Controller"; export default class HomeController extends Controller { public routes(): void { diff --git a/src/main.ts b/src/main.ts index ff2f443..8bf4ab4 100644 --- a/src/main.ts +++ b/src/main.ts @@ -6,10 +6,11 @@ process.env['NODE_CONFIG_DIR'] = + delimiter + (process.env['NODE_CONFIG_DIR'] || __dirname + '/../config/'); -import {logger} from "swaf/Logger"; -import App from "./App"; import config from "config"; import {promises as fs} from "fs"; +import {logger} from "swaf/Logger"; + +import App from "./App.js"; (async () => { logger.debug('Config path:', process.env['NODE_CONFIG_DIR']); From 5f5275ceb116a77dbc355ada1de05773c370ee90 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Fri, 24 Dec 2021 15:18:09 +0100 Subject: [PATCH 11/11] upgrade dependencies --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 5057cc4..d5a0877 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "start": "yarn build-production && node ." }, "devDependencies": { - "@tsconfig/svelte": "^2.0.1", + "@tsconfig/svelte": "^3.0.0", "@types/config": "^0.0.40", "@types/express": "^4.17.6", "@types/express-session": "^1.17.0", @@ -26,7 +26,7 @@ "@types/formidable": "^2.0.0", "@types/jest": "^27.0.3", "@types/mysql": "^2.15.15", - "@types/node": "^16.11.9", + "@types/node": "^17.0.4", "@types/nodemailer": "^6.4.0", "@types/nunjucks": "^3.1.3", "@types/ws": "^8.2.0", @@ -39,10 +39,10 @@ "eslint-plugin-svelte3": "^3.2.1", "feather-icons": "^4.28.0", "imagemin-gifsicle": "^7.0.0", - "imagemin-mozjpeg": "^9.0.0", + "imagemin-mozjpeg": "^10.0.0", "imagemin-pngquant": "^9.0.2", "imagemin-svgo": "^10.0.0", - "imagemin-webp": "^6.0.0", + "imagemin-webp": "^7.0.0", "jest": "^27.0.4", "maildev": "^1.1.0", "nodemon": "^2.0.3",