{"id":20642402,"url":"https://github.com/ipld/js-ipld-schema","last_synced_at":"2026-02-06T06:00:15.842Z","repository":{"id":35122129,"uuid":"184203208","full_name":"ipld/js-ipld-schema","owner":"ipld","description":"IPLD Schema Implementation: parser and utilities","archived":false,"fork":false,"pushed_at":"2026-01-23T00:31:59.000Z","size":648,"stargazers_count":16,"open_issues_count":3,"forks_count":5,"subscribers_count":16,"default_branch":"master","last_synced_at":"2026-01-23T18:26:50.108Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ipld.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2019-04-30T06:18:02.000Z","updated_at":"2026-01-23T16:57:18.000Z","dependencies_parsed_at":"2024-04-22T01:45:22.527Z","dependency_job_id":"fc375fb3-fbbe-4f3e-b309-242eff6b40c2","html_url":"https://github.com/ipld/js-ipld-schema","commit_stats":{"total_commits":203,"total_committers":5,"mean_commits":40.6,"dds":0.5812807881773399,"last_synced_commit":"4108b17f05bd441bc379e65a544c938deb50bd17"},"previous_names":["rvagg/js-ipld-schema"],"tags_count":80,"template":false,"template_full_name":null,"purl":"pkg:github/ipld/js-ipld-schema","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipld%2Fjs-ipld-schema","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipld%2Fjs-ipld-schema/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipld%2Fjs-ipld-schema/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipld%2Fjs-ipld-schema/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ipld","download_url":"https://codeload.github.com/ipld/js-ipld-schema/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipld%2Fjs-ipld-schema/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29153112,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-06T02:39:25.012Z","status":"ssl_error","status_checked_at":"2026-02-06T02:37:22.784Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-16T16:08:58.759Z","updated_at":"2026-02-06T06:00:15.805Z","avatar_url":"https://github.com/ipld.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @ipld/schema\n\nJavaScript [IPLD](http://ipld.io/) Schema parser, validator, and code generator.\n\n## What are IPLD Schemas?\n\nIPLD Schemas define a type system for content-addressed data. Think of them like TypeScript or Protocol Buffers, but designed for immutable, linked data structures. They help you:\n\n- 🛡️ **Validate** that your data matches an expected structure\n- 🔄 **Transform** between compact binary formats and developer-friendly JSON\n- 🏗️ **Generate** type-safe code in multiple languages (Go, Rust, TypeScript)\n- 🔗 **Link** between data structures using content identifiers (CIDs)\n\nLearn more at https://ipld.io/docs/schemas/\n\n## Features\n\n- **Parse and validate** IPLD Schema DSL (Domain Specific Language)\n- **Runtime validation** with automatic format conversion\n- **Code generation** for Go, Rust, and TypeScript\n- **Advanced type features**: optional fields, defaults, renames, type aliases\n- **Multiple data representations** for space-efficient storage\n- **CLI tools** for validation and code generation\n\n## Installation\n\n```bash\nnpm install @ipld/schema\n```\n\nFor CLI usage:\n```bash\nnpm install -g @ipld/schema\n```\n\n## Quick Start\n\n### Basic Schema Definition\n\nIPLD Schemas use a simple, readable syntax:\n\n```js\nimport { fromDSL } from '@ipld/schema/from-dsl.js'\nimport { create } from '@ipld/schema/typed.js'\n\n// Define your schema\nconst schema = fromDSL(`\n  # A simple user profile schema\n  type UserProfile struct {\n    username String\n    email String\n    age Int\n    isActive Bool\n  }\n`)\n\n// Create a validator\nconst validator = create(schema, 'UserProfile')\n\n// Validate some data\nconst userData = {\n  username: 'alice',\n  email: 'alice@example.com',\n  age: 25,\n  isActive: true\n}\n\nconst validatedData = validator.toTyped(userData)\nif (validatedData === undefined) {\n  console.error('Invalid data!')\n} else {\n  console.log('Valid user profile:', validatedData)\n}\n```\n\n## Schema Language Basics\n\n### Basic Types\n\n```ipldsch\ntype MyString String     # UTF-8 string\ntype MyInt Int           # Signed integer\ntype MyFloat Float       # Floating point\ntype MyBool Bool         # Boolean\ntype MyBytes Bytes       # Binary data\ntype MyLink \u0026Any         # IPLD Link (CID)\n```\n\n### Structs (Objects)\n\n```ipldsch\ntype Person struct {\n  name String\n  age Int\n  email String optional          # Optional field\n  nickname String (implicit \"\")  # Default value\n}\n```\n\n### Lists and Maps\n\n```ipldsch\n# List of strings\ntype Names [String]\n\n# Map from string to integers\ntype Scores {String: Int}\n\n# Nested structures\ntype Team struct {\n  name String\n  members [Person]\n  metadata {String: String}\n}\n```\n\n### Enums\n\n```ipldsch\ntype Status enum {\n  | Active\n  | Inactive\n  | Pending\n}\n\n# With custom string values\ntype Color enum {\n  | Red (\"red\")\n  | Green (\"green\")\n  | Blue (\"blue\")\n} representation string\n```\n\n### Type Aliases\n\n```ipldsch\ntype UserID = String\ntype Timestamp = Int\ntype EmailAddress = String\n```\n\n## Data Representations\n\nIPLD Schemas separate the logical structure (what developers work with) from the storage format (how it's encoded). This allows for space-efficient storage while maintaining developer-friendly APIs.\n\n### Example: Tuple Representation\n\n```js\nimport { fromDSL } from '@ipld/schema/from-dsl.js'\nimport { create } from '@ipld/schema/typed.js'\n\nconst schema = fromDSL(`\n  # Store as array instead of object to save space\n  type Point struct {\n    x Float\n    y Float\n  } representation tuple\n`)\n\nconst validator = create(schema, 'Point')\n\n// Work with nice objects in your code\nconst point = { x: 10.5, y: 20.3 }\n\n// But it's stored as a compact array\nconst stored = validator.toRepresentation(point)\nconsole.log(stored) // [10.5, 20.3]\n\n// And automatically converted back\nconst restored = validator.toTyped(stored)\nconsole.log(restored) // { x: 10.5, y: 20.3 }\n```\n\n## Code Generation\n\nGenerate type-safe code from your schemas:\n\n### Go\n\n```js\nimport { fromDSL } from '@ipld/schema/from-dsl.js'\nimport { generateGo } from '@ipld/schema/gen/go.js'\n\nconst schema = fromDSL(`\n  type Person struct {\n    name String\n    age Int optional\n  }\n`)\n\nconst goCode = generateGo(schema, { packageName: 'person' })\n// Generates Go structs with proper JSON tags and pointer types for optionals\n```\n\n### Rust\n\n```js\nimport { generateRust } from '@ipld/schema/gen/rust.js'\n\nconst rustCode = generateRust(schema)\n// Generates Rust structs with serde derives and Option\u003cT\u003e for optionals\n```\n\n### TypeScript\n\n```js\nimport { generateTypeScript } from '@ipld/schema/gen/typescript.js'\n\nconst tsCode = generateTypeScript(schema)\n// Generates TypeScript interfaces and runtime validators\n```\n\n## Advanced Features\n\n### Field Renames\n\nControl JSON field names separately from your schema field names:\n\n```ipldsch\ntype ServerConfig struct {\n  serverPort Int (rename \"server_port\")\n  debugMode Bool (rename \"debug_mode\")\n  apiKey String (rename \"api_key\")\n}\n```\n\n### Annotations\n\nAdd language-specific type information:\n\n```ipldsch\n# Use big integers in Go\n# @gotype(big.Int)\ntype Balance Int\n\ntype Transaction struct {\n  # Custom serialization in Rust\n  # @rustserde(with = \"chrono::serde::ts_seconds\")\n  timestamp Int\n\n  # Multiple annotations\n  # @gotag(`json:\"tx_id\" db:\"transaction_id\"`)\n  id String\n}\n```\n\n### Custom Transforms\n\nHandle special encoding requirements:\n\n```js\nconst customTransforms = {\n  Base64String: {\n    // Decode base64 strings to bytes\n    toTyped: (str) =\u003e {\n      try {\n        return Uint8Array.from(atob(str), c =\u003e c.charCodeAt(0))\n      } catch {\n        return undefined\n      }\n    },\n    // Encode bytes to base64 strings\n    toRepresentation: (bytes) =\u003e {\n      return btoa(String.fromCharCode(...bytes))\n    }\n  }\n}\n\nconst validator = create(schema, 'MyType', { customTransforms })\n```\n\n## Command Line Interface\n\nThe `ipld-schema` command provides tools for working with schemas:\n\n### Validation\n\n```bash\n# Validate schema files\nipld-schema validate schema.ipldsch\n\n# Extract and validate schemas from markdown\nipld-schema validate README.md\n```\n\n### Conversion\n\n```bash\n# Convert to JSON format\nipld-schema to-json schema.ipldsch\n\n# Pretty print as canonical schema\nipld-schema to-schema schema.ipldsch\n```\n\n### Code Generation\n\n```bash\n# Generate JavaScript validators\nipld-schema to-js schema.ipldsch\n\n# Generate TypeScript definitions\nipld-schema to-tsdefs schema.ipldsch\n```\n\n## API Reference\n\n### Parsing Schemas\n\n- `fromDSL(dsl: string)` - Parse schema DSL into an AST\n- `toDSL(schema: Schema)` - Convert AST back to DSL\n\n### Validation\n\n- `create(schema: Schema, type: string, options?)` - Create a validator\n  - Returns `{ toTyped, toRepresentation }`\n  - `toTyped(data)` - Validate and convert from storage format\n  - `toRepresentation(data)` - Validate and convert to storage format\n\n### Code Generation\n\n- `generateGo(schema, options)` - Generate Go code\n- `generateRust(schema, options)` - Generate Rust code\n- `generateTypeScript(schema, options)` - Generate TypeScript code\n\n## License \u0026 Copyright\n\nCopyright 2019-2025 Rod Vagg\n\nLicensed under either of\n\n * Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / http://www.apache.org/licenses/LICENSE-2.0)\n * MIT ([LICENSE-MIT](LICENSE-MIT) / http://opensource.org/licenses/MIT)\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fipld%2Fjs-ipld-schema","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fipld%2Fjs-ipld-schema","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fipld%2Fjs-ipld-schema/lists"}