{"id":10985,"library":"gubu","title":"Gubu: Object Shape Validation Utility","description":"Gubu is an object shape validation utility for JavaScript and TypeScript, designed to provide a more intuitive and less verbose developer experience compared to alternatives like Joi or JSON-Schema. Currently stable at version 9.0.0, the library differentiates itself with a \"Schema By Example\" approach, where validation schemas closely mirror the actual data structure. This design simplifies reading and reasoning about validation rules. A key feature is its ability to deeply fill out objects with default values if properties are missing, differing from shallow merge operations like `Object.assign`. It's crucial for developers to note that Gubu deliberately mutates the input object to inject these defaults, a design choice to simplify internal logic and delegate cloning decisions to the calling code. Gubu functions effectively in both browser and Node.js environments and ships with full TypeScript support.","status":"active","version":"9.0.0","language":"javascript","source_language":"en","source_url":"git://github.com/rjrodger/gubu","tags":["javascript","gubu","schema","validation","typescript"],"install":[{"cmd":"npm install gubu","lang":"bash","label":"npm"},{"cmd":"yarn add gubu","lang":"bash","label":"yarn"},{"cmd":"pnpm add gubu","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Gubu is a named export. Attempting a default import will result in an error.","wrong":"import Gubu from 'gubu'","symbol":"Gubu","correct":"import { Gubu } from 'gubu'"},{"note":"For CommonJS, use object destructuring to get the Gubu constructor from the module exports. The package supports both ESM and CJS.","wrong":"const Gubu = require('gubu').Gubu","symbol":"Gubu","correct":"const { Gubu } = require('gubu')"},{"note":"While Gubu ships with TypeScript types, specific type names like 'GubuSchema' are inferred common patterns; refer to the package's type declarations for exact type exports. Use 'import type' for type-only imports to ensure they are stripped from the JavaScript output.","symbol":"GubuSchema","correct":"import type { GubuSchema } from 'gubu'"}],"quickstart":{"code":"import { Gubu } from 'gubu' // Using ESM syntax for modern projects\n\nconst optionsShape = Gubu({\n  server: {\n    port: 8080,        // Default 8080, optional\n    host: 'localhost', // Default 'localhost', optional\n    secure: Boolean    // Required boolean, no default\n  },\n  client: {\n    timeout: Number,   // Required number, no default\n    debug: Boolean,    // Required boolean, no default\n    headers: [String], // Array of strings, optional, empty array default if not provided\n    retries: 3         // Default 3, optional\n  },\n  plugins: [            // Array of objects, optional, empty array default\n    { \n      name: String,     // Required string\n      enabled: Boolean  // Required boolean\n    }\n  ]\n})\n\nconsole.log('--- Scenario 1: Empty input, check defaults and required fields ---')\nlet config1 = {}\ntry {\n  optionsShape(config1) // Mutates config1\n  console.log('Validated Config 1:', JSON.stringify(config1, null, 2))\n} catch (e: any) {\n  console.error('Validation Error 1:', e.message)\n}\n\nconsole.log('\\n--- Scenario 2: Partial input, check deep merging and specific values ---')\nlet config2 = {\n  server: {\n    port: 9000,\n    secure: true\n  },\n  client: {\n    timeout: 5000,\n    debug: false,\n    headers: ['X-Custom-Header-A']\n  }\n}\ntry {\n  optionsShape(config2) // Mutates config2\n  console.log('Validated Config 2:', JSON.stringify(config2, null, 2))\n} catch (e: any) {\n  console.error('Validation Error 2:', e.message)\n}\n\nconsole.log('\\n--- Scenario 3: Invalid input type for a field ---')\nlet config3 = {\n  server: {\n    port: 'not-a-number', // Invalid type\n    secure: true\n  },\n  client: {\n    timeout: 1000,\n    debug: true,\n    headers: []\n  }\n}\ntry {\n  optionsShape(config3)\n  console.log('Validated Config 3:', JSON.stringify(config3, null, 2))\n} catch (e: any) {\n  console.error('Validation Error 3:', e.message)\n}\n\nconsole.log('\\n--- Scenario 4: Missing a required field ---')\nlet config4 = {\n  server: {\n    port: 8080,\n    // secure is missing\n  },\n  client: {\n    timeout: 1000,\n    debug: true,\n    headers: []\n  }\n}\ntry {\n  optionsShape(config4)\n  console.log('Validated Config 4:', JSON.stringify(config4, null, 2))\n} catch (e: any) {\n  console.error('Validation Error 4:', e.message)\n}\n","lang":"typescript","description":"This quickstart demonstrates defining a Gubu schema with optional fields (having defaults), required fields (using type constructors like `Boolean`), array validation, and deep object merging. It also showcases how Gubu mutates the input object and catches various validation errors."},"warnings":[{"fix":"If immutability is required, clone the input object before passing it to Gubu (e.g., using `structuredClone` or `lodash.cloneDeep`).","message":"Gubu deliberately mutates the input object passed to the validation function. This can lead to unexpected side effects if the original object is intended to remain immutable elsewhere in the application.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Carefully review the schema definition: use literal values for optional fields with defaults, and type constructors (Number, String, Boolean, Object, Array) for strictly required fields. If a required field needs a default, consult Gubu's documentation for specific modifiers (e.g., `.Default()` if available).","message":"The method for defining optional fields with defaults versus strictly required fields differs significantly. Literal values (e.g., `port: 8080`) define optional fields with that literal as the default, while JavaScript type constructors (e.g., `timeout: Number`, `secure: Boolean`) define required fields without defaults.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Thoroughly read the release notes for the new major version on the package's GitHub repository or npm page. Test your application comprehensively after upgrading.","message":"Upgrading to a new major version (e.g., 9.x.x) may introduce breaking changes to the API, schema definition syntax, or validation behavior. Always consult the official release notes before upgrading major versions.","severity":"breaking","affected_versions":">=9.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure all required fields are present in the object provided for validation, or modify the schema to make the field optional with a default if applicable.","cause":"A field defined with a JavaScript type constructor (e.g., `Number`, `Boolean`) was missing from the input object being validated.","error":"Gubu: [path]: is required"},{"fix":"Correct the type of the value in the input object to align with the schema's expectation for that specific field.","cause":"A field in the input object did not match the expected primitive type (e.g., a string was provided for a `Number` field) as defined in the schema.","error":"Gubu: [path]: is not a [type]"},{"fix":"For ESM, use `import { Gubu } from 'gubu'`. For CommonJS, use `const { Gubu } = require('gubu')`.","cause":"Incorrect import or require syntax, most commonly attempting to use `import Gubu from 'gubu'` when `Gubu` is a named export, or incorrectly accessing the export in CommonJS (`require('gubu').Gubu`).","error":"TypeError: Gubu is not a function"}],"ecosystem":"npm"}