hapijs / joi

The most powerful data validation library for JS
Other
20.94k stars 1.51k forks source link

Joi any.external cannot use custom error message #3047

Open rainbowMeh opened 4 months ago

rainbowMeh commented 4 months ago

Runtime

node.js

Runtime version

v20.15.1

Module version

^17.13.3

Used with

No response

Any other relevant information

No response

How can we help?

I cannot use any of custom error message when using external to validate data

const schema = Joi.object({
    name: Joi.string().required(),
    entityId: Joi.number().required().external(async (value, helpers) => {
        let entityData = await Entity.findByPk(value);
        if (!entityData) {
            return helpers.error('any.invalid');
        }
    }),
});

await schema.validateAsync({
    name,
    entityId,
});

Here is Joi utils

const JoiLib = require("joi");

const IDJoiMessage = {
    "alternatives.all": "{#label} harus memenuhi semua alternatif",
    "alternatives.any": "{#label} harus memenuhi salah satu alternatif",
    "alternatives.match": "{#label} tidak cocok dengan pola yang diharapkan",
    "alternatives.one": "{#label} harus memenuhi hanya satu alternatif",
    "alternatives.types": "{#label} tidak sesuai dengan tipe yang diharapkan",
    "any.custom": "{#label} tidak valid berdasarkan validasi khusus",
    "any.default": "{#label} memiliki nilai default yang tidak valid",
    "any.failover": "{#label} tidak valid selama failover",
    "any.invalid": "{#label} tidak valid",
    "any.only": "{#label} hanya bisa berupa nilai yang diijinkan",
    "any.ref": "{#label} tidak valid sebagai referensi",
    "any.required": "{#label} wajib diisi",
    "any.unknown": "{#label} adalah nilai yang tidak dikenal",
    "array.base": "{#label} harus berupa array",
    "array.excludes": "{#label} berisi nilai yang dikecualikan",
    "array.includesRequiredBoth": "{#label} harus menyertakan elemen {#peers} yang diperlukan",
    "array.includesRequiredKnowns": "{#label} harus menyertakan elemen yang diketahui",
    "array.includesRequiredUnknowns": "{#label} harus menyertakan elemen yang tidak diketahui",
    "array.includes": "{#label} berisi nilai yang tidak diizinkan",
    "array.length": "{#label} harus memiliki panjang {#limit}",
    "array.max": "{#label} tidak boleh memiliki lebih dari {#limit} elemen",
    "array.min": "{#label} harus memiliki setidaknya {#limit} elemen",
    "array.orderedLength": "{#label} harus memiliki panjang tepat {#limit} elemen",
    "array.sort": "{#label} harus diurutkan",
    "array.sort.mismatching": "{#label} berisi tipe yang tidak cocok untuk pengurutan",
    "array.sort.unsupported": "{#label} berisi tipe yang tidak didukung untuk pengurutan",
    "array.sparse": "{#label} tidak boleh memiliki elemen kosong",
    "array.unique": "{#label} tidak boleh memiliki elemen duplikat",
    "array.hasKnown": "{#label} harus memiliki elemen yang diketahui",
    "array.hasUnknown": "{#label} harus memiliki elemen yang tidak diketahui",
    "binary.base": "{#label} harus berupa buffer atau string",
    "binary.length": "{#label} harus memiliki panjang {#limit}",
    "binary.max": "{#label} tidak boleh lebih panjang dari {#limit}",
    "binary.min": "{#label} harus setidaknya sepanjang {#limit}",
    "boolean.base": "{#label} harus berupa boolean",
    "date.base": "{#label} harus berupa tanggal yang valid",
    "date.format": "{#label} harus dalam format {#format}",
    "date.greater": "{#label} harus lebih besar dari {#limit}",
    "date.less": "{#label} harus kurang dari {#limit}",
    "date.max": "{#label} harus sebelum atau pada {#limit}",
    "date.min": "{#label} harus setelah atau pada {#limit}",
    "date.strict": "{#label} harus berupa tanggal yang valid dan tidak boleh berupa string atau format lain",
    "function.arity": "{#label} harus memiliki arity (jumlah parameter) {#n}",
    "function.class": "{#label} harus berupa kelas",
    "function.maxArity": "{#label} tidak boleh memiliki lebih dari {#n} parameter",
    "function.minArity": "{#label} harus memiliki setidaknya {#n} parameter",
    "number.base": "{#label} harus berupa angka",
    "number.greater": "{#label} harus lebih besar dari {#limit}",
    "number.infinity": "{#label} tidak boleh berupa infinity",
    "number.integer": "{#label} harus berupa bilangan bulat",
    "number.less": "{#label} harus kurang dari {#limit}",
    "number.max": "{#label} tidak boleh lebih besar dari {#limit}",
    "number.min": "{#label} tidak boleh kurang dari {#limit}",
    "number.multiple": "{#label} harus kelipatan dari {#multiple}",
    "number.negative": "{#label} harus berupa bilangan negatif",
    "number.port": "{#label} harus berupa port yang valid",
    "number.positive": "{#label} harus berupa bilangan positif",
    "number.precision": "{#label} tidak boleh memiliki lebih dari {#limit} angka desimal",
    "number.unsafe": "{#label} harus berupa angka yang aman",
    "object.unknown": "{#label} berisi properti yang tidak dikenal",
    "object.and": "{#label} harus berisi {#peers} bersama",
    "object.assert": "{#label} tidak memenuhi kondisi yang diperlukan",
    "object.base": "{#label} harus berupa objek",
    "object.length": "{#label} harus memiliki panjang {#limit}",
    "object.max": "{#label} tidak boleh memiliki lebih dari {#limit} properti",
    "object.min": "{#label} harus memiliki setidaknya {#limit} properti",
    "object.missing": "{#label} harus berisi setidaknya salah satu dari {#peers}",
    "object.nand": "{#label} tidak boleh memiliki {#peers}",
    "object.pattern.match": "{#label} tidak cocok dengan pola yang diharapkan",
    "object.refType": "{#label} harus berupa referensi yang valid",
    "object.regex": "{#label} harus berupa regex yang valid",
    "object.rename.multiple": "{#label} tidak boleh mengganti nama properti beberapa kali",
    "object.rename.override": "{#label} tidak boleh mengganti nama properti yang ada",
    "object.schema": "{#label} tidak valid berdasarkan schema",
    "object.instance": "{#label} harus merupakan instance dari {#type}",
    "object.with": "{#main} harus memiliki {#peer} bersama",
    "object.without": "{#label} tidak boleh memiliki {#peer} bersama",
    "object.xor": "{#label} tidak boleh memiliki {#peers} bersama",
    "object.oxor": "{#label} harus memiliki hanya satu dari {#peers}",
    "string.alphanum": "{#label} hanya boleh berisi karakter alfanumerik",
    "string.base64": "{#label} harus berupa string base64 yang valid",
    "string.base": "{#label} harus berupa string",
    "string.creditCard": "{#label} harus berupa kartu kredit yang valid",
    "string.dataUri": "{#label} harus berupa data URI yang valid",
    "string.domain": "{#label} harus berupa domain yang valid",
    "string.email": "{#label} harus berupa email yang valid",
    "string.empty": "{#label} tidak boleh kosong",
    "string.guid": "{#label} harus berupa GUID yang valid",
    "string.hexAlign": "{#label} harus berupa string hex yang valid dan sejajar",
    "string.hex": "{#label} harus berupa string hex yang valid",
    "string.hostname": "{#label} harus berupa hostname yang valid",
    "string.ipVersion": "{#label} harus berupa IP dengan versi {#version} yang valid",
    "string.ip": "{#label} harus berupa alamat IP yang valid",
    "string.isoDate": "{#label} harus berupa tanggal ISO yang valid",
    "string.isoDuration": "{#label} harus berupa durasi ISO yang valid",
    "string.length": "{#label} harus memiliki panjang {#limit}",
    "string.lowercase": "{#label} harus berupa huruf kecil",
    "string.max": "{#label} tidak boleh lebih panjang dari {#limit}",
    "string.min": "{#label} harus setidaknya sepanjang {#limit}",
    "string.normalize": "{#label} harus berupa string yang dinormalisasi",
    "string.pattern.base": "{#label} tidak cocok dengan pola yang diharapkan",
    "string.pattern.name": "{#label} tidak cocok dengan pola {#name} yang diharapkan",
    "string.pattern.invert.base": "{#label} tidak cocok dengan pola terbalik yang diharapkan",
    "string.pattern.invert.name": "{#label} tidak cocok dengan pola terbalik {#name} yang diharapkan",
    "string.token": "{#label} hanya boleh berisi karakter alfanumerik dan garis bawah",
    "string.trim": "{#label} tidak boleh memiliki spasi di awal atau akhir",
    "string.uppercase": "{#label} harus berupa huruf besar",
    "string.uri": "{#label} harus berupa URI yang valid",
    "string.uriCustomScheme": "{#label} harus sesuai dengan skema kustom URI {#scheme}",
    "string.uriRelativeOnly": "{#label} harus berupa URI relatif",
    "symbol.base": "{#label} harus berupa simbol yang valid",
    "symbol.map": "{#label} harus berupa peta simbol yang valid"
}

const joiMessage = {
    'en': {},
    'id': IDJoiMessage
}

const Joi = JoiLib.defaults(schema => {
    return schema.options({
        abortEarly: false,
        messages: joiMessage,
        errors: {
            language: 'id',
        }
    })
})

module.exports = {
    Joi,
    joiMessage
}

\ When the entity error, the error message is this "\"subIndustry\" contains an invalid value" \ How to use the custom error message?

Marsup commented 4 months ago

This is considered to be a validation option, not a schema option, so you should probably pass it to your validation calls instead of applying it to all your schemas.

rainbowMeh commented 4 months ago

Could you please give me an example how to do it? Cause I dont find any docs or article to input the intl message data into the validation option

Thank you !

Marsup commented 4 months ago

Just like you did, but in the validation options, not the schema:

await schema.validateAsync({ ... }, { messages: joiMessage, errors: { language: 'id' } })