Skip to content

Commit

Permalink
feat(validator: add Validator facade
Browse files Browse the repository at this point in the history
  • Loading branch information
jlenon7 committed May 8, 2024
1 parent 87286aa commit 5a7f8c1
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 45 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@
"athenna": {
"services": [
"#src/helpers/queue",
"#src/helpers/validator",
"#src/services/user.service",
"#src/services/auth.service"
],
Expand Down
27 changes: 27 additions & 0 deletions src/helpers/validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Service } from '@athenna/ioc'

Check failure on line 1 in src/helpers/validator.ts

View workflow job for this annotation

GitHub Actions / linux (21.x)

Argument of type 'string' is not assignable to parameter of type 'keyof VineString'.
import vine, { VineString } from '@vinejs/vine'
import type { FieldContext } from '@vinejs/vine/types'

@Service({ alias: 'App/Helpers/Validator' })
export class ValidatorImpl {
public schema() {
return vine
}

public extend(
name: string,
handler: (
value: unknown,
options: any,
field: FieldContext
) => any | Promise<any>
) {
const rule = vine.createRule(handler)

VineString.macro(name, function (this: VineString, options: any) {
return this.use(rule(options))
})

return this
}
}
6 changes: 6 additions & 0 deletions src/providers/facades/validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Facade } from '@athenna/ioc'
import type { ValidatorImpl } from '#src/helpers/validator'

export const Validator = Facade.createFor<ValidatorImpl>(
'App/Helpers/Validator'
)
61 changes: 26 additions & 35 deletions src/providers/validator.provider.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Is } from '@athenna/common'
import { Database } from '@athenna/database'
import { ServiceProvider } from '@athenna/ioc'
import { SimpleErrorReporter } from '@vinejs/vine'
import type { FieldContext } from '@vinejs/vine/types'
import vine, { SimpleErrorReporter, VineString } from '@vinejs/vine'
import { Validator } from '#src/providers/facades/validator'
import { ValidationException } from '#src/exceptions/validation.exception'

type UniqueOptions = {
Expand All @@ -24,43 +25,33 @@ export class ErrorReporter extends SimpleErrorReporter {

export default class ValidatorProvider extends ServiceProvider {
public async boot() {
vine.errorReporter = () => new ErrorReporter()
Validator.schema().errorReporter = () => new ErrorReporter()

const uniqueRule = vine.createRule(this.unique)

VineString.macro(
Validator.extend(
'unique',
function (this: VineString, options: UniqueOptions) {
return this.use(uniqueRule(options))
async (value: unknown, options: UniqueOptions, field: FieldContext) => {
/**
* We do not want to deal with non-string
* values. The "string" rule will handle the
* the validation.
*/
if (!Is.String(value)) {
return
}

if (!options.column) {
options.column = field.name as string
}

const existsRow = await Database.table(options.table)
.select(options.column)
.where(options.column, value)
.exists()

if (existsRow) {
field.report('The {{ field }} field is not unique', 'unique', field)
}
}
)
}

public async unique(
value: unknown,
options: UniqueOptions,
field: FieldContext
) {
/**
* We do not want to deal with non-string
* values. The "string" rule will handle the
* the validation.
*/
if (!Is.String(value)) {
return
}

if (!options.column) {
options.column = field.name as string
}

const existsRow = await Database.table(options.table)
.select(options.column)
.where(options.column, value)
.exists()

if (existsRow) {
field.report('The {{ field }} field is not unique', 'unique', field)
}
}
}
4 changes: 2 additions & 2 deletions src/validators/base.validator.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import vine, { type Vine } from '@vinejs/vine'
import type { SchemaTypes } from '@vinejs/vine/types'
import { Validator } from '#src/providers/facades/validator'

export abstract class BaseValidator {
protected validator: Vine = vine
public validator = Validator.schema()

public abstract schema: SchemaTypes
public abstract handle(data: any): Promise<void>
Expand Down
9 changes: 1 addition & 8 deletions storage/queues.json
Original file line number Diff line number Diff line change
@@ -1,8 +1 @@
{
"default": [],
"deadletter": [],
"user:email": [],
"user:password": [],
"user:email:password": [],
"user:confirm": []
}
{"default":[],"deadletter":[],"user:email":[],"user:password":[{"user":{"name":"João Lenon","email":"[email protected]"},"password":"$2b$10$gTXEZsXmkLJhOvvge3t/IO99RUw1AD6NmddfQ3mPByHweP3hWJdoO"}],"user:email:password":[],"user:confirm":[]}

0 comments on commit 5a7f8c1

Please sign in to comment.