This commit is contained in:
parent
f828ca4491
commit
cb51a4136f
167 changed files with 21485 additions and 21212 deletions
248
providers/validator_provider.ts
Normal file
248
providers/validator_provider.ts
Normal file
|
@ -0,0 +1,248 @@
|
|||
import type { ApplicationService } from '@adonisjs/core/types';
|
||||
import { validator } from '@adonisjs/validator';
|
||||
import { Request } from '@adonisjs/core/http';
|
||||
import { RequestNegotiator } from '@adonisjs/validator/types';
|
||||
// import { Rule } from '@adonisjs/validator/types';
|
||||
// import { VanillaErrorReporter } from '@adonisjs/validator/build/src/error_reporter/index.js';
|
||||
import db from '@adonisjs/lucid/services/db';
|
||||
|
||||
type Options = {
|
||||
table: string;
|
||||
column: string;
|
||||
whereNot?: { id: any };
|
||||
};
|
||||
declare module '@adonisjs/validator/types' {
|
||||
export interface Rules {
|
||||
translatedLanguage(mainLanguageField: string, typeField: string): Rule;
|
||||
uniqueArray(field: string): Rule;
|
||||
unique(args: Options): Rule;
|
||||
}
|
||||
}
|
||||
|
||||
export default class ValidatorProvider {
|
||||
constructor(protected app: ApplicationService) {}
|
||||
|
||||
/**
|
||||
* Register bindings to the container
|
||||
*/
|
||||
register() {}
|
||||
|
||||
/**
|
||||
* The container bindings have booted
|
||||
*/
|
||||
async boot() {
|
||||
// Add custom validation rules
|
||||
|
||||
// this.app.container.resolving('validator', (validator) => {
|
||||
// validator.rule('foo', () => {})
|
||||
// })
|
||||
|
||||
// validator.configure({
|
||||
// reporter: validator.reporters.vanilla,
|
||||
// });
|
||||
await this.configureValidator();
|
||||
|
||||
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(
|
||||
'unique',
|
||||
async (data, [{ table, column, whereNot }], { pointer, errorReporter, arrayExpressionPointer, field }) => {
|
||||
const value = data; // get(data, column);'admin'
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
let ignoreId: string | null = whereNot?.id;
|
||||
// let ignoreId: string | null = null;
|
||||
// const fields = args[1].split('/');
|
||||
// const table = args[0];
|
||||
// if (args[2]) {
|
||||
// ignoreId = args[2];
|
||||
// }
|
||||
const columnName = column || field;
|
||||
const builder = db.from(table).select(columnName).where(columnName, '=', value);
|
||||
if (ignoreId) {
|
||||
builder.whereNot('id', '=', ignoreId);
|
||||
}
|
||||
const row = await builder.first();
|
||||
|
||||
if (row) {
|
||||
// throw message;
|
||||
errorReporter.report(pointer, 'unique', 'Unique validation failed', arrayExpressionPointer, { field });
|
||||
}
|
||||
},
|
||||
() => ({
|
||||
async: true,
|
||||
}),
|
||||
);
|
||||
|
||||
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); //'type' = 'Translated'
|
||||
|
||||
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);
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the validator
|
||||
*/
|
||||
async configureValidator() {
|
||||
// const config = await this.app.container.make('config');
|
||||
validator.configure({
|
||||
reporter: validator.reporters.vanilla,
|
||||
// @ts-ignore
|
||||
negotiator: (callback: RequestNegotiator) => {
|
||||
this.getRequestReporter = callback;
|
||||
},
|
||||
});
|
||||
}
|
||||
getRequestReporter(request: Request) {
|
||||
// if (request.ajax()) {
|
||||
// return ErrorReporters.ApiErrorReporter;
|
||||
// }
|
||||
switch (request.accepts(['html', 'application/vnd.api+json', 'json'])) {
|
||||
case 'html':
|
||||
case null:
|
||||
return validator.reporters.vanilla;
|
||||
case 'json':
|
||||
return validator.reporters.api;
|
||||
case 'application/vnd.api+json':
|
||||
return validator.reporters.jsonapi;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The application has been booted
|
||||
*/
|
||||
async start() {}
|
||||
|
||||
/**
|
||||
* The process has been started
|
||||
*/
|
||||
async ready() {}
|
||||
|
||||
/**
|
||||
* Preparing to shutdown the app
|
||||
*/
|
||||
async shutdown() {}
|
||||
}
|
Loading…
Add table
editor.link_modal.header
Reference in a new issue