Merge branch 'develop'
This commit is contained in:
commit
0ad9143282
@ -13,7 +13,7 @@ module.exports = {
|
|||||||
'./tsconfig.test.json',
|
'./tsconfig.test.json',
|
||||||
'./src/tsconfig.json',
|
'./src/tsconfig.json',
|
||||||
'./src/common/tsconfig.json',
|
'./src/common/tsconfig.json',
|
||||||
'./src/assets/ts/tsconfig.json',
|
'./src/assets/ts/tsconfig.eslint.json',
|
||||||
'./src/assets/views/tsconfig.json',
|
'./src/assets/views/tsconfig.json',
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "swaf",
|
"name": "swaf",
|
||||||
"version": "0.24.0",
|
"version": "0.24.1",
|
||||||
"description": "Structure Web Application Framework.",
|
"description": "Structure Web Application Framework.",
|
||||||
"repository": "https://eternae.ink/ashpie/swaf",
|
"repository": "https://eternae.ink/ashpie/swaf",
|
||||||
"author": "Alice Gaudon <alice@gaudon.pro>",
|
"author": "Alice Gaudon <alice@gaudon.pro>",
|
||||||
|
@ -23,9 +23,9 @@ export default abstract class FileUploadMiddleware extends Middleware {
|
|||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} catch (e: any) {
|
} catch (e) {
|
||||||
const bag = new ValidationBag();
|
const bag = new ValidationBag();
|
||||||
const fileError = new FileError(e);
|
const fileError = new FileError(String(e));
|
||||||
fileError.thingName = this.getDefaultField();
|
fileError.thingName = this.getDefaultField();
|
||||||
bag.addMessage(fileError);
|
bag.addMessage(fileError);
|
||||||
next(bag);
|
next(bag);
|
||||||
|
23
src/Utils.ts
23
src/Utils.ts
@ -1,4 +1,4 @@
|
|||||||
import {promises as fs} from "fs";
|
import fs, {promises as afs} from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
|
||||||
export async function sleep(ms: number): Promise<void> {
|
export async function sleep(ms: number): Promise<void> {
|
||||||
@ -49,10 +49,10 @@ export function getMethods<T extends { [p: string]: unknown }>(obj: T): string[]
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function listFilesRecursively(dir: string): Promise<string[]> {
|
export async function listFilesRecursively(dir: string): Promise<string[]> {
|
||||||
const localFiles = await fs.readdir(dir);
|
const localFiles = await afs.readdir(dir);
|
||||||
const files: string[] = [];
|
const files: string[] = [];
|
||||||
for (const file of localFiles.map(file => path.join(dir, file))) {
|
for (const file of localFiles.map(file => path.join(dir, file))) {
|
||||||
const stat = await fs.stat(file);
|
const stat = await afs.stat(file);
|
||||||
|
|
||||||
if (stat.isDirectory()) {
|
if (stat.isDirectory()) {
|
||||||
files.push(...await listFilesRecursively(file));
|
files.push(...await listFilesRecursively(file));
|
||||||
@ -65,14 +65,17 @@ 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 {
|
return await new Promise<boolean>((resolve, reject) => {
|
||||||
await fs.stat(file);
|
fs.stat(file, err => {
|
||||||
} catch (err: any) {
|
if (err) {
|
||||||
if (err?.code === 'ENOENT') {
|
if (err.code === 'ENOENT') {
|
||||||
return false;
|
return resolve(false);
|
||||||
} else {
|
} else {
|
||||||
throw err;
|
return reject(err);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return resolve(true);
|
||||||
}
|
}
|
||||||
return true;
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import feather from "feather-icons";
|
|||||||
|
|
||||||
let alreadyReplaced = false;
|
let alreadyReplaced = false;
|
||||||
|
|
||||||
export function replaceIcons(once: boolean = true) {
|
export function replaceIcons(once: boolean = true): void {
|
||||||
if (!once || !alreadyReplaced) {
|
if (!once || !alreadyReplaced) {
|
||||||
alreadyReplaced = true;
|
alreadyReplaced = true;
|
||||||
feather.replace();
|
feather.replace();
|
||||||
|
6
src/assets/ts/tsconfig.eslint.json
Normal file
6
src/assets/ts/tsconfig.eslint.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"include": [
|
||||||
|
"./**/*"
|
||||||
|
]
|
||||||
|
}
|
@ -1,14 +0,0 @@
|
|||||||
import Migration from "../../db/Migration.js";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated - TODO may be remove at next major version >= 0.24, replace with DummyMigration.
|
|
||||||
*/
|
|
||||||
export default class DropNameFromUsers extends Migration {
|
|
||||||
public async install(): Promise<void> {
|
|
||||||
await this.query('ALTER TABLE users DROP COLUMN IF EXISTS name');
|
|
||||||
}
|
|
||||||
|
|
||||||
public async rollback(): Promise<void> {
|
|
||||||
await this.query('ALTER TABLE users ADD COLUMN name VARCHAR(64)');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
import Migration from "../../db/Migration.js";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated - TODO may be remove at next major version >= 0.24, replace with DummyMigration.
|
|
||||||
*/
|
|
||||||
export default class FixUserMainEmailRelation extends Migration {
|
|
||||||
public async install(): Promise<void> {
|
|
||||||
await this.query(`ALTER TABLE users
|
|
||||||
ADD COLUMN main_email_id INT,
|
|
||||||
ADD FOREIGN KEY main_user_email_fk (main_email_id) REFERENCES user_emails (id)`);
|
|
||||||
await this.query(`UPDATE users u LEFT JOIN user_emails ue ON u.id = ue.user_id
|
|
||||||
SET u.main_email_id=ue.id
|
|
||||||
WHERE ue.main = true`);
|
|
||||||
await this.query(`ALTER TABLE user_emails
|
|
||||||
DROP COLUMN main`);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async rollback(): Promise<void> {
|
|
||||||
await this.query(`ALTER TABLE user_emails
|
|
||||||
ADD COLUMN main BOOLEAN DEFAULT false`);
|
|
||||||
await this.query(`UPDATE user_emails ue LEFT JOIN users u ON ue.id = u.main_email_id
|
|
||||||
SET ue.main = true`);
|
|
||||||
await this.query(`ALTER TABLE users
|
|
||||||
DROP FOREIGN KEY main_user_email_fk,
|
|
||||||
DROP COLUMN main_email_id`);
|
|
||||||
}
|
|
||||||
}
|
|
@ -48,8 +48,12 @@ 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: any) {
|
} catch (e) {
|
||||||
|
if (e instanceof Error) {
|
||||||
throw new MailError('Connection to mail service unsuccessful.', e);
|
throw new MailError('Connection to mail service unsuccessful.', e);
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(`Mail ready to be distributed via ${config.get('mail.host')}:${config.get('mail.port')}`);
|
logger.info(`Mail ready to be distributed via ${config.get('mail.host')}:${config.get('mail.port')}`);
|
||||||
|
@ -183,9 +183,14 @@ 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: any) {
|
} catch (e) {
|
||||||
if (e.code === 'ECONNREFUSED' || e.code !== 'ER_NO_SUCH_TABLE') {
|
if (e instanceof Error) {
|
||||||
throw new Error('Cannot run migrations: ' + e.code);
|
const mysqlError = e as MysqlError;
|
||||||
|
if (mysqlError.code !== 'ER_NO_SUCH_TABLE') {
|
||||||
|
throw new Error('Cannot run migrations: ' + mysqlError.code);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,8 +61,12 @@ export default class Validator<V> {
|
|||||||
if (result instanceof Promise) {
|
if (result instanceof Promise) {
|
||||||
result = await result;
|
result = await result;
|
||||||
}
|
}
|
||||||
} catch (e: any) {
|
} catch (e) {
|
||||||
|
if (e instanceof Error) {
|
||||||
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);
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result === false && step.throw) {
|
if (result === false && step.throw) {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import {MysqlError} from "mysql";
|
||||||
|
|
||||||
import Migration from "../db/Migration.js";
|
import Migration from "../db/Migration.js";
|
||||||
import {query} from "../db/MysqlConnectionManager.js";
|
import {query} from "../db/MysqlConnectionManager.js";
|
||||||
|
|
||||||
@ -8,8 +10,8 @@ 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: any) {
|
} catch (e) {
|
||||||
if (e.code !== 'ER_NO_SUCH_TABLE') {
|
if (!(e instanceof Error) || (e as MysqlError).code !== 'ER_NO_SUCH_TABLE') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user