uac-package 1.1.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/README.md ADDED
@@ -0,0 +1,572 @@
1
+ # uac-package
2
+
3
+ **User Activity Control** — zero-config npm package for domain registration, click tracking, device detection, and analytics. Install in any frontend project; data flows to your [UAC backend](https://github.com/sandeep-sana/uac-package) and dashboard.
4
+
5
+ ---
6
+
7
+ ## What it does
8
+
9
+ | Feature | Description |
10
+ | -------- | ------------ |
11
+ | **Domain tracking** | Auto-registers `localhost:5173`, production URLs, etc. when you run `dev` / `start` |
12
+ | **Click tracking** | Every click sent with timestamp, page route, element info, time on page |
13
+ | **Device tracking** | Unique device ID (localStorage) + platform (Windows, Mac, Mobile, Linux) |
14
+ | **Zero config** | `npm install` patches scripts and injects the tracker automatically (Vite projects) |
15
+
16
+ Works with the **UAC Dashboard** for day → platform → device → route → activity drill-down.
17
+
18
+ ---
19
+
20
+ ## Prerequisites
21
+
22
+ 1. **UAC Backend** running (MongoDB + Express API on port 3000 by default)
23
+ 2. **Node.js 18+**
24
+
25
+ ```bash
26
+ # Clone / run your backend (separate repo or monorepo)
27
+ cd uac-backend
28
+ npm install
29
+ npm start
30
+ # → http://localhost:3000
31
+ ```
32
+
33
+ ---
34
+
35
+ ## Quick start (any Vite app — Vue, React, Svelte)
36
+
37
+ ```bash
38
+ npm install uac-package
39
+ npm run dev
40
+ ```
41
+
42
+ On install, the package automatically:
43
+
44
+ - Patches `dev` / `preview` scripts to register domains from Vite output
45
+ - Injects `import 'uac-package/track'` into `src/main.js` or `src/main.ts`
46
+
47
+ No manual code required.
48
+
49
+ ---
50
+
51
+ ## Publish to npm (for maintainers)
52
+
53
+ Follow these steps to publish so **everyone can install** with `npm install uac-package`.
54
+
55
+ ### 1. Create an npm account
56
+
57
+ - Sign up at [https://www.npmjs.com/signup](https://www.npmjs.com/signup)
58
+ - Verify your email
59
+
60
+ ### 2. Log in locally
61
+
62
+ ```bash
63
+ cd uac-package
64
+ npm login
65
+ ```
66
+
67
+ Enter username, password, and OTP if 2FA is enabled.
68
+
69
+ ### 3. Check package name availability
70
+
71
+ ```bash
72
+ npm view uac-package
73
+ ```
74
+
75
+ If the name is taken, use a **scoped name** in `package.json`:
76
+
77
+ ```json
78
+ {
79
+ "name": "@your-username/uac-package",
80
+ "publishConfig": {
81
+ "access": "public"
82
+ }
83
+ }
84
+ ```
85
+
86
+ Users install with:
87
+
88
+ ```bash
89
+ npm install @your-username/uac-package
90
+ ```
91
+
92
+ ### 4. Update version before each release
93
+
94
+ ```bash
95
+ npm version patch # 1.0.0 → 1.0.1
96
+ # or
97
+ npm version minor # 1.0.0 → 1.1.0
98
+ # or
99
+ npm version major # 1.0.0 → 2.0.0
100
+ ```
101
+
102
+ ### 5. Publish
103
+
104
+ ```bash
105
+ npm publish
106
+ # scoped public package:
107
+ npm publish --access public
108
+ ```
109
+
110
+ ### 6. Verify
111
+
112
+ ```bash
113
+ npm view uac-package
114
+ npm install uac-package@latest
115
+ ```
116
+
117
+ ### 7. CI publish (optional — GitHub Actions)
118
+
119
+ ```yaml
120
+ # .github/workflows/publish.yml
121
+ name: Publish npm
122
+ on:
123
+ release:
124
+ types: [published]
125
+ jobs:
126
+ publish:
127
+ runs-on: ubuntu-latest
128
+ steps:
129
+ - uses: actions/checkout@v4
130
+ - uses: actions/setup-node@v4
131
+ with:
132
+ node-version: 20
133
+ registry-url: https://registry.npmjs.org
134
+ - run: npm ci
135
+ - run: npm publish --access public
136
+ env:
137
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
138
+ ```
139
+
140
+ Create an **npm Access Token** (Automation type) at npmjs.com → Account → Access Tokens → add as `NPM_TOKEN` in GitHub Secrets.
141
+
142
+ ---
143
+
144
+ ## Install in any project (users)
145
+
146
+ ```bash
147
+ npm install uac-package
148
+ ```
149
+
150
+ Then run your app as usual. For Vite projects, integration is automatic after install.
151
+
152
+ ---
153
+
154
+ ## Framework guides
155
+
156
+ ### Vue 3 + Vite (recommended — fully automatic)
157
+
158
+ ```bash
159
+ npm install uac-package
160
+ npm run dev
161
+ ```
162
+
163
+ After install, `package.json` scripts look like:
164
+
165
+ ```json
166
+ {
167
+ "scripts": {
168
+ "dev": "node ./node_modules/uac-package/bin/cli.js dev vite"
169
+ }
170
+ }
171
+ ```
172
+
173
+ And `src/main.js` gets:
174
+
175
+ ```js
176
+ import 'uac-package/track' // @uac-auto
177
+ ```
178
+
179
+ ---
180
+
181
+ ### React + Vite
182
+
183
+ Same as Vue — install and run:
184
+
185
+ ```bash
186
+ npm install uac-package
187
+ npm run dev
188
+ ```
189
+
190
+ If entry is `src/main.tsx`, postinstall injects there automatically.
191
+
192
+ **Manual** (if auto-inject did not run):
193
+
194
+ ```tsx
195
+ // src/main.tsx — add at the very top
196
+ import 'uac-package/track'
197
+
198
+ import React from 'react'
199
+ import ReactDOM from 'react-dom/client'
200
+ import App from './App'
201
+
202
+ ReactDOM.createRoot(document.getElementById('root')!).render(<App />)
203
+ ```
204
+
205
+ Patch `package.json` dev script:
206
+
207
+ ```json
208
+ "dev": "node ./node_modules/uac-package/bin/cli.js dev vite"
209
+ ```
210
+
211
+ ---
212
+
213
+ ### Svelte + Vite
214
+
215
+ ```bash
216
+ npm install uac-package
217
+ ```
218
+
219
+ Add to `src/main.js` if not auto-injected:
220
+
221
+ ```js
222
+ import 'uac-package/track'
223
+ ```
224
+
225
+ Use patched dev script (same as Vue).
226
+
227
+ ---
228
+
229
+ ### Next.js (App Router)
230
+
231
+ Next.js does not use Vite by default. Use **manual** setup:
232
+
233
+ **1. Install**
234
+
235
+ ```bash
236
+ npm install uac-package
237
+ ```
238
+
239
+ **2. Client tracker** — create `components/UacTracker.tsx`:
240
+
241
+ ```tsx
242
+ 'use client'
243
+
244
+ import { useEffect } from 'react'
245
+
246
+ export default function UacTracker() {
247
+ useEffect(() => {
248
+ import('uac-package/track')
249
+ }, [])
250
+ return null
251
+ }
252
+ ```
253
+
254
+ **3. Root layout** — `app/layout.tsx`:
255
+
256
+ ```tsx
257
+ import UacTracker from '@/components/UacTracker'
258
+
259
+ export default function RootLayout({ children }) {
260
+ return (
261
+ <html>
262
+ <body>
263
+ <UacTracker />
264
+ {children}
265
+ </body>
266
+ </html>
267
+ )
268
+ }
269
+ ```
270
+
271
+ **4. Domain registration** — register on start or in CI:
272
+
273
+ ```js
274
+ // scripts/register-domain.js
275
+ const uac = require('uac-package')
276
+ uac.init({ url: process.env.NEXT_PUBLIC_APP_URL || 'https://yourapp.com' })
277
+ ```
278
+
279
+ Or set `PORT` / `UAC_API_URL` when running:
280
+
281
+ ```bash
282
+ UAC_API_URL=https://api.yourapp.com node -r uac-package/register server.js
283
+ ```
284
+
285
+ **5. Environment** — `.env.local`:
286
+
287
+ ```env
288
+ NEXT_PUBLIC_UAC_API_URL=http://localhost:3000
289
+ ```
290
+
291
+ > Note: Browser tracker reads `VITE_UAC_*` in Vite apps. For Next.js you may set backend URL via a small wrapper or extend env in your build. Default backend is `http://localhost:3000`.
292
+
293
+ ---
294
+
295
+ ### Angular
296
+
297
+ **1. Install**
298
+
299
+ ```bash
300
+ npm install uac-package
301
+ ```
302
+
303
+ **2. Entry file** — `src/main.ts`:
304
+
305
+ ```ts
306
+ import 'uac-package/track'
307
+
308
+ import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'
309
+ import { AppModule } from './app/app.module'
310
+
311
+ platformBrowserDynamic().bootstrapModule(AppModule)
312
+ ```
313
+
314
+ **3. Dev script** — if using Vite-based Angular or custom server, patch `package.json`:
315
+
316
+ ```json
317
+ "start": "node ./node_modules/uac-package/bin/cli.js dev ng serve"
318
+ ```
319
+
320
+ For domain registration with `ng serve`, use the Vite plugin alternative or manual `init`:
321
+
322
+ ```js
323
+ const uac = require('uac-package')
324
+ uac.init({ port: 4200, host: 'localhost' })
325
+ ```
326
+
327
+ ---
328
+
329
+ ### Nuxt 3
330
+
331
+ **1. Install**
332
+
333
+ ```bash
334
+ npm install uac-package
335
+ ```
336
+
337
+ **2. Plugin** — `plugins/uac.client.ts`:
338
+
339
+ ```ts
340
+ import 'uac-package/track'
341
+
342
+ export default defineNuxtPlugin(() => {})
343
+ ```
344
+
345
+ **3. Domain** — register in `nuxt.config` hook or on deploy:
346
+
347
+ ```js
348
+ // server/plugins/uac.ts or build script
349
+ import uac from 'uac-package'
350
+ await uac.init({ url: process.env.NUXT_PUBLIC_SITE_URL })
351
+ ```
352
+
353
+ ---
354
+
355
+ ### Plain HTML / CDN (no bundler)
356
+
357
+ Host `track` via your bundler or copy approach — recommended to use npm + Vite/webpack. Minimal ESM setup:
358
+
359
+ ```html
360
+ <!DOCTYPE html>
361
+ <html>
362
+ <head>
363
+ <title>My App</title>
364
+ </head>
365
+ <body>
366
+ <button id="demo">Click me</button>
367
+ <script type="module">
368
+ import 'uac-package/track'
369
+ </script>
370
+ </body>
371
+ </html>
372
+ ```
373
+
374
+ Serve with Vite and use patched dev script for domain registration.
375
+
376
+ ---
377
+
378
+ ### Node.js / Express API
379
+
380
+ Register domain when server starts:
381
+
382
+ **Option A — require hook**
383
+
384
+ ```json
385
+ {
386
+ "scripts": {
387
+ "start": "node -r uac-package/register index.js"
388
+ }
389
+ }
390
+ ```
391
+
392
+ **Option B — programmatic**
393
+
394
+ ```js
395
+ const uac = require('uac-package')
396
+
397
+ const PORT = process.env.PORT || 4000
398
+
399
+ uac.init({ port: PORT, host: 'localhost' }).then(() => {
400
+ app.listen(PORT, () => console.log(`Listening on ${PORT}`))
401
+ })
402
+ ```
403
+
404
+ > Click tracking is browser-only. Node apps get **domain registration** only unless you call the backend API yourself.
405
+
406
+ ---
407
+
408
+ ### Vite plugin (manual alternative)
409
+
410
+ If you prefer not to patch `dev` script:
411
+
412
+ ```js
413
+ // vite.config.js
414
+ import { defineConfig } from 'vite'
415
+ import vue from '@vitejs/plugin-vue'
416
+ import uac from 'uac-package/vite'
417
+
418
+ export default defineConfig({
419
+ plugins: [vue(), uac()],
420
+ })
421
+ ```
422
+
423
+ Still add `import 'uac-package/track'` in your entry file for clicks.
424
+
425
+ ---
426
+
427
+ ## Environment variables
428
+
429
+ ### Server / CLI (domain registration)
430
+
431
+ | Variable | Default | Description |
432
+ | -------- | ------- | ----------- |
433
+ | `UAC_API_URL` | `https://uac-backend.clay.in` | UAC backend base URL |
434
+ | `UAC_AUTO_TRACK` | `true` | Set `false` to disable auto domain registration |
435
+ | `PORT` | — | App port (used to build domain) |
436
+ | `HOST` | `localhost` | App host |
437
+
438
+ ### Browser (click tracking — Vite projects)
439
+
440
+ | Variable | Default | Description |
441
+ | -------- | ------- | ----------- |
442
+ | `VITE_UAC_API_URL` | `https://uac-backend.clay.in` | Backend URL in the browser |
443
+ | `VITE_UAC_AUTO_TRACK` | `true` | Set `false` to disable click tracking |
444
+
445
+ Example `.env`:
446
+
447
+ ```env
448
+ VITE_UAC_API_URL=http://localhost:3000
449
+ UAC_API_URL=http://localhost:3000
450
+ ```
451
+
452
+ Production:
453
+
454
+ ```env
455
+ VITE_UAC_API_URL=https://api.yourcompany.com
456
+ ```
457
+
458
+ ---
459
+
460
+ ## What gets tracked on each click
461
+
462
+ ```json
463
+ {
464
+ "domain": "localhost:5173",
465
+ "deviceId": "uuid-from-localStorage",
466
+ "device": {
467
+ "deviceType": "windows",
468
+ "deviceOperatingSystem": "Windows"
469
+ },
470
+ "name": "click:button",
471
+ "description": "Clicked 3 times | button#home-increment | /products",
472
+ "spentTime": 5200,
473
+ "clickedAt": "2026-06-26T13:03:24.000Z"
474
+ }
475
+ ```
476
+
477
+ - **domain** — `window.location.host`
478
+ - **route** — parsed from `description` (last segment, e.g. `/products`)
479
+ - **deviceId** — persistent per browser
480
+ - **platform** — Windows / Mac / Mobile / Linux
481
+
482
+ ---
483
+
484
+ ## UAC Dashboard
485
+
486
+ Run `uac-frontend` (separate app) to view analytics:
487
+
488
+ 1. **Daily Overview** — unique users per day
489
+ 2. **Day tab** — platform chart (Windows, Mac, Mobile…)
490
+ 3. **Platform tab** — devices + page routes chart
491
+ 4. **Device tab** — routes chart + user flow log
492
+ 5. **Route tab** — all click activities on that page
493
+
494
+ ---
495
+
496
+ ## Manual API
497
+
498
+ ```js
499
+ const uac = require('uac-package')
500
+
501
+ // Register domain
502
+ await uac.init({ port: 5173, host: 'localhost' })
503
+ await uac.init({ url: 'https://myapp.com' })
504
+
505
+ // Run integration manually (patch scripts + inject tracker)
506
+ uac.integrate(process.cwd())
507
+
508
+ // Vite plugin
509
+ import uacVite from 'uac-package/vite'
510
+ ```
511
+
512
+ | Export | Description |
513
+ | ------ | ----------- |
514
+ | `init()` | Register domain with backend |
515
+ | `registerDomain()` | Register by domain string |
516
+ | `autoTrack()` | Auto-register from env/port |
517
+ | `integrate()` | Patch project scripts + inject tracker |
518
+ | `vite()` | Vite plugin for domain on server start |
519
+ | `uac-package/track` | Browser click + device tracker (ESM) |
520
+
521
+ ---
522
+
523
+ ## Disable tracking
524
+
525
+ ```bash
526
+ # Disable domain auto-track (CLI)
527
+ UAC_AUTO_TRACK=false npm run dev
528
+
529
+ # Disable click tracking (browser — Vite)
530
+ VITE_UAC_AUTO_TRACK=false npm run dev
531
+ ```
532
+
533
+ ---
534
+
535
+ ## Troubleshooting
536
+
537
+ | Problem | Fix |
538
+ | ------- | --- |
539
+ | Clicks not saved | Ensure backend is running at `UAC_API_URL` / `VITE_UAC_API_URL` |
540
+ | Domain not registered | Check dev script includes `uac-package/bin/cli.js dev` |
541
+ | No tracker in app | Add `import 'uac-package/track'` to entry file |
542
+ | CORS errors | Configure CORS on backend for your frontend origin |
543
+ | `409 Domain exists` | Normal — domain already registered |
544
+ | Windows script fails | Use `node ./node_modules/uac-package/bin/cli.js dev vite` |
545
+
546
+ Re-run integration manually:
547
+
548
+ ```js
549
+ require('uac-package').integrate(process.cwd())
550
+ ```
551
+
552
+ ---
553
+
554
+ ## Project structure (monorepo)
555
+
556
+ ```
557
+ UAC/
558
+ ├── uac-backend/ # Express + MongoDB API
559
+ ├── uac-package/ # This npm package ← publish this
560
+ ├── uac-frontend/ # Analytics dashboard
561
+ └── vue-project/ # Example test app
562
+ ```
563
+
564
+ ---
565
+
566
+ ## License
567
+
568
+ MIT
569
+
570
+ ## Repository
571
+
572
+ [https://github.com/sandeep-sana/uac-package](https://github.com/sandeep-sana/uac-package)
package/bin/cli.js ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { run } = require('./dev');
4
+
5
+ const [, , command, ...args] = process.argv;
6
+
7
+ if (command === 'dev') {
8
+ run(args);
9
+ } else {
10
+ console.log('Usage: uac-package dev <command> [args...]');
11
+ console.log('Example: uac-package dev vite');
12
+ process.exit(command ? 1 : 0);
13
+ }
package/bin/dev.js ADDED
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { spawn } = require('child_process');
4
+ const { autoTrack } = require('../lib/autoTrack');
5
+
6
+ const URL_PATTERN = /(?:Local|Network):\s+(https?:\/\/[^\s]+)/gi;
7
+ const trackedUrls = new Set();
8
+
9
+ function trackFromOutput(text) {
10
+ URL_PATTERN.lastIndex = 0;
11
+ let match;
12
+
13
+ while ((match = URL_PATTERN.exec(text)) !== null) {
14
+ const url = match[1];
15
+
16
+ if (trackedUrls.has(url)) {
17
+ continue;
18
+ }
19
+
20
+ trackedUrls.add(url);
21
+
22
+ try {
23
+ const parsed = new URL(url);
24
+ autoTrack({
25
+ host: parsed.hostname,
26
+ port: parsed.port || (parsed.protocol === 'https:' ? 443 : 80),
27
+ protocol: parsed.protocol.replace(':', ''),
28
+ });
29
+ } catch {
30
+ autoTrack({ url });
31
+ }
32
+ }
33
+ }
34
+
35
+ function run(args) {
36
+ if (!args.length) {
37
+ console.error('[UAC] Usage: uac-package dev <command> [args...]');
38
+ process.exit(1);
39
+ }
40
+
41
+ const [command, ...commandArgs] = args;
42
+ const child = spawn(command, commandArgs, {
43
+ stdio: ['inherit', 'pipe', 'pipe'],
44
+ shell: true,
45
+ cwd: process.cwd(),
46
+ env: process.env,
47
+ });
48
+
49
+ child.stdout.on('data', (chunk) => {
50
+ process.stdout.write(chunk);
51
+ trackFromOutput(chunk.toString());
52
+ });
53
+
54
+ child.stderr.on('data', (chunk) => {
55
+ process.stderr.write(chunk);
56
+ trackFromOutput(chunk.toString());
57
+ });
58
+
59
+ child.on('exit', (code) => {
60
+ process.exit(code ?? 0);
61
+ });
62
+ }
63
+
64
+ module.exports = { run };
65
+
66
+ if (require.main === module) {
67
+ run(process.argv.slice(2));
68
+ }
package/index.d.ts ADDED
@@ -0,0 +1,54 @@
1
+ export interface RegisterResult {
2
+ created: boolean;
3
+ name: string;
4
+ domain?: {
5
+ _id: string;
6
+ name: string;
7
+ createdAt: string;
8
+ updatedAt: string;
9
+ };
10
+ message?: string;
11
+ }
12
+
13
+ export interface UacOptions {
14
+ apiUrl?: string;
15
+ url?: string;
16
+ domain?: string;
17
+ name?: string;
18
+ host?: string;
19
+ port?: number | string;
20
+ protocol?: string;
21
+ headers?: Record<string, string>;
22
+ }
23
+
24
+ export interface BootResult {
25
+ port: number | string;
26
+ appUrl: string;
27
+ domain: string;
28
+ registration: RegisterResult;
29
+ apiUrl: string;
30
+ }
31
+
32
+ export interface StartResult extends BootResult {
33
+ server: import('http').Server;
34
+ }
35
+
36
+ export class UacError extends Error {
37
+ status?: number;
38
+ code?: string;
39
+ }
40
+
41
+ export function normalizeDomain(input: string): string;
42
+ export function isValidDomain(name: string): boolean;
43
+ export function resolveAppUrl(options?: UacOptions): string;
44
+ export function getApiUrl(options?: UacOptions): string;
45
+ export function registerDomain(
46
+ input: string,
47
+ options?: UacOptions
48
+ ): Promise<RegisterResult>;
49
+ export function init(input?: string | UacOptions, options?: UacOptions): Promise<RegisterResult>;
50
+ export function boot(options?: UacOptions): Promise<BootResult>;
51
+ export function start(options?: UacOptions): Promise<StartResult>;
52
+ export function autoTrack(options?: UacOptions): Promise<RegisterResult | null>;
53
+ export function integrate(projectRoot: string): boolean;
54
+ export function vite(options?: UacOptions): import('vite').Plugin;
package/index.js ADDED
@@ -0,0 +1,22 @@
1
+ const { normalizeDomain, isValidDomain, resolveAppUrl } = require('./lib/normalizeDomain');
2
+ const { UacError, getApiUrl, registerDomain, init } = require('./lib/client');
3
+ const { boot } = require('./lib/boot');
4
+ const { start } = require('./lib/start');
5
+ const { autoTrack } = require('./lib/autoTrack');
6
+ const { vitePlugin } = require('./lib/vite');
7
+ const { integrate } = require('./lib/integrate');
8
+
9
+ module.exports = {
10
+ UacError,
11
+ normalizeDomain,
12
+ isValidDomain,
13
+ resolveAppUrl,
14
+ getApiUrl,
15
+ registerDomain,
16
+ init,
17
+ boot,
18
+ start,
19
+ autoTrack,
20
+ integrate,
21
+ vite: vitePlugin,
22
+ };