Skip to content

Commit

Permalink
feat: add support for MAX uuid (new in RFC9562) (#714)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Robert Kieffer <[email protected]>
  • Loading branch information
LinusU and broofa committed Jun 3, 2024
1 parent f54a866 commit 0385cd3
Show file tree
Hide file tree
Showing 16 changed files with 119 additions and 21 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/browser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ jobs:
- uses: actions/checkout@v3
with:
fetch-depth: 10
- name: Use Node.js 16.x
- name: Use Node.js 20.x
uses: actions/setup-node@v3
with:
node-version: 16.x
node-version: 20.x
- run: npm ci
- name: Test Browser
run: npm run test:browser
Expand Down
53 changes: 44 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@ For the creation of [RFC4122](https://www.ietf.org/rfc/rfc4122.txt) UUIDs
- **Small** - Zero-dependency, small footprint, plays nice with "tree shaking" packagers
- **CLI** - Includes the [`uuid` command line](#command-line) utility

> **Note** Upgrading from `uuid@3`? Your code is probably okay, but check out [Upgrading From `uuid@3`](#upgrading-from-uuid3) for details.
<!-- prettier-ignore -->
> [!NOTE]
> Upgrading from `uuid@3`? Your code is probably okay, but check out [Upgrading From `uuid@3`](#upgrading-from-uuid3) for details.
> **Note** Only interested in creating a version 4 UUID? You might be able to use [`crypto.randomUUID()`](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/randomUUID), eliminating the need to install this library.
<!-- prettier-ignore -->
> [!NOTE]
> Only interested in creating a version 4 UUID? You might be able to use [`crypto.randomUUID()`](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/randomUUID), eliminating the need to install this library.
## Quickstart

Expand Down Expand Up @@ -53,6 +57,7 @@ For timestamp UUIDs, namespace UUIDs, and other options read on ...
| | | |
| --- | --- | --- |
| [`uuid.NIL`](#uuidnil) | The nil UUID string (all zeros) | New in `[email protected]` |
| [`uuid.MAX`](#uuidmax) | The max UUID string (all ones) | New in `[email protected]` |
| [`uuid.parse()`](#uuidparsestr) | Convert UUID string to array of bytes | New in `[email protected]` |
| [`uuid.stringify()`](#uuidstringifyarr-offset) | Convert array of bytes to UUID string | New in `[email protected]` |
| [`uuid.v1()`](#uuidv1options-buffer-offset) | Create a version 1 (timestamp) UUID | |
Expand All @@ -77,6 +82,18 @@ import { NIL as NIL_UUID } from 'uuid';
NIL_UUID; // ⇨ '00000000-0000-0000-0000-000000000000'
```

### uuid.MAX

The max UUID string (all ones).

Example:

```javascript
import { MAX as MAX_UUID } from 'uuid';

MAX_UUID; // ⇨ 'ffffffff-ffff-ffff-ffff-ffffffffffff'
```

### uuid.parse(str)

Convert UUID string to array of bytes
Expand All @@ -87,7 +104,9 @@ Convert UUID string to array of bytes
| _returns_ | `Uint8Array[16]` |
| _throws_ | `TypeError` if `str` is not a valid UUID |

Note: Ordering of values in the byte arrays used by `parse()` and `stringify()` follows the left &Rarr; right order of hex-pairs in UUID strings. As shown in the example below.
<!-- prettier-ignore -->
> [!NOTE]
> Ordering of values in the byte arrays used by `parse()` and `stringify()` follows the left &Rarr; right order of hex-pairs in UUID strings. As shown in the example below.
Example:

Expand Down Expand Up @@ -118,7 +137,9 @@ Convert array of bytes to UUID string
| _returns_ | `String` |
| _throws_ | `TypeError` if a valid UUID string cannot be generated |

Note: Ordering of values in the byte arrays used by `parse()` and `stringify()` follows the left &Rarr; right order of hex-pairs in UUID strings. As shown in the example below.
<!-- prettier-ignore -->
> [!NOTE]
> Ordering of values in the byte arrays used by `parse()` and `stringify()` follows the left &Rarr; right order of hex-pairs in UUID strings. As shown in the example below.
Example:

Expand Down Expand Up @@ -150,9 +171,13 @@ Create an RFC version 1 (timestamp) UUID
| _returns_ | UUID `String` if no `buffer` is specified, otherwise returns `buffer` |
| _throws_ | `Error` if more than 10M UUIDs/sec are requested |

Note: The default [node id](https://tools.ietf.org/html/rfc4122#section-4.1.6) (the last 12 digits in the UUID) is generated once, randomly, on process startup, and then remains unchanged for the duration of the process.
<!-- prettier-ignore -->
> [!NOTE]
> The default [node id](https://tools.ietf.org/html/rfc4122#section-4.1.6) (the last 12 digits in the UUID) is generated once, randomly, on process startup, and then remains unchanged for the duration of the process.
Note: `options.random` and `options.rng` are only meaningful on the very first call to `v1()`, where they may be passed to initialize the internal `node` and `clockseq` fields.
<!-- prettier-ignore -->
> [!NOTE]
> `options.random` and `options.rng` are only meaningful on the very first call to `v1()`, where they may be passed to initialize the internal `node` and `clockseq` fields.
Example:

Expand Down Expand Up @@ -182,7 +207,9 @@ Create an RFC version 3 (namespace w/ MD5) UUID

API is identical to `v5()`, but uses "v3" instead.

&#x26a0;&#xfe0f; Note: Per the RFC, "_If backward compatibility is not an issue, SHA-1 [Version 5] is preferred_."
<!-- prettier-ignore -->
> [!IMPORTANT]
> Per the RFC, "_If backward compatibility is not an issue, SHA-1 [Version 5] is preferred_."
### uuid.v4([options[, buffer[, offset]]])

Expand Down Expand Up @@ -230,7 +257,9 @@ Create an RFC version 5 (namespace w/ SHA-1) UUID
| [`offset` = 0] | `Number` Index to start writing UUID bytes in `buffer` |
| _returns_ | UUID `String` if no `buffer` is specified, otherwise returns `buffer` |

Note: The RFC `DNS` and `URL` namespaces are available as `v5.DNS` and `v5.URL`.
<!-- prettier-ignore -->
> [!NOTE]
> The RFC `DNS` and `URL` namespaces are available as `v5.DNS` and `v5.URL`.
Example with custom namespace:

Expand Down Expand Up @@ -329,6 +358,10 @@ uuidVersion('45637ec4-c85f-11ea-87d0-0242ac130003'); // ⇨ 1
uuidVersion('6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b'); // ⇨ 4
```

<!-- prettier-ignore -->
> [!NOTE]
> This method returns `0` for the `NIL` UUID, and `15` for the `MAX` UUID.
## Command Line

UUIDs can be generated from the command line using `uuid`.
Expand Down Expand Up @@ -413,7 +446,9 @@ import 'react-native-get-random-values';
import { v4 as uuidv4 } from 'uuid';
```

Note: If you are using Expo, you must be using at least `[email protected]` and `[email protected]`.
<!-- prettier-ignore -->
> [!NOTE]
> If you are using Expo, you must be using at least `[email protected]` and `[email protected]`.
### Web Workers / Service Workers (Edge <= 18)

Expand Down
53 changes: 44 additions & 9 deletions README_js.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,13 @@ For the creation of [RFC4122](https://www.ietf.org/rfc/rfc4122.txt) UUIDs
- **Small** - Zero-dependency, small footprint, plays nice with "tree shaking" packagers
- **CLI** - Includes the [`uuid` command line](#command-line) utility

> **Note** Upgrading from `uuid@3`? Your code is probably okay, but check out [Upgrading From `uuid@3`](#upgrading-from-uuid3) for details.
<!-- prettier-ignore -->
> [!NOTE]
> Upgrading from `uuid@3`? Your code is probably okay, but check out [Upgrading From `uuid@3`](#upgrading-from-uuid3) for details.
> **Note** Only interested in creating a version 4 UUID? You might be able to use [`crypto.randomUUID()`](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/randomUUID), eliminating the need to install this library.
<!-- prettier-ignore -->
> [!NOTE]
> Only interested in creating a version 4 UUID? You might be able to use [`crypto.randomUUID()`](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/randomUUID), eliminating the need to install this library.
## Quickstart

Expand Down Expand Up @@ -67,6 +71,7 @@ For timestamp UUIDs, namespace UUIDs, and other options read on ...
| | | |
| --- | --- | --- |
| [`uuid.NIL`](#uuidnil) | The nil UUID string (all zeros) | New in `[email protected]` |
| [`uuid.MAX`](#uuidmax) | The max UUID string (all ones) | New in `[email protected]` |
| [`uuid.parse()`](#uuidparsestr) | Convert UUID string to array of bytes | New in `[email protected]` |
| [`uuid.stringify()`](#uuidstringifyarr-offset) | Convert array of bytes to UUID string | New in `[email protected]` |
| [`uuid.v1()`](#uuidv1options-buffer-offset) | Create a version 1 (timestamp) UUID | |
Expand All @@ -91,6 +96,18 @@ import { NIL as NIL_UUID } from 'uuid';
NIL_UUID; // RESULT
```

### uuid.MAX

The max UUID string (all ones).

Example:

```javascript --run
import { MAX as MAX_UUID } from 'uuid';

MAX_UUID; // RESULT
```

### uuid.parse(str)

Convert UUID string to array of bytes
Expand All @@ -101,7 +118,9 @@ Convert UUID string to array of bytes
| _returns_ | `Uint8Array[16]` |
| _throws_ | `TypeError` if `str` is not a valid UUID |

Note: Ordering of values in the byte arrays used by `parse()` and `stringify()` follows the left &Rarr; right order of hex-pairs in UUID strings. As shown in the example below.
<!-- prettier-ignore -->
> [!NOTE]
> Ordering of values in the byte arrays used by `parse()` and `stringify()` follows the left &Rarr; right order of hex-pairs in UUID strings. As shown in the example below.
Example:

Expand All @@ -126,7 +145,9 @@ Convert array of bytes to UUID string
| _returns_ | `String` |
| _throws_ | `TypeError` if a valid UUID string cannot be generated |

Note: Ordering of values in the byte arrays used by `parse()` and `stringify()` follows the left &Rarr; right order of hex-pairs in UUID strings. As shown in the example below.
<!-- prettier-ignore -->
> [!NOTE]
> Ordering of values in the byte arrays used by `parse()` and `stringify()` follows the left &Rarr; right order of hex-pairs in UUID strings. As shown in the example below.
Example:

Expand Down Expand Up @@ -158,9 +179,13 @@ Create an RFC version 1 (timestamp) UUID
| _returns_ | UUID `String` if no `buffer` is specified, otherwise returns `buffer` |
| _throws_ | `Error` if more than 10M UUIDs/sec are requested |

Note: The default [node id](https://tools.ietf.org/html/rfc4122#section-4.1.6) (the last 12 digits in the UUID) is generated once, randomly, on process startup, and then remains unchanged for the duration of the process.
<!-- prettier-ignore -->
> [!NOTE]
> The default [node id](https://tools.ietf.org/html/rfc4122#section-4.1.6) (the last 12 digits in the UUID) is generated once, randomly, on process startup, and then remains unchanged for the duration of the process.
Note: `options.random` and `options.rng` are only meaningful on the very first call to `v1()`, where they may be passed to initialize the internal `node` and `clockseq` fields.
<!-- prettier-ignore -->
> [!NOTE]
> `options.random` and `options.rng` are only meaningful on the very first call to `v1()`, where they may be passed to initialize the internal `node` and `clockseq` fields.
Example:

Expand Down Expand Up @@ -190,7 +215,9 @@ Create an RFC version 3 (namespace w/ MD5) UUID

API is identical to `v5()`, but uses "v3" instead.

&#x26a0;&#xfe0f; Note: Per the RFC, "_If backward compatibility is not an issue, SHA-1 [Version 5] is preferred_."
<!-- prettier-ignore -->
> [!IMPORTANT]
> Per the RFC, "_If backward compatibility is not an issue, SHA-1 [Version 5] is preferred_."
### uuid.v4([options[, buffer[, offset]]])

Expand Down Expand Up @@ -238,7 +265,9 @@ Create an RFC version 5 (namespace w/ SHA-1) UUID
| [`offset` = 0] | `Number` Index to start writing UUID bytes in `buffer` |
| _returns_ | UUID `String` if no `buffer` is specified, otherwise returns `buffer` |

Note: The RFC `DNS` and `URL` namespaces are available as `v5.DNS` and `v5.URL`.
<!-- prettier-ignore -->
> [!NOTE]
> The RFC `DNS` and `URL` namespaces are available as `v5.DNS` and `v5.URL`.
Example with custom namespace:

Expand Down Expand Up @@ -337,6 +366,10 @@ uuidVersion('45637ec4-c85f-11ea-87d0-0242ac130003'); // RESULT
uuidVersion('6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b'); // RESULT
```

<!-- prettier-ignore -->
> [!NOTE]
> This method returns `0` for the `NIL` UUID, and `15` for the `MAX` UUID.
## Command Line

UUIDs can be generated from the command line using `uuid`.
Expand Down Expand Up @@ -421,7 +454,9 @@ import 'react-native-get-random-values';
import { v4 as uuidv4 } from 'uuid';
```

Note: If you are using Expo, you must be using at least `[email protected]` and `[email protected]`.
<!-- prettier-ignore -->
> [!NOTE]
> If you are using Expo, you must be using at least `[email protected]` and `[email protected]`.
### Web Workers / Service Workers (Edge <= 18)

Expand Down
3 changes: 3 additions & 0 deletions examples/browser-esmodules/example.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
NIL as NIL_UUID,
MAX as MAX_UUID,
parse as uuidParse,
stringify as uuidStringify,
v1 as uuidv1,
Expand Down Expand Up @@ -46,6 +47,7 @@ console.log('uuidv5() MY_NAMESPACE', uuidv5('Hello, World!', MY_NAMESPACE));

// Utility functions
console.log('NIL_UUID', NIL_UUID);
console.log('MAX_UUID', MAX_UUID);
console.log('uuidParse()', uuidParse(MY_NAMESPACE));
console.log('uuidStringify()', uuidStringify(uuidParse(MY_NAMESPACE)));
console.log('uuidValidate()', uuidValidate(MY_NAMESPACE));
Expand All @@ -64,6 +66,7 @@ console.log('uuid.v5() URL', uuid.v5('http://example.com/hello', uuid.v5.URL));
console.log('uuid.v5() MY_NAMESPACE', uuid.v5('Hello, World!', MY_NAMESPACE));

console.log('uuid.NIL', uuid.NIL);
console.log('uuid.MAX', uuid.MAX);
console.log('uuid.parse()', uuid.parse(MY_NAMESPACE));
console.log('uuid.stringify()', uuid.stringify(uuid.parse(MY_NAMESPACE)));
console.log('uuid.validate()', uuid.validate(MY_NAMESPACE));
Expand Down
3 changes: 3 additions & 0 deletions examples/browser-rollup/example-all.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
NIL as NIL_UUID,
MAX as MAX_UUID,
parse as uuidParse,
stringify as uuidStringify,
v1 as uuidv1,
Expand Down Expand Up @@ -51,6 +52,7 @@ testpage(function (addTest, done) {

// Utility functions
addTest('NIL_UUID', NIL_UUID);
addTest('MAX_UUID', MAX_UUID);
addTest('uuidParse()', uuidParse(MY_NAMESPACE));
addTest('uuidStringify()', uuidStringify(uuidParse(MY_NAMESPACE)));
addTest('uuidValidate()', uuidValidate(MY_NAMESPACE));
Expand All @@ -69,6 +71,7 @@ testpage(function (addTest, done) {
addTest('uuid.v5() MY_NAMESPACE', uuid.v5('Hello, World!', MY_NAMESPACE));

addTest('uuid.NIL', uuid.NIL);
addTest('uuid.MAX', uuid.MAX);
addTest('uuid.parse()', uuid.parse(MY_NAMESPACE));
addTest('uuid.stringify()', uuid.stringify(uuid.parse(MY_NAMESPACE)));
addTest('uuid.validate()', uuid.validate(MY_NAMESPACE));
Expand Down
3 changes: 3 additions & 0 deletions examples/browser-webpack/example-all-require.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const uuid = require('uuid');
const {
NIL: NIL_UUID,
MAX: MAX_UUID,
parse: uuidParse,
stringify: uuidStringify,
v1: uuidv1,
Expand Down Expand Up @@ -51,6 +52,7 @@ testpage(function (addTest, done) {

// Utility functions
addTest('NIL_UUID', NIL_UUID);
addTest('MAX_UUID', MAX_UUID);
addTest('uuidParse()', uuidParse(MY_NAMESPACE));
addTest('uuidStringify()', uuidStringify(uuidParse(MY_NAMESPACE)));
addTest('uuidValidate()', uuidValidate(MY_NAMESPACE));
Expand All @@ -69,6 +71,7 @@ testpage(function (addTest, done) {
addTest('uuid.v5() MY_NAMESPACE', uuid.v5('Hello, World!', MY_NAMESPACE));

addTest('uuid.NIL', uuid.NIL);
addTest('uuid.MAX', uuid.MAX);
addTest('uuid.parse()', uuid.parse(MY_NAMESPACE));
addTest('uuid.stringify()', uuid.stringify(uuid.parse(MY_NAMESPACE)));
addTest('uuid.validate()', uuid.validate(MY_NAMESPACE));
Expand Down
3 changes: 3 additions & 0 deletions examples/browser-webpack/example-all.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
NIL as NIL_UUID,
MAX as MAX_UUID,
parse as uuidParse,
stringify as uuidStringify,
v1 as uuidv1,
Expand Down Expand Up @@ -51,6 +52,7 @@ testpage(function (addTest, done) {

// Utility functions
addTest('NIL_UUID', NIL_UUID);
addTest('MAX_UUID', MAX_UUID);
addTest('uuidParse()', uuidParse(MY_NAMESPACE));
addTest('uuidStringify()', uuidStringify(uuidParse(MY_NAMESPACE)));
addTest('uuidValidate()', uuidValidate(MY_NAMESPACE));
Expand All @@ -69,6 +71,7 @@ testpage(function (addTest, done) {
addTest('uuid.v5() MY_NAMESPACE', uuid.v5('Hello, World!', MY_NAMESPACE));

addTest('uuid.NIL', uuid.NIL);
addTest('uuid.MAX', uuid.MAX);
addTest('uuid.parse()', uuid.parse(MY_NAMESPACE));
addTest('uuid.stringify()', uuid.stringify(uuid.parse(MY_NAMESPACE)));
addTest('uuid.validate()', uuid.validate(MY_NAMESPACE));
Expand Down
3 changes: 3 additions & 0 deletions examples/node-commonjs/example.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const {
NIL: NIL_UUID,
MAX: MAX_UUID,
parse: uuidParse,
stringify: uuidStringify,
v1: uuidv1,
Expand Down Expand Up @@ -47,6 +48,7 @@ console.log('uuidv5() MY_NAMESPACE', uuidv5('Hello, World!', MY_NAMESPACE));

// Utility functions
console.log('NIL_UUID', NIL_UUID);
console.log('MAX_UUID', MAX_UUID);
console.log('uuidParse()', uuidParse(MY_NAMESPACE));
console.log('uuidStringify()', uuidStringify(uuidParse(MY_NAMESPACE)));
console.log('uuidValidate()', uuidValidate(MY_NAMESPACE));
Expand All @@ -65,6 +67,7 @@ console.log('uuid.v5() URL', uuid.v5('http://example.com/hello', uuid.v5.URL));
console.log('uuid.v5() MY_NAMESPACE', uuid.v5('Hello, World!', MY_NAMESPACE));

console.log('uuid.NIL', uuid.NIL);
console.log('uuid.MAX', uuid.MAX);
console.log('uuid.parse()', uuid.parse(MY_NAMESPACE));
console.log('uuid.stringify()', uuid.stringify(uuid.parse(MY_NAMESPACE)));
console.log('uuid.validate()', uuid.validate(MY_NAMESPACE));
Expand Down
Loading

0 comments on commit 0385cd3

Please sign in to comment.