Unreleased changes
These pages document main, which has changes 0.1.2 does not. npm install @evanion/token gives you 0.1.2, documented here. Values on these pages are produced by running the current source on every build.
@evanion/token
Eliminate “No Such Order” errors with built-in error detection for human-readable codes.
When a customer reads a pickup code over the phone or types it into a form, a single misheard character can turn a valid code into a “no such order” error. This is frustrating for the user and makes it impossible for the staff to know if the code was truly invalid or just mistyped.
@evanion/token solves this by minting codes with built-in error detection. Its validate function can identify a misheard character before your application ever touches the database, allowing you to tell the user “That code looks slightly wrong” instead of “Order not found.”
The Problem: The “Invisible Typo”
In traditional systems, a code is just a random string. If a user types a4kp-9mx8 instead of a4kp-9mxa, the system performs a database lookup, finds nothing, and returns a generic 404 Not Found.
This creates a poor user experience:
- User Frustration: The user knows they typed something and doesn’t know where the error is.
- Staff Blindness: Support staff cannot tell the difference between a malicious probe and a simple typo.
- Database Waste: Every mistyped code triggers an unnecessary database query.
The Solution: Check Characters
@evanion/token implements a check-character system (similar to how credit card numbers work). A token consists of a random body followed by a single check character computed from that body.
For example, in the code a4kp-9mxa, the final a is the check character.
import { } from '@evanion/token';
const = ();
// ✅ Valid: matches the check character
.('a4kp-9mxa'); // -> { valid: true, body: 'a4kp9mx' }
// ❌ Invalid: rejected instantly due to a typo
.('a4kp-9mx8'); // -> { valid: false, reason: 'check-failed' }When you call validate, the library recalculates the check character from the body. If a customer reads a4kp-9mx8 (where the a was misheard as 8), validate immediately returns reason: 'check-failed'.
Your system can now refuse the code instantly, distinguishing a typo from a non-existent order without a single database call.
The Token Vocabulary
To help you use the API, here are the core terms:
- Code: The full string the user sees, such as
a4kp-9mxa. - Body: The random characters excluding separators and the check character. This is the part you store in your database.
- Check Character: The final character used for error detection, computed using the Luhn algorithm.
- Dictionary: The set of characters used to generate the code. The default dictionary excludes confusing characters like
i,l,o, andwto prevent misreads. - Chunk: A group of characters (four by default) used to make codes easier to read.
- Separator: The character between chunks (a hyphen by default).
- Prefix: An optional identifier, such as
ORD, added to the front of a code for categorization.
Core Capabilities
| You want to… | Use this tool |
|---|---|
| Mint a human-readable code | generate(), using cryptographically strong random values |
| Refuse a mistyped code instantly | validate(), which returns a specific reason for failure |
| Support flexible user input | validate(), which cleans hyphens and case before checking |
| Categorize codes (e.g., “ORD-”) | generate({ prefix: 'ORD' }) |
| Customize length or chunks | createToken({ length, chunkSize, separator }) |
| Use a custom character set | createToken({ dictionary }) |
| Calculate collision risk | entropyBits, to match code length to your volume |
Important Constraints
@evanion/token is an error-detection library, not a full identity or security system:
- Uniqueness:
generatedoes not check your database. Use aUNIQUEindex on your database column to ensure uniqueness. - Existence: A
valid: trueresult only means the code is well-formed. It does not mean the code was actually issued. - Security: These codes are for convenience (like pickup codes), not high-security credentials. They are susceptible to enumeration.
- Prefixes: The check character only covers the body. You must strip the prefix (e.g.,
ORD-) manually before callingvalidate. - Retrofitting: It cannot add check characters to existing IDs. For that, use the
@evanion/luhnpackage directly.
Install and Issue Your First Code
Now that you understand how check characters prevent “no such order” errors, you can set it up in your project. Getting started guides you through installing the package and implementing a pickup code flow.