@auralogiclabs/client-uuid-gen 1.0.0

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/dist/index.js ADDED
@@ -0,0 +1,261 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ EnhancedDeviceFingerprint: () => EnhancedDeviceFingerprint,
34
+ getFingerprint: () => getFingerprint
35
+ });
36
+ module.exports = __toCommonJS(index_exports);
37
+
38
+ // src/fingerprint.ts
39
+ var import_crypto_js = __toESM(require("crypto-js"));
40
+
41
+ // src/utils.ts
42
+ var getOS = () => {
43
+ if (typeof navigator === "undefined") return "Unknown OS";
44
+ const ua = navigator.userAgent;
45
+ const iosMatch = /OS (\d+)_/.exec(ua);
46
+ if (/iPhone|iPad|iPod/.test(ua)) return iosMatch ? `iOS ${iosMatch[1]}` : "iOS";
47
+ const androidMatch = /Android (\d+(\.\d+)?)/.exec(ua);
48
+ if (/Android/.test(ua)) return androidMatch ? `Android ${androidMatch[1]}` : "Android";
49
+ const winMatch = /Windows NT (\d+\.\d+)/.exec(ua);
50
+ if (/Windows NT/.test(ua)) return winMatch ? `Windows ${winMatch[1]}` : "Windows";
51
+ const macMatch = /Mac OS X (\d+[_\d]*)/.exec(ua);
52
+ if (/Mac OS X/.test(ua))
53
+ return macMatch ? `macOS ${macMatch[1].replace(/_/g, ".")}` : "macOS";
54
+ if (/Linux/.test(ua)) return "Linux";
55
+ return "Unknown OS";
56
+ };
57
+ var getBrowser = () => {
58
+ if (typeof navigator === "undefined") return "Unknown Browser";
59
+ const ua = navigator.userAgent;
60
+ const edgeMatch = /Edg\/(\d+)/.exec(ua);
61
+ if (/Edg\//.test(ua)) return edgeMatch ? `Edge ${edgeMatch[1]}` : "Edge";
62
+ const chromeMatch = /Chrome\/(\d+)/.exec(ua);
63
+ if (/Chrome\//.test(ua) && !/Edg/.test(ua))
64
+ return chromeMatch ? `Chrome ${chromeMatch[1]}` : "Chrome";
65
+ const safariMatch = /Version\/(\d+)/.exec(ua);
66
+ if (/Safari\//.test(ua) && !/Chrome/.test(ua))
67
+ return safariMatch ? `Safari ${safariMatch[1]}` : "Safari";
68
+ const ffMatch = /Firefox\/(\d+)/.exec(ua);
69
+ if (/Firefox\//.test(ua)) return ffMatch ? `Firefox ${ffMatch[1]}` : "Firefox";
70
+ return "Unknown Browser";
71
+ };
72
+ var getDeviceType = () => {
73
+ if (typeof navigator === "undefined") return "unknown";
74
+ const ua = navigator.userAgent;
75
+ if (/Mobile|Android|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(ua)) return "mobile";
76
+ if (/iPad|Tablet|PlayBook/i.test(ua)) return "tablet";
77
+ if (/Smart-?TV|GoogleTV|AppleTV|HbbTV|NetCast\.TV/i.test(ua)) return "smarttv";
78
+ return "desktop";
79
+ };
80
+
81
+ // src/fingerprint.ts
82
+ var EnhancedDeviceFingerprint = class {
83
+ constructor() {
84
+ this.components = {};
85
+ }
86
+ getBasicFingerprint(isStable = false) {
87
+ if (typeof navigator === "undefined" || typeof window === "undefined" || typeof screen === "undefined") {
88
+ return {};
89
+ }
90
+ const nav = navigator;
91
+ const screenRes = isStable ? `${screen.width}x(Authored)` : `${screen.width}x${screen.height}`;
92
+ return {
93
+ userAgent: navigator.userAgent,
94
+ os: getOS(),
95
+ browser: getBrowser(),
96
+ deviceType: getDeviceType(),
97
+ language: navigator.language || nav.userLanguage || "",
98
+ languages: Array.isArray(navigator.languages) ? navigator.languages.join(",") : "",
99
+ platform: navigator.platform || "",
100
+ hardwareConcurrency: navigator.hardwareConcurrency || 0,
101
+ deviceMemory: nav.deviceMemory || 0,
102
+ screenResolution: screenRes,
103
+ screenColorDepth: screen.colorDepth,
104
+ screenPixelDepth: screen.pixelDepth || screen.colorDepth,
105
+ timezone: Intl.DateTimeFormat().resolvedOptions().timeZone || "",
106
+ timezoneOffset: (/* @__PURE__ */ new Date()).getTimezoneOffset(),
107
+ touchSupport: "ontouchstart" in window || navigator.maxTouchPoints > 0,
108
+ vendor: navigator.vendor || "",
109
+ doNotTrack: navigator.doNotTrack || "unknown"
110
+ };
111
+ }
112
+ getCanvasFingerprint(isStable = false) {
113
+ if (isStable) return "canvas-omitted-for-stability";
114
+ if (typeof document === "undefined") return "canvas-unavailable";
115
+ try {
116
+ const canvas = document.createElement("canvas");
117
+ canvas.width = 240;
118
+ canvas.height = 60;
119
+ const ctx = canvas.getContext("2d");
120
+ if (!ctx) return "canvas-unavailable";
121
+ ctx.textBaseline = "alphabetic";
122
+ ctx.fillStyle = "#f60";
123
+ ctx.fillRect(125, 1, 62, 20);
124
+ ctx.fillStyle = "#069";
125
+ ctx.font = "13pt Arial";
126
+ ctx.fillText("DOOH Device ID", 2, 20);
127
+ ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
128
+ ctx.font = 'bold 18px "Times New Roman"';
129
+ ctx.fillText("Canvas 123", 4, 45);
130
+ return canvas.toDataURL();
131
+ } catch (e) {
132
+ console.warn("Canvas fingerprinting failed:", e);
133
+ return "canvas-unavailable";
134
+ }
135
+ }
136
+ getWebGLFingerprint(isStable = false) {
137
+ if (isStable) return "webgl-omitted-for-stability";
138
+ if (typeof document === "undefined") return "webgl-unavailable";
139
+ try {
140
+ const canvas = document.createElement("canvas");
141
+ const gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
142
+ if (!gl) return "webgl-unsupported";
143
+ const debugInfo = gl.getExtension("WEBGL_debug_renderer_info");
144
+ const vendor = debugInfo ? gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL) : gl.getParameter(gl.VENDOR);
145
+ const renderer = debugInfo ? gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) : gl.getParameter(gl.RENDERER);
146
+ const result = {
147
+ vendor,
148
+ renderer,
149
+ version: gl.getParameter(gl.VERSION),
150
+ shadingLanguageVersion: gl.getParameter(gl.SHADING_LANGUAGE_VERSION),
151
+ maxTextureSize: gl.getParameter(gl.MAX_TEXTURE_SIZE),
152
+ maxViewportDims: gl.getParameter(gl.MAX_VIEWPORT_DIMS) ? gl.getParameter(gl.MAX_VIEWPORT_DIMS).join("x") : ""
153
+ };
154
+ return JSON.stringify(result);
155
+ } catch (e) {
156
+ console.warn("WebGL fingerprinting failed:", e);
157
+ return "webgl-unavailable";
158
+ }
159
+ }
160
+ async getAudioFingerprint(isStable = false) {
161
+ if (isStable) return "audio-omitted-for-stability";
162
+ if (typeof window === "undefined") return "audio-unsupported";
163
+ try {
164
+ const win = window;
165
+ const OfflineAudioContext = window.OfflineAudioContext || win.webkitOfflineAudioContext;
166
+ if (!OfflineAudioContext) return "audio-unsupported";
167
+ const ctx = new OfflineAudioContext(1, 44100, 44100);
168
+ const osc = ctx.createOscillator();
169
+ osc.type = "triangle";
170
+ osc.frequency.value = 1e4;
171
+ const compressor = ctx.createDynamicsCompressor();
172
+ compressor.threshold.value = -50;
173
+ compressor.knee.value = 40;
174
+ compressor.ratio.value = 12;
175
+ compressor.attack.value = 0;
176
+ compressor.release.value = 0.25;
177
+ osc.connect(compressor);
178
+ compressor.connect(ctx.destination);
179
+ osc.start(0);
180
+ osc.stop(1);
181
+ const buffer = await ctx.startRendering();
182
+ const data = buffer.getChannelData(0);
183
+ let sum = 0;
184
+ for (let i = 0; i < data.length; i += 100) sum += Math.abs(data[i]);
185
+ return sum.toString();
186
+ } catch (e) {
187
+ console.warn("Audio fingerprinting failed:", e);
188
+ return "audio-unavailable";
189
+ }
190
+ }
191
+ async getStorageFingerprint() {
192
+ if (typeof navigator === "undefined") return "storage-unsupported";
193
+ try {
194
+ if (!navigator.storage || !navigator.storage.estimate) return "storage-unsupported";
195
+ const estimate = await navigator.storage.estimate();
196
+ const quota = estimate.quota || 0;
197
+ const usage = estimate.usage || 0;
198
+ const usageRatio = quota > 0 ? usage / quota * 100 : 0;
199
+ const bucket = usageRatio < 10 ? "0-10%" : usageRatio < 25 ? "10-25%" : usageRatio < 50 ? "25-50%" : usageRatio < 75 ? "50-75%" : "75-100%";
200
+ const result = {
201
+ quotaMB: Math.floor(quota / (1024 * 1024)),
202
+ usageMB: Math.floor(usage / (1024 * 1024)),
203
+ usageRatio: `${usageRatio.toFixed(2)}%`,
204
+ usageBucket: bucket
205
+ };
206
+ return JSON.stringify(result);
207
+ } catch (e) {
208
+ console.warn("Storage fingerprinting failed:", e);
209
+ return "storage-unavailable";
210
+ }
211
+ }
212
+ hashString(str, algo = "md5") {
213
+ if (algo === "sha256") {
214
+ return import_crypto_js.default.SHA256(str).toString(import_crypto_js.default.enc.Hex);
215
+ }
216
+ return import_crypto_js.default.MD5(str).toString(import_crypto_js.default.enc.Hex);
217
+ }
218
+ async generateFingerprint(options = {}) {
219
+ const { algo = "md5", enableStableFingerprinting = true } = options;
220
+ try {
221
+ const basic = this.getBasicFingerprint(enableStableFingerprinting);
222
+ const [canvas, webgl, audio, storage] = await Promise.all([
223
+ Promise.resolve(this.getCanvasFingerprint(enableStableFingerprinting)),
224
+ Promise.resolve(this.getWebGLFingerprint(enableStableFingerprinting)),
225
+ this.getAudioFingerprint(enableStableFingerprinting),
226
+ this.getStorageFingerprint()
227
+ ]);
228
+ const components = { basic, canvas, webgl, audio, storage };
229
+ this.components = components;
230
+ const combined = JSON.stringify(components);
231
+ return this.hashString(combined, algo);
232
+ } catch (e) {
233
+ console.error("Fingerprint generation failed:", e);
234
+ const minimal = { userAgent: navigator ? navigator.userAgent : "unknown" };
235
+ return this.hashString(JSON.stringify(minimal), algo);
236
+ }
237
+ }
238
+ async get(options = {}) {
239
+ if (typeof navigator === "undefined" || typeof screen === "undefined") {
240
+ return "non-browser-env";
241
+ }
242
+ const { algo = "md5" } = options;
243
+ try {
244
+ return await this.generateFingerprint(options);
245
+ } catch (e) {
246
+ console.error("Failed to get device UUID:", e);
247
+ return this.hashString(`${navigator.userAgent}${screen.width}${screen.height}`, algo);
248
+ }
249
+ }
250
+ };
251
+
252
+ // src/index.ts
253
+ var fingerprinter = new EnhancedDeviceFingerprint();
254
+ var getFingerprint = (options) => {
255
+ return fingerprinter.get(options);
256
+ };
257
+ // Annotate the CommonJS export names for ESM import in node:
258
+ 0 && (module.exports = {
259
+ EnhancedDeviceFingerprint,
260
+ getFingerprint
261
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,223 @@
1
+ // src/fingerprint.ts
2
+ import CryptoJS from "crypto-js";
3
+
4
+ // src/utils.ts
5
+ var getOS = () => {
6
+ if (typeof navigator === "undefined") return "Unknown OS";
7
+ const ua = navigator.userAgent;
8
+ const iosMatch = /OS (\d+)_/.exec(ua);
9
+ if (/iPhone|iPad|iPod/.test(ua)) return iosMatch ? `iOS ${iosMatch[1]}` : "iOS";
10
+ const androidMatch = /Android (\d+(\.\d+)?)/.exec(ua);
11
+ if (/Android/.test(ua)) return androidMatch ? `Android ${androidMatch[1]}` : "Android";
12
+ const winMatch = /Windows NT (\d+\.\d+)/.exec(ua);
13
+ if (/Windows NT/.test(ua)) return winMatch ? `Windows ${winMatch[1]}` : "Windows";
14
+ const macMatch = /Mac OS X (\d+[_\d]*)/.exec(ua);
15
+ if (/Mac OS X/.test(ua))
16
+ return macMatch ? `macOS ${macMatch[1].replace(/_/g, ".")}` : "macOS";
17
+ if (/Linux/.test(ua)) return "Linux";
18
+ return "Unknown OS";
19
+ };
20
+ var getBrowser = () => {
21
+ if (typeof navigator === "undefined") return "Unknown Browser";
22
+ const ua = navigator.userAgent;
23
+ const edgeMatch = /Edg\/(\d+)/.exec(ua);
24
+ if (/Edg\//.test(ua)) return edgeMatch ? `Edge ${edgeMatch[1]}` : "Edge";
25
+ const chromeMatch = /Chrome\/(\d+)/.exec(ua);
26
+ if (/Chrome\//.test(ua) && !/Edg/.test(ua))
27
+ return chromeMatch ? `Chrome ${chromeMatch[1]}` : "Chrome";
28
+ const safariMatch = /Version\/(\d+)/.exec(ua);
29
+ if (/Safari\//.test(ua) && !/Chrome/.test(ua))
30
+ return safariMatch ? `Safari ${safariMatch[1]}` : "Safari";
31
+ const ffMatch = /Firefox\/(\d+)/.exec(ua);
32
+ if (/Firefox\//.test(ua)) return ffMatch ? `Firefox ${ffMatch[1]}` : "Firefox";
33
+ return "Unknown Browser";
34
+ };
35
+ var getDeviceType = () => {
36
+ if (typeof navigator === "undefined") return "unknown";
37
+ const ua = navigator.userAgent;
38
+ if (/Mobile|Android|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(ua)) return "mobile";
39
+ if (/iPad|Tablet|PlayBook/i.test(ua)) return "tablet";
40
+ if (/Smart-?TV|GoogleTV|AppleTV|HbbTV|NetCast\.TV/i.test(ua)) return "smarttv";
41
+ return "desktop";
42
+ };
43
+
44
+ // src/fingerprint.ts
45
+ var EnhancedDeviceFingerprint = class {
46
+ constructor() {
47
+ this.components = {};
48
+ }
49
+ getBasicFingerprint(isStable = false) {
50
+ if (typeof navigator === "undefined" || typeof window === "undefined" || typeof screen === "undefined") {
51
+ return {};
52
+ }
53
+ const nav = navigator;
54
+ const screenRes = isStable ? `${screen.width}x(Authored)` : `${screen.width}x${screen.height}`;
55
+ return {
56
+ userAgent: navigator.userAgent,
57
+ os: getOS(),
58
+ browser: getBrowser(),
59
+ deviceType: getDeviceType(),
60
+ language: navigator.language || nav.userLanguage || "",
61
+ languages: Array.isArray(navigator.languages) ? navigator.languages.join(",") : "",
62
+ platform: navigator.platform || "",
63
+ hardwareConcurrency: navigator.hardwareConcurrency || 0,
64
+ deviceMemory: nav.deviceMemory || 0,
65
+ screenResolution: screenRes,
66
+ screenColorDepth: screen.colorDepth,
67
+ screenPixelDepth: screen.pixelDepth || screen.colorDepth,
68
+ timezone: Intl.DateTimeFormat().resolvedOptions().timeZone || "",
69
+ timezoneOffset: (/* @__PURE__ */ new Date()).getTimezoneOffset(),
70
+ touchSupport: "ontouchstart" in window || navigator.maxTouchPoints > 0,
71
+ vendor: navigator.vendor || "",
72
+ doNotTrack: navigator.doNotTrack || "unknown"
73
+ };
74
+ }
75
+ getCanvasFingerprint(isStable = false) {
76
+ if (isStable) return "canvas-omitted-for-stability";
77
+ if (typeof document === "undefined") return "canvas-unavailable";
78
+ try {
79
+ const canvas = document.createElement("canvas");
80
+ canvas.width = 240;
81
+ canvas.height = 60;
82
+ const ctx = canvas.getContext("2d");
83
+ if (!ctx) return "canvas-unavailable";
84
+ ctx.textBaseline = "alphabetic";
85
+ ctx.fillStyle = "#f60";
86
+ ctx.fillRect(125, 1, 62, 20);
87
+ ctx.fillStyle = "#069";
88
+ ctx.font = "13pt Arial";
89
+ ctx.fillText("DOOH Device ID", 2, 20);
90
+ ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
91
+ ctx.font = 'bold 18px "Times New Roman"';
92
+ ctx.fillText("Canvas 123", 4, 45);
93
+ return canvas.toDataURL();
94
+ } catch (e) {
95
+ console.warn("Canvas fingerprinting failed:", e);
96
+ return "canvas-unavailable";
97
+ }
98
+ }
99
+ getWebGLFingerprint(isStable = false) {
100
+ if (isStable) return "webgl-omitted-for-stability";
101
+ if (typeof document === "undefined") return "webgl-unavailable";
102
+ try {
103
+ const canvas = document.createElement("canvas");
104
+ const gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
105
+ if (!gl) return "webgl-unsupported";
106
+ const debugInfo = gl.getExtension("WEBGL_debug_renderer_info");
107
+ const vendor = debugInfo ? gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL) : gl.getParameter(gl.VENDOR);
108
+ const renderer = debugInfo ? gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) : gl.getParameter(gl.RENDERER);
109
+ const result = {
110
+ vendor,
111
+ renderer,
112
+ version: gl.getParameter(gl.VERSION),
113
+ shadingLanguageVersion: gl.getParameter(gl.SHADING_LANGUAGE_VERSION),
114
+ maxTextureSize: gl.getParameter(gl.MAX_TEXTURE_SIZE),
115
+ maxViewportDims: gl.getParameter(gl.MAX_VIEWPORT_DIMS) ? gl.getParameter(gl.MAX_VIEWPORT_DIMS).join("x") : ""
116
+ };
117
+ return JSON.stringify(result);
118
+ } catch (e) {
119
+ console.warn("WebGL fingerprinting failed:", e);
120
+ return "webgl-unavailable";
121
+ }
122
+ }
123
+ async getAudioFingerprint(isStable = false) {
124
+ if (isStable) return "audio-omitted-for-stability";
125
+ if (typeof window === "undefined") return "audio-unsupported";
126
+ try {
127
+ const win = window;
128
+ const OfflineAudioContext = window.OfflineAudioContext || win.webkitOfflineAudioContext;
129
+ if (!OfflineAudioContext) return "audio-unsupported";
130
+ const ctx = new OfflineAudioContext(1, 44100, 44100);
131
+ const osc = ctx.createOscillator();
132
+ osc.type = "triangle";
133
+ osc.frequency.value = 1e4;
134
+ const compressor = ctx.createDynamicsCompressor();
135
+ compressor.threshold.value = -50;
136
+ compressor.knee.value = 40;
137
+ compressor.ratio.value = 12;
138
+ compressor.attack.value = 0;
139
+ compressor.release.value = 0.25;
140
+ osc.connect(compressor);
141
+ compressor.connect(ctx.destination);
142
+ osc.start(0);
143
+ osc.stop(1);
144
+ const buffer = await ctx.startRendering();
145
+ const data = buffer.getChannelData(0);
146
+ let sum = 0;
147
+ for (let i = 0; i < data.length; i += 100) sum += Math.abs(data[i]);
148
+ return sum.toString();
149
+ } catch (e) {
150
+ console.warn("Audio fingerprinting failed:", e);
151
+ return "audio-unavailable";
152
+ }
153
+ }
154
+ async getStorageFingerprint() {
155
+ if (typeof navigator === "undefined") return "storage-unsupported";
156
+ try {
157
+ if (!navigator.storage || !navigator.storage.estimate) return "storage-unsupported";
158
+ const estimate = await navigator.storage.estimate();
159
+ const quota = estimate.quota || 0;
160
+ const usage = estimate.usage || 0;
161
+ const usageRatio = quota > 0 ? usage / quota * 100 : 0;
162
+ const bucket = usageRatio < 10 ? "0-10%" : usageRatio < 25 ? "10-25%" : usageRatio < 50 ? "25-50%" : usageRatio < 75 ? "50-75%" : "75-100%";
163
+ const result = {
164
+ quotaMB: Math.floor(quota / (1024 * 1024)),
165
+ usageMB: Math.floor(usage / (1024 * 1024)),
166
+ usageRatio: `${usageRatio.toFixed(2)}%`,
167
+ usageBucket: bucket
168
+ };
169
+ return JSON.stringify(result);
170
+ } catch (e) {
171
+ console.warn("Storage fingerprinting failed:", e);
172
+ return "storage-unavailable";
173
+ }
174
+ }
175
+ hashString(str, algo = "md5") {
176
+ if (algo === "sha256") {
177
+ return CryptoJS.SHA256(str).toString(CryptoJS.enc.Hex);
178
+ }
179
+ return CryptoJS.MD5(str).toString(CryptoJS.enc.Hex);
180
+ }
181
+ async generateFingerprint(options = {}) {
182
+ const { algo = "md5", enableStableFingerprinting = true } = options;
183
+ try {
184
+ const basic = this.getBasicFingerprint(enableStableFingerprinting);
185
+ const [canvas, webgl, audio, storage] = await Promise.all([
186
+ Promise.resolve(this.getCanvasFingerprint(enableStableFingerprinting)),
187
+ Promise.resolve(this.getWebGLFingerprint(enableStableFingerprinting)),
188
+ this.getAudioFingerprint(enableStableFingerprinting),
189
+ this.getStorageFingerprint()
190
+ ]);
191
+ const components = { basic, canvas, webgl, audio, storage };
192
+ this.components = components;
193
+ const combined = JSON.stringify(components);
194
+ return this.hashString(combined, algo);
195
+ } catch (e) {
196
+ console.error("Fingerprint generation failed:", e);
197
+ const minimal = { userAgent: navigator ? navigator.userAgent : "unknown" };
198
+ return this.hashString(JSON.stringify(minimal), algo);
199
+ }
200
+ }
201
+ async get(options = {}) {
202
+ if (typeof navigator === "undefined" || typeof screen === "undefined") {
203
+ return "non-browser-env";
204
+ }
205
+ const { algo = "md5" } = options;
206
+ try {
207
+ return await this.generateFingerprint(options);
208
+ } catch (e) {
209
+ console.error("Failed to get device UUID:", e);
210
+ return this.hashString(`${navigator.userAgent}${screen.width}${screen.height}`, algo);
211
+ }
212
+ }
213
+ };
214
+
215
+ // src/index.ts
216
+ var fingerprinter = new EnhancedDeviceFingerprint();
217
+ var getFingerprint = (options) => {
218
+ return fingerprinter.get(options);
219
+ };
220
+ export {
221
+ EnhancedDeviceFingerprint,
222
+ getFingerprint
223
+ };
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@auralogiclabs/client-uuid-gen",
3
+ "version": "1.0.0",
4
+ "description": "A robust device UUID generator with enhanced fingerprinting parameters.",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "scripts": {
15
+ "build": "tsup src/index.ts --format cjs,esm,iife --dts --clean --global-name ClientUUIDGen",
16
+ "test": "vitest run",
17
+ "lint": "eslint src/**",
18
+ "format": "prettier --write src/**"
19
+ },
20
+ "keywords": [
21
+ "uuid",
22
+ "device-fingerprint",
23
+ "unique-id",
24
+ "client-id",
25
+ "browser-fingerprint"
26
+ ],
27
+ "author": "Amartya Mondal <amartya@auralogiclabs.com>",
28
+ "license": "MIT",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/auralogiclabs/client-uuid-gen.git"
32
+ },
33
+ "bugs": {
34
+ "url": "https://github.com/auralogiclabs/client-uuid-gen/issues"
35
+ },
36
+ "homepage": "https://github.com/auralogiclabs/client-uuid-gen#readme",
37
+ "dependencies": {
38
+ "crypto-js": "^4.2.0"
39
+ },
40
+ "devDependencies": {
41
+ "@eslint/js": "^9.0.0",
42
+ "@types/crypto-js": "^4.2.0",
43
+ "@types/node": "^20.0.0",
44
+ "eslint": "^9.0.0",
45
+ "eslint-config-prettier": "^9.0.0",
46
+ "happy-dom": "^20.0.11",
47
+ "prettier": "^3.0.0",
48
+ "tsup": "^8.0.0",
49
+ "typescript": "^5.0.0",
50
+ "typescript-eslint": "^8.0.0",
51
+ "vitest": "^1.0.0"
52
+ }
53
+ }