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

@wulperstd/editor-core

v2.0.0

Published

Tiptap extension/command layer bound to @wulperstd/schema's block set.

Downloads

548

Readme

@wulperstd/editor-core

Tiptap extension/command layer bound to @wulperstd/schema's block set. It ships the node/mark extensions, editor-behavior bundle, and authoring utilities (paste detection/parsing, MDX serialization, a headless slash-command layer) needed to build a Tiptap editor for this block schema, without depending on any UI framework (@tiptap/react, @tiptap/vue-3, react, vue, ...) at import time.

Install

pnpm add @wulperstd/editor-core @tiptap/core @tiptap/pm @floating-ui/dom

@tiptap/core, @tiptap/pm, and @floating-ui/dom are required peer dependencies, not bundled ones: they are singletons — a second copy of @tiptap/core/@tiptap/pm in your dependency tree breaks instanceof checks and plugin identity — so install them alongside this package rather than relying on a transitive copy. Every other Tiptap extension this package uses internally (@tiptap/extension-details, @tiptap/extension-link, @tiptap/extension-list, @tiptap/extension-table, @tiptap/extensions, @tiptap/suggestion) is bundled and re-exported through blockExtensions, so you never install those directly.

ESM-only: this package is published as "type": "module" with no CommonJS entry in its exports map. It cannot be require()d from a CommonJS-only consumer — import it from ESM (or an async import()) instead.

Usage

import { Editor } from '@tiptap/core';
import { blockExtensions, behaviorExtensions } from '@wulperstd/editor-core';

const editor = new Editor({
  extensions: [...blockExtensions, ...behaviorExtensions()],
});

blockExtensions is the full node/mark extension set matching @wulperstd/schema's block set. behaviorExtensions(options?) bundles the editor-behavior extensions (UndoRedo, Dropcursor, Gapcursor, TrailingNode, Placeholder, ListKeymap) — both, and each extension individually, are also available as named exports.

Authoring utilities

Named exports outside blockExtensions (none of these are node/mark extensions, so none affect the schema extension-coverage check):

  • serializeMdx — serializes editor content to MDX.
  • detectPasteKind, mdxToHtml, PasteParser, pastePluginKey — paste-source detection and parsing.
  • createSlashCommand, filterSlashItems, slashActions — a headless slash-command suggestion layer.
  • classifyEmbedSrc, isCuratedEmbedSrc, toEmbedSrc — the embed-service matching/classification helpers behind embedExtension; the curated service list itself is supplied by your app via embedExtension's services option.

Security: CardLinkResolver

cardLinkExtension.configure({ resolver }) accepts a host-supplied CardLinkResolver:

type CardLinkResolver = (href: string) => Promise<CardLinkMetadata | null>;

No package in this repository ships an implementation — you write and register this function, and it performs SSRF-exposed network I/O. href is attacker-controllable: whoever can type in the editor chooses it, and the request is issued by your own backend, from inside your network. The obvious implementation — fetch(href), parse the og: tags — is the vulnerable one: a pasted http://169.254.169.254/latest/meta-data/... makes your backend read its own cloud credentials and persist them into a card's description.

Your implementation must, at minimum:

  • Accept only http/https, declining every other scheme before any access is attempted.
  • Block private, loopback, link-local, and other reserved IP ranges, explicitly including the cloud metadata address 169.254.169.254, before connecting to a resolved address.
  • Resolve the hostname once and connect to that validated IP, and repeat both the range validation and the pinned connection independently for every redirect hop — a hostname's resolution can change between the moment it is validated and the moment the connection is made (DNS rebinding).
  • Cap redirect depth, request timeout, and total response size, and validate the response Content-Type before parsing it for metadata. The specific limits are left to your deployment: choose values that suit it and make each one configurable rather than hardcoded.

Resolve to null — do not throw — when the URL legitimately has no discoverable preview data; throw or reject only for an actual I/O or parse failure. This package enforces no timeout of its own, so a timeout is your resolver's obligation and surfaces as a rejection. Either way, the node is left unpatched and marked failed; a partial CardLinkMetadata populating only some fields is a valid non-null result.

These obligations are normative (see specs/card-link-resolution/spec.md in this repository's internal planning); this README is the only consumer-facing place they are documented, since openspec/ does not ship to npm.