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

@ooxml-tools/xml

v0.2.3

Published

Some XML helpers to help with OOXML development

Downloads

504

Readme

Some XML helpers to help with OOXML development

[!NOTE] These are all based around xml-js and output that modules internal format

API

asXmlElement

When working with xml-js it's really handy to not have to worry about when you're passing an XML string our the xml-js JSON type called Element

This helper function just outputs an Element for either input

asXmlElement("<name>foo</name>"); // => {name: "name", text: "foo"}
asXmlElement({ name: "name", text: "foo" }); // => {name: "name", text: "foo"}

[!NOTE] All the other functions in this document that accept XML, also accept this Element (using this function)

safeXml

An XML tagged template literal with the following features

  • error if XML is incorrect
  • array support in substitution

The following will error in development, because of mismatched start/end tags

safeXml`<foo>hello</bar>`;

Substitution of arrays "just works" so you can map values in the tagged template literals

const items = [1, 2, 3].map((n) => safeXml`<name>item ${1}</name>`);
const outXml = safeXml`<test>${items}</test>`;
assert.equal(
  outXml,
  `<test><name>item 1</name><name>item 2</name><name>item 3</name></test>`,
);

This also makes it easy to support https://prettier.io/docs/en/options#embedded-language-formatting

compact

Removes non required whitespace from the XML

const outXml = compact(`
    <test>
        something
    </test>
`);
assert.equal(outXml, "<test>something</test>");

collapseFragments

For XML to be valid, there must be a single root node. When composing apps it's handy for that not to be true.

For example the following would error

const xml = safeXml`
    <name>foo</name>
    <name>bar</name>
`;

So instead we'd like something like a HTML fragment

const xml = safeXml`
    <XML_FRAGMENT>
        <name>foo</name>
        <name>bar</name>
    </XML_FRAGMENT>
`;

So we did just that, collapseFragments walks over a tree removing <XML_FRAGMENT>...</XML_FRAGMENT> nodes.

const innerBit = safeXml`
    <XML_FRAGMENT>
        <name>foo</name>
        <name>bar</name>
    </XML_FRAGMENT>
`;
const newXml = collapseFragments(
  safeXml`
        <doc>
            ${innerBit}
        </doc>
    `,
);
assert.equal(
  newXml,
  `
    <doc>
        <name>foo</name>
        <name>bar</name>
    </doc>
`,
);

cdata

From the wikipedia page

CDATA section is a piece of element content that is marked up to be interpreted literally, as textual data, not as marked-up content.

But <name><![CDATA[one < two]]><name> is ugly and hard to read, so instead

safeXml`<name>${cdata("one < two")}</name>`;

format

Format XML in a consistent way, useful for logging and snapshot testing

format(`
   <test> one
      </test>
`); /* =>
 * <test>
 *   one
 * </test>
 */

getAllByTestId

const element = getAllByTestId(`
    <root>
        <name _testid="test">
            Hello
        </name>
    </test>
`)

getByTestId

const element = getByTestId(`
    <root>
        <name _testid="test">
            Hello
        </name>
    </test>
`)

getSingleTextNode

Returns a single text node if one exists

getSingleTextNode(`<test>hello world</test>`) // => {type: "text", text: "hello world"}

Else throws an error

getSingleTextNode(`<test>hello <foo>inner node</foo> world</test>`) // => throws Error

removeTestIds

const element = removeTestIds(`
    <root>
        <name _testid="test">
            Hello
        </name>
    </test>
`) /* =>
 * <root>
 *     <name>
 *         Hello
 *     </name>
 * </test>
 */

CI

codecov

License

MIT