npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@ipld/schema

v6.0.4

Published

IPLD Schema parser and CLI utilities for JavaScript

Downloads

2,915

Readme

@ipld/schema

JavaScript IPLD Schema utilities.

Since v4.0.0 this package has been renamed to @ipld/schema. It was previously published to npm as ipld-schema.

Read more about IPLD Schemas at https://ipld.io/docs/schemas/

Usage

Parsing IPLD Schema DSL

IPLD Schemas have a parsed form, called a Data Model Tree (DMT), which is consumed where schemas are used. We can parse the DSL into the DMT with from-dsl.js:

import { fromDSL } from '@ipld/schema/from-dsl.js'

let schema = fromDSL(`
  type SimpleStruct struct {
    foo Int
    bar Bool
    baz String
  }
  type MyMap { String: SimpleStruct }
`)

console.dir(schema.types, { depth: Infinity })

// →
// {
//   SimpleStruct: {
//     struct: {
//       fields: {
//         foo: { type: 'Int' },
//         bar: { type: 'Bool' },
//         baz: { type: 'String' }
//       }
//     }
//   },
//   MyMap: { map: { keyType: 'String', valueType: 'SimpleStruct' } }
// }

You can also convert the DMT form back to DSL form with to-dsl.js:

import { toDSL } from '@ipld/schema/to-dsl.js'
const schema = {
  types: {
    SimpleStruct: {
      struct: {
        fields: {
          foo: { type: 'Int' },
          bar: { type: 'Bool' },
          baz: { type: 'String' }
        }
      }
    },
    MyMap: { map: { keyType: 'String', valueType: 'SimpleStruct' } }
  }
}

console.log(toDSL(schema))

// →
// type SimpleStruct struct {
//   foo Int
//   bar Bool
//   baz String
// }
//
// type MyMap {String:SimpleStruct}

Typed converters / validators

Use typed.js to create a converter/validator from an IPLD Schema that can receive IPLD block data and return either undefined if the data form doesn't match the Schema, or the same data if the Schema doesn't involve any transformation, or a transformed form of the data according to the Schema.

Note that create() will create a toTyped() / toRepresentation() function pair for you to run. For best performance results, you should do this just once with any given schema and reuse these functions whenever you need to process or validate data.

Typically, your application will want to interact with typed data, particularly when the representation form is terse and not as easy to modify. IPLD Schemas give you the ability to validate, decode and transform representation data to safely hand off to your application layer.

From representation form to typed form

import { fromDSL } from '@ipld/schema/from-dsl.js'
import { create } from '@ipld/schema/typed.js'

// a schema for a terse data format
const schemaDsl = `
type Garden struct {
  name String
  width Int
  depth Int
  plants [Plant]
} representation tuple

type Plant struct {
  species PlantSpecies
  height Int
} representation tuple

type PlantSpecies enum {
  | Murraya     ("1")
  | StarJasmine ("2")
  | Lemon       ("3")
  | Camellia    ("4")
} representation int
`

// parse schema
const schemaDmt = fromDSL(schemaDsl)

// create a typed converter/validator
const schemaTyped = create(schemaDmt, 'Garden')

// some terse input data
const data = ['Home', 460, 200, [[1, 30], [1, 28], [1, 29], [2, 10], [2, 11], [3, 140], [4, 230], [4, 200]]]

// validate and transform
const typedData = schemaTyped.toTyped(data)
if (typedData === undefined) {
  throw new TypeError('Invalid data form, does not match schema')
}

// what do we have?
console.log('Typed form:', typedData)

// →
// Typed form: {
//   name: 'Home',
//   width: 460,
//   depth: 200,
//   plants: [
//     { species: 'Murraya', height: 30 },
//     { species: 'Murraya', height: 28 },
//     { species: 'Murraya', height: 29 },
//     { species: 'StarJasmine', height: 10 },
//     { species: 'StarJasmine', height: 11 },
//     { species: 'Lemon', height: 140 },
//     { species: 'Camellia', height: 230 },
//     { species: 'Camellia', height: 200 }
//   ]
// }

From typed form to representation form

Once your application has a typed form of data and makes modifications, the data can be validated and transformed back into the representation form.

// modify our typed form now we have it in a form that makes sense to our application
typedData.depth += 50
typedData.plants[0].height += 2
typedData.plants[1].height += 2
typedData.plants[2].height += 1
typedData.plants.push({ species: 'StarJasmine', height: 5 })

// validate and transform back into representation form
const newData = schemaTyped.toRepresentation(typedData)
if (newData === undefined) {
  throw new TypeError('Invalid data form, does not match schema')
}

// what do we have?
console.log('Modified representation data:', JSON.stringify(newData))

// →
// ["Home",460,250,[[1,32],[1,30],[1,30],[2,10],[2,11],[3,140],[4,230],[4,200],[2,5]]]

Command line

@ipld/schema also exports an executable: if installed with -g you will get an ipld-schema command in your PATH.

This executable has two commands that operate on files or stdin.

  • ipld-schema validate [files...]: Accepts .ipldsch and .md files, if none are passed will read from stdin, returns exit code 0 on successful validation
  • ipld-schema to-json [-t] [files...]: Accepts .ipldsch files, if none are passed will read from stdin, prints the JSON form of the schema
  • ipld-schema to-schema [-t] [files...]: Accepts .ipldsch and .md files, if none are passed will read from stdin, prints the canonical IPLD Schema form of the schema
  • ipld-schema json-to-schema [files...]: Accepts .json files, if none are passed will read from stdin, prints the canonical IPLD Schema form of the schema represented by the JSON
  • ipld-schema to-js [--cjs] [files...]: Accepts .ipldsch files, if none are passed will read from stdin, prints a JavaScript module that exports a typed and representation converter/validator pair. If --cjs is passed, the returned JavaScript with be in CJS form, otherwise it will be in ESM form. These are the same pair that are generated from a @ipld/schema/typed.js#create() call for the schema in question, except that all types discovered within the schema will be exported as well.

validate, to-json, to-schema, and to-js take either .ipldsch or .md files. When using .md files, ipld-schema will extract any ``` code blocks using the ipldsch or sh language codes.

License & Copyright

Copyright 2019 Rod Vagg

Licensed under either of

  • Apache 2.0, (LICENSE-APACHE / http://www.apache.org/licenses/LICENSE-2.0)
  • MIT (LICENSE-MIT / http://opensource.org/licenses/MIT)

Contribution

Unless 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.