Skip to content

Commit

Permalink
Feat/uuid25 (#74)
Browse files Browse the repository at this point in the history
* Implement uuid25 support
* refactor: Move constants to object
* 5.1.0
  • Loading branch information
oculus42 committed May 1, 2024
1 parent 1605e65 commit 47ea79a
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 27 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).

## [5.1.0] - 2024-04-30
### Added
- Added `uuid25Base36` constant to support uuid25 style

## [5.0.1] - 2024-04-30
### Changed
- Updated `engines` in `package.json` to reflect correct support (Node >=14)
Expand Down
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

Generate and translate standard UUIDs into shorter - or just *different* - formats and back.


## v5.0.1
5.0.1 corrects node support in the `engine` section of `package.json`.
## v5.1.0
5.1.0 adds translation support for the [uuid25](https://github.com/uuid25/javascript) (Base36) format
with the `uuid25Base36` constant.

### Major Changes in 5.0.0
- 🛑 5.0.0 drops support for Node 10 and 12.
Expand Down Expand Up @@ -61,8 +61,9 @@ translator.alphabet;
translator.maxLength;

// View the constants
short.constants.flickrBase58; // Avoids similar characters (0/O, 1/I/l, etc.)
short.constants.cookieBase90; // Safe for HTTP cookies values for smaller IDs.
short.constants.flickrBase58; // Avoids similar characters (0/O, 1/I/l, etc.)
short.constants.uuid25Base36; // The uuid25 (string length 25) format
```

### Options
Expand All @@ -86,7 +87,7 @@ translator.new(); // mhvXdrZT4jP5T8vBxuvm75

## Support

short-uuid [5.0.0](https://github.com/oculus42/short-uuid/blob/v5.0.0/README.md)
short-uuid [5.x](https://github.com/oculus42/short-uuid/blob/v5.1.0/README.md)
and later is tested on Node 14.x and later.

short-uuid [4.x](https://github.com/oculus42/short-uuid/blob/v3.2.2/README.md)
Expand All @@ -106,6 +107,7 @@ TypeScript definitions are included, thanks to
[alexturek](https://github.com/alexturek).

## Previous Release Note Highlights
5.0.0 drops support for Node 12 and below.
4.1.0 adds a maxLength value to translators for reference
4.0.1 adds consistent length translation and throws an error if provided an invalid alphabet.
3.1.1 removed Node 4.x tests. Last included Browserify distribution.
Expand Down
7 changes: 4 additions & 3 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ declare module 'short-uuid' {

namespace shortUUID {
export const constants: {
flickrBase58: string;
cookieBase90: string;
flickrBase58: string;
uuid25Base36: string;
};

export type UUID = string & { _guidBrand: 'short-uuid' };
export type SUUID = string & { _guidBrand: 'uuid' };
export type UUID = string & { _guidBrand: 'uuid' };
export type SUUID = string & { _guidBrand: 'short-uuid' };

/** Generate a new regular UUID. */
export function uuid(): UUID;
Expand Down
24 changes: 12 additions & 12 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
* Simple wrapper functions to produce shorter UUIDs for cookies, maybe everything?
*/

const { v4: uuidv4 } = require('uuid');
const { v4: uuidV4 } = require('uuid');
const anyBase = require('any-base');

const flickrBase58 = '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ';
const cookieBase90 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#$%&'()*+-./:<=>?@[]^_`{|}~";
const constants = {
cookieBase90: "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#$%&'()*+-./:<=>?@[]^_`{|}~",
flickrBase58: '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ',
uuid25Base36: '0123456789abcdefghijklmnopqrstuvwxyz',
};

const baseOptions = {
consistentLength: true,
Expand Down Expand Up @@ -67,7 +70,7 @@ module.exports = (() => {
*/
const makeConvertor = (toAlphabet, options) => {
// Default to Flickr 58
const useAlphabet = toAlphabet || flickrBase58;
const useAlphabet = toAlphabet || constants.flickrBase58;

// Default to baseOptions
const selectedOptions = { ...baseOptions, ...options };
Expand All @@ -89,12 +92,12 @@ module.exports = (() => {
// UUIDs are in hex, so we translate to and from.
const fromHex = anyBase(anyBase.HEX, useAlphabet);
const toHex = anyBase(useAlphabet, anyBase.HEX);
const generate = () => shortenUUID(uuidv4(), fromHex, paddingParams);
const generate = () => shortenUUID(uuidV4(), fromHex, paddingParams);

const translator = {
new: generate,
generate,
uuid: uuidv4,
uuid: uuidV4,
fromUUID: (uuid) => shortenUUID(uuid, fromHex, paddingParams),
toUUID: (shortUuid) => enlargeUUID(shortUuid, toHex),
alphabet: useAlphabet,
Expand All @@ -107,19 +110,16 @@ module.exports = (() => {
};

// Expose the constants for other purposes.
makeConvertor.constants = {
flickrBase58,
cookieBase90,
};
makeConvertor.constants = constants;

// Expose the generic v4 UUID generator for convenience
makeConvertor.uuid = uuidv4;
makeConvertor.uuid = uuidV4;

// Provide a generic generator
makeConvertor.generate = () => {
if (!toFlickr) {
// Generate on first use;
toFlickr = makeConvertor(flickrBase58).generate;
toFlickr = makeConvertor(constants.flickrBase58).generate;
}
return toFlickr();
};
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "short-uuid",
"version": "5.0.1",
"version": "5.1.0",
"description": "Create and translate standard UUIDs with shorter formats.",
"main": "index.js",
"typings": "index.d.ts",
Expand Down
32 changes: 27 additions & 5 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,19 @@ const test = require('tape');
const uuid = require('uuid');
const short = require('../index');

const uuid25Tests = require('./uuid25examples');

const b90 = short(short.constants.cookieBase90);
const b58 = short(short.constants.flickrBase58);
const b36 = short(short.constants.uuid25Base36);

const cycle = (testcb) => {
const cycle = (testCallback) => {
const uu = short.uuid();
const f58 = b58.fromUUID(uu);
const f90 = b90.fromUUID(uu);
const f36 = b36.fromUUID(uu);

testcb(uu, f58, f90);
testCallback(uu, f58, f90, f36);
};

test('short-uuid setup', (t) => {
Expand Down Expand Up @@ -45,10 +49,11 @@ test('short-uuid setup', (t) => {
});

test('constants', (t) => {
t.plan(3);
t.plan(4);
t.ok(Object.prototype.hasOwnProperty.call(short, 'constants') && typeof short.constants === 'object', 'should contain a "constants" object');
t.equal(short.constants.flickrBase58, '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ', 'should contain flicker58 constant');
t.equal(short.constants.cookieBase90, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#$%&'()*+-./:<=>?@[]^_`{|}~", 'should contain cookie90 constant');
t.equal(short.constants.uuid25Base36, '0123456789abcdefghijklmnopqrstuvwxyz', 'should contain uuid25 constant');
});

// Operations
Expand All @@ -65,14 +70,17 @@ test('should generate valid UUIDs', (t) => {
});

test('should translate back from multiple bases', (t) => {
t.plan(40);
t.plan(60);

const action = (uu, f58, f90) => {
const action = (uu, f58, f90, f36) => {
t.equal(b58.toUUID(f58), uu, 'Translated b58 matches original');
t.ok(uuid.validate(b58.toUUID(f58)), 'Translated UUID is valid');

t.equal(b90.toUUID(f90), uu, 'Translated b90 matches original');
t.ok(uuid.validate(b90.toUUID(f90)), 'Translated UUID is valid');

t.equal(b36.toUUID(f36), uu, 'Translated b36 matches original');
t.ok(uuid.validate(b36.toUUID(f36)), 'Translated UUID is valid');
};

for (let i = 0; i < 10; i += 1) {
Expand Down Expand Up @@ -252,6 +260,20 @@ test('generate should generate an ID with the Flickr set', (t) => {
t.ok(val2, 'Generate should reuse the default translator successfully');
});

// Test examples from https://github.com/uuid25/test_cases/blob/main/examples
test('uuid25 should be compatible with uuid25 examples', (t) => {
t.plan(uuid25Tests.length * 2);
uuid25Tests.forEach(({ uuid25, hyphenated }) => {
t.equal(b36.toUUID(uuid25), hyphenated);
t.equal(b36.fromUUID(hyphenated), uuid25);
});
});

test('uuid25 translator should provide maxLength 25', (t) => {
t.plan(1);
t.equal(b36.maxLength, 25);
});

test('Default generate quantity tests', (t) => {
t.plan(1);
let underLength = 0;
Expand Down
74 changes: 74 additions & 0 deletions test/uuid25examples.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
module.exports = [
{
uuid25: '0000000000000000000000000',
hyphenated: '00000000-0000-0000-0000-000000000000',
},
{
uuid25: 'f5lxx1zz5pnorynqglhzmsp33',
hyphenated: 'ffffffff-ffff-ffff-ffff-ffffffffffff',
},
{
uuid25: '8j7qcpk2yebp9ouobnujfc312',
hyphenated: '90252ae1-bdee-b5e6-4549-83a13e69d556',
},
{
uuid25: '1ixkdgkqeu8wln1vfrw6csla3',
hyphenated: '19c63717-dd78-907f-153d-c2d12a357ebb',
},
{
uuid25: '1rt96u8g5mehk7anquaf5v0yd',
hyphenated: '1df0de92-3543-c988-6d44-6b0ef75df795',
},
{
uuid25: '18hye57ickp5c2mg8x9w4o1ji',
hyphenated: '14e0fa56-29c7-0c0d-663f-5d326e51f1ce',
},
{
uuid25: 'b7b5eir8qxbgpe8ofpfx0jmk4',
hyphenated: 'bd3ba1d1-ed92-4804-b900-4b6f96124cf4',
},
{
uuid25: 'dsc6tknluzhcyoh0wbdhtfm91',
hyphenated: 'e8e1d087-617c-3a88-e8f4-789ab4a7cf65',
},
{
uuid25: 'edzg3t2pm0tzkjolrcmvlyhtx',
hyphenated: 'f309d5b0-2bf3-a736-7400-75948ad1ffc5',
},
{
uuid25: '1da9001w3ld329fiyf574wuk2',
hyphenated: '171fd840-f315-e732-2796-dea092d372b2',
},
{
uuid25: 'bvdc0zy20yoipgda8sb65tczv',
hyphenated: 'c885af25-4a61-954a-1687-c08e41f9940b',
},
{
uuid25: '3mll19wjhi37qe68vtgobt04h',
hyphenated: '3d46fe79-7828-7d4f-f1e5-7bdf80ab30e1',
},
{
uuid25: 'dlut3j4j5hudfwua508w8h25v',
hyphenated: 'e5d7215d-6e2c-3299-1506-498b84b32d33',
},
{
uuid25: 'bi0ifb9jmm2tig1hsdb9uol2v',
hyphenated: 'c2416789-944c-b584-e886-ac162d9112b7',
},
{
uuid25: '0js3yf434vbqa069pkebbly89',
hyphenated: '0947fa84-3806-088a-77aa-1b1ed69b7789',
},
{
uuid25: '42ur2gf0i7xgtnlislvutk5fq',
hyphenated: '44e76ce2-1f2e-77bd-badb-64850026fd86',
},
{
uuid25: '6ry55bbvow6mllk9nvfsd4w5f',
hyphenated: '7275ea47-7628-0fa8-2afb-0c4b47f148c3',
},
{
uuid25: '1xl7tld67nekvdlrp0pkvsut5',
hyphenated: '20a6bdda-fff4-faa1-4e8f-c0eb75a169f9',
},
];

0 comments on commit 47ea79a

Please sign in to comment.