Add svelte as a view engine to swaf #33
42
package.json
42
package.json
@ -25,25 +25,23 @@
|
|||||||
"release": "yarn build && yarn lint && yarn test && cd dist && yarn publish"
|
"release": "yarn build && yarn lint && yarn test && cd dist && yarn publish"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rollup/plugin-commonjs": "^18.0.0",
|
"@rollup/plugin-commonjs": "^21.0.1",
|
||||||
"@rollup/plugin-node-resolve": "^11.2.0",
|
"@rollup/plugin-node-resolve": "^13.0.6",
|
||||||
"@sveltejs/eslint-config": "sveltejs/eslint-config",
|
"@sveltejs/eslint-config": "sveltejs/eslint-config",
|
||||||
"@tsconfig/svelte": "^1.0.10",
|
"@tsconfig/svelte": "^2.0.1",
|
||||||
"@types/compression": "^1.7.0",
|
"@types/compression": "^1.7.0",
|
||||||
"@types/config": "^0.0.38",
|
"@types/config": "^0.0.40",
|
||||||
"@types/connect-flash": "^0.0.36",
|
"@types/connect-flash": "^0.0.37",
|
||||||
"@types/cookie": "^0.4.0",
|
"@types/cookie": "^0.4.0",
|
||||||
"@types/cookie-parser": "^1.4.2",
|
"@types/cookie-parser": "^1.4.2",
|
||||||
"@types/express": "^4.17.6",
|
"@types/express": "^4.17.6",
|
||||||
"@types/express-session": "^1.17.0",
|
"@types/express-session": "^1.17.0",
|
||||||
"@types/feather-icons": "^4.7.0",
|
"@types/feather-icons": "^4.7.0",
|
||||||
"@types/formidable": "^1.0.31",
|
"@types/formidable": "^2.0.0",
|
||||||
"@types/geoip-lite": "^1.1.31",
|
"@types/geoip-lite": "^1.1.31",
|
||||||
"@types/jest": "^26.0.4",
|
"@types/jest": "^27.0.2",
|
||||||
"@types/mjml": "^4.0.4",
|
"@types/mjml": "^4.0.4",
|
||||||
"@types/mysql": "^2.15.10",
|
"@types/mysql": "^2.15.10",
|
||||||
"@types/nanoid": "^2.1.0",
|
|
||||||
"@types/node-fetch": "^2.5.7",
|
|
||||||
"@types/nodemailer": "^6.4.0",
|
"@types/nodemailer": "^6.4.0",
|
||||||
"@types/nunjucks": "^3.1.3",
|
"@types/nunjucks": "^3.1.3",
|
||||||
"@types/on-finished": "^2.3.1",
|
"@types/on-finished": "^2.3.1",
|
||||||
@ -51,23 +49,23 @@
|
|||||||
"@types/require-from-string": "^1.2.0",
|
"@types/require-from-string": "^1.2.0",
|
||||||
"@types/supertest": "^2.0.10",
|
"@types/supertest": "^2.0.10",
|
||||||
"@types/uuid": "^8.0.0",
|
"@types/uuid": "^8.0.0",
|
||||||
"@types/ws": "^7.2.4",
|
"@types/ws": "^8.2.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.2.0",
|
"@typescript-eslint/eslint-plugin": "^5.3.0",
|
||||||
"@typescript-eslint/parser": "^4.2.0",
|
"@typescript-eslint/parser": "^5.3.0",
|
||||||
"chokidar": "^3.5.1",
|
"chokidar": "^3.5.1",
|
||||||
"clear-module": "^4.1.1",
|
"clear-module": "^4.1.1",
|
||||||
"concurrently": "^6.0.0",
|
"concurrently": "^6.0.0",
|
||||||
"eslint": "^7.9.0",
|
"eslint": "^8.2.0",
|
||||||
"eslint-plugin-import": "^2.22.1",
|
"eslint-plugin-import": "^2.22.1",
|
||||||
"eslint-plugin-node": "^11.1.0",
|
"eslint-plugin-node": "^11.1.0",
|
||||||
"eslint-plugin-simple-import-sort": "^7.0.0",
|
"eslint-plugin-simple-import-sort": "^7.0.0",
|
||||||
"eslint-plugin-svelte3": "^3.1.2",
|
"eslint-plugin-svelte3": "^3.1.2",
|
||||||
"feather-icons": "^4.28.0",
|
"feather-icons": "^4.28.0",
|
||||||
"jest": "^26.1.0",
|
"jest": "^27.3.1",
|
||||||
"jest-resolve": "^26.6.2",
|
"jest-resolve": "^27.3.1",
|
||||||
"jest-ts-webcompat-resolver": "^1.0.0",
|
"jest-ts-webcompat-resolver": "^1.0.0",
|
||||||
"maildev": "^1.1.0",
|
"maildev": "^1.1.0",
|
||||||
"node-fetch": "^2.6.0",
|
"node-fetch": "^3.0.0",
|
||||||
"nodemon": "^2.0.6",
|
"nodemon": "^2.0.6",
|
||||||
"normalize.css": "^8.0.1",
|
"normalize.css": "^8.0.1",
|
||||||
"require-from-string": "^2.0.2",
|
"require-from-string": "^2.0.2",
|
||||||
@ -80,13 +78,13 @@
|
|||||||
"sass": "^1.32.12",
|
"sass": "^1.32.12",
|
||||||
"supertest": "^6.0.0",
|
"supertest": "^6.0.0",
|
||||||
"svelte": "^3.35.0",
|
"svelte": "^3.35.0",
|
||||||
"svelte-check": "^1.2.3",
|
"svelte-check": "^2.2.8",
|
||||||
"svelte-preprocess": "4.6.9",
|
"svelte-preprocess": "4.6.9",
|
||||||
"ts-jest": "^26.1.1",
|
"ts-jest": "^27.0.7",
|
||||||
"typescript": "^4.0.2"
|
"typescript": "^4.0.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"argon2": "^0.27.0",
|
"argon2": "^0.28.2",
|
||||||
"compression": "^1.7.4",
|
"compression": "^1.7.4",
|
||||||
"config": "^3.3.1",
|
"config": "^3.3.1",
|
||||||
"connect-flash": "^0.1.1",
|
"connect-flash": "^0.1.1",
|
||||||
@ -94,7 +92,7 @@
|
|||||||
"cookie-parser": "^1.4.5",
|
"cookie-parser": "^1.4.5",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"express-session": "^1.17.1",
|
"express-session": "^1.17.1",
|
||||||
"formidable": "^1.2.2",
|
"formidable": "^2.0.1",
|
||||||
"geoip-lite": "^1.4.2",
|
"geoip-lite": "^1.4.2",
|
||||||
"mjml": "^4.6.2",
|
"mjml": "^4.6.2",
|
||||||
"mysql": "^2.18.1",
|
"mysql": "^2.18.1",
|
||||||
@ -103,9 +101,9 @@
|
|||||||
"nunjucks": "^3.2.1",
|
"nunjucks": "^3.2.1",
|
||||||
"on-finished": "^2.3.0",
|
"on-finished": "^2.3.0",
|
||||||
"redis": "^3.0.2",
|
"redis": "^3.0.2",
|
||||||
"ts-node": "^9.0.0",
|
"ts-node": "^10.4.0",
|
||||||
"tslog": "^3.0.1",
|
"tslog": "^3.0.1",
|
||||||
"uuid": "^8.0.0",
|
"uuid": "^8.0.0",
|
||||||
"ws": "^7.2.3"
|
"ws": "^8.2.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import {NextFunction, Request, Response} from "express";
|
import {NextFunction, Request, Response} from "express";
|
||||||
import Formidable from "formidable";
|
import IncomingForm from "formidable/Formidable.js";
|
||||||
|
|
||||||
import {FileError, ValidationBag} from "./db/Validator.js";
|
import {FileError, ValidationBag} from "./db/Validator.js";
|
||||||
import Middleware from "./Middleware.js";
|
import Middleware from "./Middleware.js";
|
||||||
|
|
||||||
export default abstract class FileUploadMiddleware extends Middleware {
|
export default abstract class FileUploadMiddleware extends Middleware {
|
||||||
protected abstract makeForm(): Formidable;
|
protected abstract makeForm(): IncomingForm;
|
||||||
|
|
||||||
protected abstract getDefaultField(): string;
|
protected abstract getDefaultField(): string;
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ export default abstract class FileUploadMiddleware extends Middleware {
|
|||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e: any) {
|
||||||
const bag = new ValidationBag();
|
const bag = new ValidationBag();
|
||||||
const fileError = new FileError(e);
|
const fileError = new FileError(e);
|
||||||
fileError.thingName = this.getDefaultField();
|
fileError.thingName = this.getDefaultField();
|
||||||
|
@ -58,14 +58,26 @@ export default class TestApp extends Application {
|
|||||||
private readonly addr: string;
|
private readonly addr: string;
|
||||||
private readonly port: number;
|
private readonly port: number;
|
||||||
|
|
||||||
public constructor(version: string, addr: string, port: number, ignoreCommandLine: boolean = false) {
|
public constructor(
|
||||||
|
version: string,
|
||||||
|
addr: string,
|
||||||
|
port: number,
|
||||||
|
ignoreCommandLine: boolean = false,
|
||||||
|
private readonly approvalMode: boolean,
|
||||||
|
) {
|
||||||
super(version, ignoreCommandLine);
|
super(version, ignoreCommandLine);
|
||||||
this.addr = addr;
|
this.addr = addr;
|
||||||
this.port = port;
|
this.port = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getMigrations(): MigrationType<Migration>[] {
|
protected getMigrations(): MigrationType<Migration>[] {
|
||||||
return [...MIGRATIONS, AddApprovedFieldToUsersTableMigration];
|
const migrations = [...MIGRATIONS];
|
||||||
|
|
||||||
|
if (this.approvalMode) {
|
||||||
|
migrations.push(AddApprovedFieldToUsersTableMigration);
|
||||||
|
}
|
||||||
|
|
||||||
|
return migrations;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async init(): Promise<void> {
|
protected async init(): Promise<void> {
|
||||||
|
@ -67,8 +67,8 @@ export async function listFilesRecursively(dir: string): Promise<string[]> {
|
|||||||
export async function doesFileExist(file: string): Promise<boolean> {
|
export async function doesFileExist(file: string): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
await fs.stat(file);
|
await fs.stat(file);
|
||||||
} catch (err) {
|
} catch (err: any) {
|
||||||
if (err.code === 'ENOENT') {
|
if (err?.code === 'ENOENT') {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
throw err;
|
throw err;
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
const setRoutes = Routing.R.setRoutes;
|
const setRoutes = Routing.R.setRoutes;
|
||||||
const setPublicUrl = Routing.R.setPublicUrl;
|
const setPublicUrl = Routing.R.setPublicUrl;
|
||||||
import * as stores from '/js/stores.js';
|
import * as stores from '/js/stores.js';
|
||||||
const localStore = stores.s.locals;
|
const localStore = stores.l;
|
||||||
|
|
||||||
const localMap = %locals%;
|
const localMap = %locals%;
|
||||||
localStore.set((key, args) => {
|
localStore.set((key, args) => {
|
||||||
|
@ -48,7 +48,7 @@ export default class MailComponent extends ApplicationComponent {
|
|||||||
try {
|
try {
|
||||||
await util.promisify(transporter.verify)();
|
await util.promisify(transporter.verify)();
|
||||||
this.transporter = transporter;
|
this.transporter = transporter;
|
||||||
} catch (e) {
|
} catch (e: any) {
|
||||||
throw new MailError('Connection to mail service unsuccessful.', e);
|
throw new MailError('Connection to mail service unsuccessful.', e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import cookie from "cookie";
|
|||||||
import cookieParser from "cookie-parser";
|
import cookieParser from "cookie-parser";
|
||||||
import {Express, Request} from "express";
|
import {Express, Request} from "express";
|
||||||
import {Session} from "express-session";
|
import {Session} from "express-session";
|
||||||
import WebSocket from "ws";
|
import {WebSocketServer} from "ws";
|
||||||
|
|
||||||
import Application from "../Application.js";
|
import Application from "../Application.js";
|
||||||
import ApplicationComponent from "../ApplicationComponent.js";
|
import ApplicationComponent from "../ApplicationComponent.js";
|
||||||
@ -14,7 +14,7 @@ import FrontendToolsComponent from "./FrontendToolsComponent.js";
|
|||||||
import RedisComponent from "./RedisComponent.js";
|
import RedisComponent from "./RedisComponent.js";
|
||||||
|
|
||||||
export default class WebSocketServerComponent extends ApplicationComponent {
|
export default class WebSocketServerComponent extends ApplicationComponent {
|
||||||
private wss?: WebSocket.Server;
|
private wss?: WebSocketServer;
|
||||||
|
|
||||||
public async init(): Promise<void> {
|
public async init(): Promise<void> {
|
||||||
const app = this.getApp();
|
const app = this.getApp();
|
||||||
@ -32,7 +32,7 @@ export default class WebSocketServerComponent extends ApplicationComponent {
|
|||||||
const app = this.getApp();
|
const app = this.getApp();
|
||||||
|
|
||||||
const listeners: { [p: string]: WebSocketListener<Application> } = app.getWebSocketListeners();
|
const listeners: { [p: string]: WebSocketListener<Application> } = app.getWebSocketListeners();
|
||||||
this.wss = new WebSocket.Server({
|
this.wss = new WebSocketServer({
|
||||||
server: app.as(ExpressAppComponent).getServer(),
|
server: app.as(ExpressAppComponent).getServer(),
|
||||||
}, () => {
|
}, () => {
|
||||||
logger.info(`Websocket server started over webserver.`);
|
logger.info(`Websocket server started over webserver.`);
|
||||||
|
@ -183,7 +183,7 @@ export default class MysqlConnectionManager {
|
|||||||
try {
|
try {
|
||||||
const result = await query('SELECT id FROM migrations ORDER BY id DESC LIMIT 1');
|
const result = await query('SELECT id FROM migrations ORDER BY id DESC LIMIT 1');
|
||||||
currentVersion = Number(result.results[0]?.id);
|
currentVersion = Number(result.results[0]?.id);
|
||||||
} catch (e) {
|
} catch (e: any) {
|
||||||
if (e.code === 'ECONNREFUSED' || e.code !== 'ER_NO_SUCH_TABLE') {
|
if (e.code === 'ECONNREFUSED' || e.code !== 'ER_NO_SUCH_TABLE') {
|
||||||
throw new Error('Cannot run migrations: ' + e.code);
|
throw new Error('Cannot run migrations: ' + e.code);
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ export default class Validator<V> {
|
|||||||
if (result instanceof Promise) {
|
if (result instanceof Promise) {
|
||||||
result = await result;
|
result = await result;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e: any) {
|
||||||
throw new ServerError(`An error occurred while validating ${thingName} with value "${value}".`, e);
|
throw new ServerError(`An error occurred while validating ${thingName} with value "${value}".`, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,13 @@ import TestApp from "./TestApp.js";
|
|||||||
|
|
||||||
const packageJson = JSON.parse((await fs.readFile('package.json')).toString());
|
const packageJson = JSON.parse((await fs.readFile('package.json')).toString());
|
||||||
|
|
||||||
const app = new TestApp(packageJson.version, config.get<string>('app.listen_addr'), config.get<number>('app.port'));
|
const app = new TestApp(
|
||||||
|
packageJson.version,
|
||||||
|
config.get<string>('app.listen_addr'),
|
||||||
|
config.get<number>('app.port'),
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
);
|
||||||
await app.start();
|
await app.start();
|
||||||
})().catch(err => {
|
})().catch(err => {
|
||||||
logger.error(err);
|
logger.error(err);
|
||||||
|
@ -8,7 +8,7 @@ export default class CreateMigrationsTable extends Migration {
|
|||||||
public async shouldRun(currentVersion: number): Promise<boolean> {
|
public async shouldRun(currentVersion: number): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
await query('SELECT 1 FROM migrations LIMIT 1');
|
await query('SELECT 1 FROM migrations LIMIT 1');
|
||||||
} catch (e) {
|
} catch (e: any) {
|
||||||
if (e.code !== 'ER_NO_SUCH_TABLE') {
|
if (e.code !== 'ER_NO_SUCH_TABLE') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ useApp(async (addr, port) => {
|
|||||||
|
|
||||||
await super.init();
|
await super.init();
|
||||||
}
|
}
|
||||||
}('test', addr, port, true);
|
}('test', addr, port, true, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Test CSRF protection', () => {
|
describe('Test CSRF protection', () => {
|
||||||
|
@ -8,7 +8,7 @@ import {setupMailServer, teardownMailServer} from "./_mail_server.js";
|
|||||||
export default function useApp<T extends TestApp>(appSupplier: AppSupplier<T>): () => T {
|
export default function useApp<T extends TestApp>(appSupplier: AppSupplier<T>): () => T {
|
||||||
let app: T;
|
let app: T;
|
||||||
|
|
||||||
beforeAll(async (done) => {
|
beforeAll(async () => {
|
||||||
await MysqlConnectionManager.prepare();
|
await MysqlConnectionManager.prepare();
|
||||||
await MysqlConnectionManager.query('DROP DATABASE IF EXISTS ' + config.get<string>('mysql.database'));
|
await MysqlConnectionManager.query('DROP DATABASE IF EXISTS ' + config.get<string>('mysql.database'));
|
||||||
await MysqlConnectionManager.endPool();
|
await MysqlConnectionManager.endPool();
|
||||||
@ -17,10 +17,9 @@ export default function useApp<T extends TestApp>(appSupplier: AppSupplier<T>):
|
|||||||
app = await appSupplier('127.0.0.1', 8966);
|
app = await appSupplier('127.0.0.1', 8966);
|
||||||
|
|
||||||
await app.start();
|
await app.start();
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async (done) => {
|
afterAll(async () => {
|
||||||
const errors = [];
|
const errors = [];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -36,7 +35,6 @@ export default function useApp<T extends TestApp>(appSupplier: AppSupplier<T>):
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (errors.length > 0) throw errors;
|
if (errors.length > 0) throw errors;
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return () => app;
|
return () => app;
|
||||||
|
@ -85,16 +85,12 @@ export function authAppProvider(withUsername: boolean = true, approvalMode: bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected getMigrations(): MigrationType<Migration>[] {
|
protected getMigrations(): MigrationType<Migration>[] {
|
||||||
let migrations = withUsername ?
|
const migrations = withUsername ?
|
||||||
super.getMigrations() :
|
super.getMigrations() :
|
||||||
super.getMigrations().filter(m => m !== AddNameToUsersMigration);
|
super.getMigrations().filter(m => m !== AddNameToUsersMigration);
|
||||||
|
|
||||||
migrations = approvalMode ?
|
|
||||||
[...migrations, AddApprovedFieldToUsersTableMigration] :
|
|
||||||
migrations;
|
|
||||||
|
|
||||||
return migrations;
|
return migrations;
|
||||||
}
|
}
|
||||||
}('test', addr, port, true);
|
}('test', addr, port, true, approvalMode);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user