{"_id":"@anclatechs/serde-js","_rev":"7-cc6d49dd06647956db960ed8feffea06","name":"@anclatechs/serde-js","dist-tags":{"latest":"1.0.7"},"versions":{"1.0.1":{"name":"@anclatechs/serde-js","version":"1.0.1","keywords":["nodejs","serde","serialization","validation","context-aware","declarative","drf","schema","api","json","serializer","transformer","data-validation","joi","express"],"author":{"url":"AnclaTechs","name":"Ancla Technologies"},"license":"MIT","_id":"@anclatechs/serde-js@1.0.1","maintainers":[{"name":"olamigokayphils","email":"olamigokayphils+gravatar@gmail.com"}],"homepage":"https://github.com/AnclaTechs/serde-js#readme","bugs":{"url":"https://github.com/AnclaTechs/serde-js/issues"},"dist":{"shasum":"0db616e8e055ab2347a03e6ca55692671bf8df40","tarball":"https://registry.npmjs.org/@anclatechs/serde-js/-/serde-js-1.0.1.tgz","fileCount":8,"integrity":"sha512-mdYTJfRpb4LXcM9x8Jp1S8QlVQrbnmzs5ikC1TO8BvSU/wz8F9EPvkl/gtsTmd1oIhv4A3Y6ulTTdenDkhkIAg==","signatures":[{"sig":"MEUCIFp7vMngM5tPT6O119FTY8dnzdnhqePqCIcgAFxNNhnvAiEAnp01BeqNqzd4N0Y5eVySxCe4smdsTV6MUZUJ1Ql3Xkc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":18581},"main":"src/index.js","types":"src/dist.d.ts","exports":{".":"./src/dist.js"},"gitHead":"51946d494b0b3b626da36caf6c4b298264bfeab5","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_npmUser":{"name":"olamigokayphils","email":"olamigokayphils+gravatar@gmail.com"},"repository":{"url":"git+https://github.com/AnclaTechs/serde-js.git","type":"git"},"_npmVersion":"10.8.2","description":"Composable, schema-driven serialization and validation for JavaScript.","directories":{},"_nodeVersion":"20.19.4","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/serde-js_1.0.1_1769689364779_0.8942511798465982","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@anclatechs/serde-js","version":"1.0.2","keywords":["nodejs","serde","serialization","validation","context-aware","declarative","drf","schema","api","json","serializer","transformer","data-validation","joi","express"],"author":{"url":"AnclaTechs","name":"Ancla Technologies"},"license":"MIT","_id":"@anclatechs/serde-js@1.0.2","maintainers":[{"name":"olamigokayphils","email":"olamigokayphils+gravatar@gmail.com"}],"homepage":"https://github.com/AnclaTechs/serde-js#readme","bugs":{"url":"https://github.com/AnclaTechs/serde-js/issues"},"dist":{"shasum":"ac86618dd7d1c9b5488bb2d2c44ed2aa40e5c4b7","tarball":"https://registry.npmjs.org/@anclatechs/serde-js/-/serde-js-1.0.2.tgz","fileCount":8,"integrity":"sha512-6T0Efprc7OwFt1ZqXrzKY3rD8xhqxJUioJ8RlqMQKSBJw21wQpDWNUEdmJcy8w27hoL+RlhF8a/Y0/g3zopMTA==","signatures":[{"sig":"MEQCIHoQP9fwTK3GWtYfhHubG6wW1xUQRXahzlUnw9jPmxSBAiBC4ijEw+2w5khTpM/TOqz/wziqcEtex2qCas/crY9FLQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":19656},"main":"src/index.js","types":"src/dist.d.ts","exports":{".":"./src/dist.js"},"gitHead":"af31b8684f6c1535a9748c9ad116fefcd03875de","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_npmUser":{"name":"olamigokayphils","email":"olamigokayphils+gravatar@gmail.com"},"repository":{"url":"git+https://github.com/AnclaTechs/serde-js.git","type":"git"},"_npmVersion":"10.8.2","description":"Composable, schema-driven serialization and validation for JavaScript.","directories":{},"_nodeVersion":"20.19.4","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/serde-js_1.0.2_1769692369991_0.4595955884630083","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@anclatechs/serde-js","version":"1.0.3","keywords":["nodejs","serde","serialization","validation","context-aware","declarative","drf","schema","api","json","serializer","transformer","data-validation","joi","express"],"author":{"url":"AnclaTechs","name":"Ancla Technologies"},"license":"MIT","_id":"@anclatechs/serde-js@1.0.3","maintainers":[{"name":"olamigokayphils","email":"olamigokayphils+gravatar@gmail.com"}],"homepage":"https://github.com/AnclaTechs/serde-js#readme","bugs":{"url":"https://github.com/AnclaTechs/serde-js/issues"},"dist":{"shasum":"6d26eeb9232a2146fb26495c7db812a051963e49","tarball":"https://registry.npmjs.org/@anclatechs/serde-js/-/serde-js-1.0.3.tgz","fileCount":8,"integrity":"sha512-f6C4uq7H70Gi6AICxMo1j74v7VDfqe5pH/wPuq17Vva3mZmMjk+qMk6J6EFPRQ/adOOr6WGCEd2ia3umZ5h85w==","signatures":[{"sig":"MEYCIQCke78ygVHV3IsyyrwipgDgVX/voUdQq1y3Jy1MMnX/zwIhAJJLcfxXSIFWWxwJksVdEjxfS/bCzd80pX8+9n/jYoZb","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":19891},"main":"src/index.js","types":"src/dist.d.ts","exports":{".":"./src/dist.js"},"gitHead":"1e691893f66c7597541f9d43d3d8dcbbe1e5226c","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_npmUser":{"name":"olamigokayphils","email":"olamigokayphils+gravatar@gmail.com"},"repository":{"url":"git+https://github.com/AnclaTechs/serde-js.git","type":"git"},"_npmVersion":"10.8.2","description":"Composable, schema-driven serialization and validation for JavaScript.","directories":{},"_nodeVersion":"20.19.4","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/serde-js_1.0.3_1769692741380_0.9282648401598037","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@anclatechs/serde-js","version":"1.0.4","keywords":["nodejs","serde","serialization","validation","context-aware","declarative","drf","schema","api","json","serializer","transformer","data-validation","joi","express"],"author":{"url":"AnclaTechs","name":"Ancla Technologies"},"license":"MIT","_id":"@anclatechs/serde-js@1.0.4","maintainers":[{"name":"olamigokayphils","email":"olamigokayphils+gravatar@gmail.com"}],"homepage":"https://github.com/AnclaTechs/serde-js#readme","bugs":{"url":"https://github.com/AnclaTechs/serde-js/issues"},"dist":{"shasum":"8a717098811ce0483d2253b1f1cce36457eedda5","tarball":"https://registry.npmjs.org/@anclatechs/serde-js/-/serde-js-1.0.4.tgz","fileCount":8,"integrity":"sha512-o1ThAAvhz1vbnv7Gwm72pSqRIzcrvtYQ3wQP+K+tV6475W9KVecor7X/fWbiVjtcwID7rphnHSJJ/PFzxNk+RA==","signatures":[{"sig":"MEUCIGio7YH1ebIEVrENA0JLUTD64v808sLFIgk6pHowTB7iAiEAlX+S9i65KOykWkoKZ6p6ou2RKctUvvXX2AP9Jgfp7OM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":20873},"main":"src/index.js","types":"src/dist.d.ts","exports":{".":"./src/dist.js"},"gitHead":"252b8897ffdd553b7feb5efe6a605f265983a362","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_npmUser":{"name":"olamigokayphils","email":"olamigokayphils+gravatar@gmail.com"},"repository":{"url":"git+https://github.com/AnclaTechs/serde-js.git","type":"git"},"_npmVersion":"10.8.2","description":"Composable, schema-driven serialization and validation for JavaScript.","directories":{},"_nodeVersion":"20.19.4","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/serde-js_1.0.4_1769725762869_0.3405938061934253","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@anclatechs/serde-js","version":"1.0.5","keywords":["nodejs","serde","serialization","validation","context-aware","declarative","drf","schema","api","json","serializer","transformer","data-validation","joi","express"],"author":{"url":"AnclaTechs","name":"Ancla Technologies"},"license":"MIT","_id":"@anclatechs/serde-js@1.0.5","maintainers":[{"name":"olamigokayphils","email":"olamigokayphils+gravatar@gmail.com"}],"homepage":"https://github.com/AnclaTechs/serde-js#readme","bugs":{"url":"https://github.com/AnclaTechs/serde-js/issues"},"dist":{"shasum":"6495c19ec6e49150ab78e29ac4d2f0bab6353649","tarball":"https://registry.npmjs.org/@anclatechs/serde-js/-/serde-js-1.0.5.tgz","fileCount":8,"integrity":"sha512-NvNVLKGqcsUDuK/QI2InTptBqhu7WpBs9pZwHN7aeZiS0Rv8S78f2yRjcNcG/Guh5i0TpyGn1nCePeIvtg7ZOw==","signatures":[{"sig":"MEYCIQC0A5g36mmKhFte5mHFSb8U1Tj72klz/Q1nu3qpYVM2EAIhAIr9aDzAzTVAvdvDj4ArWMF4eKQZ61dgXACJr8k4EQCa","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":21706},"main":"src/index.js","types":"src/dist.d.ts","exports":{".":"./src/dist.js"},"gitHead":"2b38ceb19ae9ba48e529e2b163013cb0dd5618d9","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_npmUser":{"name":"olamigokayphils","email":"olamigokayphils+gravatar@gmail.com"},"repository":{"url":"git+https://github.com/AnclaTechs/serde-js.git","type":"git"},"_npmVersion":"10.8.2","description":"Composable, schema-driven serialization and validation for JavaScript.","directories":{},"_nodeVersion":"20.19.4","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/serde-js_1.0.5_1769746435168_0.5357573313225574","host":"s3://npm-registry-packages-npm-production"}},"1.0.6":{"name":"@anclatechs/serde-js","version":"1.0.6","keywords":["nodejs","serde","serialization","validation","context-aware","declarative","drf","schema","api","json","serializer","transformer","data-validation","joi","express"],"author":{"url":"AnclaTechs","name":"Ancla Technologies"},"license":"MIT","_id":"@anclatechs/serde-js@1.0.6","maintainers":[{"name":"olamigokayphils","email":"olamigokayphils+gravatar@gmail.com"}],"homepage":"https://github.com/AnclaTechs/serde-js#readme","bugs":{"url":"https://github.com/AnclaTechs/serde-js/issues"},"dist":{"shasum":"99989db78ae657f185df96aa64f365dc76e91b4f","tarball":"https://registry.npmjs.org/@anclatechs/serde-js/-/serde-js-1.0.6.tgz","fileCount":8,"integrity":"sha512-CJ6FDiQV3rYEAMtVP7GVyYc+ri0UsLMVaLMxU+mR7IfeqaEQYgIuvzUJFlo6yxAk3btqCJAMzfQhMhtPK+HYbA==","signatures":[{"sig":"MEYCIQDNN67uPX83tLA0le4oKRTHcNPuF+nGtXayZWOFETFchgIhANq7Ch80k9GrCTJ3ZDJrpOCOwI1Ow2x+Px6bpA411DEm","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":23559},"main":"src/index.js","types":"src/dist.d.ts","exports":{".":"./src/dist.js"},"gitHead":"3e3449c271d0bec36c6793aba871449a37e9d18b","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_npmUser":{"name":"olamigokayphils","email":"olamigokayphils+gravatar@gmail.com"},"repository":{"url":"git+https://github.com/AnclaTechs/serde-js.git","type":"git"},"_npmVersion":"10.8.2","description":"Composable, schema-driven serialization and validation for JavaScript.","directories":{},"_nodeVersion":"20.19.4","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/serde-js_1.0.6_1770040852661_0.29610975249433924","host":"s3://npm-registry-packages-npm-production"}},"1.0.7":{"name":"@anclatechs/serde-js","version":"1.0.7","description":"Composable, schema-driven serialization and validation for JavaScript.","main":"src/index.js","types":"src/dist.d.ts","exports":{".":"./src/dist.js"},"repository":{"type":"git","url":"git+https://github.com/AnclaTechs/serde-js.git"},"keywords":["nodejs","serde","serialization","validation","context-aware","declarative","drf","schema","api","json","serializer","transformer","data-validation","joi","express"],"scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"author":{"name":"Ancla Technologies","url":"AnclaTechs"},"license":"MIT","_id":"@anclatechs/serde-js@1.0.7","gitHead":"59118168303faf2c8ddfadd7f5317d3a4cb41ac3","bugs":{"url":"https://github.com/AnclaTechs/serde-js/issues"},"homepage":"https://github.com/AnclaTechs/serde-js#readme","_nodeVersion":"20.19.4","_npmVersion":"10.8.2","dist":{"integrity":"sha512-ImcHXZdE6STXVpMi4S7QVocG+0wdXez1Ys/vNIjYMMOyZUvqlWTSQjtp5jJICHYqeBTlmvqngNObSHVuHrHquA==","shasum":"40700e78cb46b4ab2bd1678bd417cb16965930b1","tarball":"https://registry.npmjs.org/@anclatechs/serde-js/-/serde-js-1.0.7.tgz","fileCount":8,"unpackedSize":24531,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGlQ9AKTL140ovOdyQOtyy96no0X2lcoj4dx6nTKcB/WAiEA0NaT0jbnjzWgtSgSEKMi+mH08rPiKbz6bhaw7aIiIqU="}]},"_npmUser":{"name":"olamigokayphils","email":"olamigokayphils+gravatar@gmail.com"},"directories":{},"maintainers":[{"name":"olamigokayphils","email":"olamigokayphils+gravatar@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/serde-js_1.0.7_1770296349233_0.04876750537784624"},"_hasShrinkwrap":false}},"time":{"created":"2026-01-29T12:22:44.680Z","modified":"2026-02-05T12:59:09.546Z","1.0.1":"2026-01-29T12:22:44.914Z","1.0.2":"2026-01-29T13:12:50.140Z","1.0.3":"2026-01-29T13:19:01.536Z","1.0.4":"2026-01-29T22:29:23.002Z","1.0.5":"2026-01-30T04:13:55.319Z","1.0.6":"2026-02-02T14:00:52.817Z","1.0.7":"2026-02-05T12:59:09.435Z"},"bugs":{"url":"https://github.com/AnclaTechs/serde-js/issues"},"author":{"name":"Ancla Technologies","url":"AnclaTechs"},"license":"MIT","homepage":"https://github.com/AnclaTechs/serde-js#readme","keywords":["nodejs","serde","serialization","validation","context-aware","declarative","drf","schema","api","json","serializer","transformer","data-validation","joi","express"],"repository":{"type":"git","url":"git+https://github.com/AnclaTechs/serde-js.git"},"description":"Composable, schema-driven serialization and validation for JavaScript.","maintainers":[{"name":"olamigokayphils","email":"olamigokayphils+gravatar@gmail.com"}],"readme":"## @anclatechs/serde-js\n\nA **context-aware, declarative serialization and validation framework** for JavaScript.\n\n`serde-js` lets you define **one schema** that can:\n\n- validate user input (writes)\n- safely serialize output (reads)\n- enforce conditional logic via context\n- support nested objects and arrays\n- aggregate errors with precise paths\n\nInspired by Django REST Framework, Zod, and Joi — but designed to stay **lightweight, explicit, and extensible**.\n\n---\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Core Concepts](#core-concepts)\n- [Quick Start](#quick-start)\n- [Fields](#fields)\n- [Serializer](#serializer)\n- [Read vs Write Modes](#read-vs-write-modes)\n- [Context-Aware Rules](#context-aware-rules)\n- [Validation](#validation)\n- [Nested Serializers](#nested-serializers)\n- [ArrayField](#arrayfield)\n- [Error Handling](#error-handling)\n- [Schema Introspection](#schema-introspection)\n- [Advanced Patterns](#advanced-patterns)\n- [Design Philosophy](#design-philosophy)\n\n---\n\n## Installation\n\n```bash\nnpm install @anclatechs/serde-js\n```\n\n```js\nconst {\n  Serializer,\n  CharField,\n  NumberField,\n  IntegerField,\n  BooleanField,\n  DateTimeField,\n  DateField,\n  EmailField,\n  UrlField,\n  ArrayField,\n  ObjectField,\n  JsonField,\n} = require(\"@anclatechs/serde-js\");\n```\n\n---\n\n## Core Concepts\n\n### 1. One schema — many use cases\n\nA single `Serializer` definition can:\n\n- validate **input** (e.g. signup, update)\n- serialize **output** (API responses)\n- behave differently based on **context**\n\nNo duplicate schemas. No conditionals scattered across controllers.\n\n---\n\n### 2. Fields are intelligent\n\nEach field:\n\n- knows whether it is required\n- can be optional or have defaults\n- supports custom validators\n- can be read-only or write-only\n- can be conditionally included\n\n---\n\n### 3. Context drives behavior\n\nContext is an arbitrary object you pass at runtime. Example:\n\n```js\n{\n  mode: \"input\" | \"output\",\n  isSignup: true,\n  userRole: \"admin\"\n}\n```\n\nFields and validators can react to it.\n\n---\n\n## Quick Start\n\n```js\nconst UserSerializer = new Serializer({\n  name: new CharField(),\n  age: new IntegerField().optional(),\n  email: new EmailField(),\n});\n\nconst result = UserSerializer.serialize({\n  name: \"Ada\",\n  age: 30,\n  email: \"ada@example.com\",\n});\n\nconsole.log(result.data); // serialized output\nconsole.log(result.errors); // error mapping\nconsole.log(result.isValid()) // boolean status for any available error\nconsole.log(result.verboseErrorList()) // simplified, \"verbosed\" errors data retunred as an Array of object; accessible via .message.\n```\n\n---\n\n## Fields\n\n### Base `Field`\n\nAll fields inherit from `Field`.\n\nSupported features:\n\n```js\nnew Field()\n  .optional()\n  .default(value)\n  .validate(fn)\n  .onlyIf((ctx) => boolean)\n  .readOnly()\n  .writeOnly();\n```\n\n`CharField`, in addition to the validate function, also provide helper methods:\n\n```js\n.enumOptions([])\n.minLength(num)\n.maxLength(num)\n```\n\n`NumberField` and `IntegerField` also both support the `.min()` and `.max()` helper methods.\n\n---\n\n### Available Field Types\n\n| Field           | Description    |\n| --------------- | -------------- |\n| `CharField`     | String values  |\n| `NumberField`   | Any number     |\n| `IntegerField`  | Integer-only   |\n| `BooleanField`  | Boolean        |\n| `DateTimeField` | JS Date (ISO)  |\n| `DateField`     | Date-only      |\n| `EmailField`    | Email string   |\n| `UrlField`      | URL string     |\n| `ArrayField`    | Arrays         |\n| `ObjectField`   | Nested structured objects |\n| `JsonField`   | dynamic JSON object |\n\n---\n\n## Serializer\n\n### Creating a Serializer\n\n```js\nconst UserSerializer = new Serializer(schema, options);\n```\n\n### Options\n\n```js\n{\n  many?: boolean // expect an array of objects\n}\n```\n\n---\n\n## Read vs Write Modes\n\n### Why this matters\n\nOften:\n\n- some fields should only be **accepted** (password)\n- some should only be **returned** (id, timestamps)\n\n### Example\n\n```js\nconst UserSerializer = new Serializer({\n  id: new IntegerField().readOnly(),\n  email: new EmailField(),\n  password: new CharField().writeOnly(),\n});\n```\n\n#### Input (write)\n\n```js\nUserSerializer.serialize(req.body, { mode: \"input\" });\n```\n\n#### Output (read)\n\n```js\nUserSerializer.serialize(user, { mode: \"output\" });\n```\n\n---\n\n## Context-Aware Rules\n\n### `onlyIf(fn)`\n\nConditionally include a field.\n\n```js\nrole: new CharField().onlyIf((ctx) => ctx.userRole === \"admin\");\n```\n\n### Signup-only fields\n\n```js\npassword: new CharField().onlyIf((ctx) => ctx.isSignup);\n```\n\nIf the condition fails, the field is:\n\n- not required\n- not validated\n- not serialized\n\n---\n## Default Values\n\nThe `Field.default()` method allows you to provide a value when the input does not specify one.\n\nIt can be either:\n\n### 1. A constant value\n\n```js\nconst UserSerializer = new Serializer({\n  name: new CharField().default(\"Ada\"),\n});\n```\n\n### 2. A function for dynamic computation\n\nYou can compute the default value based on other fields in the serializer or context:\n\n```js\nconst UserSerializer = new Serializer({\n  name: new CharField(),\n  age: new IntegerField(),\n  ageInTwoYears: new IntegerField().default((_, root, ctx) => root.age * 2).readOnly(),\n});\n```\n\n#### Parameters of the default function\n\n| Parameter | Description                                                                                                            |\n| --------- | ---------------------------------------------------------------------------------------------------------------------- |\n| `value`   | The input value for this field. If the input is missing, it will be `undefined`. May be ignored and represented as `_`. |\n| `root`    | The partially built serialized object. Lets you reference other fields in the same serializer.                         |\n| `ctx`     | Optional context object passed to `serialize(input, context)`. Useful for user info, request metadata, etc.            |\n\n⚠️ Order matters: The field you reference in root (e.g., age) must appear before the dependent field (ageInTwoYears) in the schema.\n\n---\n\n## Validation\n\n### Custom Validators\n\n```js\nage: new IntegerField().validate((v) => v >= 18 || \"Must be 18+\");\n```\n\nValidators return:\n\n- `true` → pass\n- `false` or `string` → fail\n\n---\n\n### Reusable Validator Helpers\n\n```js\nconst min = (n) => (v) => v >= n || `Must be ≥ ${n}`;\nconst minLength = (n) => (v) => v.length >= n || `Min length ${n}`;\n```\n\n```js\npassword: new CharField().validate(minLength(8));\n```\n\n---\n\n## Nested Serializers\n\n### `ObjectField`\n\n```js\nconst AddressSerializer = new Serializer({\n  street: new CharField(),\n  city: new CharField(),\n});\n\nconst UserSerializer = new Serializer({\n  name: new CharField(),\n  address: new ObjectField(AddressSerializer),\n});\n```\n\nNested errors are merged automatically:\n\n```\naddress.city: Field is required\n```\n\n---\n\n## ArrayField\n\n### Array of scalars\n\n```js\ntags: new ArrayField(new CharField());\n```\n\n### Array of objects\n\n```js\nposts: new ArrayField(PostSerializer);\n```\n\nEach item is validated independently with full error paths:\n\n```\nposts[2].title: Field is required\n```\n\n---\n\n## Error Handling\n\nErrors are aggregated on the serializer:\n\n```js\nserializer.errors;\n```\n\nExample:\n\n```js\n{\n  \"email\": \"Invalid EmailField\",\n  \"address.city\": \"Field is required\",\n  \"tags[1]\": \"Invalid CharField\"\n}\n```\n\nNo exceptions. Full visibility.\n\n---\n\n## Schema Introspection\n\n### `describe()`\n\n```js\nUserSerializer.describe();\n```\n\nReturns:\n\n```js\n{\n  email: {\n    type: \"EmailField\",\n    required: true\n  },\n  tags: {\n    type: \"ArrayField\",\n    child: \"CharField\"\n  }\n}\n```\n\nUseful for:\n\n- documentation\n- form generation\n- schema inspection\n\n---\n\n## Advanced Patterns\n\n### Cross-field validation\n\n```js\npassword: new CharField(),\nconfirmPassword: new CharField().validate((v, ctx) =>\n  v === ctx.password || \"Passwords do not match\"\n)\n```\n\n### Role-based schemas\n\n```js\nsalary: new NumberField().onlyIf((ctx) => ctx.userRole === \"admin\");\n```\n\n### Partial updates\n\n```js\nnew CharField().optional().onlyIf((ctx) => ctx.isUpdate);\n```\n\n---\n\n## Design Philosophy\n\n- Explicit over magical\n- One schema, many flows\n- Context drives behavior\n- Errors should be precise\n- Composition over inheritance\n\n`serde-js` is intentionally unopinionated about:\n\n- HTTP frameworks\n- Databases\n- ORMs\n\nIt fits cleanly into Express, Fastify, NestJS, or serverless setups.\n\n---\n\n## Final Note\n\nThis library is intentionally **small but powerful**; supporting optional fields, default values, custom validators, aggregated error reporting, and context-aware serialization. Fields are required by default, your may define defaults or validation rules, and can dynamically include or validate data based on your preferred runtime context. Validation errors are collected and returned in a structured, predictable format suitable for APIs and batch processing.\n\nIf you understand how context flows, you can model:\n\n- signup\n- updates\n- admin overrides\n- read/write separation\n\n…without ever duplicating schemas.\n\n<br/>\n\n📜 License\n\n[MIT](./LICENSE) — use it, hack it, ship it.\n\nHappy building 🚀\n","readmeFilename":"README.md"}