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 +572 -0
- package/bin/cli.js +13 -0
- package/bin/dev.js +68 -0
- package/index.d.ts +54 -0
- package/index.js +22 -0
- package/lib/apiConfig.js +22 -0
- package/lib/apiConfig.mjs +15 -0
- package/lib/autoTrack.js +56 -0
- package/lib/boot.js +33 -0
- package/lib/client.js +85 -0
- package/lib/device.mjs +67 -0
- package/lib/integrate.js +120 -0
- package/lib/normalizeDomain.js +62 -0
- package/lib/register.js +1 -0
- package/lib/start.js +34 -0
- package/lib/track.mjs +147 -0
- package/lib/vite.d.ts +5 -0
- package/lib/vite.js +28 -0
- package/lib/vite.mjs +10 -0
- package/package.json +64 -0
- package/scripts/postinstall.js +14 -0
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
|
+
};
|