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 🙏

© 2025 – Pkg Stats / Ryan Hefner

xsd-to-xast

v0.5.0

Published

Generate xast TypeScript types from an XSD schema

Downloads

65

Readme

xsd-to-xast

npm version badge

This is a fork of cxsd which tries to turn the output from cxsd into something for use with [xast](https://github.com/syntax-tree/xast).

It will output types that look like

/** A container for all title-level metadata for a single book that is not part of a series or set. */
export interface BookMetadata extends Element {
  type: 'element'
  name: 'book_metadata'
  attributes: {
    language?: Language
    referenceDistributionOpts?: ReferenceDistributionOpts
  }
  children: RequiredMap<BookMetadataChildren>
}

export interface BookMetadataChildren {
  /** Abstract */
  abstract?: jats.Abstract[]
  /** The date a manuscript was accepted for publication. */
  acceptanceDate?: AcceptanceDate
  /** Container element for archive information */
  archiveLocations?: ArchiveLocations
  /** A list of articles, books, and other content cited by the item being registered */
  citationList?: CitationList
  /** The container for all who contributed to authoring or editing an item. */
  contributors?: Contributors
  /** Container element for CrossMark data. */
  crossmark?: Crossmark
  /** The container for elements related directly to a DOI. */
  doiData?: DoiData
  /** The edition Text of a book. edition_number should include only a number and not additional text such as "edition". For example, you should submit "3", not "third edition" or "3rd edition". Roman numerals are acceptable. */
  editionNumber?: Text
  /** The ISBN assigned to an entity. */
  isbn: Isbn[]
  /** Identifies books or conference proceedings that have no ISBN assigned. */
  noisbn: Noisbn
  /** Wrapper element for relationship metadata */
  program?: rel.Program
  /** The date of publication. Multiple dates are allowed to allow for different dates of publication for online and print versions. */
  publicationDate: PublicationDate[]
  /** A container for information about the publisher of the item being registered */
  publisher: Publisher[]
  /** A container for item identification numbers set by a publisher. */
  publisherItem?: PublisherItem
  /** A container for the title and original language title elements. */
  titles: Titles
}

Explanation

Since its kinda hard to accurately represent XSDs in typescript, the children prop is not very true to the actual constraints provided by the XCSD.

It's difficult to represent an array of arbitrary size with some required members in Typescript, so to simplify things the children are something like

type BookMetdata['children'] = (jats.Abstract  | AcceptanceDate | CitationList ...)[]

This is not ideal, but the alternatives (tuples) really care about the order, which doesn't matter for the schema. If we have to choose between types that are too loose or too strict, I think too loose is better.

Install

npm i -g xsd-to-xast prettier

# yarn global add xsd-to-xast prettier
# pnpm add --global xsd-to-xast prettier

Usage

Ideally your types are accessible from a remote url.

If so, simply do e.g.

xsd-to-xast https://data.crossref.org/schemas/crossref5.3.1.xsd

and the types will be output somewhere.

Local xsds

To parse local xsds, do

npx serve /path/to/dir/containing/xsds
xsd-to-xast http://localhost:3000/schemafilename.xsd

However, this step has also been automated, so if you do

npx xsd-to-xast /path/to/dir/containing/xsds/filename.xsd

it should work.

Development

yarn
yarn build
./cxsd-cli.js <something>

The code is a bit of a mess, very hard to understand the structure of this project.

Sponsors

Love these legends

OLD README

cxsd is a streaming XSD parser and XML parser generator for Node.js and (optionally but highly recommended) TypeScript. It automatically downloads all referenced .xsd files and outputs two files for each defined namespace:

  • .js JavaScript code for Node.js containing a compact state machine table for the cxml parser.
  • .d.ts TypeScript definition with JSDoc comments to help editors with tab completion, type verification and tooltips.

Since namespaces map to source files, compiled namespaces can import others like normal JavaScript files.

cxml itself is highly advanced and unlike other JavaScript XML parsers. It fully supports namespaces, derived types and (soon) substitution groups. Output structure is defined mainly by schema, not the XML input. You can correctly parse files with completely unexpected structures (conditions apply) and element names, if they refer to a schema mapping the contents to supported equivalents.

Usage

echo '{ "scripts": { "cxsd": "cxsd" } }' > package.json
npm install cxsd
npm run cxsd http://schemas.opengis.net/wfs/1.1.0/wfs.xsd

The first line just sets up NPM to allow calling cxsd without installing it globally. It also works on Windows if you omit the single quotes (').

This downloads 96 .xsd files (total about 720 kilobytes) and produces 9 .js files for the XML parser (total about 90 kilobytes) and 9 .d.ts files (total about 480 kilobytes) for TypeScript editors to statically verify the parser output is correctly used and generally help the programmer.

You can import the resulting .d.ts and .js files from TypeScript:

import * as wfs from './xmlns/www.opengis.net/wfs';
import * as ows from './xmlns/www.opengis.net/ows';

var metadata = wfs.document.WFS_Capabilities.OperationsMetadata;

See how the Atom editor with atom-typescript understands the code in the screenshot at the top.

Features

  • Automatically download and cache to disk all imported .xsd files
  • Convert XSD contents to ES6 equivalents (generated .js files call cxml to parse themselves into JavaScript structures)
    • Types to classes
      • Deriving from other types to inheriting other classes
    • Imports from remote URLs to imports from local relative paths
    • Strings, numbers and dates to matching primitive types
    • Lists to arrays
  • To TypeScript equivalents (defined in .d.ts for working with source code)
    • Annotations to JSDoc comments
    • Enumerations to unions of string literals

Related projects

License

The MIT License

Copyright (c) 2015-2016 BusFaster Ltd