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

@danceroutine/tango-schema

v1.10.3

Published

Model factory, Zod helpers, and metadata utilities for Tango

Readme

@danceroutine/tango-schema

@danceroutine/tango-schema defines Tango models, structural metadata, and model-owned write lifecycle hooks.

A Tango model is the shared contract that the ORM, migrations, resources, OpenAPI generation, and code generation read from. The schema package keeps those layers aligned by giving them one model definition to build on.

Install

pnpm add @danceroutine/tango-schema zod

Quick start

import { z } from 'zod';
import { Model, t } from '@danceroutine/tango-schema';

const PostSchema = z.object({
    id: t.primaryKey(z.number().int()),
    title: z.string(),
    slug: z.string(),
    content: z.string(),
    createdAt: z.string(),
    updatedAt: z.string(),
});

export const PostModel = Model({
    namespace: 'blog',
    name: 'Post',
    schema: PostSchema,
    hooks: {
        async beforeCreate({ data }) {
            const now = new Date().toISOString();

            return {
                ...data,
                createdAt: now,
                updatedAt: now,
            };
        },
        async beforeUpdate({ patch }) {
            return {
                ...patch,
                updatedAt: new Date().toISOString(),
            };
        },
    },
});

PostModel becomes the source of truth for:

  • field metadata and primary-key identity
  • relation and index metadata
  • migration generation
  • Model.objects manager attachment in the ORM
  • model-owned write lifecycle hooks

Model lifecycle hooks

Model hooks live on the model definition through hooks. They run inside Model.objects, which means the same persistence rules apply across serializers, viewsets, scripts, and direct manager usage.

Use model hooks for persistence rules such as:

  • timestamp stamping
  • slug generation that should apply for every write path
  • default persisted values
  • normalization that belongs to the record itself

The write hook surface includes:

  • beforeCreate and afterCreate
  • beforeUpdate and afterUpdate
  • beforeDelete and afterDelete
  • beforeBulkCreate and afterBulkCreate

before* hooks may return normalized data to persist. after* hooks are for observation and side effects after the write succeeds.

How the schema package fits with serializers

Serializers stay Zod-backed and continue to own request validation, update validation, and output representation.

Model hooks serve a different role. They hold persistence rules that should run for every caller of Model.objects, even when the write does not come from a resource.

That split keeps the model responsible for record lifecycle behavior while the serializer stays focused on the HTTP-facing contract.

Public API

The root export includes:

  • Model
  • RelationBuilder
  • ModelRegistry
  • metadata helpers such as t, m, c, and i
  • model and relation domain types
  • model write hook types such as ModelWriteHooks

The root import is the normal entrypoint for application code. The domain and model subpaths are available when you want narrower imports.

Documentation

Development

pnpm --filter @danceroutine/tango-schema build
pnpm --filter @danceroutine/tango-schema typecheck
pnpm --filter @danceroutine/tango-schema test

For the wider contributor workflow, use:

License

MIT