{"_id":"@loydjs/schema","_rev":"3-858650f2d9e2db60f4c0e9af092a6bf0","name":"@loydjs/schema","dist-tags":{"latest":"1.1.0"},"versions":{"0.0.0":{"name":"@loydjs/schema","version":"0.0.0","keywords":["loyd","validation","typescript","schema"],"license":"MIT","_id":"@loydjs/schema@0.0.0","maintainers":[{"name":"benitobledje","email":"taylorbenito424@gmail.com"}],"dist":{"shasum":"daf63bb273ad40a2ad9ec4f72a8e8c200b835904","tarball":"https://registry.npmjs.org/@loydjs/schema/-/schema-0.0.0.tgz","fileCount":32,"integrity":"sha512-5TiPRdw1dc/O4JjuMZxTP6FnpkhvlRdjPOvFLhkWkD4lgfKbTQiLLnQc5FwXL1sI/dsZ1hO8Ef6e+ZyyQMlD8A==","signatures":[{"sig":"MEYCIQDLFvnlrBIzJAn9IJUp+q/cCnjyJ14DVBcyMRNfXqgclwIhAJGLckHIHmGRqlvhoWXu9sg6WBdXfDSIMqKvNoQfeGD9","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":273295},"main":"./dist/index.cjs","type":"module","_from":"file:loydjs-schema-0.0.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"scripts":{"dev":"tsup --watch","test":"vitest run","bench":"echo no benchmarks","build":"tsup","clean":"rm -rf dist *.tsbuildinfo","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"benitobledje","email":"taylorbenito424@gmail.com"},"_resolved":"/tmp/3cb43dce68bba3e2e32a42472b787111/loydjs-schema-0.0.0.tgz","_integrity":"sha512-5TiPRdw1dc/O4JjuMZxTP6FnpkhvlRdjPOvFLhkWkD4lgfKbTQiLLnQc5FwXL1sI/dsZ1hO8Ef6e+ZyyQMlD8A==","_npmVersion":"10.8.2","description":"Loyd schema — functional, tree-shakeable DSL","directories":{},"sideEffects":false,"_nodeVersion":"20.20.2","dependencies":{"@loydjs/core":"0.0.0","@loydjs/types":"0.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.2"},"_npmOperationalInternal":{"tmp":"tmp/schema_0.0.0_1776420165885_0.27126357832147985","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@loydjs/schema","version":"1.0.0","keywords":["loyd","validation","typescript","schema"],"license":"MIT","_id":"@loydjs/schema@1.0.0","maintainers":[{"name":"benitobledje","email":"taylorbenito424@gmail.com"}],"dist":{"shasum":"e3a16feea2557ceac39c4b60c73dc736b2d7123a","tarball":"https://registry.npmjs.org/@loydjs/schema/-/schema-1.0.0.tgz","fileCount":33,"integrity":"sha512-0p9SqF4RyRmTaR7urXa7b9fRYvtRkA98UqZ8GCpthFolKteA54jNCFpTBmc+FRcn6Cg9HufclV8nj1WWHU4IMQ==","signatures":[{"sig":"MEUCIQCi2F+/WMb45PGKjgFomggoVgKFosVCOM/XU6+FsyvOJwIgEOMSjW2ebO687EVeSxRDuebiFLYvc366FDftwLw3i6A=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":279023},"main":"./dist/index.cjs","type":"module","_from":"file:loydjs-schema-1.0.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"scripts":{"dev":"tsup --watch","test":"vitest run","bench":"echo no benchmarks","build":"tsup","clean":"rm -rf dist *.tsbuildinfo","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"benitobledje","email":"taylorbenito424@gmail.com"},"_resolved":"/tmp/702046a99b17c839cf7070fbf45ca7e3/loydjs-schema-1.0.0.tgz","_integrity":"sha512-0p9SqF4RyRmTaR7urXa7b9fRYvtRkA98UqZ8GCpthFolKteA54jNCFpTBmc+FRcn6Cg9HufclV8nj1WWHU4IMQ==","_npmVersion":"10.8.2","description":"Loyd schema — functional, tree-shakeable DSL","directories":{},"sideEffects":false,"_nodeVersion":"20.20.2","dependencies":{"@loydjs/core":"1.0.0","@loydjs/types":"1.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.2"},"_npmOperationalInternal":{"tmp":"tmp/schema_1.0.0_1776423588414_0.943042310427596","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@loydjs/schema","version":"1.1.0","description":"Loyd schema — functional, tree-shakeable DSL","keywords":["loyd","validation","typescript","schema"],"license":"MIT","type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"sideEffects":false,"dependencies":{"@loydjs/core":"1.1.0","@loydjs/types":"1.1.0"},"devDependencies":{"typescript":"^5.7.2","tsup":"^8.3.5","vitest":"^2.1.8"},"publishConfig":{"access":"public"},"scripts":{"build":"tsup","dev":"tsup --watch","typecheck":"tsc --noEmit","test":"vitest run","test:watch":"vitest","bench":"echo no benchmarks","clean":"rm -rf dist *.tsbuildinfo"},"_id":"@loydjs/schema@1.1.0","_integrity":"sha512-KfV26Eah7DNzoqPdN4s9S9oL5BUP4dGs0KxRAiAcw+xycrXD6W4eYHjlXGLYzgYL3tSCAZoyaFdkI3jxO9TcVQ==","_resolved":"/tmp/96cb101d7bfefb796348728e9688177b/loydjs-schema-1.1.0.tgz","_from":"file:loydjs-schema-1.1.0.tgz","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-KfV26Eah7DNzoqPdN4s9S9oL5BUP4dGs0KxRAiAcw+xycrXD6W4eYHjlXGLYzgYL3tSCAZoyaFdkI3jxO9TcVQ==","shasum":"4d01576d2cfe5221e7da0f2ff06b19ec5d5b6e99","tarball":"https://registry.npmjs.org/@loydjs/schema/-/schema-1.1.0.tgz","fileCount":33,"unpackedSize":279991,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCmgYegX+Bza8oZE3WpejJlMmqVu81Yk9xTLYIJRug78wIhAPe7vwGEJUj2e+y5rzCp+yuHZ/4TZG/vRwxmHQHmZTMS"}]},"_npmUser":{"name":"benitobledje","email":"taylorbenito424@gmail.com"},"directories":{},"maintainers":[{"name":"benitobledje","email":"taylorbenito424@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/schema_1.1.0_1779155349046_0.1750360460448792"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-17T10:02:45.833Z","modified":"2026-05-19T01:49:09.359Z","0.0.0":"2026-04-17T10:02:46.024Z","1.0.0":"2026-04-17T10:59:48.585Z","1.1.0":"2026-05-19T01:49:09.232Z"},"license":"MIT","keywords":["loyd","validation","typescript","schema"],"description":"Loyd schema — functional, tree-shakeable DSL","maintainers":[{"name":"benitobledje","email":"taylorbenito424@gmail.com"}],"readme":"<div align=\"center\">\n\n<h1>@loydjs/schema</h1>\n\n<p><strong>All schema types for Loyd.</strong><br/>\nPrimitives · Composites · Modifiers · Refinements · Fully tree-shakeable.</p>\n\n[![CI](https://github.com/b3nito404/loyd/actions/workflows/ci.yml/badge.svg)](https://github.com/b3nito404/loyd/actions/workflows/ci.yml)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n[![Bundle](https://img.shields.io/badge/bundle-tree--shakeable-brightgreen.svg)](https://bundlephobia.com/package/@loydjs/schema)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.4%2B-blue.svg)](https://www.typescriptlang.org)\n[![npm downloads](https://img.shields.io/npm/dm/@loydjs/schema?color=6366f1&label=downloads)](https://www.npmjs.com/package/@loydjs/schema)\n\n</div>\n\n---\n\n## Overview\n\n`@loydjs/schema` provides every schema type you need - primitives, composites, modifiers, and refinements. Every export is tree-shakeable: if you only use `string()` and `number()`, only those end up in your bundle.\n\n---\n\n## Installation\n\n```sh\nnpm install @loydjs/schema @loydjs/core\n```\n\n> **Requires** `@loydjs/core` · Node.js ≥ 20 · TypeScript ≥ 5.4 · `\"strict\": true` in `tsconfig.json`\n\n---\n\n## Primitives\n\n### `string()`\n\n```ts\nimport { string } from \"@loydjs/schema\";\n\nstring()\n  .minLength(2)\n  .maxLength(100)\n  .email()\n  .url()\n  .uuid()\n  .regex(/^\\d{4}$/)\n  .startsWith(\"prefix_\")\n  .endsWith(\"_suffix\")\n  .includes(\"keyword\")\n  .nonempty()\n  .trim()\n  .toLowerCase()\n  .toUpperCase()\n```\n\n### `number()`\n\n```ts\nimport { number } from \"@loydjs/schema\";\n\nnumber()\n  .min(0)      // >= 0\n  .max(120)    // <= 120\n  .gt(0)       // > 0\n  .gte(1)      // >= 1\n  .lt(100)     // < 100\n  .lte(99)     // <= 99\n  .int()       // integer only\n  .positive()  // > 0\n  .negative()  // < 0\n  .nonnegative() // >= 0\n  .multipleOf(5)\n  .finite()\n  .safe()      // Number.isSafeInteger\n```\n\n### `boolean()`\n\n```ts\nimport { boolean } from \"@loydjs/schema\";\n\nconst Active = boolean();\n```\n\n### `bigint()`\n\n```ts\nimport { bigint } from \"@loydjs/schema\";\n\nconst Id = bigint();\n```\n\n### `date()`\n\n```ts\nimport { date } from \"@loydjs/schema\";\n\nconst CreatedAt = date();\n```\n\n### `literal(value)`\n\n```ts\nimport { literal } from \"@loydjs/schema\";\n\nconst Admin  = literal(\"admin\");\nconst Active = literal(true);\nconst Zero   = literal(0);\n```\n\n---\n\n## Composites\n\n### `object(shape)`\n\n```ts\nimport { object, string, number } from \"@loydjs/schema\";\n\nconst User = object({\n  name:  string().minLength(2),\n  email: string().email(),\n  age:   number().int().min(0),\n});\n\n// Unknown key handling\nUser.strict();       // error on unknown keys\nUser.strip();        // remove unknown keys (default)\nUser.passthrough();  // keep unknown keys\n\n// Shape operations\nUser.pick([\"name\", \"email\"]);\nUser.omit([\"age\"]);\nUser.partial();           // all fields optional\nUser.required();          // all fields required\nUser.extend({ role: string() });\nUser.merge(OtherSchema);\n```\n\n### `array(element)`\n\n```ts\nimport { array, string } from \"@loydjs/schema\";\n\narray(string())\n  .min(1)\n  .max(100)\n  .length(5)\n  .nonempty()\n```\n\n### `tuple(elements)`\n\n```ts\nimport { tuple, string, number } from \"@loydjs/schema\";\n\nconst Point = tuple([number(), number()]);\n// [number, number]\n```\n\n### `union(options)`\n\n```ts\nimport { union, string, number } from \"@loydjs/schema\";\n\nconst StringOrNumber = union([string(), number()]);\n```\n\n### `discriminatedUnion(key, options)`\n\n```ts\nimport { discriminatedUnion, object, literal, string, number } from \"@loydjs/schema\";\n\n// O(1) variant lookup via Map - compiled to constant-time dispatch\nconst Shape = discriminatedUnion(\"kind\", [\n  object({ kind: literal(\"circle\"),   radius: number().min(0) }),\n  object({ kind: literal(\"rect\"),     width: number().min(0), height: number().min(0) }),\n  object({ kind: literal(\"triangle\"), base: number().min(0),  height: number().min(0) }),\n]);\n```\n\n### `record(valueSchema)`\n\n```ts\nimport { record, number } from \"@loydjs/schema\";\n\nconst Scores = record(number().int().min(0).max(100));\n// Record<string, number>\n```\n\n### `map(keySchema, valueSchema)`\n\n```ts\nimport { map, string, number } from \"@loydjs/schema\";\n\nconst Cache = map(string(), number());\n```\n\n### `set(elementSchema)`\n\n```ts\nimport { set, string } from \"@loydjs/schema\";\n\nconst Tags = set(string());\n```\n\n---\n\n## Modifiers\n\n### `optional(schema)`\n\n```ts\nimport { optional, string } from \"@loydjs/schema\";\n\nconst MaybeEmail = optional(string().email());\n// string | undefined\n```\n\n### `nullable(schema)`\n\n```ts\nimport { nullable, string } from \"@loydjs/schema\";\n\nconst MaybeName = nullable(string());\n// string | null\n```\n\n### `nullish(schema)`\n\n```ts\nimport { nullish, string } from \"@loydjs/schema\";\n\nconst MaybeValue = nullish(string());\n// string | null | undefined\n```\n\n### `brand(schema, brand)`\n\n```ts\nimport { brand, string } from \"@loydjs/schema\";\n\nconst UserId = brand(string().uuid(), \"UserId\");\ntype UserId = Infer<typeof UserId>; // string & { readonly [brand]: \"UserId\" }\n```\n\n### `transform(schema, fn)`\n\n```ts\nimport { transform, string } from \"@loydjs/schema\";\n\nconst TrimmedEmail = transform(\n  string().email(),\n  (email) => email.toLowerCase().trim()\n);\n```\n\n### `pipe(schema, ...rules)`\n\n```ts\nimport { pipe, string, minLength, email } from \"@loydjs/schema\";\n\n// Compose rules functionally\nconst EmailField = pipe(string(), minLength(1), email());\n```\n\n---\n\n## Refinements\n\n### `refine(schema, predicate, options)`\n\n```ts\nimport { refine, string } from \"@loydjs/schema\";\n\nconst StrongPassword = refine(\n  string().minLength(8),\n  (v) => /[A-Z]/.test(v) && /[0-9]/.test(v),\n  { code: \"ERR_PASSWORD_TOO_WEAK\" }\n);\n```\n\n### `refineAsync(schema, predicate, options)`\n\n```ts\nimport { refineAsync, string } from \"@loydjs/schema\";\n\nconst UniqueUsername = refineAsync(\n  string().minLength(3),\n  async (username) => {\n    const taken = await db.users.exists({ username });\n    return !taken;\n  },\n  { code: \"ERR_USERNAME_TAKEN\" }\n);\n```\n\n### `defineRule(definition, predicate)`\n\nDefine a reusable rule with a name and code that can be applied to any schema.\n\n```ts\nimport { defineRule, string } from \"@loydjs/schema\";\n\nconst noEmoji = defineRule(\n  { code: \"ERR_STRING_HAS_EMOJI\", description: \"No emoji allowed\" },\n  (v: string) => !/\\p{Emoji}/u.test(v)\n);\n\nconst CleanString = noEmoji.apply(string());\n```\n\n---\n\n## Dependencies\n\n| Package | Role |\n|:---|:---|\n| `@loydjs/core` | `BaseSchema`, `LoydResult` |\n| `@loydjs/types` | `SchemaMap`, `InferSchemaMap` |\n\n---\n\n## Documentation\n\n**[loyddev-psi.vercel.app](https://loyddev-psi.vercel.app)**\n\n---\n\n## License\n\nMIT © [b3nito404](https://github.com/b3nito404)","readmeFilename":"README.md"}