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

@ilingo/validup

v1.0.1

Published

Translate validup Issues through ilingo — framework-agnostic core with default EN/DE/FR/ES catalogs.

Readme

@ilingo/validup

Translate validup Issues through ilingo — default EN / DE / FR / ES catalogs for the built-in IssueCodes, a pre-seeded Store, and pure translateIssue / translateIssues helpers.

No Vue dependency. Embeddable in any runtime: Node SSR, edge workers, queue handlers, CLI tools. Vue 3 users add @ilingo/validup-vue on top for composables, the renderless component, and the install plugin.

Installation

npm install @ilingo/validup ilingo validup

Quick start

import { Ilingo } from 'ilingo';
import { translateIssue } from '@ilingo/validup';
import { createMemoryStore } from '@ilingo/validup/store/memory';
import { defineIssueItem, IssueCode } from 'validup';

const ilingo = new Ilingo({ locale: 'en' });
ilingo.registerStore(createMemoryStore()); // EN/DE/FR/ES 'validup' catalog (idempotent)

const issue = defineIssueItem({
    path: ['email'],
    message: 'The value is invalid',
    code: IssueCode.VALUE_INVALID,
});

const message = await translateIssue(issue, ilingo);
// "The value is invalid" (or the German / French / Spanish form when locale flips)

API

The package core (@ilingo/validup) is data-free — it carries the translateIssue(s) helpers, the NAMESPACE / STORE_ID constants, and the catalog types, but no translation modules. The catalog stores live behind two subpaths so you pay only for the backend you choose.

@ilingo/validup/store/memory — eager

createMemoryStore() builds an in-memory store with all four locales materialised up front, keyed by STORE_ID. Ilingo.registerStore dedupes by store.id, so registering twice (or from a duplicate package copy) is a no-op:

import { Ilingo } from 'ilingo';
import { createMemoryStore } from '@ilingo/validup/store/memory';
import { STORE_ID } from '@ilingo/validup';

const ilingo = new Ilingo();
ilingo.registerStore(createMemoryStore());
ilingo.registerStore(createMemoryStore()); // no-op — same STORE_ID
ilingo.stores.has(STORE_ID);               // → true

This subpath also exports Store, extendStore(), and the raw per-locale catalogs (en, de, fr, es — each a TranslationsNode).

@ilingo/validup/store/loader — lazy

createLoaderStore() builds a LoaderStore that fetches each locale on first use via dynamic import() — every locale is a separate bundle chunk, so a browser app ships only the locales it actually renders. Importing this subpath pulls in none of the translation data up front.

import { Ilingo } from 'ilingo';
import { createLoaderStore } from '@ilingo/validup/store/loader';

const ilingo = new Ilingo();
ilingo.registerStore(createLoaderStore());

@ilingo/validup-vue's install hook registers the eager memory store (Vue apps default to bundling all locales); opt into the loader by skipping it and registering createLoaderStore() yourself.

translateIssue(issue, ilingo, opts?)

Resolve a single Issue (item or group) to a localized string. Lookup order is issue.code → catalog entry → fall back to issue.message, so the UI always renders something even when an extension code isn't in the catalog.

translateIssues(issues, ilingo, opts?)

Flatten an Issue[] to its leaf IssueItems and translate each in parallel via Promise.all. Useful in SSR template loops, queue workers, log formatters — anywhere outside Vue. Returns IssueTranslation[] ({ issue, message }).

translateIssueGroups(groups, ilingo, opts?)

Translate an IssueGroup[] — each by its own code (e.g. one_of_failed) — without descending into the group's children. The group-level counterpart to translateIssues: where that flattens to per-field leaves, this keeps each group intact for whole-form / banner rendering ("none of the alternatives validated"). Returns IssueGroupTranslation[] ({ issue, message }, where issue is the IssueGroup).

Options on all three: { locale?: string, namespace?: string }. The default namespace is 'validup'; override when you've mounted translations under a different name.

Default catalogs

import { en, de, fr, es } from '@ilingo/validup/store/memory';

Each is a TranslationsNode (defineTranslations(...), i.e. { type: 'translations', data }) keyed by the built-in IssueCode runtime values. (They live on the ./store/memory subpath — the eager entry — so the data-free core stays free of translation modules.)

Extending / overriding the validup namespace

The validup namespace is a shared key-space — it isn't owned solely by this package. ilingo's serial store walk falls through store-by-store per key, so an app co-owns the namespace by registering its own store first: it adds translations for its custom extension IssueCodes and overrides individual built-in messages, while this catalog supplies the defaults for everything else.

import { Ilingo, MemoryStore, defineCatalog, defineLocale, defineNamespace, defineTranslations } from 'ilingo';
import { createMemoryStore } from '@ilingo/validup/store/memory';

const ilingo = new Ilingo({ locale: 'en' });

// app store FIRST → wins per (locale, namespace, key)
ilingo.registerStore(new MemoryStore({
    data: defineCatalog([
        defineLocale('en', [
            defineNamespace('validup', [
                defineTranslations({
                    email_taken: 'That email is already registered', // custom extension code
                    value_invalid: 'Please check this field',        // overrides the built-in
                }),
            ]),
        ]),
        defineLocale('de', [
            defineNamespace('validup', [
                defineTranslations({ email_taken: 'Diese E-Mail ist bereits registriert' }),
            ]),
        ]),
    ]),
}));

// built-in catalog appended → fills every code the app store doesn't define
ilingo.registerStore(createMemoryStore());

The validup namespace name is exported as NAMESPACE if you'd rather build the catalog programmatically.

Going Vue

For composables (useTranslationsForIssues, useTranslationsForField, useTranslationsForComposable, useTranslationsForGroupErrors, useFieldValidation), the <IValidup> / <IValidupT> / <IFieldValidation> renderless components, and the Vue plugin install hook, add @ilingo/validup-vue.

License

MIT © Peter Placzek