{"_id":"@artyomguybov2002/joi-config-util","_rev":"2-0183224b5ece38e23cec3922c0099eb5","name":"@artyomguybov2002/joi-config-util","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@artyomguybov2002/joi-config-util","version":"1.0.0","_id":"@artyomguybov2002/joi-config-util@1.0.0","maintainers":[{"name":"artyomguybov2002","email":"artyomguybov2002@gmail.com"}],"dist":{"shasum":"4abc5059de0242cb6af6149aa668a2a40a787cfd","tarball":"https://registry.npmjs.org/@artyomguybov2002/joi-config-util/-/joi-config-util-1.0.0.tgz","fileCount":7,"integrity":"sha512-kyuhRAPYiUnOevtj2JenQkWMy+0Ayz7Cif6sVQpFQzc48LqU7NKb8B/623yGHiJiQXNlpwEsZxcxqXnawkZJiQ==","signatures":[{"sig":"MEQCIGzILS29EQEPT+aZ8uupjfZOsfI6GPQda5b+gAs3qs69AiBN1hOSanPju6G0aYRfr+xx4taOGNK2YJD0uceTYG0mGw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":4337},"main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc","prepublishOnly":"npm run build"},"_npmUser":{"name":"artyomguybov2002","email":"artyomguybov2002@gmail.com"},"_npmVersion":"10.9.0","description":"Type-safe Joi utility for validating configuration objects in Node.js.","directories":{},"_nodeVersion":"23.2.0","dependencies":{"joi":"^18.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.3"},"_npmOperationalInternal":{"tmp":"tmp/joi-config-util_1.0.0_1770623160700_0.08126352619922206","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@artyomguybov2002/joi-config-util","version":"1.0.1","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc","prepublishOnly":"npm run build"},"devDependencies":{"typescript":"^5.9.3"},"dependencies":{"joi":"^18.0.2"},"publishConfig":{"access":"public"},"_id":"@artyomguybov2002/joi-config-util@1.0.1","description":"A small, type-safe utility built on top of **Joi** to validate configuration objects (for example, environment variables) in Node.js and TypeScript projects.","_nodeVersion":"23.2.0","_npmVersion":"10.9.0","dist":{"integrity":"sha512-KPT6J2rXXVKEywXG4k5tnbX0HALFbw7jJ0Deh44odqeGxpLiD4E3MZBPmNjcuTnXg6RFqfVf7mToCqxHukgnCA==","shasum":"6b0c3166f11683dffc7949682e4246e4ab775e8d","tarball":"https://registry.npmjs.org/@artyomguybov2002/joi-config-util/-/joi-config-util-1.0.1.tgz","fileCount":6,"unpackedSize":10062,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIF0wvdJZECaSSNkfJ/4kkY2DdCLq3L5AAgoNHIX/EPzyAiEAg7sfHrpVAoGIYvXX2KGd6m4wDpWg74qjlqjNjdcdrv0="}]},"_npmUser":{"name":"artyomguybov2002","email":"artyomguybov2002@gmail.com"},"directories":{},"maintainers":[{"name":"artyomguybov2002","email":"artyomguybov2002@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/joi-config-util_1.0.1_1770745227768_0.590714167742546"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-09T07:46:00.528Z","modified":"2026-02-10T17:40:28.034Z","1.0.0":"2026-02-09T07:46:00.848Z","1.0.1":"2026-02-10T17:40:27.935Z"},"description":"A small, type-safe utility built on top of **Joi** to validate configuration objects (for example, environment variables) in Node.js and TypeScript projects.","maintainers":[{"name":"artyomguybov2002","email":"artyomguybov2002@gmail.com"}],"readme":"# Joi Config Util\n\nA small, type-safe utility built on top of **Joi** to validate configuration objects (for example, environment variables) in Node.js and TypeScript projects.\n\nThis package helps you:\n\n* avoid repetitive Joi schema code\n* validate configs in a structured, readable way\n* fail fast when required configuration is missing or invalid\n\n---\n\n## Installation\n\n```bash\nnpm install @artyom-gaibovich/joi-config-util\n\n```\n\n## Why this package?\n\nWhen working with environment variables or configuration objects, validation logic often becomes repetitive and messy.\n\n`joi-config-util` provides a clean pattern where:\n\n* each config key has a value and a Joi schema\n* validation happens once, at startup\n* the result is strongly typed\n\n---\n\n## Basic Usage\n\n### Example: validating environment variables\n\n```ts\nimport Joi from 'joi';\nimport { JoiUtil } from 'joi-config-util';\n\ninterface AppConfig {\n  PORT: number;\n  NODE_ENV: 'development' | 'production';\n}\n\nconst config = JoiUtil.validate<AppConfig>({\n  PORT: {\n    value: process.env.PORT,\n    joi: Joi.number().port().required(),\n  },\n  NODE_ENV: {\n    value: process.env.NODE_ENV,\n    joi: Joi.string()\n      .valid('development', 'production')\n      .required(),\n  },\n});\n\nconsole.log(config.PORT);      // number\nconsole.log(config.NODE_ENV);  // 'development' | 'production'\n```\n\nIf validation fails, the application throws an error immediately:\n\n```text\nValidation failed - Is there an environment variable missing?\n\"PORT\" must be a number\n```\n\n---\n\n## How it works\n\nEach configuration key is defined as an object with two properties:\n\n| Property | Description                                |\n| -------- | ------------------------------------------ |\n| `value`  | The actual value (e.g. from `process.env`) |\n| `joi`    | A Joi schema used to validate the value    |\n\nInternally, the utility:\n\n1. Builds a Joi schema object\n2. Extracts the raw values\n3. Validates everything at once\n4. Returns a fully typed config object\n\n---\n\n## API\n\n### `JoiUtil.validate<T>(config: JoiConfig<T>): T`\n\nValidates the provided configuration object.\n\n* **Returns**: validated config of type `T`\n* **Throws**: `Error` if validation fails\n\n---\n\n### `JoiConfig<T>`\n\n```ts\ntype JoiConfig<T> = Record<\n  keyof T,\n  {\n    value: unknown;\n    joi: Joi.Schema;\n  }\n>;\n```\n\n---\n\n## When to use this\n\nThis utility is especially useful for:\n\n* application bootstrap configuration\n* environment variable validation\n* shared configuration modules\n* monorepos with multiple services\n\n---\n\n## TypeScript support\n\nThis package is written in TypeScript and ships with full type definitions.\n\nNo additional configuration is required.\n\n\n## Best Practices\n\n### 1. Validate configuration at application startup\n\nAlways validate your configuration as early as possible (before creating servers, database connections, or background jobs).\n\n```ts\n// config.ts\nexport const config = JoiUtil.validate<AppConfig>({ ... });\n```\n\nIf validation fails, the application should crash immediately.\nFailing fast prevents hard-to-debug runtime errors later.\n\n---\n\n### 2. Keep all configuration in one place\n\nAvoid spreading `process.env` usage across the codebase.\n\n❌ Bad:\n\n```ts\nconst port = Number(process.env.PORT);\n```\n\n✅ Good:\n\n```ts\nimport { config } from './config';\n\napp.listen(config.PORT);\n```\n\n---\n\n### 3. Use explicit types for configuration\n\nAlways define an interface for your config object.\n\n```ts\ninterface AppConfig {\n  PORT: number;\n  DATABASE_URL: string;\n}\n```\n\nThis gives you:\n\n* autocomplete\n* compile-time safety\n* clear documentation of required values\n\n---\n\n### 4. Mark required values explicitly\n\nIf a value is required — make it required in Joi.\n\n```ts\njoi: Joi.string().required()\n```\n\nNever rely on implicit defaults unless you intentionally define them.\n\n---\n\n### 5. Avoid runtime casting\n\nLet Joi handle parsing and validation instead of manually casting values.\n\n❌ Bad:\n\n```ts\nvalue: Number(process.env.PORT)\n```\n\n✅ Good:\n\n```ts\nvalue: process.env.PORT,\njoi: Joi.number().required()\n```\n\n---\n\n## Example: NestJS\n\n### Configuration file\n\n```ts\n// src/config/app.config.ts\nimport Joi from 'joi';\nimport { JoiUtil } from 'joi-config-util';\n\nexport interface AppConfig {\n  PORT: number;\n  NODE_ENV: 'development' | 'production';\n}\n\nexport const appConfig = JoiUtil.validate<AppConfig>({\n  PORT: {\n    value: process.env.PORT,\n    joi: Joi.number().port().required(),\n  },\n  NODE_ENV: {\n    value: process.env.NODE_ENV,\n    joi: Joi.string()\n      .valid('development', 'production')\n      .required(),\n  },\n});\n```\n\n---\n\n### Using config in NestJS\n\n```ts\n// src/main.ts\nimport { NestFactory } from '@nestjs/core';\nimport { AppModule } from './app.module';\nimport { appConfig } from './config/app.config';\n\nasync function bootstrap() {\n  const app = await NestFactory.create(AppModule);\n  await app.listen(appConfig.PORT);\n}\nbootstrap();\n```\n\nIf configuration is invalid, NestJS will never start — exactly what you want.\n\n---\n\n## Example: Express\n\n### Configuration file\n\n```ts\n// src/config/app.config.ts\nimport Joi from 'joi';\nimport { JoiUtil } from 'joi-config-util';\n\nexport interface AppConfig {\n  PORT: number;\n  NODE_ENV: string;\n}\n\nexport const appConfig = JoiUtil.validate<AppConfig>({\n  PORT: {\n    value: process.env.PORT,\n    joi: Joi.number().port().required(),\n  },\n  NODE_ENV: {\n    value: process.env.NODE_ENV,\n    joi: Joi.string().required(),\n  },\n});\n```\n\n---\n\n### Using config in Express\n\n```ts\n// src/server.ts\nimport express from 'express';\nimport { appConfig } from './config/app.config';\n\nconst app = express();\n\napp.listen(appConfig.PORT, () => {\n  console.log(\n    `Server running in ${appConfig.NODE_ENV} mode on port ${appConfig.PORT}`,\n  );\n});\n```\n\n---\n\n## Final tip\n\nThis utility is intentionally small and opinionated.\nUse it as a **boundary** between untrusted input (`process.env`) and the rest of your application.\n\nOnce validation passes, your config can be treated as **trusted and type-safe**.\n\n---\n\n## License\n\nMIT\n\n---\n\n## Author\n\n**Artyom Gaibovich**\nGitHub: [https://github.com/artyom-gaibovich](https://github.com/artyom-gaibovich)\n","readmeFilename":"README.md"}