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

webapp-factory

v0.1.1

Published

webapp-factory — verzamelpackage. De backend-foundation-collectie (domein-loze, herbruikbare backend-kits: config, http, persistence, ...) is bereikbaar onder de subpath `webapp-factory/backend-foundation`.

Readme

webapp-factory

Collectie van domein-loze, herbruikbare backend-kits. Elke kit is een pure TypeScript-module (ports & adapters, geen domeinkennis) die via een namespace of subpath geïmporteerd wordt. Eén package, één versielijn, semver.

// Namespace-import (root):
import { config } from 'webapp-factory/backend-foundation';
const cfg = await config.loadConfig({ schema, env: process.env });

// of subpath-import (laadt alleen die kit):
import { loadConfig } from 'webapp-factory/backend-foundation/config';

Installatie

npm install webapp-factory zod

zod is een (optionele) peer-dependency voor de kits die schemavalidatie bieden.

Kits

| Kit | Namespace | Subpath | Status | |-----|-----------|---------|--------| | config | config | webapp-factory/backend-foundation/config | Integratiegids | ✅ EPIC-01 (US-0101 t/m US-0105) | | http | http | webapp-factory/backend-foundation/http | Integratiegids | ✅ EPIC-02 (US-0201 t/m US-0207) | | persistence | persistence | webapp-factory/backend-foundation/persistence | Integratiegids | ✅ EPIC-03 (US-0301 t/m US-0305) | | auth | auth | webapp-factory/backend-foundation/auth | Integratiegids | ✅ EPIC-04 (US-0401 t/m US-0404) | | access-control | accessControl | webapp-factory/backend-foundation/access-control | Integratiegids | ✅ EPIC-05 (US-0501 t/m US-0504) | | rate-limit | rateLimit | webapp-factory/backend-foundation/rate-limit | Integratiegids | ✅ EPIC-06 (US-0601 t/m US-0604) | | cache | cache | webapp-factory/backend-foundation/cache | Integratiegids | ✅ EPIC-07 (US-0701 t/m US-0704) | | jobs | jobs | webapp-factory/backend-foundation/jobs | Integratiegids | ✅ EPIC-08 (US-0801 t/m US-0804) | | audit-log | auditLog | webapp-factory/backend-foundation/audit-log | Integratiegids | ✅ EPIC-10 (US-1001 t/m US-1004) | | observability | observability | webapp-factory/backend-foundation/observability | Integratiegids | ✅ EPIC-11 (US-1101 t/m US-1104) | | i18n | i18n | webapp-factory/backend-foundation/i18n | Integratiegids | ✅ EPIC-13 (US-1301 t/m US-1304) | | mailer | mailer | webapp-factory/backend-foundation/mailer | Integratiegids | ✅ EPIC-09 (US-0901 t/m US-0904) | | privacy | privacy | webapp-factory/backend-foundation/privacy | Integratiegids | ✅ EPIC-12 (US-1201 t/m US-1205) | | test-kit | testKit | webapp-factory/backend-foundation/test-kit | Integratiegids | ✅ EPIC-14 (US-1401 t/m US-1404) |

De kolom-kop hierboven is: Kit · Namespace · Subpath · Integratiegids · Status.

Per kit is er een taakgerichte integratiegids in docs/: poorten, wiring, recepten, testadvies en valkuilen (deze README geeft alleen het API-overzicht).

Een nieuwe kit toevoegen betekent:

  1. src/<kit>/ met een eigen index.ts (pure core + adapters).
  2. een namespace-export in de root-src/index.ts (export * as <kit> from './<kit>/index.js').
  3. een subpath in exports (en /<kit>/nestjs als er een Nest-adapter is).
  4. een integratiegids docs/<kit>.md volgens de vaste opbouw in docs/README.md.

Kit: config

Getypte configuratie- en secret-loading met schemavalidatie, fail-fast start en per-omgeving overrides.

