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

@latimer-woods-tech/intake

v0.2.0

Published

The portfolio's customer intake horizontal — requests/jobs with attached files, a role-aware lifecycle state machine, hardened upload handling (magic-byte sniffing, ownership-scoped keys), and a mountable Hono router. Built once under the extraction contr

Readme

@latimer-woods-tech/intake

The portfolio's customer intake horizontal: customers open requests/jobs, attach files, exchange messages, and track a role-aware lifecycle — built once, mounted by hosts. Charter: docs/planning/intake-portal.md (RATIFIED 2026-07-13); access model: ADR-0016.

Extraction contract

The package never imports a host package and never owns a user table. A host injects four narrow ports at mount time; swap the host and only these change:

| Port | Question it answers | COH v1 implementation | |---|---|---| | IdentityPort | Who is making this HTTP request? | cookie/Bearer JWT → {id, email, role} (clientcustomer, adminstaff) | | StoragePort | Where do file bytes live? | R2 MEDIA binding under the intake/ prefix | | NotifierPort | How do participants hear about activity? (best-effort) | Resend templates | | AuditPort | Where do staff mutations get recorded? | writeAuditaudit_log |

Mount (Hono host)

import { createIntakeRouter, DrizzleIntakeStore } from '@latimer-woods-tech/intake';

const portal = createIntakeRouter({
  store: new DrizzleIntakeStore(db),          // any Drizzle pg handle
  identity: {                                  // host auth → Viewer | null
    getViewer: async (c) => {
      const user = await resolveYourSession(c as Context);
      if (!user) return null;
      return {
        id: user.id,
        email: user.email,
        role: user.role === 'client' ? 'customer' : 'staff',
      };
    },
  },
  storage: wrapR2(env.MEDIA, 'your-bucket-name'), // R2-shaped StoragePort
  notifier: { notify: async (n) => sendYourEmail(n) },
  audit: { record: async (e) => writeYourAudit(e) },
  limits: {
    categories: ['consultation', 'custom-order', 'other'],
    maxRelayBytes: 20 * 1024 * 1024,
  },
});

app.route('/api/portal', portal); // host adds its own rate limits around this

The host owns rate limiting, CORS, and monitoring around the mount. The router 401s when getViewer returns null and 404s (never 403s) cross-customer probes — no existence oracle.

Routes

| Route | Actor | Notes | |---|---|---| | POST /requests | customer, or staff with onBehalfOf | 201 | | GET /requests | both | customers: own; staff: ?status=&customerEmail=&limit=&before= | | GET /requests/:id | both | detail + timeline + files + allowedTransitions | | POST /requests/:id/messages | both | customer reply on needs_info auto-returns it to in_review | | POST /requests/:id/transition | per machine | server-enforced REQUEST_TRANSITIONS | | POST /requests/:id/assign | staff | audited | | POST /requests/:id/files | both | relayed multipart ≤ maxRelayBytes; magic-byte sniffed inline | | POST /requests/:id/files/presign | both | 501 unless the storage port implements presignPut | | POST /requests/:id/files/:fileId/confirm | uploader | HEAD size check + post-confirm byte-range sniff | | GET /requests/:id/files/:fileId | both | Worker-streamed, attachment, private, no-store | | DELETE /requests/:id/files/:fileId | uploader or staff | soft delete; staff audited |

Upload rejections map to precise statuses: 413 too large, 415 type not allowed (image/svg+xml is hard-banned), 422 declared≠sniffed / size mismatch / not uploaded / file cap, 409 request closed.

Lifecycle

submitted → in_review → in_progress → needs_info ⇄ (customer reply) → completed | declined | cancelled

REQUEST_TRANSITIONS is exported — render UI controls from the same table the server enforces (allowedTransitions(status, role)).

Migrations

migrations/0000_intake_core.sql is canonical. Hosts COPY it into their own migration rail (COH: drizzle/0003_intake_tables.sql) — never fork the table definitions. Statements are separated with --> statement-breakpoint for embedded runners; the SQL is IF NOT EXISTS-idempotent.

DSR (privacy) wiring

createIntakeServices(config) returns the service pair without the router. For GET /privacy/export include store.listFilesForCustomer(scope, userId) + the customer's requests; for erasure, delete the customer's storage prefix (customerStoragePrefix(scope, userId)) and their rows.

Known limits (v1)

  • No antivirus: infected status is reserved for a future scanner; downloads are attachment-only so nothing renders inline.
  • Presigned uploads can't be sniffed in-flight; the post-confirm range sniff covers them after landing. Presign credentials must be bucket-scoped + write-only (ADR-0016).
  • The store is non-transactional; writes are ordered request-row-first so a crash can lose a timeline entry but never corrupt request state.