- replaced validation library @adonisjs/validator with @vinejs/vine (performance)
Some checks failed
CI Pipeline / japa-tests (push) Failing after 56s
Some checks failed
CI Pipeline / japa-tests (push) Failing after 56s
- npm updates
This commit is contained in:
parent
08c2edca3b
commit
ec17d79cf2
32 changed files with 1677 additions and 1670 deletions
|
@ -24,7 +24,8 @@ import router from '@adonisjs/core/services/router';
|
|||
import type { HttpContext } from '@adonisjs/core/http';
|
||||
|
||||
// import Inertia from '@ioc:EidelLev/Inertia';
|
||||
import AuthValidator from '#validators/auth_validator';
|
||||
// import AuthValidator from '#validators/auth_validator';
|
||||
import { authValidator } from '#validators/auth';
|
||||
// import HealthCheck from '@ioc:Adonis/Core/HealthCheck';
|
||||
import User from '#models/user';
|
||||
import AuthController from '#controllers/Http/Auth/AuthController';
|
||||
|
@ -101,7 +102,7 @@ router.group(() => {
|
|||
registerBody: request.body(),
|
||||
});
|
||||
|
||||
const data = await request.validate(AuthValidator);
|
||||
const data = await request.validateUsing(authValidator);
|
||||
console.log({ data });
|
||||
|
||||
return response.redirect().toRoute('app.index');
|
||||
|
@ -140,10 +141,10 @@ router.group(() => {
|
|||
.as('user.update')
|
||||
.where('id', router.matchers.number())
|
||||
.use(middleware.can(['user-edit']));
|
||||
// // Route.delete('/user/:id', [AdminuserController, 'destroy'])
|
||||
// // .as('user.destroy')
|
||||
// // .where('id', Route.matchers.number())
|
||||
// // .use(middleware.can(['user-delete']));
|
||||
router.delete('/user/:id', [AdminuserController, 'destroy'])
|
||||
.as('user.destroy')
|
||||
.where('id', router.matchers.number())
|
||||
.use(middleware.can(['user-delete']));
|
||||
// // Route.resource('user', 'AdminuserController');
|
||||
|
||||
router.get('/role', [RoleController, 'index']).as('role.index').use(middleware.can(['user-list']));
|
||||
|
|
48
start/rules/translated_language.ts
Normal file
48
start/rules/translated_language.ts
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Preloaded File - node ace make:preload rules/translatedLanguage
|
||||
|--------------------------------------------------------------------------
|
||||
|*/
|
||||
|
||||
import { FieldContext } from '@vinejs/vine/types';
|
||||
import vine from '@vinejs/vine';
|
||||
import { VineString } from '@vinejs/vine';
|
||||
|
||||
/**
|
||||
* Options accepted by the unique rule
|
||||
*/
|
||||
type Options = {
|
||||
mainLanguageField: string;
|
||||
typeField: string;
|
||||
};
|
||||
|
||||
async function translatedLanguage(value: unknown, options: Options, field: FieldContext) {
|
||||
if (typeof value !== 'string' && typeof value != 'number') {
|
||||
return;
|
||||
}
|
||||
|
||||
// const type = validator.helpers.getFieldValue(typeField, root, tip); //'type' = 'Translated'
|
||||
const typeValue = vine.helpers.getNestedValue(options.typeField, field); //'Main' or 'Translated'
|
||||
|
||||
// const mainLanguage = validator.helpers.getFieldValue(mainLanguageField, root, tip);
|
||||
const mainLanguage = field.data[options.mainLanguageField]; // 'en' or 'de'
|
||||
|
||||
if (typeValue === 'Translated') {
|
||||
if (value === mainLanguage) {
|
||||
// report thattranlated language field is same as main language field of dataset
|
||||
field.report('The tranlated {{ field }} hast the same language seted as dataset language', 'translatedLanguage', field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const translatedLanguageRule = vine.createRule(translatedLanguage);
|
||||
|
||||
declare module '@vinejs/vine' {
|
||||
interface VineString {
|
||||
translatedLanguage(options: Options): this;
|
||||
}
|
||||
}
|
||||
|
||||
VineString.macro('translatedLanguage', function (this: VineString, options: Options) {
|
||||
return this.use(translatedLanguageRule(options));
|
||||
});
|
60
start/rules/unique.ts
Normal file
60
start/rules/unique.ts
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Preloaded File - node ace make:preload rules/unique
|
||||
|--------------------------------------------------------------------------
|
||||
|*/
|
||||
|
||||
import { FieldContext } from '@vinejs/vine/types';
|
||||
import db from '@adonisjs/lucid/services/db';
|
||||
import vine from '@vinejs/vine';
|
||||
import { VineString, VineNumber } from '@vinejs/vine';
|
||||
|
||||
/**
|
||||
* Options accepted by the unique rule
|
||||
*/
|
||||
type Options = {
|
||||
table: string;
|
||||
column: string;
|
||||
whereNot?: ((field: FieldContext) => string);
|
||||
};
|
||||
|
||||
async function isUnique(value: unknown, options: Options, field: FieldContext) {
|
||||
if (typeof value !== 'string' && typeof value != 'number') {
|
||||
return;
|
||||
}
|
||||
|
||||
let ignoreId: string | undefined;
|
||||
if (options.whereNot) {
|
||||
ignoreId = options.whereNot(field);
|
||||
}
|
||||
|
||||
const builder = db.from(options.table).select(options.column).where(options.column, value);
|
||||
if (ignoreId) {
|
||||
builder.whereNot('id', '=', ignoreId);
|
||||
}
|
||||
const result = await builder.first();
|
||||
if (result) {
|
||||
// report that value is NOT unique
|
||||
field.report('The {{ field }} field is not unique', 'isUnique', field);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export const isUniqueRule = vine.createRule(isUnique);
|
||||
|
||||
|
||||
declare module '@vinejs/vine' {
|
||||
interface VineString {
|
||||
isUnique(options: Options): this;
|
||||
}
|
||||
interface VineNumber {
|
||||
isUnique(options: Options): this;
|
||||
}
|
||||
}
|
||||
|
||||
VineString.macro('isUnique', function (this: VineString, options: Options) {
|
||||
return this.use(isUniqueRule(options));
|
||||
});
|
||||
VineNumber.macro('isUnique', function (this: VineNumber, options: Options) {
|
||||
return this.use(isUniqueRule(options));
|
||||
});
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Preloaded File
|
||||
| Preloaded File - node ace make:preload validator
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Any code written inside this file will be executed during the application
|
||||
|
@ -8,133 +8,71 @@
|
|||
https://issuehunt.io/r/adonisjs/validator/issues/84
|
||||
|
|
||||
*/
|
||||
// import { string } from '@ioc:Adonis/Core/Helpers';
|
||||
import { validator } from '@adonisjs/validator';
|
||||
import vine from '@vinejs/vine';
|
||||
// import { FieldContext } from '@vinejs/vine/types';
|
||||
// import db from '@adonisjs/lucid/services/db';
|
||||
import { VanillaErrorReporter } from '#validators/vanilla_error_reporter';
|
||||
// import { SimpleErrorReporter } from '@vinejs/vine';
|
||||
|
||||
validator.rule('uniqueArray', (dataArray, [field], { pointer, arrayExpressionPointer, errorReporter }) => {
|
||||
const array = dataArray; //validator.helpers.getFieldValue(data, field, tip);
|
||||
|
||||
if (!Array.isArray(array)) {
|
||||
throw new Error(`The ${pointer} must be an array.`);
|
||||
}
|
||||
|
||||
const uniqueValues = new Set();
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const item = array[i];
|
||||
const attributeValue = item[field]; // Extract the attribute value for uniqueness check
|
||||
// vine.messagesProvider = new SimpleMessagesProvider({
|
||||
// // Applicable for all fields
|
||||
// 'required': 'The {{ field }} field is required',
|
||||
// 'string': 'The value of {{ field }} field must be a string',
|
||||
// 'email': 'The value is not a valid email address',
|
||||
|
||||
// // 'contacts.0.email.required': 'The primary email of the contact is required',
|
||||
// // 'contacts.*.email.required': 'Contact email is required',
|
||||
// 'permissions.minLength': 'at least {{ options.minLength }} permission must be defined',
|
||||
// 'permissions.*.number': 'Define permissions as valid numbers',
|
||||
// })
|
||||
vine.errorReporter = () => new VanillaErrorReporter();
|
||||
|
||||
|
||||
if (uniqueValues.has(attributeValue)) {
|
||||
// throw new Error(`The ${field} array contains duplicate values for the ${field} attribute.`)
|
||||
errorReporter.report(
|
||||
pointer,
|
||||
'uniqueArray', // Keep an eye on this
|
||||
`The ${pointer} array contains duplicate values for the ${field} attribute.`,
|
||||
arrayExpressionPointer,
|
||||
{ field, array: pointer },
|
||||
);
|
||||
return;
|
||||
}
|
||||
// /**
|
||||
// * Options accepted by the unique rule
|
||||
// */
|
||||
// type Options = {
|
||||
// table: string;
|
||||
// column: string;
|
||||
// };
|
||||
|
||||
uniqueValues.add(attributeValue);
|
||||
}
|
||||
});
|
||||
// /**
|
||||
// * Implementation
|
||||
// */
|
||||
// async function unique(value: unknown, options: Options, field: FieldContext) {
|
||||
// /**
|
||||
// * We do not want to deal with non-string
|
||||
// * values. The "string" rule will handle the
|
||||
// * the validation.
|
||||
// */
|
||||
// if (typeof value !== 'string') {
|
||||
// return;
|
||||
// }
|
||||
|
||||
validator.rule(
|
||||
'translatedLanguage',
|
||||
(value, [mainLanguageField, typeField], { root, tip, pointer, arrayExpressionPointer, errorReporter }) => {
|
||||
if (typeof value !== 'string') {
|
||||
return;
|
||||
}
|
||||
// const fieldValue = validator. getValue(data, field)
|
||||
// this should return the "category_id" value present in "root", but i got undefined
|
||||
const mainLanguage = validator.helpers.getFieldValue(mainLanguageField, root, tip);
|
||||
const type = validator.helpers.getFieldValue(typeField, root, tip);
|
||||
// const builder = await db
|
||||
// .from(options.table)
|
||||
// .select(options.column)
|
||||
// .where(options.column, value).first();
|
||||
// const row = await builder.first();
|
||||
|
||||
if (type && type === 'Translated') {
|
||||
if (value === mainLanguage) {
|
||||
errorReporter.report(
|
||||
pointer,
|
||||
'translatedLanguage', // Keep an eye on this
|
||||
'translatedLanguage validation failed',
|
||||
arrayExpressionPointer,
|
||||
{ mainLanguage },
|
||||
);
|
||||
}
|
||||
}
|
||||
// if (row) {
|
||||
// field.report('The {{ field }} field is not unique', 'unique', field);
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (value !== string.camelCase(value)) {
|
||||
// options.errorReporter.report(
|
||||
// options.pointer,
|
||||
// 'camelCase',
|
||||
// 'camelCase validation failed',
|
||||
// options.arrayExpressionPointer
|
||||
// );
|
||||
// }
|
||||
},
|
||||
);
|
||||
// /**
|
||||
// * Converting a function to a VineJS rule
|
||||
// */
|
||||
// export const uniqueRule = vine.createRule(unique);
|
||||
|
||||
validator.rule('fileExtension', async (value, [extensions], { pointer, arrayExpressionPointer, errorReporter }) => {
|
||||
const allowedExtensions = extensions.map((ext: string) => ext.toLowerCase());
|
||||
const uploadedFile = value;
|
||||
|
||||
if (!uploadedFile) {
|
||||
return;
|
||||
}
|
||||
|
||||
const extension = uploadedFile.extname.toLowerCase().replace('.', '');
|
||||
|
||||
if (!allowedExtensions.includes(extension)) {
|
||||
errorReporter.report(
|
||||
pointer,
|
||||
'fileExtension',
|
||||
'Invalid file extension. Only {{ extensions }} files are allowed.',
|
||||
arrayExpressionPointer,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// validator.rule(
|
||||
// 'clamavScan',
|
||||
// (value, [field], { root, tip, pointer, arrayExpressionPointer, errorReporter }) => {
|
||||
// if (typeof value !== 'object') {
|
||||
// return;
|
||||
// }
|
||||
// const uploadedFile = validator.helpers.getFieldValue(field, root, tip);
|
||||
// // return rules.file({}, [
|
||||
// // async (file) => {
|
||||
// // const clamdhost = process.env['CLAMD_HOST'] ?? '127.0.0.1';
|
||||
// // const clamdport = Number(process.env['CLAMD_PORT']) ?? '3310';
|
||||
// // try {
|
||||
// // var isInfected = await scanFileForViruses(file.tmpPath, clamdhost, clamdport);
|
||||
// // } catch (error) {
|
||||
// // throw new Error(`${pointer}: ${error.message}`);
|
||||
// // }
|
||||
// // },
|
||||
// // ]);
|
||||
// VineString.macro('unique', function (this: VineString, options: Options) {
|
||||
// return this.use(uniqueRule(options));
|
||||
// });
|
||||
|
||||
// async function scanFileForViruses(filePath, host, port): Promise<boolean> {
|
||||
// // const clamscan = await (new ClamScan().init());
|
||||
// const opts: ClamScan.Options = {
|
||||
// preference: 'clamdscan',
|
||||
// clamdscan: {
|
||||
// active: true,
|
||||
// host,
|
||||
// port,
|
||||
// multiscan: true,
|
||||
// },
|
||||
// };
|
||||
// const clamscan = await new ClamScan().init(opts);
|
||||
|
||||
// return new Promise((resolve, reject) => {
|
||||
// clamscan.isInfected(filePath, (err, file, isInfected: boolean) => {
|
||||
// if (err) {
|
||||
// reject(err);
|
||||
// } else if (isInfected) {
|
||||
// reject(new Error(`File ${file} is infected!`));
|
||||
// } else {
|
||||
// resolve(isInfected);
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
// // declare module '@vinejs/vine' {
|
||||
// // interface VineString {
|
||||
// // unique(options: Options): this;
|
||||
// // }
|
||||
// // }
|
||||
|
|
140
start/validator_old.ts
Normal file
140
start/validator_old.ts
Normal file
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Preloaded File
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Any code written inside this file will be executed during the application
|
||||
| boot.
|
||||
https://issuehunt.io/r/adonisjs/validator/issues/84
|
||||
|
|
||||
*/
|
||||
// import { string } from '@ioc:Adonis/Core/Helpers';
|
||||
import { validator } from '@adonisjs/validator';
|
||||
|
||||
validator.rule('uniqueArray', (dataArray, [field], { pointer, arrayExpressionPointer, errorReporter }) => {
|
||||
const array = dataArray; //validator.helpers.getFieldValue(data, field, tip);
|
||||
|
||||
if (!Array.isArray(array)) {
|
||||
throw new Error(`The ${pointer} must be an array.`);
|
||||
}
|
||||
|
||||
const uniqueValues = new Set();
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const item = array[i];
|
||||
const attributeValue = item[field]; // Extract the attribute value for uniqueness check
|
||||
|
||||
if (uniqueValues.has(attributeValue)) {
|
||||
// throw new Error(`The ${field} array contains duplicate values for the ${field} attribute.`)
|
||||
errorReporter.report(
|
||||
pointer,
|
||||
'uniqueArray', // Keep an eye on this
|
||||
`The ${pointer} array contains duplicate values for the ${field} attribute.`,
|
||||
arrayExpressionPointer,
|
||||
{ field, array: pointer },
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
uniqueValues.add(attributeValue);
|
||||
}
|
||||
});
|
||||
|
||||
validator.rule(
|
||||
'translatedLanguage',
|
||||
(value, [mainLanguageField, typeField], { root, tip, pointer, arrayExpressionPointer, errorReporter }) => {
|
||||
if (typeof value !== 'string') {
|
||||
return;
|
||||
}
|
||||
// const fieldValue = validator. getValue(data, field)
|
||||
// this should return the "category_id" value present in "root", but i got undefined
|
||||
const mainLanguage = validator.helpers.getFieldValue(mainLanguageField, root, tip);
|
||||
const type = validator.helpers.getFieldValue(typeField, root, tip);
|
||||
|
||||
if (type && type === 'Translated') {
|
||||
if (value === mainLanguage) {
|
||||
errorReporter.report(
|
||||
pointer,
|
||||
'translatedLanguage', // Keep an eye on this
|
||||
'translatedLanguage validation failed',
|
||||
arrayExpressionPointer,
|
||||
{ mainLanguage },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// if (value !== string.camelCase(value)) {
|
||||
// options.errorReporter.report(
|
||||
// options.pointer,
|
||||
// 'camelCase',
|
||||
// 'camelCase validation failed',
|
||||
// options.arrayExpressionPointer
|
||||
// );
|
||||
// }
|
||||
},
|
||||
);
|
||||
|
||||
validator.rule('fileExtension', async (value, [extensions], { pointer, arrayExpressionPointer, errorReporter }) => {
|
||||
const allowedExtensions = extensions.map((ext: string) => ext.toLowerCase());
|
||||
const uploadedFile = value;
|
||||
|
||||
if (!uploadedFile) {
|
||||
return;
|
||||
}
|
||||
|
||||
const extension = uploadedFile.extname.toLowerCase().replace('.', '');
|
||||
|
||||
if (!allowedExtensions.includes(extension)) {
|
||||
errorReporter.report(
|
||||
pointer,
|
||||
'fileExtension',
|
||||
'Invalid file extension. Only {{ extensions }} files are allowed.',
|
||||
arrayExpressionPointer,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// validator.rule(
|
||||
// 'clamavScan',
|
||||
// (value, [field], { root, tip, pointer, arrayExpressionPointer, errorReporter }) => {
|
||||
// if (typeof value !== 'object') {
|
||||
// return;
|
||||
// }
|
||||
// const uploadedFile = validator.helpers.getFieldValue(field, root, tip);
|
||||
// // return rules.file({}, [
|
||||
// // async (file) => {
|
||||
// // const clamdhost = process.env['CLAMD_HOST'] ?? '127.0.0.1';
|
||||
// // const clamdport = Number(process.env['CLAMD_PORT']) ?? '3310';
|
||||
// // try {
|
||||
// // var isInfected = await scanFileForViruses(file.tmpPath, clamdhost, clamdport);
|
||||
// // } catch (error) {
|
||||
// // throw new Error(`${pointer}: ${error.message}`);
|
||||
// // }
|
||||
// // },
|
||||
// // ]);
|
||||
// });
|
||||
|
||||
// async function scanFileForViruses(filePath, host, port): Promise<boolean> {
|
||||
// // const clamscan = await (new ClamScan().init());
|
||||
// const opts: ClamScan.Options = {
|
||||
// preference: 'clamdscan',
|
||||
// clamdscan: {
|
||||
// active: true,
|
||||
// host,
|
||||
// port,
|
||||
// multiscan: true,
|
||||
// },
|
||||
// };
|
||||
// const clamscan = await new ClamScan().init(opts);
|
||||
|
||||
// return new Promise((resolve, reject) => {
|
||||
// clamscan.isInfected(filePath, (err, file, isInfected: boolean) => {
|
||||
// if (err) {
|
||||
// reject(err);
|
||||
// } else if (isInfected) {
|
||||
// reject(new Error(`File ${file} is infected!`));
|
||||
// } else {
|
||||
// resolve(isInfected);
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// }
|
Loading…
Add table
editor.link_modal.header
Reference in a new issue