Generating and validating
@evanion/token 0.1.0 and its patch releases up to 0.1.2, the version on npm. Values on this page were produced by running the source at 77650ee, a later commit than the 0.1.0 tag, and are not re-executed.
To issue a pickup code as ORD-a4kp-9mxa and redeem it regardless of how a customer types it, you combine generate with a custom prefix and use validate to screen the input.
Minting a Pickup Code with a Prefix
You can make your codes more recognizable by adding a prefix like ORD-. This helps both users and staff identify the code’s purpose at a glance.
When you pass a prefix to generate, it returns the code in four fields:
const = ();
const = .({ : 'ORD' });
.; // -> 'ORD'
..; // -> 7
..; // -> 13
..(.); // -> truevalue: The full code as printed (ORD-a4kp-9mxa).body: The random characters used as the database key.check: The final check character.prefix: The prefix you provided.
Redeeming a Prefixed Code
The validate method is designed to work on the code’s body and check character; it does not know about your custom prefixes.
If you pass ORD-a4kp-9mxa directly to validate, it will treat ORD as part of the code and refuse it (often as outside-alphabet). You must strip the prefix before validating:
const = ();
const { } = .({ : 'ORD' });
.(); // -> { valid: false, reason: 'outside-alphabet' }
/** Validates a pickup code read back with or without its `ORD` prefix. */
function (: string) {
return .(.(/^ord-?/i, ''));
}
().; // -> true
(.()).; // -> true
(.('-', '')).; // -> trueIn the example above, validatePickupCode handles the stripping. Because the default dictionary excludes the letter o, no valid code can start with ord. This makes it safe to strip any leading ord (case-insensitively) without risk of accidentally removing part of the actual code.
Understanding Validation Failures
validate returns valid: true and the body if the code is well-formed, or valid: false and a reason if it fails.
const = ();
.('b0zg-7kqb'); // -> { valid: true, body: 'b0zg7kq' }
.('b0zg-7kq8'); // -> { valid: false, reason: 'check-failed' }
.('bozg-7kqb'); // -> { valid: false, reason: 'outside-alphabet' }
.('b0zg-7kq'); // -> { valid: false, reason: 'wrong-length' }reason | Meaning |
|---|---|
outside-alphabet | The code contains a character not found in the dictionary. |
wrong-length | The code does not match the required length. |
check-failed | The check character does not match the calculated value for the body. |
validate checks these conditions in order and reports the first failure. Since it has no side effects and never throws, you can run it on every request before performing a database lookup.
token.validate('b0zg-7kqb')Produced by @evanion/token 0.1.0 at 77650ee. Not re-executed. Run it live on the unreleased page.
Try typing a code above. Try changing the last character, typing an o for a
0, or dropping a character.
Flexible User Input
Customers rarely type codes perfectly. They might omit hyphens, use different grouping, or type everything in capitals.
validate handles this by automatically stripping the separator and folding the case before performing its checks.
const = ();
.('a4kp9mxa').; // -> true
.('a4-kp-9m-xa').; // -> true
.('A4KP-9MXA'); // -> { valid: true, body: 'a4kp9mx' }Because every variation of the spelling returns the same body, they all resolve to the same record in your database.
What the Check Character Catches
@evanion/token uses the Luhn algorithm to compute the check character. This provides a high degree of confidence in detecting common human errors:
- Single-Character Substitutions: Any single character misread or mistyped at any position is always caught.
- Adjacent Swaps: Almost every swap of two neighboring characters is caught.
const = ();
.('a4kp-9mza').; // -> false
.('a4pk-9mxa').; // -> false
.('b0zg-7kqb').; // -> true
.('bz0g-7kqb').; // -> trueThe “Blind Spot”
There is one rare exception: a swap of the first and last characters of the dictionary (by default, 0 and z). Because of the way the Luhn doubling step works, these two characters are mathematically interchangeable in the sum.
While this is a technical limitation of the Luhn algorithm, it is an acceptable trade-off for the speed and simplicity of the check.
A Longer Code for Gift Cards
Every example on this page uses the default shape: eight characters in two chunks. If you need a longer, more complex code for something like a gift card, you can customize the shape. Code shape shows how to set length, chunkSize and separator.