deno.land / x / uuid7@v0.0.1 / mod.ts

نووسراو ببینە
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/** * Generate a UUIDv7. * * ## Options * * To generate a UUID at a specific time, you can pass a `number` timestamp or * `Date` object to this function. * * You can also further customize UUID generation by providing * {@link GenerateOptions an object} with your preferences: * * - `time`: Generate with this time instead of the current system time. You can * provide a `number` millisecond-precision UNIX timestamp (as `Date.now` * returns), a Date object, or a function returning a `number` timestamp. * - `dashes`: `true` to include `-` characters in the generated UUID string; * `false` to omit them. (default: `true`) * - `upper`: Capitalize the A-F characters in the UUID. (default: `false`) * - `version`: The value of the UUID `version` field (default: `7`) * - `entropy`: A function to generate the random part of the UUID. Must return * a `Uint8Array` containing 10 bytes. * (default: uses `crypto.getRandomValues`) */export const v7: Generator = (opt?: Clock | Time | GenerateOptions | null): string => { const time = getTime(opt); let dashes = true; let upper = false; let version = 7 << 4; let rand: () => Uint8Array = defaultEntropy;
if (typeof opt === 'object' && opt !== null && !(opt instanceof Date)) { if (opt.dashes != null) dashes = opt.dashes; if (opt.version != null) version = (opt.version & 0x0f) << 4; if (opt.upper != null) upper = opt.upper; if (opt.entropy != null) rand = opt.entropy; }
let timestamp = hex(time, 12); if (dashes) timestamp = timestamp.slice(0, 8) + '-' + timestamp.slice(8);
const suffixBytes: string[] = Array(10); rand().forEach((b, i) => { if (i === 0) { b = version | (b & 0x0f); } else if (i === 2) { b = variant | (b & 0x3f); } suffixBytes[i] = hex(b); });
const suffix = suffixBytes.join('');
const id = dashes ? `${timestamp}-${suffix.slice(0, 4)}-${suffix.slice(4, 8)}-${suffix.slice(8)}` : timestamp + suffix;
return upper ? id.toUpperCase() : id;};
export default v7;
/** * Return the timestamp portion of the UUID (a millisecond-precision UNIX * timestamp, as returned by `Date.now`). * * Throws a {@link ParseError} if no timestamp can be extracted. */export const timestamp = (uuid: string): number => { const match = pattern.exec(uuid); if (match == null) throw new ParseError('Invalid v7 UUID; cannot determine timestamp');
const ts = match[1].replace('-', ''); return parseInt(ts, 16);};
/** * A regular expression that recognizes UUID's generated by this package. * * Capture group `1` is the timestamp portion, and `2` is the random portion * (including the 2-bit constant UUID variant field). */export const pattern = /^([0-9a-f]{8}-?[0-9a-f]{4})-?7([0-9a-f]{3}-?[0-9a-f]{4}-?[0-9a-f]{12})$/i;
/** The type of {@link v7 the UUID function} of this package. */export interface Generator { /** Generate a UUIDv7 with default options. */ (): string;
/** Generate a UUIDv7 using the given time as its timestamp. */ (time: Clock | Time | null | undefined): string;
/** Generate a UUIDv7 using the given {@link GenerateOptions options}. */ (options: GenerateOptions): string;}
/** * A function that returns a millisecond-precision UNIX timestamp, like * `Date.now`. */export type Clock = typeof Date['now'];
/** A `Date` object or millisecond-precision UNIX timestamp. */export type Time = number | Date;
/** {@link v7 UUID generation} options. */export interface GenerateOptions { /** * Set the timestamp portion of the UUID to the given `Date`, UNIX timestamp * (as returned by `Date.now`), or the timestamp returned by the given * {@link Clock clock function}. */ time?: Clock | Time;
/** * `true` to include dashes in the UUID; `false` to omit them. * (default: `true`) */ dashes?: boolean;
/** Capitalize the A-F characters in the UUID. (default: `false`) */ upper?: boolean;
/** Set the version field of the UUID. (default: `8`) */ version?: 7 | 8;
/** * Generate the random part of the UUID. The returned `Uint8Array` must be at * least 10 bytes long. */ entropy?: () => Uint8Array;}
/** The exception thrown by {@link timestamp} if UUID parsing fails. */export class ParseError extends Error { public readonly name = 'ParseError';}
const getTime = (time: Clock | Time | GenerateOptions | null | undefined): number => { if (time == null) return Date.now(); if (typeof time === 'number') return time; if (time instanceof Date) return +time; if (typeof time === 'function') return time(); return getTime(time.time);};
const hex = (n: number, width = 2) => pad(n.toString(16), width);
const pad = (text: string, width: number) => { const remainder = width - text.length; return remainder > 0 ? '0'.repeat(remainder) + text : text;};
const defaultEntropy = (): Uint8Array => crypto.getRandomValues(new Uint8Array(10));
const variant = 2 << 6;
uuid7

Version Info

Tagged at
a year ago