/* |-------------------------------------------------------------------------- | 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)); });