import { z } from 'zod';
import { config } from 'webapp-factory/backend-foundation';

const schema = config.zodSchema(
  z.object({
    app: z.object({ name: z.string() }),
    db: z.object({
      host: z.string(),
      port: z.coerce.number().int().min(1).max(65535).default(5432),
      password: config.zodSecret(), // opgelost + geredigeerd
    }),
    log: z.object({ level: z.enum(['debug', 'info', 'warn', 'error']).default('info') }),
  }),
);

const cfg = await config.loadConfig({
  schema,
  base: { log: { level: 'info' } },
  overrides: { production: { log: { level: 'warn' } } },
  environmentKey: 'APP_ENV',
  env: process.env, // DB__HOST -> db.host, DB__PORT -> db.port (gecoerced)
  resolver: config.compositeSecretResolver(
    config.fileSecretResolver(), // file:///run/secrets/...
    config.mapSecretResolver('vault', { 'kv/data/db#password': '…' }),
  ),
  reporter: config.consoleReporter(),
  onFailure: 'exit', // fail-fast met niet-nul exitcode
});

cfg.db.port; // number, default toegepast
cfg.db.password.reveal(); // pas op het punt van gebruik
JSON.stringify(cfg); // db.password -> "***"

Kernconcepten

  • Env (US-0101): DB__HOST → db.host; scheidingsteken __, lowercased; optionele prefix. Voorrang laag→hoog: base → per-omgeving override → sources → .env → env. Coercie schema-gedreven (z.coerce.*) of standalone met coerceByMap.
  • Secrets (US-0102): referenties (file://, vault://, custom) worden via de SecretResolver-poort opgelost en in een Secret gewrapt die zichzelf consequent redigeert (JSON.stringify/inspect/String/spread). Onoplosbaar → SecretResolutionError zonder secretwaarde.
  • Validatie (US-0103): zodSchema(...) leidt het type af via z.infer, verzamelt álle overtredingen (pad + reden, geen invoerwaarden) en levert een bevroren object.
  • Fail-fast (US-0104): geaggregeerd, geredigeerd rapport via de Reporter-poort; onFailure: 'exit' → niet-nul exitcode, anders ConfigValidationError.
  • Overrides (US-0105): base + overrides[<env>] diepe merge (override wint); onbekende omgeving valt terug op de basis; fouten benoemen de omgeving.

Ports (injecteer je eigen adapters)

| Port | Verantwoordelijkheid | Meegeleverde adapters | |------|----------------------|-----------------------| | ConfigSchema<T> | valideren + type afleiden | zodSchema, zodSecret | | SecretResolver | referenties oplossen | fileSecretResolver, mapSecretResolver, functionSecretResolver, compositeSecretResolver | | Reporter | foutrapport uitschrijven | consoleReporter, collectingReporter |

NestJS

import { ConfigKitModule, CONFIG_KIT } from 'webapp-factory/backend-foundation/config/nestjs';

@Module({ imports: [ConfigKitModule.forRootAsync({ schema, env: process.env })] })
export class AppModule {}
// constructor(@Inject(CONFIG_KIT) private readonly cfg: AppConfig) {}

Ontwikkeling

npm install        # vanuit de repo-root (npm workspaces) of vanuit deze package
npm run build      # tsc -> dist/
npm test           # vitest run (324 tests, incl. HTTP-e2e, echte Postgres- en Redis-testcontainer-e2e, auth-flow- en guard-e2e)
npm run typecheck

Portabiliteits-contract (per kit)

  • Geen domeinkennis — alleen abstracties (schema, resolver, reporter, omgevingen).
  • Ports & adapters — de core definieert interfaces; het project levert adapters/config.
  • Config-injectie — geen hardcoded waardes of vaste omgevingsnamen.
  • Semver — breaking changes aan de publieke API vereisen een major-bump van de collectie.

Bron & conventies: ../../GENERATION-GUIDE.md.