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

putitdigital-api-v1

v0.0.1

Published

User API v1 routes and controllers for the project

Readme

API v1 — Overview

This document describes the endpoints, configuration, and operational notes for the v1 API in this repository.

Getting Started

  • Install dependencies:
npm install
  • Run the server (development using nodemon):
npm run start
  • Environment variables: create a .env in the project root with at least:
PORT=8080
JWT_SECRET=<your_jwt_secret>
REFRESH_TOKEN_SECRET=<your_refresh_secret>

You can generate secure secrets in Node:

node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"

The app loads .env from the project root (see server.js).

Publishing v1

  • The v1 folder is configured as a local scoped package with name: "@putitdigital/api-v1" in v1/package.json.
  • It also uses public access by default in v1/package.json via publishConfig.access.
  • To publish to npm, run:
cd v1
npm publish --otp=<your-2fa-code>
  • Replace <your-2fa-code> with the current code from your npm authenticator app.
  • If you are using a granular token, it must allow publish and bypass 2FA.

Configuration If id is not AUTO_INCREMENT, run:

ALTER TABLE users MODIFY id INT NOT NULL AUTO_INCREMENT PRIMARY KEY;

Use a text/varchar column for phone numbers:

ALTER TABLE users MODIFY number VARCHAR(20);
  • DB config is in v1/config/db.js. Update host/port/user/password/database to match your MySQL instance.
  • The v1 module is also set up as a local scoped package. In server.js it is imported as:
const userRoutes = require('@putitdigital/api-v1');

This makes the v1 folder behave like a module package instead of requiring a deeper relative path.

API Endpoints (v1)

  • All endpoints are mounted under /api (see server.js).

  • GET /api/users

    • Description: List all users
    • Response: 200 JSON array of user objects (password field is stored hashed and not returned by the login helper)
  • GET /api/users/:id

    • Description: Get a single user by id
    • Response: 200 user object, 404 if not found
  • POST /api/users

    • Description: Create a new user
    • Required fields (JSON body): email, password (also provide name recommended)
    • Optional: number (phone number — must be digits only and sent as a string)
    • Validations and responses:
      • 400 — invalid JSON or missing/invalid fields (e.g., missing password or invalid number)
      • 409Email already exists (controller checks for existing email)
      • 201 — created: { id: <newId> }
    • Behavior: password is hashed with bcrypt before insert. The API strips any id provided by clients so the DB can auto-increment.
  • PUT /api/users/:id

    • Description: Update user fields
    • Responses: 200 success, 404 not found, 500 server errors
  • DELETE /api/users/:id

    • Description: Delete a user
    • Responses: 200 success, 404 not found
  • POST /api/login

    • Description: Authenticate user
    • Body: { "email": "...", "password": "..." }
    • Responses:
      • 200 — success: { message: 'Login successful', user: { ...userWithoutPassword, token } }
      • 404 — user not found
      • 401 — invalid password
      • 400 — account has no password set
    • Behavior: Returns a JWT signed with JWT_SECRET and valid for 1 hour.

Scripts

  • scripts/setPassword.js — generate a bcrypt hash and set the password column for a user by email. Usage:
node scripts/setPassword.js '[email protected]' 'newPassword'

Database notes & recommended schema

  • Recommended column types:

    • idINT NOT NULL AUTO_INCREMENT PRIMARY KEY
    • emailVARCHAR(255) with a UNIQUE index
    • passwordVARCHAR(255) (bcrypt hashes)
    • numberVARCHAR(20) (phone numbers stored as strings)
  • Useful SQL to fix schema issues:

ALTER TABLE users MODIFY id INT NOT NULL AUTO_INCREMENT PRIMARY KEY;
ALTER TABLE users MODIFY number VARCHAR(20);
ALTER TABLE users ADD UNIQUE INDEX ux_users_email (email);

Common problems & troubleshooting

  • 400 Invalid JSON payload — your request body may be malformed (e.g., numeric literals with leading zeros). Always send valid JSON; send phone numbers as strings.
  • Out of range value for column 'number' — change number column to VARCHAR(20).
  • This account has no password set or Invalid password — verify the password column has a bcrypt hash. Use scripts/setPassword.js to set a hash.
  • process.env.PORT undefined — ensure .env exists in project root. server.js loads .env explicitly from the project root.

Security notes

  • Passwords are hashed using bcrypt before storing.
  • JWTs are issued using JWT_SECRET and expire in 1 hour.

Where to look in the code

If you want, I can also add an OpenAPI (Swagger) spec or expand the README with example curl or Postman requests. Which would you prefer next?

cd v1 npm publish --access public --otp=123456