hapijs / joi

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

Must run on Joi instance #3023

Closed mukhammadjon-s closed 3 months ago

mukhammadjon-s commented 4 months ago

Runtime

Node.js

Runtime version

Node.js 16

Module version

17.9.2

Used with

No response

Any other relevant information

No response

How can we help?

import * as Joi from Joi;

I have imported Joi like this in my node/typescript project. But SonarQube is complaining about this import like "Explicitly import the specific member needed."

I have used another approach.

import {object, string, boolean} from 'joi';

But when I am running tests. Tests are failing with following error "ust be invoked on a Joi instance."

How can I fix this issue so when I explicitly import from joi and not to have errors in tests

jifrivly commented 3 months ago

I have faced same issue with joi v17.12.1 in between migrating a node cjs project to esm. Tried different ways, explicit imports, destructuring assignment after import. but always getting this error.

node_modules\@hapi\hoek\lib\error.js:23 Error.captureStackTrace(this, exports.assert); ^ Error: Must be invoked on a Joi instance. at new module.exports (node_modules\@hapi\hoek\lib\error.js:23:19) at module.exports (node_modules\@hapi\hoek\lib\assert.js:21:11) at internals.generate (node_modules\joi\lib\index.js:249:5) at root. (node_modules\joi\lib\index.js:58:30) at file:///path/../userschema.js:6:11 at ModuleJob.run (node:internal/modules/esm/module_job:218:25) at async ModuleLoader.import (node:internal/modules/esm/loader:329:24) at async loadESM (node:internal/process/esm_loader:28:7) at async handleMainPromise (node:internal/modules/run_main:113:12) Node.js v20.11.0

This format helped me to get rid of the issue (not tested with sonarqube).

import Joi from 'joi';

export const userSchema = Joi.object({
    name: Joi.string().min(3).max(50).required(),
    username: Joi.string().min(3).max(30).required(),
    password: Joi.string().min(3).max(30).required(),
    role_id: Joi.number().required(),
    phone: Joi.string().allow(null, ''),
    id: Joi.number().allow(null, 0),
});
Marsup commented 3 months ago

That's indeed the correct way, joi types need to be bound to their instance (mainly because of extensions). If you want usable types, you can use this https://joi.dev/api/?v=17.12.2#types from the joi instance you want to use