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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@miqro/parser

v2.0.6

Published

Schema validation and coercion with full TypeScript inference.

Downloads

609

Readme

@miqro/parser

Schema validation and coercion with full TypeScript inference.

basic usage

import { Parser } from "@miqro/parser";

const parser = new Parser();

// Type is inferred automatically from the schema
const result = parser.parse({ id: "1", title: "hello" }, {
  type: "object",
  properties: {
    id: "integer",
    title: "string",
    published: "boolean?"
  }
});

result.id        // number  (coerced from string)
result.title     // string
result.published // boolean | undefined

If you prefer to declare the schema separately, annotate it with Schema<T> to carry the explicit type (inference still works on inline schemas without it):

import { Parser, Schema } from "@miqro/parser";

interface Post { id: number; title: string; published?: boolean; }

const PostSchema: Schema<Post> = {
  type: "object",
  properties: { id: "integer", title: "string", published: "boolean?" }
};

const post = parser.parse(raw, PostSchema); // → Post

type string syntax

"string"         required string
"string?"        optional string (undefined if absent)
"number"         required number
"integer"        required integer (coerced)
"boolean"        required boolean ("true"/"false" coerced)
"string[]"       array of strings
"string[]?"      optional array of strings
"string[]!"      force single value into array, always returns string[]
"string[]!?"     optional force-array
"string|number"  string or number (first match wins)
"string|number?" string or optional number

built-in types

string, string1 (non-empty), number, integer, boolean
url, email, regex, regexp, function, any
object, array, dict, enum
decodeHTML, encodeHTML, schema

object schema

const result = parser.parse(raw, {
  type: "object",
  properties: {
    name: "string",
    age: "integer?",
    address: {
      type: "object?",
      properties: {
        city: "string",
        zip: "string?"
      }
    },
    tags: {
      type: "array",
      arrayType: "string"
    }
  }
});

result.name           // string
result.age            // number | undefined
result.address?.city  // string
result.tags           // string[]

mode

mode: "no_extra"     (default) throws if unknown properties are present
mode: "remove_extra" strips unknown properties, returns defined shape only
mode: "add_extra"    keeps unknown properties, type is defined shape & Record<string, unknown>
const result = parser.parse(raw, {
  type: "object",
  mode: "add_extra",
  properties: { id: "integer" }
});

result.id          // number
result["anything"] // unknown

array

// array of primitives
parser.parse(raw, { type: "array", arrayType: "string" }); // string[]

// array of objects — define element shape with co-located properties
const result = parser.parse(raw, {
  type: "array",
  arrayType: "object",
  properties: {
    id: "integer",
    label: "string"
  }
});
result[0].id    // number
result[0].label // string

// array of arrays
parser.parse(raw, { type: "array", arrayType: "number[]" }); // number[][]

enum

const result = parser.parse(raw, {
  type: "enum",
  enumValues: ["a", "b", "c"]
});
// result → "a" | "b" | "c"

dict

// dict of primitives
parser.parse(raw, { type: "dict", dictType: "number" });
// → Record<string, number>

// dict of objects — define value shape with co-located properties
const result = parser.parse(raw, {
  type: "dict",
  dictType: "object",
  properties: { x: "string", y: "number?" }
});
result["key"].x // string
result["key"].y // number | undefined

Aliases: Dict<string>, dict<string> are equivalent as type strings.

allowNull

parser.parse(raw, { type: "string", allowNull: true }); // string | null
parser.parse(raw, { type: "enum", enumValues: ["a", "b"], allowNull: true }); // "a" | "b" | null

InferSchema utility type

Use InferSchema<S> to derive the TypeScript type from a schema definition without calling parse:

import { InferSchema } from "@miqro/parser";

type T1 = InferSchema<"string?">;                                    // string | undefined
type T2 = InferSchema<"number[]">;                                   // number[]
type T3 = InferSchema<{ type: "object"; properties: { x: "string" } }>; // { x: string }
type T4 = InferSchema<{ type: "enum"; enumValues: readonly ["a","b"] }>; // "a" | "b"
type T5 = InferSchema<{ type: "number"; allowNull: true }>;          // number | null

custom parser

import { Parser } from "@miqro/parser";

const parser = new Parser();
parser.register("uuid", (value) => {
  if (typeof value === "string" && /^[0-9a-f-]{36}$/.test(value)) {
    return value;
  }
  // return undefined or throw ParseOptionsError to fail validation
});

parser.parse("123e4567-...", "uuid"); // → unknown

To get type inference for custom parsers, augment TypeMap in the module where it is declared:

declare module "@miqro/parser/build/built-in-parsers" {
  interface TypeMap {
    uuid: string;
  }
}

parser.parse("123e4567-...", "uuid");  // → string
parser.parse(raw, "uuid[]");           // → string[]
parser.parse(raw, "dict<uuid>");       // → Record<string, string>