@arc-js/id-generator 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +547 -0
- package/id-generator.all.js +447 -0
- package/id-generator.all.min.js +1 -0
- package/index.d.ts +103 -0
- package/index.js +360 -0
- package/index.min.d.ts +103 -0
- package/index.min.js +1 -0
- package/package.json +18 -0
- package/tsconfig.json +19 -0
package/index.js
ADDED
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
class IdentifierGenerator {
|
|
2
|
+
static instance;
|
|
3
|
+
cache = new Map();
|
|
4
|
+
constructor() { }
|
|
5
|
+
static getInstance() {
|
|
6
|
+
if (!IdentifierGenerator.instance) {
|
|
7
|
+
IdentifierGenerator.instance = new IdentifierGenerator();
|
|
8
|
+
}
|
|
9
|
+
return IdentifierGenerator.instance;
|
|
10
|
+
}
|
|
11
|
+
generate(format, customHandlers = {}) {
|
|
12
|
+
const tokens = this.parseFormat(format);
|
|
13
|
+
return tokens.map(token => this.resolveToken(token, customHandlers)).join('');
|
|
14
|
+
}
|
|
15
|
+
parseFormat(format) {
|
|
16
|
+
const tokens = [];
|
|
17
|
+
let currentIndex = 0;
|
|
18
|
+
while (currentIndex < format.length) {
|
|
19
|
+
const nextHashIndex = format.indexOf('#', currentIndex);
|
|
20
|
+
if (nextHashIndex > currentIndex) {
|
|
21
|
+
tokens.push({
|
|
22
|
+
type: 'string',
|
|
23
|
+
value: format.substring(currentIndex, nextHashIndex)
|
|
24
|
+
});
|
|
25
|
+
currentIndex = nextHashIndex;
|
|
26
|
+
}
|
|
27
|
+
if (format[currentIndex] === '#') {
|
|
28
|
+
const tokenEnd = this.findTokenEnd(format, currentIndex + 1);
|
|
29
|
+
if (tokenEnd === -1) {
|
|
30
|
+
throw new Error(`Format invalide à la position ${currentIndex}`);
|
|
31
|
+
}
|
|
32
|
+
const tokenContent = format.substring(currentIndex + 1, tokenEnd);
|
|
33
|
+
const token = this.parseToken(tokenContent);
|
|
34
|
+
tokens.push(token);
|
|
35
|
+
currentIndex = tokenEnd;
|
|
36
|
+
}
|
|
37
|
+
else if (nextHashIndex === -1) {
|
|
38
|
+
tokens.push({
|
|
39
|
+
type: 'string',
|
|
40
|
+
value: format.substring(currentIndex)
|
|
41
|
+
});
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return tokens;
|
|
46
|
+
}
|
|
47
|
+
findTokenEnd(format, startIndex) {
|
|
48
|
+
let braceCount = 0;
|
|
49
|
+
let inString = false;
|
|
50
|
+
let escapeNext = false;
|
|
51
|
+
for (let i = startIndex; i < format.length; i++) {
|
|
52
|
+
const char = format[i];
|
|
53
|
+
if (escapeNext) {
|
|
54
|
+
escapeNext = false;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (char === '\\') {
|
|
58
|
+
escapeNext = true;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (char === '"' || char === "'") {
|
|
62
|
+
inString = !inString;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (!inString) {
|
|
66
|
+
if (char === '{') {
|
|
67
|
+
braceCount++;
|
|
68
|
+
}
|
|
69
|
+
else if (char === '}') {
|
|
70
|
+
if (braceCount === 0) {
|
|
71
|
+
return i;
|
|
72
|
+
}
|
|
73
|
+
braceCount--;
|
|
74
|
+
}
|
|
75
|
+
else if (char === '#' && braceCount === 0) {
|
|
76
|
+
return i;
|
|
77
|
+
}
|
|
78
|
+
else if (/[a-zA-Z0-9]/.test(char) === false && char !== ',' && char !== ':' && char !== '-' && char !== '_' && braceCount === 0) {
|
|
79
|
+
return i;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return format.length;
|
|
84
|
+
}
|
|
85
|
+
parseToken(tokenContent) {
|
|
86
|
+
if (tokenContent.includes('{') === false) {
|
|
87
|
+
return { type: 'string', value: tokenContent };
|
|
88
|
+
}
|
|
89
|
+
const [type, optionsStr] = tokenContent.split('{', 2);
|
|
90
|
+
const optionsContent = optionsStr.slice(0, -1);
|
|
91
|
+
if (type === 'rand') {
|
|
92
|
+
return {
|
|
93
|
+
type: 'random',
|
|
94
|
+
value: this.parseRandomOptions(optionsContent)
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
else if (type === 'uuid') {
|
|
98
|
+
return {
|
|
99
|
+
type: 'uuid',
|
|
100
|
+
value: this.parseUUIDOptions(optionsContent)
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
else if (type === 'custom') {
|
|
104
|
+
return {
|
|
105
|
+
type: 'custom',
|
|
106
|
+
value: optionsContent
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
throw new Error(`Type de token non supporté: ${type}`);
|
|
110
|
+
}
|
|
111
|
+
parseRandomOptions(optionsStr) {
|
|
112
|
+
const defaults = {
|
|
113
|
+
size: 8,
|
|
114
|
+
type: 'alphanumeric',
|
|
115
|
+
variant: false
|
|
116
|
+
};
|
|
117
|
+
const options = this.parseOptions(optionsStr);
|
|
118
|
+
return {
|
|
119
|
+
size: options.size ? parseInt(options.size) : defaults.size,
|
|
120
|
+
type: options.type || defaults.type,
|
|
121
|
+
variant: options.variant === 'true' ? true : defaults.variant
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
parseUUIDOptions(optionsStr) {
|
|
125
|
+
const defaults = {
|
|
126
|
+
version: 'v4'
|
|
127
|
+
};
|
|
128
|
+
const options = this.parseOptions(optionsStr);
|
|
129
|
+
return {
|
|
130
|
+
version: options.version || defaults.version
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
parseOptions(optionsStr) {
|
|
134
|
+
const options = {};
|
|
135
|
+
let currentKey = '';
|
|
136
|
+
let currentValue = '';
|
|
137
|
+
let inString = false;
|
|
138
|
+
let stringChar = '';
|
|
139
|
+
let braceCount = 0;
|
|
140
|
+
for (let i = 0; i < optionsStr.length; i++) {
|
|
141
|
+
const char = optionsStr[i];
|
|
142
|
+
if (char === '"' || char === "'") {
|
|
143
|
+
if (!inString) {
|
|
144
|
+
inString = true;
|
|
145
|
+
stringChar = char;
|
|
146
|
+
}
|
|
147
|
+
else if (stringChar === char) {
|
|
148
|
+
inString = false;
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
currentValue += char;
|
|
152
|
+
}
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
if (inString) {
|
|
156
|
+
currentValue += char;
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
if (char === ':') {
|
|
160
|
+
if (braceCount === 0) {
|
|
161
|
+
currentKey = currentValue.trim();
|
|
162
|
+
currentValue = '';
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
else if (char === '{') {
|
|
167
|
+
braceCount++;
|
|
168
|
+
}
|
|
169
|
+
else if (char === '}') {
|
|
170
|
+
braceCount--;
|
|
171
|
+
}
|
|
172
|
+
else if (char === ',' && braceCount === 0) {
|
|
173
|
+
options[currentKey] = currentValue.trim();
|
|
174
|
+
currentKey = '';
|
|
175
|
+
currentValue = '';
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
currentValue += char;
|
|
179
|
+
}
|
|
180
|
+
if (currentKey) {
|
|
181
|
+
options[currentKey] = currentValue.trim();
|
|
182
|
+
}
|
|
183
|
+
return options;
|
|
184
|
+
}
|
|
185
|
+
resolveToken(token, customHandlers) {
|
|
186
|
+
switch (token.type) {
|
|
187
|
+
case 'string':
|
|
188
|
+
return token.value;
|
|
189
|
+
case 'random':
|
|
190
|
+
return this.generateRandomString(token.value);
|
|
191
|
+
case 'uuid':
|
|
192
|
+
return this.generateUUID(token.value);
|
|
193
|
+
case 'custom':
|
|
194
|
+
const handlerName = token.value.split('}').join('').split('{').join('');
|
|
195
|
+
const checker = Object.keys(customHandlers).includes(handlerName);
|
|
196
|
+
if (checker) {
|
|
197
|
+
return customHandlers[handlerName]();
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
console.log(`[id-generator -> id-generator] IdentifierGenerator | resolveToken - custom - token:: `, token);
|
|
201
|
+
console.log(`[id-generator -> id-generator] IdentifierGenerator | resolveToken - custom - handlerName:: `, handlerName);
|
|
202
|
+
console.log(`[id-generator -> id-generator] IdentifierGenerator | resolveToken - custom - checker:: `, checker);
|
|
203
|
+
console.log(`[id-generator -> id-generator] IdentifierGenerator | resolveToken - custom - Object.keys(customHandlers):: `, Object.keys(customHandlers));
|
|
204
|
+
console.log(`[id-generator -> id-generator] IdentifierGenerator | resolveToken - custom - customHandlers:: `, customHandlers);
|
|
205
|
+
throw new Error(`Handler personnalisé non trouvé: ${handlerName}`);
|
|
206
|
+
}
|
|
207
|
+
default:
|
|
208
|
+
throw new Error(`Type de token inconnu: ${token.type}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
generateRandomString(options) {
|
|
212
|
+
const cacheKey = this.getRandomCacheKey(options);
|
|
213
|
+
if (!options.variant) {
|
|
214
|
+
if (!this.cache.has('random')) {
|
|
215
|
+
this.cache.set('random', new Map());
|
|
216
|
+
}
|
|
217
|
+
const randomCache = this.cache.get('random');
|
|
218
|
+
if (randomCache.has(cacheKey)) {
|
|
219
|
+
return randomCache.get(cacheKey);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
let charset = '';
|
|
223
|
+
let result = '';
|
|
224
|
+
switch (options.type) {
|
|
225
|
+
case 'numeric':
|
|
226
|
+
charset = '0123456789';
|
|
227
|
+
break;
|
|
228
|
+
case 'alphabetic':
|
|
229
|
+
charset = 'abcdefghijklmnopqrstuvwxyz';
|
|
230
|
+
break;
|
|
231
|
+
case 'alphabetic-case':
|
|
232
|
+
charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
233
|
+
break;
|
|
234
|
+
case 'alphanumeric':
|
|
235
|
+
charset = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
236
|
+
break;
|
|
237
|
+
case 'alphanumeric-case':
|
|
238
|
+
charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
const randomValues = new Uint32Array(options.size);
|
|
242
|
+
crypto.getRandomValues(randomValues);
|
|
243
|
+
for (let i = 0; i < options.size; i++) {
|
|
244
|
+
result += charset[randomValues[i] % charset.length];
|
|
245
|
+
}
|
|
246
|
+
if (!options.variant) {
|
|
247
|
+
this.cache.get('random').set(cacheKey, result);
|
|
248
|
+
}
|
|
249
|
+
return result;
|
|
250
|
+
}
|
|
251
|
+
generateUUID(options) {
|
|
252
|
+
const cacheKey = `uuid-${options.version}`;
|
|
253
|
+
if (!this.cache.has('uuid')) {
|
|
254
|
+
this.cache.set('uuid', new Map());
|
|
255
|
+
}
|
|
256
|
+
const uuidCache = this.cache.get('uuid');
|
|
257
|
+
if (uuidCache.has(cacheKey)) {
|
|
258
|
+
if (options.version === 'v4') {
|
|
259
|
+
return this.generateUUIDv4();
|
|
260
|
+
}
|
|
261
|
+
return uuidCache.get(cacheKey);
|
|
262
|
+
}
|
|
263
|
+
let uuid;
|
|
264
|
+
switch (options.version) {
|
|
265
|
+
case 'v1':
|
|
266
|
+
uuid = this.generateUUIDv1();
|
|
267
|
+
break;
|
|
268
|
+
case 'v2':
|
|
269
|
+
uuid = this.generateUUIDv2();
|
|
270
|
+
break;
|
|
271
|
+
case 'v3':
|
|
272
|
+
uuid = this.generateUUIDv3();
|
|
273
|
+
break;
|
|
274
|
+
case 'v4':
|
|
275
|
+
uuid = this.generateUUIDv4();
|
|
276
|
+
break;
|
|
277
|
+
case 'v5':
|
|
278
|
+
uuid = this.generateUUIDv5();
|
|
279
|
+
break;
|
|
280
|
+
default:
|
|
281
|
+
uuid = this.generateUUIDv4();
|
|
282
|
+
}
|
|
283
|
+
if (options.version === 'v3' || options.version === 'v5') {
|
|
284
|
+
uuidCache.set(cacheKey, uuid);
|
|
285
|
+
}
|
|
286
|
+
return uuid;
|
|
287
|
+
}
|
|
288
|
+
generateUUIDv1() {
|
|
289
|
+
const now = Date.now();
|
|
290
|
+
const hexTime = now.toString(16).padStart(12, '0');
|
|
291
|
+
return `${hexTime.slice(0, 8)}-${hexTime.slice(8, 12)}-1000-8000-${this.getRandomHex(12)}`;
|
|
292
|
+
}
|
|
293
|
+
generateUUIDv2() {
|
|
294
|
+
return this.generateUUIDv1();
|
|
295
|
+
}
|
|
296
|
+
generateUUIDv3() {
|
|
297
|
+
return 'xxxxxxxx-xxxx-3xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
298
|
+
const r = Math.random() * 16 | 0;
|
|
299
|
+
const v = c === 'x' ? r : (r & 0x3 | 0x8);
|
|
300
|
+
return v.toString(16);
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
generateUUIDv4() {
|
|
304
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
305
|
+
const r = crypto.getRandomValues(new Uint8Array(1))[0] % 16 | 0;
|
|
306
|
+
const v = c === 'x' ? r : (r & 0x3 | 0x8);
|
|
307
|
+
return v.toString(16);
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
generateUUIDv5() {
|
|
311
|
+
return 'xxxxxxxx-xxxx-5xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
312
|
+
const r = Math.random() * 16 | 0;
|
|
313
|
+
const v = c === 'x' ? r : (r & 0x3 | 0x8);
|
|
314
|
+
return v.toString(16);
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
getRandomHex(size) {
|
|
318
|
+
const bytes = new Uint8Array(Math.ceil(size / 2));
|
|
319
|
+
crypto.getRandomValues(bytes);
|
|
320
|
+
return Array.from(bytes)
|
|
321
|
+
.map(b => b.toString(16).padStart(2, '0'))
|
|
322
|
+
.join('')
|
|
323
|
+
.slice(0, size);
|
|
324
|
+
}
|
|
325
|
+
getRandomCacheKey(options) {
|
|
326
|
+
return `${options.size}-${options.type}-${options.variant}`;
|
|
327
|
+
}
|
|
328
|
+
clearCache() {
|
|
329
|
+
this.cache.clear();
|
|
330
|
+
}
|
|
331
|
+
static generateId(format, customHandlers = {}) {
|
|
332
|
+
return this.getInstance().generate(format, customHandlers);
|
|
333
|
+
}
|
|
334
|
+
static exposeToGlobal() {
|
|
335
|
+
if (typeof window !== 'undefined') {
|
|
336
|
+
window.IdentifierGenerator = IdentifierGenerator;
|
|
337
|
+
window.IdentifierGeneratorHandlers = IdentifierGeneratorHandlers;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
const IdentifierGeneratorHandlers = {
|
|
342
|
+
timestamp: () => Date.now().toString(),
|
|
343
|
+
date: () => new Date().toISOString().slice(0, 10).replace(/-/g, ''),
|
|
344
|
+
time: () => new Date().toISOString().slice(11, 19).replace(/:/g, ''),
|
|
345
|
+
counter: (() => {
|
|
346
|
+
let count = 0;
|
|
347
|
+
return () => (++count).toString().padStart(6, '0');
|
|
348
|
+
})(),
|
|
349
|
+
env: (envVar) => process.env[envVar] || ''
|
|
350
|
+
};
|
|
351
|
+
if (typeof window !== 'undefined') {
|
|
352
|
+
window.IdentifierGenerator = IdentifierGenerator;
|
|
353
|
+
window.IdentifierGeneratorHandlers = IdentifierGeneratorHandlers;
|
|
354
|
+
}
|
|
355
|
+
var index = {
|
|
356
|
+
IdentifierGenerator,
|
|
357
|
+
IdentifierGeneratorHandlers,
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
export { IdentifierGenerator, IdentifierGeneratorHandlers, index as default };
|
package/index.min.d.ts
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
type RandomType = 'numeric' | 'alphabetic' | 'alphabetic-case' | 'alphanumeric' | 'alphanumeric-case';
|
|
2
|
+
type UUIDVersion = 'v1' | 'v2' | 'v3' | 'v4' | 'v5';
|
|
3
|
+
interface RandomOptions {
|
|
4
|
+
size: number;
|
|
5
|
+
type: RandomType;
|
|
6
|
+
variant: boolean;
|
|
7
|
+
}
|
|
8
|
+
interface UUIDOptions {
|
|
9
|
+
version: UUIDVersion;
|
|
10
|
+
}
|
|
11
|
+
interface TokenDefinition {
|
|
12
|
+
type: 'string' | 'random' | 'uuid' | 'custom';
|
|
13
|
+
value: string | RandomOptions | UUIDOptions | CustomHandler;
|
|
14
|
+
}
|
|
15
|
+
type CustomHandler = () => string;
|
|
16
|
+
declare global {
|
|
17
|
+
interface Window {
|
|
18
|
+
IdentifierGenerator: typeof IdentifierGenerator;
|
|
19
|
+
IdentifierGeneratorHandlers: any;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
declare class IdentifierGenerator {
|
|
23
|
+
private static instance;
|
|
24
|
+
private cache;
|
|
25
|
+
private constructor();
|
|
26
|
+
static getInstance(): IdentifierGenerator;
|
|
27
|
+
/**
|
|
28
|
+
* Parse un format d'identifiant et génère l'identifiant
|
|
29
|
+
*/
|
|
30
|
+
generate(format: string, customHandlers?: Record<string, CustomHandler>): string;
|
|
31
|
+
/**
|
|
32
|
+
* Parse le format en tokens
|
|
33
|
+
*/
|
|
34
|
+
private parseFormat;
|
|
35
|
+
/**
|
|
36
|
+
* Trouve la fin d'un token
|
|
37
|
+
*/
|
|
38
|
+
private findTokenEnd;
|
|
39
|
+
/**
|
|
40
|
+
* Parse un token individuel
|
|
41
|
+
*/
|
|
42
|
+
private parseToken;
|
|
43
|
+
/**
|
|
44
|
+
* Parse les options pour un random string
|
|
45
|
+
*/
|
|
46
|
+
private parseRandomOptions;
|
|
47
|
+
/**
|
|
48
|
+
* Parse les options pour un UUID
|
|
49
|
+
*/
|
|
50
|
+
private parseUUIDOptions;
|
|
51
|
+
/**
|
|
52
|
+
* Parse une chaîne d'options key:value
|
|
53
|
+
*/
|
|
54
|
+
private parseOptions;
|
|
55
|
+
/**
|
|
56
|
+
* Résout un token en sa valeur
|
|
57
|
+
*/
|
|
58
|
+
private resolveToken;
|
|
59
|
+
/**
|
|
60
|
+
* Génère une chaîne aléatoire
|
|
61
|
+
*/
|
|
62
|
+
private generateRandomString;
|
|
63
|
+
/**
|
|
64
|
+
* Génère un UUID selon la version spécifiée
|
|
65
|
+
*/
|
|
66
|
+
private generateUUID;
|
|
67
|
+
private generateUUIDv1;
|
|
68
|
+
private generateUUIDv2;
|
|
69
|
+
private generateUUIDv3;
|
|
70
|
+
private generateUUIDv4;
|
|
71
|
+
private generateUUIDv5;
|
|
72
|
+
private getRandomHex;
|
|
73
|
+
private getRandomCacheKey;
|
|
74
|
+
/**
|
|
75
|
+
* Vide le cache
|
|
76
|
+
*/
|
|
77
|
+
clearCache(): void;
|
|
78
|
+
/**
|
|
79
|
+
* Méthode utilitaire pour générer un identifiant unique
|
|
80
|
+
*/
|
|
81
|
+
static generateId(format: string, customHandlers?: Record<string, CustomHandler>): string;
|
|
82
|
+
static exposeToGlobal(): void;
|
|
83
|
+
}
|
|
84
|
+
declare const IdentifierGeneratorHandlers: {
|
|
85
|
+
timestamp: () => string;
|
|
86
|
+
date: () => string;
|
|
87
|
+
time: () => string;
|
|
88
|
+
counter: () => string;
|
|
89
|
+
env: (envVar: string) => string;
|
|
90
|
+
};
|
|
91
|
+
declare const _default: {
|
|
92
|
+
IdentifierGenerator: typeof IdentifierGenerator;
|
|
93
|
+
IdentifierGeneratorHandlers: {
|
|
94
|
+
timestamp: () => string;
|
|
95
|
+
date: () => string;
|
|
96
|
+
time: () => string;
|
|
97
|
+
counter: () => string;
|
|
98
|
+
env: (envVar: string) => string;
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export { IdentifierGenerator, IdentifierGeneratorHandlers, _default as default };
|
|
103
|
+
export type { CustomHandler, RandomOptions, RandomType, TokenDefinition, UUIDOptions, UUIDVersion };
|
package/index.min.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
class IdentifierGenerator{static instance;cache=new Map;constructor(){}static getInstance(){return IdentifierGenerator.instance||(IdentifierGenerator.instance=new IdentifierGenerator),IdentifierGenerator.instance}generate(e,r={}){return this.parseFormat(e).map(e=>this.resolveToken(e,r)).join("")}parseFormat(e){var r=[];let t=0;for(;t<e.length;){var n=e.indexOf("#",t);if(n>t&&(r.push({type:"string",value:e.substring(t,n)}),t=n),"#"===e[t]){var a=this.findTokenEnd(e,t+1);if(-1===a)throw new Error("Format invalide à la position "+t);var i=e.substring(t+1,a),i=this.parseToken(i);r.push(i),t=a}else if(-1===n){r.push({type:"string",value:e.substring(t)});break}}return r}findTokenEnd(r,t){let n=0,a=!1,i=!1;for(let e=t;e<r.length;e++){var s=r[e];if(i)i=!1;else if("\\"===s)i=!0;else if('"'===s||"'"===s)a=!a;else if(!a)if("{"===s)n++;else if("}"===s){if(0===n)return e;n--}else{if("#"===s&&0===n)return e;if(!1===/[a-zA-Z0-9]/.test(s)&&","!==s&&":"!==s&&"-"!==s&&"_"!==s&&0===n)return e}}return r.length}parseToken(e){if(!1===e.includes("{"))return{type:"string",value:e};var[e,r]=e.split("{",2),r=r.slice(0,-1);if("rand"===e)return{type:"random",value:this.parseRandomOptions(r)};if("uuid"===e)return{type:"uuid",value:this.parseUUIDOptions(r)};if("custom"===e)return{type:"custom",value:r};throw new Error("Type de token non supporté: "+e)}parseRandomOptions(e){const r=8,t="alphanumeric",n=!1;e=this.parseOptions(e);return{size:e.size?parseInt(e.size):r,type:e.type||t,variant:"true"===e.variant||n}}parseUUIDOptions(e){return{version:this.parseOptions(e).version||"v4"}}parseOptions(r){var t={};let n="",a="",i=!1,s="",o=0;for(let e=0;e<r.length;e++){var x=r[e];if('"'===x||"'"===x)i?s===x?i=!1:a+=x:(i=!0,s=x);else{if(!i)if(":"===x){if(0===o){n=a.trim(),a="";continue}}else if("{"===x)o++;else if("}"===x)o--;else if(","===x&&0===o){t[n]=a.trim(),n="",a="";continue}a+=x}}return n&&(t[n]=a.trim()),t}resolveToken(e,r){switch(e.type){case"string":return e.value;case"random":return this.generateRandomString(e.value);case"uuid":return this.generateUUID(e.value);case"custom":var t=e.value.split("}").join("").split("{").join(""),n=Object.keys(r).includes(t);if(n)return r[t]();throw new Error("Handler personnalisé non trouvé: "+t);default:throw new Error("Type de token inconnu: "+e.type)}}generateRandomString(r){var e=this.getRandomCacheKey(r);if(!r.variant){this.cache.has("random")||this.cache.set("random",new Map);var t=this.cache.get("random");if(t.has(e))return t.get(e)}let n="",a="";switch(r.type){case"numeric":n="0123456789";break;case"alphabetic":n="abcdefghijklmnopqrstuvwxyz";break;case"alphabetic-case":n="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";break;case"alphanumeric":n="abcdefghijklmnopqrstuvwxyz0123456789";break;case"alphanumeric-case":n="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"}var i=new Uint32Array(r.size);crypto.getRandomValues(i);for(let e=0;e<r.size;e++)a+=n[i[e]%n.length];return r.variant||this.cache.get("random").set(e,a),a}generateUUID(e){var r="uuid-"+e.version,t=(this.cache.has("uuid")||this.cache.set("uuid",new Map),this.cache.get("uuid"));if(t.has(r))return"v4"===e.version?this.generateUUIDv4():t.get(r);let n;switch(e.version){case"v1":n=this.generateUUIDv1();break;case"v2":n=this.generateUUIDv2();break;case"v3":n=this.generateUUIDv3();break;case"v4":n=this.generateUUIDv4();break;case"v5":n=this.generateUUIDv5();break;default:n=this.generateUUIDv4()}return"v3"!==e.version&&"v5"!==e.version||t.set(r,n),n}generateUUIDv1(){var e=Date.now().toString(16).padStart(12,"0");return`${e.slice(0,8)}-${e.slice(8,12)}-1000-8000-`+this.getRandomHex(12)}generateUUIDv2(){return this.generateUUIDv1()}generateUUIDv3(){return"xxxxxxxx-xxxx-3xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{var r=16*Math.random()|0;return("x"===e?r:3&r|8).toString(16)})}generateUUIDv4(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{var r=crypto.getRandomValues(new Uint8Array(1))[0]%16|0;return("x"===e?r:3&r|8).toString(16)})}generateUUIDv5(){return"xxxxxxxx-xxxx-5xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{var r=16*Math.random()|0;return("x"===e?r:3&r|8).toString(16)})}getRandomHex(e){var r=new Uint8Array(Math.ceil(e/2));return crypto.getRandomValues(r),Array.from(r).map(e=>e.toString(16).padStart(2,"0")).join("").slice(0,e)}getRandomCacheKey(e){return e.size+`-${e.type}-`+e.variant}clearCache(){this.cache.clear()}static generateId(e,r={}){return this.getInstance().generate(e,r)}static exposeToGlobal(){"undefined"!=typeof window&&(window.IdentifierGenerator=IdentifierGenerator,window.IdentifierGeneratorHandlers=IdentifierGeneratorHandlers)}}let IdentifierGeneratorHandlers={timestamp:()=>Date.now().toString(),date:()=>(new Date).toISOString().slice(0,10).replace(/-/g,""),time:()=>(new Date).toISOString().slice(11,19).replace(/:/g,""),counter:(()=>{let e=0;return()=>(++e).toString().padStart(6,"0")})(),env:e=>process.env[e]||""};"undefined"!=typeof window&&(window.IdentifierGenerator=IdentifierGenerator,window.IdentifierGeneratorHandlers=IdentifierGeneratorHandlers);var index={IdentifierGenerator:IdentifierGenerator,IdentifierGeneratorHandlers:IdentifierGeneratorHandlers};export{IdentifierGenerator,IdentifierGeneratorHandlers,index as default};
|
package/package.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@arc-js/id-generator",
|
|
3
|
+
"publishConfig": {
|
|
4
|
+
"access": "public"
|
|
5
|
+
},
|
|
6
|
+
"version": "0.0.1",
|
|
7
|
+
"description": "ID-GENERATOR est une bibliothèque TypeScript robuste pour générer des identifiants uniques avec des formats personnalisables. Elle offre une syntaxe expressive pour créer des identifiants complexes combinant texte, chaînes aléatoires, UUID et fonctions personnalisées.",
|
|
8
|
+
"main": "index.js",
|
|
9
|
+
"keywords": [],
|
|
10
|
+
"author": "INICODE <contact@inicode@gmail.com>",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"scripts": {
|
|
13
|
+
"init": "npm init --scope=@arc-js/id-generator",
|
|
14
|
+
"login": "npm login"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {},
|
|
17
|
+
"dependencies": {}
|
|
18
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES6",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable", "ESNext"],
|
|
6
|
+
"strict": false,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"declaration": false,
|
|
10
|
+
"sourceMap": false,
|
|
11
|
+
"allowSyntheticDefaultImports": true,
|
|
12
|
+
"noEmit": false
|
|
13
|
+
},
|
|
14
|
+
"include": [],
|
|
15
|
+
"exclude": [
|
|
16
|
+
"node_modules",
|
|
17
|
+
"**/*.d.ts"
|
|
18
|
+
]
|
|
19
|
+
}
|